1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-21 13:00:56 +01:00

Fully modularize the "Quick Actions" menu

Summary:
Ref T10077. Currently, we issue 6+ queries on every page to build this menu, since the menu is built application-by-application.

Build the menu with dedicated modules instead so a single "EditEngine" module can provide all of them with one query.

I'd like to reduce this to 0 queries but I'm not totally sure what we want to do with this menu.

This change removes these items, because EditEngine can not currently provide them:

  - Calendar: Eventually via EditEngine eventually.
  - Conpherence: Probably via EditEngine, doesn't seem too important.
  - People: Maybe via EditEngine, doesn't seem too important? "Welcome" is likely better?
  - Pholio: Eventually via EditEngine.

It adds a bunch of other items as a side effect:

{F1677151}

This reduces the queries issued on every page by ~5.

This also makes quick create actions visible while logged out (see T7073).

Test Plan:
  - Viewed menu while logged in.
  - Viewed menu while logged out.
  - Viewed standalone version of menu.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T10077

Differential Revision: https://secure.phabricator.com/D16045
This commit is contained in:
epriestley 2016-06-05 07:26:47 -07:00
parent aa4ba0fa92
commit 7969f66dfe
14 changed files with 151 additions and 146 deletions

View file

@ -2370,6 +2370,7 @@ phutil_register_library_map(array(
'PhabricatorEditEngineConfigurationTransactionQuery' => 'applications/transactions/query/PhabricatorEditEngineConfigurationTransactionQuery.php', 'PhabricatorEditEngineConfigurationTransactionQuery' => 'applications/transactions/query/PhabricatorEditEngineConfigurationTransactionQuery.php',
'PhabricatorEditEngineConfigurationViewController' => 'applications/transactions/controller/PhabricatorEditEngineConfigurationViewController.php', 'PhabricatorEditEngineConfigurationViewController' => 'applications/transactions/controller/PhabricatorEditEngineConfigurationViewController.php',
'PhabricatorEditEngineController' => 'applications/transactions/controller/PhabricatorEditEngineController.php', 'PhabricatorEditEngineController' => 'applications/transactions/controller/PhabricatorEditEngineController.php',
'PhabricatorEditEngineCreateQuickActions' => 'applications/settings/quickmenu/PhabricatorEditEngineCreateQuickActions.php',
'PhabricatorEditEngineExtension' => 'applications/transactions/engineextension/PhabricatorEditEngineExtension.php', 'PhabricatorEditEngineExtension' => 'applications/transactions/engineextension/PhabricatorEditEngineExtension.php',
'PhabricatorEditEngineExtensionModule' => 'applications/transactions/engineextension/PhabricatorEditEngineExtensionModule.php', 'PhabricatorEditEngineExtensionModule' => 'applications/transactions/engineextension/PhabricatorEditEngineExtensionModule.php',
'PhabricatorEditEngineListController' => 'applications/transactions/controller/PhabricatorEditEngineListController.php', 'PhabricatorEditEngineListController' => 'applications/transactions/controller/PhabricatorEditEngineListController.php',
@ -3191,6 +3192,7 @@ phutil_register_library_map(array(
'PhabricatorQueryOrderItem' => 'infrastructure/query/order/PhabricatorQueryOrderItem.php', 'PhabricatorQueryOrderItem' => 'infrastructure/query/order/PhabricatorQueryOrderItem.php',
'PhabricatorQueryOrderTestCase' => 'infrastructure/query/order/__tests__/PhabricatorQueryOrderTestCase.php', 'PhabricatorQueryOrderTestCase' => 'infrastructure/query/order/__tests__/PhabricatorQueryOrderTestCase.php',
'PhabricatorQueryOrderVector' => 'infrastructure/query/order/PhabricatorQueryOrderVector.php', 'PhabricatorQueryOrderVector' => 'infrastructure/query/order/PhabricatorQueryOrderVector.php',
'PhabricatorQuickActions' => 'applications/settings/quickmenu/PhabricatorQuickActions.php',
'PhabricatorRateLimitRequestExceptionHandler' => 'aphront/handler/PhabricatorRateLimitRequestExceptionHandler.php', 'PhabricatorRateLimitRequestExceptionHandler' => 'aphront/handler/PhabricatorRateLimitRequestExceptionHandler.php',
'PhabricatorRecaptchaConfigOptions' => 'applications/config/option/PhabricatorRecaptchaConfigOptions.php', 'PhabricatorRecaptchaConfigOptions' => 'applications/config/option/PhabricatorRecaptchaConfigOptions.php',
'PhabricatorRecipientHasBadgeEdgeType' => 'applications/badges/edge/PhabricatorRecipientHasBadgeEdgeType.php', 'PhabricatorRecipientHasBadgeEdgeType' => 'applications/badges/edge/PhabricatorRecipientHasBadgeEdgeType.php',
@ -6962,6 +6964,7 @@ phutil_register_library_map(array(
'PhabricatorEditEngineConfigurationTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'PhabricatorEditEngineConfigurationTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'PhabricatorEditEngineConfigurationViewController' => 'PhabricatorEditEngineController', 'PhabricatorEditEngineConfigurationViewController' => 'PhabricatorEditEngineController',
'PhabricatorEditEngineController' => 'PhabricatorApplicationTransactionController', 'PhabricatorEditEngineController' => 'PhabricatorApplicationTransactionController',
'PhabricatorEditEngineCreateQuickActions' => 'PhabricatorQuickActions',
'PhabricatorEditEngineExtension' => 'Phobject', 'PhabricatorEditEngineExtension' => 'Phobject',
'PhabricatorEditEngineExtensionModule' => 'PhabricatorConfigModule', 'PhabricatorEditEngineExtensionModule' => 'PhabricatorConfigModule',
'PhabricatorEditEngineListController' => 'PhabricatorEditEngineController', 'PhabricatorEditEngineListController' => 'PhabricatorEditEngineController',
@ -7916,6 +7919,7 @@ phutil_register_library_map(array(
'Phobject', 'Phobject',
'Iterator', 'Iterator',
), ),
'PhabricatorQuickActions' => 'Phobject',
'PhabricatorRateLimitRequestExceptionHandler' => 'PhabricatorRequestExceptionHandler', 'PhabricatorRateLimitRequestExceptionHandler' => 'PhabricatorRequestExceptionHandler',
'PhabricatorRecaptchaConfigOptions' => 'PhabricatorApplicationConfigOptions', 'PhabricatorRecaptchaConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorRecipientHasBadgeEdgeType' => 'PhabricatorEdgeType', 'PhabricatorRecipientHasBadgeEdgeType' => 'PhabricatorEdgeType',

View file

@ -335,17 +335,6 @@ abstract class PhabricatorApplication
} }
/**
* Build items for the "quick create" menu.
*
* @param PhabricatorUser The viewing user.
* @return list<PHUIListItemView> List of menu items.
*/
public function getQuickCreateItems(PhabricatorUser $viewer) {
return array();
}
/* -( Application Management )--------------------------------------------- */ /* -( Application Management )--------------------------------------------- */

View file

@ -73,18 +73,6 @@ final class PhabricatorCalendarApplication extends PhabricatorApplication {
); );
} }
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() { public function getMailCommandObjects() {
return array( return array(
'event' => array( 'event' => array(

View file

@ -48,19 +48,6 @@ final class PhabricatorConpherenceApplication extends PhabricatorApplication {
); );
} }
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() { public function getQuicksandURIPatternBlacklist() {
return array( return array(
'/conpherence/.*', '/conpherence/.*',

View file

@ -42,51 +42,29 @@ final class PhabricatorHomeApplication extends PhabricatorApplication {
PhabricatorUser $user, PhabricatorUser $user,
PhabricatorController $controller = null) { PhabricatorController $controller = null) {
$quick_create_items = $this->loadAllQuickCreateItems($user);
$items = array(); $items = array();
$create_id = celerity_generate_unique_node_id();
if ($user->isLoggedIn() && Javelin::initBehavior(
$user->isUserActivated() && 'aphlict-dropdown',
$quick_create_items) { array(
$create_id = celerity_generate_unique_node_id(); 'bubbleID' => $create_id,
Javelin::initBehavior( 'dropdownID' => 'phabricator-quick-create-menu',
'aphlict-dropdown', 'local' => true,
array( 'desktop' => true,
'bubbleID' => $create_id, 'right' => true,
'dropdownID' => 'phabricator-quick-create-menu', ));
'local' => true,
'desktop' => true,
'right' => true,
));
$item = id(new PHUIListItemView()) $item = id(new PHUIListItemView())
->setName(pht('Create New...')) ->setName(pht('Quick Actions'))
->setIcon('fa-plus') ->setIcon('fa-plus')
->addClass('core-menu-item') ->addClass('core-menu-item')
->setHref('/home/create/') ->setHref('/home/create/')
->addSigil('quick-create-menu') ->addSigil('quick-create-menu')
->setID($create_id) ->setID($create_id)
->setAural(pht('Quick Create')) ->setAural(pht('Quick Actions'))
->setOrder(300); ->setOrder(300);
$items[] = $item; $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;
}
}
return $items; return $items;
} }
@ -95,7 +73,7 @@ final class PhabricatorHomeApplication extends PhabricatorApplication {
PhabricatorUser $viewer, PhabricatorUser $viewer,
PhabricatorController $controller = null) { PhabricatorController $controller = null) {
$items = $this->loadAllQuickCreateItems($viewer); $items = PhabricatorQuickActions::loadMenuItemsForUser($viewer);
$view = null; $view = null;
if ($items) { if ($items) {

View file

@ -6,7 +6,7 @@ final class PhabricatorHomeQuickCreateController
public function handleRequest(AphrontRequest $request) { public function handleRequest(AphrontRequest $request) {
$viewer = $this->getViewer(); $viewer = $this->getViewer();
$items = $this->getCurrentApplication()->loadAllQuickCreateItems($viewer); $items = PhabricatorQuickActions::loadMenuItemsForUser($viewer);
$list = id(new PHUIObjectItemListView()) $list = id(new PHUIObjectItemListView())
->setUser($viewer); ->setUser($viewer);

View file

@ -90,12 +90,6 @@ final class PhabricatorManiphestApplication extends PhabricatorApplication {
return $status; return $status;
} }
public function getQuickCreateItems(PhabricatorUser $viewer) {
return id(new ManiphestEditEngine())
->setViewer($viewer)
->loadQuickCreateItems();
}
public function supportsEmailIntegration() { public function supportsEmailIntegration() {
return true; return true;
} }

View file

@ -76,12 +76,6 @@ final class PhabricatorPasteApplication extends PhabricatorApplication {
); );
} }
public function getQuickCreateItems(PhabricatorUser $viewer) {
return id(new PhabricatorPasteEditEngine())
->setViewer($viewer)
->loadQuickCreateItems();
}
public function getMailCommandObjects() { public function getMailCommandObjects() {
return array( return array(
'paste' => array( 'paste' => array(

View file

@ -127,31 +127,6 @@ final class PhabricatorPeopleApplication extends PhabricatorApplication {
return $status; 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() { public function getApplicationSearchDocumentTypes() {
return array( return array(
PhabricatorPeopleUserPHIDType::TYPECONST, PhabricatorPeopleUserPHIDType::TYPECONST,

View file

@ -59,18 +59,6 @@ final class PhabricatorPholioApplication extends PhabricatorApplication {
); );
} }
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() { protected function getCustomCapabilities() {
return array( return array(
PholioDefaultViewCapability::CAPABILITY => array( PholioDefaultViewCapability::CAPABILITY => array(

View file

@ -108,12 +108,6 @@ final class PhabricatorProjectApplication extends PhabricatorApplication {
); );
} }
public function getQuickCreateItems(PhabricatorUser $viewer) {
return id(new PhabricatorProjectEditEngine())
->setViewer($viewer)
->loadQuickCreateItems();
}
protected function getCustomCapabilities() { protected function getCustomCapabilities() {
return array( return array(
ProjectCreateProjectsCapability::CAPABILITY => array(), ProjectCreateProjectsCapability::CAPABILITY => array(),

View file

@ -0,0 +1,46 @@
<?php
final class PhabricatorEditEngineCreateQuickActions
extends PhabricatorQuickActions {
const QUICKACTIONSKEY = 'editengine.create';
public function getQuickMenuItems() {
$viewer = $this->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;
}
}

View file

@ -0,0 +1,54 @@
<?php
abstract class PhabricatorQuickActions extends Phobject {
private $viewer;
public function setViewer(PhabricatorUser $viewer) {
$this->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;
}
}

View file

@ -1972,20 +1972,34 @@ abstract class PhabricatorEditEngine
return $application->getIcon(); return $application->getIcon();
} }
public function loadQuickCreateItems() { public function hasQuickCreateActions() {
$items = array(); if (!$this->isEngineConfigurable()) {
return false;
if (!$this->hasCreateCapability()) {
return $items;
} }
$configs = $this->loadUsableConfigurationsForCreate(); return true;
}
public function newQuickCreateActions(array $configs) {
$items = array();
if (!$configs) { if (!$configs) {
// No items to add. return array();
} else if (count($configs) == 1) { }
// 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 (count($configs) == 1) {
$config = head($configs); $config = head($configs);
$items[] = $this->newQuickCreateItem($config); $items[] = $this->newQuickCreateAction($config);
} else { } else {
$group_name = $this->getQuickCreateMenuHeaderText(); $group_name = $this->getQuickCreateMenuHeaderText();
@ -1994,7 +2008,7 @@ abstract class PhabricatorEditEngine
->setName($group_name); ->setName($group_name);
foreach ($configs as $config) { foreach ($configs as $config) {
$items[] = $this->newQuickCreateItem($config) $items[] = $this->newQuickCreateAction($config)
->setIndented(true); ->setIndented(true);
} }
} }
@ -2017,7 +2031,7 @@ abstract class PhabricatorEditEngine
return $configs; return $configs;
} }
private function newQuickCreateItem( private function newQuickCreateAction(
PhabricatorEditEngineConfiguration $config) { PhabricatorEditEngineConfiguration $config) {
$item_name = $config->getName(); $item_name = $config->getName();