mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-20 20:40: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:
parent
aa4ba0fa92
commit
7969f66dfe
14 changed files with 151 additions and 146 deletions
|
@ -2370,6 +2370,7 @@ phutil_register_library_map(array(
|
|||
'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 @@ phutil_register_library_map(array(
|
|||
'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 @@ phutil_register_library_map(array(
|
|||
'PhabricatorEditEngineConfigurationTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||
'PhabricatorEditEngineConfigurationViewController' => 'PhabricatorEditEngineController',
|
||||
'PhabricatorEditEngineController' => 'PhabricatorApplicationTransactionController',
|
||||
'PhabricatorEditEngineCreateQuickActions' => 'PhabricatorQuickActions',
|
||||
'PhabricatorEditEngineExtension' => 'Phobject',
|
||||
'PhabricatorEditEngineExtensionModule' => 'PhabricatorConfigModule',
|
||||
'PhabricatorEditEngineListController' => 'PhabricatorEditEngineController',
|
||||
|
@ -7916,6 +7919,7 @@ phutil_register_library_map(array(
|
|||
'Phobject',
|
||||
'Iterator',
|
||||
),
|
||||
'PhabricatorQuickActions' => 'Phobject',
|
||||
'PhabricatorRateLimitRequestExceptionHandler' => 'PhabricatorRequestExceptionHandler',
|
||||
'PhabricatorRecaptchaConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
||||
'PhabricatorRecipientHasBadgeEdgeType' => 'PhabricatorEdgeType',
|
||||
|
|
|
@ -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 )--------------------------------------------- */
|
||||
|
||||
|
||||
|
|
|
@ -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() {
|
||||
return array(
|
||||
'event' => array(
|
||||
|
|
|
@ -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() {
|
||||
return array(
|
||||
'/conpherence/.*',
|
||||
|
|
|
@ -42,13 +42,9 @@ final class PhabricatorHomeApplication extends PhabricatorApplication {
|
|||
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(
|
||||
|
@ -60,33 +56,15 @@ final class PhabricatorHomeApplication extends PhabricatorApplication {
|
|||
));
|
||||
|
||||
$item = id(new PHUIListItemView())
|
||||
->setName(pht('Create New...'))
|
||||
->setName(pht('Quick Actions'))
|
||||
->setIcon('fa-plus')
|
||||
->addClass('core-menu-item')
|
||||
->setHref('/home/create/')
|
||||
->addSigil('quick-create-menu')
|
||||
->setID($create_id)
|
||||
->setAural(pht('Quick Create'))
|
||||
->setAural(pht('Quick Actions'))
|
||||
->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;
|
||||
}
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
@ -95,7 +73,7 @@ final class PhabricatorHomeApplication extends PhabricatorApplication {
|
|||
PhabricatorUser $viewer,
|
||||
PhabricatorController $controller = null) {
|
||||
|
||||
$items = $this->loadAllQuickCreateItems($viewer);
|
||||
$items = PhabricatorQuickActions::loadMenuItemsForUser($viewer);
|
||||
|
||||
$view = null;
|
||||
if ($items) {
|
||||
|
|
|
@ -6,7 +6,7 @@ final class PhabricatorHomeQuickCreateController
|
|||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$items = $this->getCurrentApplication()->loadAllQuickCreateItems($viewer);
|
||||
$items = PhabricatorQuickActions::loadMenuItemsForUser($viewer);
|
||||
|
||||
$list = id(new PHUIObjectItemListView())
|
||||
->setUser($viewer);
|
||||
|
|
|
@ -90,12 +90,6 @@ final class PhabricatorManiphestApplication extends PhabricatorApplication {
|
|||
return $status;
|
||||
}
|
||||
|
||||
public function getQuickCreateItems(PhabricatorUser $viewer) {
|
||||
return id(new ManiphestEditEngine())
|
||||
->setViewer($viewer)
|
||||
->loadQuickCreateItems();
|
||||
}
|
||||
|
||||
public function supportsEmailIntegration() {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -76,12 +76,6 @@ final class PhabricatorPasteApplication extends PhabricatorApplication {
|
|||
);
|
||||
}
|
||||
|
||||
public function getQuickCreateItems(PhabricatorUser $viewer) {
|
||||
return id(new PhabricatorPasteEditEngine())
|
||||
->setViewer($viewer)
|
||||
->loadQuickCreateItems();
|
||||
}
|
||||
|
||||
public function getMailCommandObjects() {
|
||||
return array(
|
||||
'paste' => array(
|
||||
|
|
|
@ -127,31 +127,6 @@ final class PhabricatorPeopleApplication extends PhabricatorApplication {
|
|||
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,
|
||||
|
|
|
@ -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() {
|
||||
return array(
|
||||
PholioDefaultViewCapability::CAPABILITY => array(
|
||||
|
|
|
@ -108,12 +108,6 @@ final class PhabricatorProjectApplication extends PhabricatorApplication {
|
|||
);
|
||||
}
|
||||
|
||||
public function getQuickCreateItems(PhabricatorUser $viewer) {
|
||||
return id(new PhabricatorProjectEditEngine())
|
||||
->setViewer($viewer)
|
||||
->loadQuickCreateItems();
|
||||
}
|
||||
|
||||
protected function getCustomCapabilities() {
|
||||
return array(
|
||||
ProjectCreateProjectsCapability::CAPABILITY => array(),
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -1972,20 +1972,34 @@ abstract class PhabricatorEditEngine
|
|||
return $application->getIcon();
|
||||
}
|
||||
|
||||
public function loadQuickCreateItems() {
|
||||
$items = array();
|
||||
|
||||
if (!$this->hasCreateCapability()) {
|
||||
return $items;
|
||||
public function hasQuickCreateActions() {
|
||||
if (!$this->isEngineConfigurable()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$configs = $this->loadUsableConfigurationsForCreate();
|
||||
return true;
|
||||
}
|
||||
|
||||
public function newQuickCreateActions(array $configs) {
|
||||
$items = array();
|
||||
|
||||
if (!$configs) {
|
||||
// No items to add.
|
||||
} else if (count($configs) == 1) {
|
||||
return array();
|
||||
}
|
||||
|
||||
// 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);
|
||||
$items[] = $this->newQuickCreateItem($config);
|
||||
$items[] = $this->newQuickCreateAction($config);
|
||||
} else {
|
||||
$group_name = $this->getQuickCreateMenuHeaderText();
|
||||
|
||||
|
@ -1994,7 +2008,7 @@ abstract class PhabricatorEditEngine
|
|||
->setName($group_name);
|
||||
|
||||
foreach ($configs as $config) {
|
||||
$items[] = $this->newQuickCreateItem($config)
|
||||
$items[] = $this->newQuickCreateAction($config)
|
||||
->setIndented(true);
|
||||
}
|
||||
}
|
||||
|
@ -2017,7 +2031,7 @@ abstract class PhabricatorEditEngine
|
|||
return $configs;
|
||||
}
|
||||
|
||||
private function newQuickCreateItem(
|
||||
private function newQuickCreateAction(
|
||||
PhabricatorEditEngineConfiguration $config) {
|
||||
|
||||
$item_name = $config->getName();
|
||||
|
|
Loading…
Reference in a new issue