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:
@@ -2530,6 +2530,7 @@ phutil_register_library_map(array(
|
|||||||
'PhabricatorDashboardProfileController' => 'applications/dashboard/controller/PhabricatorDashboardProfileController.php',
|
'PhabricatorDashboardProfileController' => 'applications/dashboard/controller/PhabricatorDashboardProfileController.php',
|
||||||
'PhabricatorDashboardProfileMenuItem' => 'applications/search/menuitem/PhabricatorDashboardProfileMenuItem.php',
|
'PhabricatorDashboardProfileMenuItem' => 'applications/search/menuitem/PhabricatorDashboardProfileMenuItem.php',
|
||||||
'PhabricatorDashboardQuery' => 'applications/dashboard/query/PhabricatorDashboardQuery.php',
|
'PhabricatorDashboardQuery' => 'applications/dashboard/query/PhabricatorDashboardQuery.php',
|
||||||
|
'PhabricatorDashboardQueryPanelInstallController' => 'applications/dashboard/controller/PhabricatorDashboardQueryPanelInstallController.php',
|
||||||
'PhabricatorDashboardQueryPanelType' => 'applications/dashboard/paneltype/PhabricatorDashboardQueryPanelType.php',
|
'PhabricatorDashboardQueryPanelType' => 'applications/dashboard/paneltype/PhabricatorDashboardQueryPanelType.php',
|
||||||
'PhabricatorDashboardRemarkupRule' => 'applications/dashboard/remarkup/PhabricatorDashboardRemarkupRule.php',
|
'PhabricatorDashboardRemarkupRule' => 'applications/dashboard/remarkup/PhabricatorDashboardRemarkupRule.php',
|
||||||
'PhabricatorDashboardRemovePanelController' => 'applications/dashboard/controller/PhabricatorDashboardRemovePanelController.php',
|
'PhabricatorDashboardRemovePanelController' => 'applications/dashboard/controller/PhabricatorDashboardRemovePanelController.php',
|
||||||
@@ -7610,6 +7611,7 @@ phutil_register_library_map(array(
|
|||||||
'PhabricatorDashboardProfileController' => 'PhabricatorController',
|
'PhabricatorDashboardProfileController' => 'PhabricatorController',
|
||||||
'PhabricatorDashboardProfileMenuItem' => 'PhabricatorProfileMenuItem',
|
'PhabricatorDashboardProfileMenuItem' => 'PhabricatorProfileMenuItem',
|
||||||
'PhabricatorDashboardQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
'PhabricatorDashboardQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
|
'PhabricatorDashboardQueryPanelInstallController' => 'PhabricatorDashboardController',
|
||||||
'PhabricatorDashboardQueryPanelType' => 'PhabricatorDashboardPanelType',
|
'PhabricatorDashboardQueryPanelType' => 'PhabricatorDashboardPanelType',
|
||||||
'PhabricatorDashboardRemarkupRule' => 'PhabricatorObjectRemarkupRule',
|
'PhabricatorDashboardRemarkupRule' => 'PhabricatorObjectRemarkupRule',
|
||||||
'PhabricatorDashboardRemovePanelController' => 'PhabricatorDashboardController',
|
'PhabricatorDashboardRemovePanelController' => 'PhabricatorDashboardController',
|
||||||
|
|||||||
@@ -36,6 +36,8 @@ final class PhabricatorDashboardApplication extends PhabricatorApplication {
|
|||||||
'removepanel/(?P<id>\d+)/'
|
'removepanel/(?P<id>\d+)/'
|
||||||
=> 'PhabricatorDashboardRemovePanelController',
|
=> 'PhabricatorDashboardRemovePanelController',
|
||||||
'panel/' => array(
|
'panel/' => array(
|
||||||
|
'install/(?P<engineKey>[^/]+)/(?:(?P<queryKey>[^/]+)/)?' =>
|
||||||
|
'PhabricatorDashboardQueryPanelInstallController',
|
||||||
'(?:query/(?P<queryKey>[^/]+)/)?'
|
'(?:query/(?P<queryKey>[^/]+)/)?'
|
||||||
=> 'PhabricatorDashboardPanelListController',
|
=> 'PhabricatorDashboardPanelListController',
|
||||||
'create/' => 'PhabricatorDashboardPanelEditController',
|
'create/' => 'PhabricatorDashboardPanelEditController',
|
||||||
|
|||||||
@@ -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'));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -555,8 +555,9 @@ final class PhabricatorApplicationSearchController
|
|||||||
->setTag('a')
|
->setTag('a')
|
||||||
->setHref('#')
|
->setHref('#')
|
||||||
->setText(pht('Use Results...'))
|
->setText(pht('Use Results...'))
|
||||||
->setIcon('fa-road')
|
->setIcon('fa-bars')
|
||||||
->setDropdownMenu($action_list);
|
->setDropdownMenu($action_list)
|
||||||
|
->addClass('dropdown');
|
||||||
}
|
}
|
||||||
|
|
||||||
private function newOverflowingView() {
|
private function newOverflowingView() {
|
||||||
@@ -600,9 +601,32 @@ final class PhabricatorApplicationSearchController
|
|||||||
|
|
||||||
private function newBuiltinUseActions() {
|
private function newBuiltinUseActions() {
|
||||||
$actions = array();
|
$actions = array();
|
||||||
|
$request = $this->getRequest();
|
||||||
|
$viewer = $request->getUser();
|
||||||
|
|
||||||
$is_dev = PhabricatorEnv::getEnvConfig('phabricator.developer-mode');
|
$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) {
|
if ($is_dev) {
|
||||||
$engine = $this->getSearchEngine();
|
$engine = $this->getSearchEngine();
|
||||||
$nux_uri = $engine->getQueryBaseURI();
|
$nux_uri = $engine->getQueryBaseURI();
|
||||||
@@ -610,8 +634,8 @@ final class PhabricatorApplicationSearchController
|
|||||||
->setQueryParam('nux', true);
|
->setQueryParam('nux', true);
|
||||||
|
|
||||||
$actions[] = id(new PhabricatorActionView())
|
$actions[] = id(new PhabricatorActionView())
|
||||||
->setIcon('fa-bug')
|
->setIcon('fa-user-plus')
|
||||||
->setName(pht('Developer: Show New User State'))
|
->setName(pht('DEV: New User State'))
|
||||||
->setHref($nux_uri);
|
->setHref($nux_uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -620,8 +644,8 @@ final class PhabricatorApplicationSearchController
|
|||||||
->setQueryParam('overheated', true);
|
->setQueryParam('overheated', true);
|
||||||
|
|
||||||
$actions[] = id(new PhabricatorActionView())
|
$actions[] = id(new PhabricatorActionView())
|
||||||
->setIcon('fa-bug')
|
->setIcon('fa-fire')
|
||||||
->setName(pht('Developer: Show Overheated State'))
|
->setName(pht('DEV: Overheated State'))
|
||||||
->setHref($overheated_uri);
|
->setHref($overheated_uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user