@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+193 -6
+2
src/__phutil_library_map__.php
··· 2530 2530 'PhabricatorDashboardProfileController' => 'applications/dashboard/controller/PhabricatorDashboardProfileController.php', 2531 2531 'PhabricatorDashboardProfileMenuItem' => 'applications/search/menuitem/PhabricatorDashboardProfileMenuItem.php', 2532 2532 'PhabricatorDashboardQuery' => 'applications/dashboard/query/PhabricatorDashboardQuery.php', 2533 + 'PhabricatorDashboardQueryPanelInstallController' => 'applications/dashboard/controller/PhabricatorDashboardQueryPanelInstallController.php', 2533 2534 'PhabricatorDashboardQueryPanelType' => 'applications/dashboard/paneltype/PhabricatorDashboardQueryPanelType.php', 2534 2535 'PhabricatorDashboardRemarkupRule' => 'applications/dashboard/remarkup/PhabricatorDashboardRemarkupRule.php', 2535 2536 'PhabricatorDashboardRemovePanelController' => 'applications/dashboard/controller/PhabricatorDashboardRemovePanelController.php', ··· 7610 7611 'PhabricatorDashboardProfileController' => 'PhabricatorController', 7611 7612 'PhabricatorDashboardProfileMenuItem' => 'PhabricatorProfileMenuItem', 7612 7613 'PhabricatorDashboardQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 7614 + 'PhabricatorDashboardQueryPanelInstallController' => 'PhabricatorDashboardController', 7613 7615 'PhabricatorDashboardQueryPanelType' => 'PhabricatorDashboardPanelType', 7614 7616 'PhabricatorDashboardRemarkupRule' => 'PhabricatorObjectRemarkupRule', 7615 7617 'PhabricatorDashboardRemovePanelController' => 'PhabricatorDashboardController',
+2
src/applications/dashboard/application/PhabricatorDashboardApplication.php
··· 36 36 'removepanel/(?P<id>\d+)/' 37 37 => 'PhabricatorDashboardRemovePanelController', 38 38 'panel/' => array( 39 + 'install/(?P<engineKey>[^/]+)/(?:(?P<queryKey>[^/]+)/)?' => 40 + 'PhabricatorDashboardQueryPanelInstallController', 39 41 '(?:query/(?P<queryKey>[^/]+)/)?' 40 42 => 'PhabricatorDashboardPanelListController', 41 43 'create/' => 'PhabricatorDashboardPanelEditController',
+159
src/applications/dashboard/controller/PhabricatorDashboardQueryPanelInstallController.php
··· 1 + <?php 2 + 3 + final class PhabricatorDashboardQueryPanelInstallController 4 + extends PhabricatorDashboardController { 5 + 6 + public function handleRequest(AphrontRequest $request) { 7 + $viewer = $request->getViewer(); 8 + 9 + $v_dashboard = null; 10 + $v_name = null; 11 + $v_column = 0; 12 + $v_engine = $request->getURIData('engineKey'); 13 + $v_query = $request->getURIData('queryKey'); 14 + 15 + // Validate Engines 16 + $engines = PhabricatorApplicationSearchEngine::getAllEngines(); 17 + foreach ($engines as $name => $engine) { 18 + if (!$engine->canUseInPanelContext()) { 19 + unset($engines[$name]); 20 + } 21 + } 22 + if (!in_array($v_engine, array_keys($engines))) { 23 + return new Aphront404Response(); 24 + } 25 + 26 + // Validate Queries 27 + $engine = $engines[$v_engine]; 28 + $engine->setViewer($viewer); 29 + $queries = array_keys($engine->loadEnabledNamedQueries()); 30 + if (!in_array($v_query, $queries)) { 31 + return new Aphront404Response(); 32 + } 33 + 34 + $errors = array(); 35 + 36 + if ($request->isFormPost()) { 37 + $v_dashboard = $request->getInt('dashboardID'); 38 + $v_name = $request->getStr('name'); 39 + if (!$v_name) { 40 + $errors[] = pht('You must provide a name for this panel.'); 41 + } 42 + 43 + $dashboard = id(new PhabricatorDashboardQuery()) 44 + ->setViewer($viewer) 45 + ->withIDs(array($v_dashboard)) 46 + ->requireCapabilities( 47 + array( 48 + PhabricatorPolicyCapability::CAN_VIEW, 49 + PhabricatorPolicyCapability::CAN_EDIT, 50 + )) 51 + ->executeOne(); 52 + 53 + if (!$dashboard) { 54 + $errors[] = pht('Please select a valid dashboard.'); 55 + } 56 + 57 + if (!$errors) { 58 + $redirect_uri = "/dashboard/arrange/{$v_dashboard}/"; 59 + 60 + $panel_type = id(new PhabricatorDashboardQueryPanelType()) 61 + ->getPanelTypeKey(); 62 + $panel = PhabricatorDashboardPanel::initializeNewPanel($viewer); 63 + $panel->setPanelType($panel_type); 64 + 65 + $field_list = PhabricatorCustomField::getObjectFields( 66 + $panel, 67 + PhabricatorCustomField::ROLE_EDIT); 68 + 69 + $field_list 70 + ->setViewer($viewer) 71 + ->readFieldsFromStorage($panel); 72 + 73 + $panel->requireImplementation()->initializeFieldsFromRequest( 74 + $panel, 75 + $field_list, 76 + $request); 77 + 78 + $xactions = array(); 79 + 80 + $xactions[] = id(new PhabricatorDashboardPanelTransaction()) 81 + ->setTransactionType(PhabricatorDashboardPanelTransaction::TYPE_NAME) 82 + ->setNewValue($v_name); 83 + 84 + $xactions[] = id(new PhabricatorDashboardPanelTransaction()) 85 + ->setTransactionType(PhabricatorTransactions::TYPE_CUSTOMFIELD) 86 + ->setMetadataValue('customfield:key', 'std:dashboard:core:class') 87 + ->setOldValue(null) 88 + ->setNewValue($v_engine); 89 + 90 + $xactions[] = id(new PhabricatorDashboardPanelTransaction()) 91 + ->setTransactionType(PhabricatorTransactions::TYPE_CUSTOMFIELD) 92 + ->setMetadataValue('customfield:key', 'std:dashboard:core:key') 93 + ->setOldValue(null) 94 + ->setNewValue($v_query); 95 + 96 + $editor = id(new PhabricatorDashboardPanelTransactionEditor()) 97 + ->setActor($viewer) 98 + ->setContinueOnNoEffect(true) 99 + ->setContentSourceFromRequest($request) 100 + ->applyTransactions($panel, $xactions); 101 + 102 + PhabricatorDashboardTransactionEditor::addPanelToDashboard( 103 + $viewer, 104 + PhabricatorContentSource::newFromRequest($request), 105 + $panel, 106 + $dashboard, 107 + $request->getInt('column', 0)); 108 + 109 + return id(new AphrontRedirectResponse())->setURI($redirect_uri); 110 + } 111 + } 112 + 113 + // Make this a select for now, as we don't expect someone to have 114 + // edit access to a vast number of dashboards. 115 + // Can add optiongroup if needed down the road. 116 + $dashboards = id(new PhabricatorDashboardQuery()) 117 + ->setViewer($viewer) 118 + ->withStatuses(array( 119 + PhabricatorDashboard::STATUS_ACTIVE, 120 + )) 121 + ->requireCapabilities( 122 + array( 123 + PhabricatorPolicyCapability::CAN_VIEW, 124 + PhabricatorPolicyCapability::CAN_EDIT, 125 + )) 126 + ->execute(); 127 + $options = mpull($dashboards, 'getName', 'getID'); 128 + asort($options); 129 + 130 + $redirect_uri = '#'; // ?? 131 + 132 + $form = id(new AphrontFormView()) 133 + ->setUser($viewer) 134 + ->addHiddenInput('engine', $v_engine) 135 + ->addHiddenInput('query', $v_query) 136 + ->addHiddenInput('column', $v_column) 137 + ->appendChild( 138 + id(new AphrontFormTextControl()) 139 + ->setLabel(pht('Name')) 140 + ->setName('name') 141 + ->setValue($v_name)) 142 + ->appendChild( 143 + id(new AphrontFormSelectControl()) 144 + ->setUser($this->getViewer()) 145 + ->setValue($v_dashboard) 146 + ->setName('dashboardID') 147 + ->setOptions($options) 148 + ->setLabel(pht('Dashboard'))); 149 + 150 + return $this->newDialog() 151 + ->setTitle(pht('Add Panel to Dashboard')) 152 + ->setErrors($errors) 153 + ->setWidth(AphrontDialogView::WIDTH_FORM) 154 + ->appendChild($form->buildLayoutView()) 155 + ->addCancelButton($redirect_uri) 156 + ->addSubmitButton(pht('Add Panel')); 157 + } 158 + 159 + }
+30 -6
src/applications/search/controller/PhabricatorApplicationSearchController.php
··· 555 555 ->setTag('a') 556 556 ->setHref('#') 557 557 ->setText(pht('Use Results...')) 558 - ->setIcon('fa-road') 559 - ->setDropdownMenu($action_list); 558 + ->setIcon('fa-bars') 559 + ->setDropdownMenu($action_list) 560 + ->addClass('dropdown'); 560 561 } 561 562 562 563 private function newOverflowingView() { ··· 600 601 601 602 private function newBuiltinUseActions() { 602 603 $actions = array(); 604 + $request = $this->getRequest(); 605 + $viewer = $request->getUser(); 603 606 604 607 $is_dev = PhabricatorEnv::getEnvConfig('phabricator.developer-mode'); 605 608 609 + $engine = $this->getSearchEngine(); 610 + $engine_class = get_class($engine); 611 + $query_key = $this->getQueryKey(); 612 + if (!$query_key) { 613 + $query_key = head_key($engine->loadEnabledNamedQueries()); 614 + } 615 + 616 + $can_use = $engine->canUseInPanelContext(); 617 + $is_installed = PhabricatorApplication::isClassInstalledForViewer( 618 + 'PhabricatorDashboardApplication', 619 + $viewer); 620 + 621 + if ($can_use && $is_installed) { 622 + $dashboard_uri = '/dashboard/install/'; 623 + $actions[] = id(new PhabricatorActionView()) 624 + ->setIcon('fa-dashboard') 625 + ->setName(pht('Add to Dasbhoard')) 626 + ->setWorkflow(true) 627 + ->setHref("/dashboard/panel/install/{$engine_class}/{$query_key}/"); 628 + } 629 + 606 630 if ($is_dev) { 607 631 $engine = $this->getSearchEngine(); 608 632 $nux_uri = $engine->getQueryBaseURI(); ··· 610 634 ->setQueryParam('nux', true); 611 635 612 636 $actions[] = id(new PhabricatorActionView()) 613 - ->setIcon('fa-bug') 614 - ->setName(pht('Developer: Show New User State')) 637 + ->setIcon('fa-user-plus') 638 + ->setName(pht('DEV: New User State')) 615 639 ->setHref($nux_uri); 616 640 } 617 641 ··· 620 644 ->setQueryParam('overheated', true); 621 645 622 646 $actions[] = id(new PhabricatorActionView()) 623 - ->setIcon('fa-bug') 624 - ->setName(pht('Developer: Show Overheated State')) 647 + ->setIcon('fa-fire') 648 + ->setName(pht('DEV: Overheated State')) 625 649 ->setHref($overheated_uri); 626 650 } 627 651