diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -2370,6 +2370,7 @@ 'PhabricatorEditEngineConfigurationTransactionQuery' => 'applications/transactions/query/PhabricatorEditEngineConfigurationTransactionQuery.php', 'PhabricatorEditEngineConfigurationViewController' => 'applications/transactions/controller/PhabricatorEditEngineConfigurationViewController.php', 'PhabricatorEditEngineController' => 'applications/transactions/controller/PhabricatorEditEngineController.php', + 'PhabricatorEditEngineCreateQuickActions' => 'applications/settings/quickmenu/PhabricatorEditEngineCreateQuickActions.php', 'PhabricatorEditEngineExtension' => 'applications/transactions/engineextension/PhabricatorEditEngineExtension.php', 'PhabricatorEditEngineExtensionModule' => 'applications/transactions/engineextension/PhabricatorEditEngineExtensionModule.php', 'PhabricatorEditEngineListController' => 'applications/transactions/controller/PhabricatorEditEngineListController.php', @@ -3191,6 +3192,7 @@ 'PhabricatorQueryOrderItem' => 'infrastructure/query/order/PhabricatorQueryOrderItem.php', 'PhabricatorQueryOrderTestCase' => 'infrastructure/query/order/__tests__/PhabricatorQueryOrderTestCase.php', 'PhabricatorQueryOrderVector' => 'infrastructure/query/order/PhabricatorQueryOrderVector.php', + 'PhabricatorQuickActions' => 'applications/settings/quickmenu/PhabricatorQuickActions.php', 'PhabricatorRateLimitRequestExceptionHandler' => 'aphront/handler/PhabricatorRateLimitRequestExceptionHandler.php', 'PhabricatorRecaptchaConfigOptions' => 'applications/config/option/PhabricatorRecaptchaConfigOptions.php', 'PhabricatorRecipientHasBadgeEdgeType' => 'applications/badges/edge/PhabricatorRecipientHasBadgeEdgeType.php', @@ -6962,6 +6964,7 @@ 'PhabricatorEditEngineConfigurationTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'PhabricatorEditEngineConfigurationViewController' => 'PhabricatorEditEngineController', 'PhabricatorEditEngineController' => 'PhabricatorApplicationTransactionController', + 'PhabricatorEditEngineCreateQuickActions' => 'PhabricatorQuickActions', 'PhabricatorEditEngineExtension' => 'Phobject', 'PhabricatorEditEngineExtensionModule' => 'PhabricatorConfigModule', 'PhabricatorEditEngineListController' => 'PhabricatorEditEngineController', @@ -7916,6 +7919,7 @@ 'Phobject', 'Iterator', ), + 'PhabricatorQuickActions' => 'Phobject', 'PhabricatorRateLimitRequestExceptionHandler' => 'PhabricatorRequestExceptionHandler', 'PhabricatorRecaptchaConfigOptions' => 'PhabricatorApplicationConfigOptions', 'PhabricatorRecipientHasBadgeEdgeType' => 'PhabricatorEdgeType', diff --git a/src/applications/base/PhabricatorApplication.php b/src/applications/base/PhabricatorApplication.php --- a/src/applications/base/PhabricatorApplication.php +++ b/src/applications/base/PhabricatorApplication.php @@ -335,17 +335,6 @@ } - /** - * Build items for the "quick create" menu. - * - * @param PhabricatorUser The viewing user. - * @return list List of menu items. - */ - public function getQuickCreateItems(PhabricatorUser $viewer) { - return array(); - } - - /* -( Application Management )--------------------------------------------- */ diff --git a/src/applications/calendar/application/PhabricatorCalendarApplication.php b/src/applications/calendar/application/PhabricatorCalendarApplication.php --- a/src/applications/calendar/application/PhabricatorCalendarApplication.php +++ b/src/applications/calendar/application/PhabricatorCalendarApplication.php @@ -73,18 +73,6 @@ ); } - public function getQuickCreateItems(PhabricatorUser $viewer) { - $items = array(); - - $item = id(new PHUIListItemView()) - ->setName(pht('Calendar Event')) - ->setIcon('fa-calendar') - ->setHref($this->getBaseURI().'event/create/'); - $items[] = $item; - - return $items; - } - public function getMailCommandObjects() { return array( 'event' => array( diff --git a/src/applications/conpherence/application/PhabricatorConpherenceApplication.php b/src/applications/conpherence/application/PhabricatorConpherenceApplication.php --- a/src/applications/conpherence/application/PhabricatorConpherenceApplication.php +++ b/src/applications/conpherence/application/PhabricatorConpherenceApplication.php @@ -48,19 +48,6 @@ ); } - public function getQuickCreateItems(PhabricatorUser $viewer) { - $items = array(); - - $item = id(new PHUIListItemView()) - ->setName(pht('Conpherence Room')) - ->setIcon('fa-comments') - ->setWorkflow(true) - ->setHref($this->getBaseURI().'new/'); - $items[] = $item; - - return $items; - } - public function getQuicksandURIPatternBlacklist() { return array( '/conpherence/.*', diff --git a/src/applications/home/application/PhabricatorHomeApplication.php b/src/applications/home/application/PhabricatorHomeApplication.php --- a/src/applications/home/application/PhabricatorHomeApplication.php +++ b/src/applications/home/application/PhabricatorHomeApplication.php @@ -42,51 +42,29 @@ PhabricatorUser $user, PhabricatorController $controller = null) { - $quick_create_items = $this->loadAllQuickCreateItems($user); $items = array(); - - if ($user->isLoggedIn() && - $user->isUserActivated() && - $quick_create_items) { - $create_id = celerity_generate_unique_node_id(); - Javelin::initBehavior( - 'aphlict-dropdown', - array( - 'bubbleID' => $create_id, - 'dropdownID' => 'phabricator-quick-create-menu', - 'local' => true, - 'desktop' => true, - 'right' => true, - )); - - $item = id(new PHUIListItemView()) - ->setName(pht('Create New...')) - ->setIcon('fa-plus') - ->addClass('core-menu-item') - ->setHref('/home/create/') - ->addSigil('quick-create-menu') - ->setID($create_id) - ->setAural(pht('Quick Create')) - ->setOrder(300); - $items[] = $item; - } - - return $items; - } - - public function loadAllQuickCreateItems(PhabricatorUser $viewer) { - $applications = id(new PhabricatorApplicationQuery()) - ->setViewer($viewer) - ->withInstalled(true) - ->execute(); - - $items = array(); - foreach ($applications as $application) { - $app_items = $application->getQuickCreateItems($viewer); - foreach ($app_items as $app_item) { - $items[] = $app_item; - } - } + $create_id = celerity_generate_unique_node_id(); + + Javelin::initBehavior( + 'aphlict-dropdown', + array( + 'bubbleID' => $create_id, + 'dropdownID' => 'phabricator-quick-create-menu', + 'local' => true, + 'desktop' => true, + 'right' => true, + )); + + $item = id(new PHUIListItemView()) + ->setName(pht('Quick Actions')) + ->setIcon('fa-plus') + ->addClass('core-menu-item') + ->setHref('/home/create/') + ->addSigil('quick-create-menu') + ->setID($create_id) + ->setAural(pht('Quick Actions')) + ->setOrder(300); + $items[] = $item; return $items; } @@ -95,7 +73,7 @@ PhabricatorUser $viewer, PhabricatorController $controller = null) { - $items = $this->loadAllQuickCreateItems($viewer); + $items = PhabricatorQuickActions::loadMenuItemsForUser($viewer); $view = null; if ($items) { diff --git a/src/applications/home/controller/PhabricatorHomeQuickCreateController.php b/src/applications/home/controller/PhabricatorHomeQuickCreateController.php --- a/src/applications/home/controller/PhabricatorHomeQuickCreateController.php +++ b/src/applications/home/controller/PhabricatorHomeQuickCreateController.php @@ -6,7 +6,7 @@ public function handleRequest(AphrontRequest $request) { $viewer = $this->getViewer(); - $items = $this->getCurrentApplication()->loadAllQuickCreateItems($viewer); + $items = PhabricatorQuickActions::loadMenuItemsForUser($viewer); $list = id(new PHUIObjectItemListView()) ->setUser($viewer); diff --git a/src/applications/maniphest/application/PhabricatorManiphestApplication.php b/src/applications/maniphest/application/PhabricatorManiphestApplication.php --- a/src/applications/maniphest/application/PhabricatorManiphestApplication.php +++ b/src/applications/maniphest/application/PhabricatorManiphestApplication.php @@ -90,12 +90,6 @@ return $status; } - public function getQuickCreateItems(PhabricatorUser $viewer) { - return id(new ManiphestEditEngine()) - ->setViewer($viewer) - ->loadQuickCreateItems(); - } - public function supportsEmailIntegration() { return true; } diff --git a/src/applications/paste/application/PhabricatorPasteApplication.php b/src/applications/paste/application/PhabricatorPasteApplication.php --- a/src/applications/paste/application/PhabricatorPasteApplication.php +++ b/src/applications/paste/application/PhabricatorPasteApplication.php @@ -76,12 +76,6 @@ ); } - public function getQuickCreateItems(PhabricatorUser $viewer) { - return id(new PhabricatorPasteEditEngine()) - ->setViewer($viewer) - ->loadQuickCreateItems(); - } - public function getMailCommandObjects() { return array( 'paste' => array( diff --git a/src/applications/people/application/PhabricatorPeopleApplication.php b/src/applications/people/application/PhabricatorPeopleApplication.php --- a/src/applications/people/application/PhabricatorPeopleApplication.php +++ b/src/applications/people/application/PhabricatorPeopleApplication.php @@ -127,31 +127,6 @@ return $status; } - public function getQuickCreateItems(PhabricatorUser $viewer) { - $items = array(); - - $can_create = PhabricatorPolicyFilter::hasCapability( - $viewer, - $this, - PeopleCreateUsersCapability::CAPABILITY); - - if ($can_create) { - $item = id(new PHUIListItemView()) - ->setName(pht('User Account')) - ->setIcon('fa-users') - ->setHref($this->getBaseURI().'create/'); - $items[] = $item; - } else if ($viewer->getIsAdmin()) { - $item = id(new PHUIListItemView()) - ->setName(pht('Bot Account')) - ->setIcon('fa-android') - ->setHref($this->getBaseURI().'new/bot/'); - $items[] = $item; - } - - return $items; - } - public function getApplicationSearchDocumentTypes() { return array( PhabricatorPeopleUserPHIDType::TYPECONST, diff --git a/src/applications/pholio/application/PhabricatorPholioApplication.php b/src/applications/pholio/application/PhabricatorPholioApplication.php --- a/src/applications/pholio/application/PhabricatorPholioApplication.php +++ b/src/applications/pholio/application/PhabricatorPholioApplication.php @@ -59,18 +59,6 @@ ); } - public function getQuickCreateItems(PhabricatorUser $viewer) { - $items = array(); - - $item = id(new PHUIListItemView()) - ->setName(pht('Pholio Mock')) - ->setIcon('fa-picture-o') - ->setHref($this->getBaseURI().'create/'); - $items[] = $item; - - return $items; - } - protected function getCustomCapabilities() { return array( PholioDefaultViewCapability::CAPABILITY => array( diff --git a/src/applications/project/application/PhabricatorProjectApplication.php b/src/applications/project/application/PhabricatorProjectApplication.php --- a/src/applications/project/application/PhabricatorProjectApplication.php +++ b/src/applications/project/application/PhabricatorProjectApplication.php @@ -108,12 +108,6 @@ ); } - public function getQuickCreateItems(PhabricatorUser $viewer) { - return id(new PhabricatorProjectEditEngine()) - ->setViewer($viewer) - ->loadQuickCreateItems(); - } - protected function getCustomCapabilities() { return array( ProjectCreateProjectsCapability::CAPABILITY => array(), diff --git a/src/applications/settings/quickmenu/PhabricatorEditEngineCreateQuickActions.php b/src/applications/settings/quickmenu/PhabricatorEditEngineCreateQuickActions.php new file mode 100644 --- /dev/null +++ b/src/applications/settings/quickmenu/PhabricatorEditEngineCreateQuickActions.php @@ -0,0 +1,46 @@ +getViewer(); + + $engines = PhabricatorEditEngine::getAllEditEngines(); + + foreach ($engines as $key => $engine) { + if (!$engine->hasQuickCreateActions()) { + unset($engines[$key]); + } + } + + if (!$engines) { + return array(); + } + + $engine_keys = array_keys($engines); + + $configs = id(new PhabricatorEditEngineConfigurationQuery()) + ->setViewer($viewer) + ->withEngineKeys($engine_keys) + ->withIsDefault(true) + ->withIsDisabled(false) + ->execute(); + $configs = msort($configs, 'getCreateSortKey'); + $configs = mgroup($configs, 'getEngineKey'); + + $items = array(); + foreach ($engines as $key => $engine) { + $engine_configs = idx($configs, $key, array()); + $engine_items = $engine->newQuickCreateActions($engine_configs); + foreach ($engine_items as $engine_item) { + $items[] = $engine_item; + } + } + + return $items; + } + +} diff --git a/src/applications/settings/quickmenu/PhabricatorQuickActions.php b/src/applications/settings/quickmenu/PhabricatorQuickActions.php new file mode 100644 --- /dev/null +++ b/src/applications/settings/quickmenu/PhabricatorQuickActions.php @@ -0,0 +1,54 @@ +viewer = $viewer; + return $this; + } + + public function getViewer() { + return $this->viewer; + } + + public function isEnabled() { + return true; + } + + abstract public function getQuickMenuItems(); + + final public function getQuickActionsKey() { + return $this->getPhobjectClassConstant('QUICKACTIONSKEY'); + } + + public static function getAllQuickActions() { + return id(new PhutilClassMapQuery()) + ->setAncestorClass(__CLASS__) + ->setUniqueMethod('getQuickActionsKey') + ->execute(); + } + + public static function loadMenuItemsForUser(PhabricatorUser $viewer) { + $actions = self::getAllQuickActions(); + + foreach ($actions as $key => $action) { + $action->setViewer($viewer); + if (!$action->isEnabled()) { + unset($actions[$key]); + continue; + } + } + + $items = array(); + foreach ($actions as $key => $action) { + foreach ($action->getQuickMenuItems() as $item) { + $items[] = $item; + } + } + + return $items; + } + +} diff --git a/src/applications/transactions/editengine/PhabricatorEditEngine.php b/src/applications/transactions/editengine/PhabricatorEditEngine.php --- a/src/applications/transactions/editengine/PhabricatorEditEngine.php +++ b/src/applications/transactions/editengine/PhabricatorEditEngine.php @@ -1972,20 +1972,34 @@ return $application->getIcon(); } - public function loadQuickCreateItems() { + public function hasQuickCreateActions() { + if (!$this->isEngineConfigurable()) { + return false; + } + + return true; + } + + public function newQuickCreateActions(array $configs) { $items = array(); - if (!$this->hasCreateCapability()) { - return $items; + if (!$configs) { + return array(); } - $configs = $this->loadUsableConfigurationsForCreate(); + // If the viewer is logged in and can't create objects, don't show the + // menu item. If they're logged out, we assume they could create objects + // if they logged in, so we show the item as a hint about how to + // accomplish the action. + if ($this->getViewer()->isLoggedIn()) { + if (!$this->hasCreateCapability()) { + return array(); + } + } - if (!$configs) { - // No items to add. - } else if (count($configs) == 1) { + if (count($configs) == 1) { $config = head($configs); - $items[] = $this->newQuickCreateItem($config); + $items[] = $this->newQuickCreateAction($config); } else { $group_name = $this->getQuickCreateMenuHeaderText(); @@ -1994,7 +2008,7 @@ ->setName($group_name); foreach ($configs as $config) { - $items[] = $this->newQuickCreateItem($config) + $items[] = $this->newQuickCreateAction($config) ->setIndented(true); } } @@ -2017,7 +2031,7 @@ return $configs; } - private function newQuickCreateItem( + private function newQuickCreateAction( PhabricatorEditEngineConfiguration $config) { $item_name = $config->getName();