1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2025-01-11 07:11:04 +01:00

Add an action to adding Panels from ApplicationSearch

Summary: Ref T5307. This adds an additional action to Use Results for creating a panel from the query.

Test Plan:
Navigate to Maniphest, select dropdown for Use Results. Try any of the following:

 - Try to set a panel without a name (fail)
 - Muck up query or engine (fail)
 - Set a fake Dashboard ID (fail)

Give panel a name and select a dashboard I have edit permissions to, get taken to dashboard.

Reviewers: epriestley

Subscribers: Korvin

Maniphest Tasks: T5307

Differential Revision: https://secure.phabricator.com/D17516
This commit is contained in:
Chad Little 2017-03-20 14:15:16 -07:00
parent 85d9a009a9
commit 2921bad1ff
4 changed files with 193 additions and 6 deletions

View file

@ -2530,6 +2530,7 @@ phutil_register_library_map(array(
'PhabricatorDashboardProfileController' => 'applications/dashboard/controller/PhabricatorDashboardProfileController.php',
'PhabricatorDashboardProfileMenuItem' => 'applications/search/menuitem/PhabricatorDashboardProfileMenuItem.php',
'PhabricatorDashboardQuery' => 'applications/dashboard/query/PhabricatorDashboardQuery.php',
'PhabricatorDashboardQueryPanelInstallController' => 'applications/dashboard/controller/PhabricatorDashboardQueryPanelInstallController.php',
'PhabricatorDashboardQueryPanelType' => 'applications/dashboard/paneltype/PhabricatorDashboardQueryPanelType.php',
'PhabricatorDashboardRemarkupRule' => 'applications/dashboard/remarkup/PhabricatorDashboardRemarkupRule.php',
'PhabricatorDashboardRemovePanelController' => 'applications/dashboard/controller/PhabricatorDashboardRemovePanelController.php',
@ -7610,6 +7611,7 @@ phutil_register_library_map(array(
'PhabricatorDashboardProfileController' => 'PhabricatorController',
'PhabricatorDashboardProfileMenuItem' => 'PhabricatorProfileMenuItem',
'PhabricatorDashboardQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorDashboardQueryPanelInstallController' => 'PhabricatorDashboardController',
'PhabricatorDashboardQueryPanelType' => 'PhabricatorDashboardPanelType',
'PhabricatorDashboardRemarkupRule' => 'PhabricatorObjectRemarkupRule',
'PhabricatorDashboardRemovePanelController' => 'PhabricatorDashboardController',

View file

@ -36,6 +36,8 @@ final class PhabricatorDashboardApplication extends PhabricatorApplication {
'removepanel/(?P<id>\d+)/'
=> 'PhabricatorDashboardRemovePanelController',
'panel/' => array(
'install/(?P<engineKey>[^/]+)/(?:(?P<queryKey>[^/]+)/)?' =>
'PhabricatorDashboardQueryPanelInstallController',
'(?:query/(?P<queryKey>[^/]+)/)?'
=> 'PhabricatorDashboardPanelListController',
'create/' => 'PhabricatorDashboardPanelEditController',

View file

@ -0,0 +1,159 @@
<?php
final class PhabricatorDashboardQueryPanelInstallController
extends PhabricatorDashboardController {
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$v_dashboard = null;
$v_name = null;
$v_column = 0;
$v_engine = $request->getURIData('engineKey');
$v_query = $request->getURIData('queryKey');
// Validate Engines
$engines = PhabricatorApplicationSearchEngine::getAllEngines();
foreach ($engines as $name => $engine) {
if (!$engine->canUseInPanelContext()) {
unset($engines[$name]);
}
}
if (!in_array($v_engine, array_keys($engines))) {
return new Aphront404Response();
}
// Validate Queries
$engine = $engines[$v_engine];
$engine->setViewer($viewer);
$queries = array_keys($engine->loadEnabledNamedQueries());
if (!in_array($v_query, $queries)) {
return new Aphront404Response();
}
$errors = array();
if ($request->isFormPost()) {
$v_dashboard = $request->getInt('dashboardID');
$v_name = $request->getStr('name');
if (!$v_name) {
$errors[] = pht('You must provide a name for this panel.');
}
$dashboard = id(new PhabricatorDashboardQuery())
->setViewer($viewer)
->withIDs(array($v_dashboard))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
if (!$dashboard) {
$errors[] = pht('Please select a valid dashboard.');
}
if (!$errors) {
$redirect_uri = "/dashboard/arrange/{$v_dashboard}/";
$panel_type = id(new PhabricatorDashboardQueryPanelType())
->getPanelTypeKey();
$panel = PhabricatorDashboardPanel::initializeNewPanel($viewer);
$panel->setPanelType($panel_type);
$field_list = PhabricatorCustomField::getObjectFields(
$panel,
PhabricatorCustomField::ROLE_EDIT);
$field_list
->setViewer($viewer)
->readFieldsFromStorage($panel);
$panel->requireImplementation()->initializeFieldsFromRequest(
$panel,
$field_list,
$request);
$xactions = array();
$xactions[] = id(new PhabricatorDashboardPanelTransaction())
->setTransactionType(PhabricatorDashboardPanelTransaction::TYPE_NAME)
->setNewValue($v_name);
$xactions[] = id(new PhabricatorDashboardPanelTransaction())
->setTransactionType(PhabricatorTransactions::TYPE_CUSTOMFIELD)
->setMetadataValue('customfield:key', 'std:dashboard:core:class')
->setOldValue(null)
->setNewValue($v_engine);
$xactions[] = id(new PhabricatorDashboardPanelTransaction())
->setTransactionType(PhabricatorTransactions::TYPE_CUSTOMFIELD)
->setMetadataValue('customfield:key', 'std:dashboard:core:key')
->setOldValue(null)
->setNewValue($v_query);
$editor = id(new PhabricatorDashboardPanelTransactionEditor())
->setActor($viewer)
->setContinueOnNoEffect(true)
->setContentSourceFromRequest($request)
->applyTransactions($panel, $xactions);
PhabricatorDashboardTransactionEditor::addPanelToDashboard(
$viewer,
PhabricatorContentSource::newFromRequest($request),
$panel,
$dashboard,
$request->getInt('column', 0));
return id(new AphrontRedirectResponse())->setURI($redirect_uri);
}
}
// Make this a select for now, as we don't expect someone to have
// edit access to a vast number of dashboards.
// Can add optiongroup if needed down the road.
$dashboards = id(new PhabricatorDashboardQuery())
->setViewer($viewer)
->withStatuses(array(
PhabricatorDashboard::STATUS_ACTIVE,
))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->execute();
$options = mpull($dashboards, 'getName', 'getID');
asort($options);
$redirect_uri = '#'; // ??
$form = id(new AphrontFormView())
->setUser($viewer)
->addHiddenInput('engine', $v_engine)
->addHiddenInput('query', $v_query)
->addHiddenInput('column', $v_column)
->appendChild(
id(new AphrontFormTextControl())
->setLabel(pht('Name'))
->setName('name')
->setValue($v_name))
->appendChild(
id(new AphrontFormSelectControl())
->setUser($this->getViewer())
->setValue($v_dashboard)
->setName('dashboardID')
->setOptions($options)
->setLabel(pht('Dashboard')));
return $this->newDialog()
->setTitle(pht('Add Panel to Dashboard'))
->setErrors($errors)
->setWidth(AphrontDialogView::WIDTH_FORM)
->appendChild($form->buildLayoutView())
->addCancelButton($redirect_uri)
->addSubmitButton(pht('Add Panel'));
}
}

View file

@ -555,8 +555,9 @@ final class PhabricatorApplicationSearchController
->setTag('a')
->setHref('#')
->setText(pht('Use Results...'))
->setIcon('fa-road')
->setDropdownMenu($action_list);
->setIcon('fa-bars')
->setDropdownMenu($action_list)
->addClass('dropdown');
}
private function newOverflowingView() {
@ -600,9 +601,32 @@ final class PhabricatorApplicationSearchController
private function newBuiltinUseActions() {
$actions = array();
$request = $this->getRequest();
$viewer = $request->getUser();
$is_dev = PhabricatorEnv::getEnvConfig('phabricator.developer-mode');
$engine = $this->getSearchEngine();
$engine_class = get_class($engine);
$query_key = $this->getQueryKey();
if (!$query_key) {
$query_key = head_key($engine->loadEnabledNamedQueries());
}
$can_use = $engine->canUseInPanelContext();
$is_installed = PhabricatorApplication::isClassInstalledForViewer(
'PhabricatorDashboardApplication',
$viewer);
if ($can_use && $is_installed) {
$dashboard_uri = '/dashboard/install/';
$actions[] = id(new PhabricatorActionView())
->setIcon('fa-dashboard')
->setName(pht('Add to Dasbhoard'))
->setWorkflow(true)
->setHref("/dashboard/panel/install/{$engine_class}/{$query_key}/");
}
if ($is_dev) {
$engine = $this->getSearchEngine();
$nux_uri = $engine->getQueryBaseURI();
@ -610,8 +634,8 @@ final class PhabricatorApplicationSearchController
->setQueryParam('nux', true);
$actions[] = id(new PhabricatorActionView())
->setIcon('fa-bug')
->setName(pht('Developer: Show New User State'))
->setIcon('fa-user-plus')
->setName(pht('DEV: New User State'))
->setHref($nux_uri);
}
@ -620,8 +644,8 @@ final class PhabricatorApplicationSearchController
->setQueryParam('overheated', true);
$actions[] = id(new PhabricatorActionView())
->setIcon('fa-bug')
->setName(pht('Developer: Show Overheated State'))
->setIcon('fa-fire')
->setName(pht('DEV: Overheated State'))
->setHref($overheated_uri);
}