1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-10 08:52:39 +01:00

Allow EditEngine configurations to be disabled and marked as "Default"

Summary:
Ref T9132.

Let configurations be enabled/disabled. This doesn't do much right now.

Let configurations be marked as default entries in the application "Create" menu. This makes them show up in the application in a dropdown, so you can replace the default form and/or provide several forms.

In Maniphest, we'll do this to provide a menu something like this:

  - New Bug Report
  - New Feature Request
  - ADVANCED TASK CREATION!!11~ (only available for Community members)

Test Plan: {F1005679}

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T9132

Differential Revision: https://secure.phabricator.com/D14584
This commit is contained in:
epriestley 2015-11-19 14:16:44 -08:00
parent 760655aa09
commit 37893ba2e6
16 changed files with 377 additions and 24 deletions

View file

@ -2114,7 +2114,9 @@ phutil_register_library_map(array(
'PhabricatorEditEngine' => 'applications/transactions/editengine/PhabricatorEditEngine.php',
'PhabricatorEditEngineAPIMethod' => 'applications/transactions/editengine/PhabricatorEditEngineAPIMethod.php',
'PhabricatorEditEngineConfiguration' => 'applications/transactions/storage/PhabricatorEditEngineConfiguration.php',
'PhabricatorEditEngineConfigurationDefaultCreateController' => 'applications/transactions/controller/PhabricatorEditEngineConfigurationDefaultCreateController.php',
'PhabricatorEditEngineConfigurationDefaultsController' => 'applications/transactions/controller/PhabricatorEditEngineConfigurationDefaultsController.php',
'PhabricatorEditEngineConfigurationDisableController' => 'applications/transactions/controller/PhabricatorEditEngineConfigurationDisableController.php',
'PhabricatorEditEngineConfigurationEditController' => 'applications/transactions/controller/PhabricatorEditEngineConfigurationEditController.php',
'PhabricatorEditEngineConfigurationEditEngine' => 'applications/transactions/editor/PhabricatorEditEngineConfigurationEditEngine.php',
'PhabricatorEditEngineConfigurationEditor' => 'applications/transactions/editor/PhabricatorEditEngineConfigurationEditor.php',
@ -6210,7 +6212,9 @@ phutil_register_library_map(array(
'PhabricatorApplicationTransactionInterface',
'PhabricatorPolicyInterface',
),
'PhabricatorEditEngineConfigurationDefaultCreateController' => 'PhabricatorEditEngineController',
'PhabricatorEditEngineConfigurationDefaultsController' => 'PhabricatorEditEngineController',
'PhabricatorEditEngineConfigurationDisableController' => 'PhabricatorEditEngineController',
'PhabricatorEditEngineConfigurationEditController' => 'PhabricatorEditEngineController',
'PhabricatorEditEngineConfigurationEditEngine' => 'PhabricatorEditEngine',
'PhabricatorEditEngineConfigurationEditor' => 'PhabricatorApplicationTransactionEditor',

View file

@ -640,7 +640,7 @@ abstract class PhabricatorApplication
'(?P<id>[0-9]\d*)/)?'.
'(?:'.
'(?:'.
'(?P<editAction>parameters)'.
'(?P<editAction>parameters|nodefault)'.
'|'.
'(?:form/(?P<formKey>[^/]+))'.
')'.

View file

@ -15,11 +15,9 @@ final class PhabricatorPasteListController extends PhabricatorPasteController {
protected function buildApplicationCrumbs() {
$crumbs = parent::buildApplicationCrumbs();
$crumbs->addAction(
id(new PHUIListItemView())
->setName(pht('Create Paste'))
->setHref($this->getApplicationURI('edit/'))
->setIcon('fa-plus-square'));
id(new PhabricatorPasteEditEngine())
->setViewer($this->getViewer())
->addActionToCrumbs($crumbs);
return $crumbs;
}

View file

@ -51,6 +51,10 @@ final class PhabricatorTransactionsApplication extends PhabricatorApplication {
'PhabricatorEditEngineConfigurationDefaultsController',
'lock/(?P<key>[^/]+)/' =>
'PhabricatorEditEngineConfigurationLockController',
'defaultcreate/(?P<key>[^/]+)/' =>
'PhabricatorEditEngineConfigurationDefaultCreateController',
'disable/(?P<key>[^/]+)/' =>
'PhabricatorEditEngineConfigurationDisableController',
),
),
),

View file

@ -0,0 +1,61 @@
<?php
final class PhabricatorEditEngineConfigurationDefaultCreateController
extends PhabricatorEditEngineController {
public function handleRequest(AphrontRequest $request) {
$viewer = $this->getViewer();
$config = $this->loadConfigForEdit();
if (!$config) {
return id(new Aphront404Response());
}
$engine_key = $config->getEngineKey();
$key = $config->getIdentifier();
$cancel_uri = "/transactions/editengine/{$engine_key}/view/{$key}/";
$type = PhabricatorEditEngineConfigurationTransaction::TYPE_DEFAULTCREATE;
if ($request->isFormPost()) {
$xactions = array();
$xactions[] = id(new PhabricatorEditEngineConfigurationTransaction())
->setTransactionType($type)
->setNewValue(!$config->getIsDefault());
$editor = id(new PhabricatorEditEngineConfigurationEditor())
->setActor($viewer)
->setContentSourceFromRequest($request)
->setContinueOnMissingFields(true)
->setContinueOnNoEffect(true);
$editor->applyTransactions($config, $xactions);
return id(new AphrontRedirectResponse())
->setURI($cancel_uri);
}
if ($config->getIsDefault()) {
$title = pht('Remove From "Create" Menu');
$body = pht(
'Remove this form from the application "Create" menu? It will still '.
'function properly, but no longer be reachable directly from the '.
'application.');
$button = pht('Remove From Menu');
} else {
$title = pht('Add To "Create" Menu');
$body = pht(
'Add this form to the application "Create" menu? Users will '.
'be able to choose it when creating new objects.');
$button = pht('Add To Menu');
}
return $this->newDialog()
->setTitle($title)
->appendParagraph($body)
->addSubmitButton($button)
->addCancelbutton($cancel_uri);
}
}

View file

@ -0,0 +1,59 @@
<?php
final class PhabricatorEditEngineConfigurationDisableController
extends PhabricatorEditEngineController {
public function handleRequest(AphrontRequest $request) {
$viewer = $this->getViewer();
$config = $this->loadConfigForEdit();
if (!$config) {
return id(new Aphront404Response());
}
$engine_key = $config->getEngineKey();
$key = $config->getIdentifier();
$cancel_uri = "/transactions/editengine/{$engine_key}/view/{$key}/";
$type = PhabricatorEditEngineConfigurationTransaction::TYPE_DISABLE;
if ($request->isFormPost()) {
$xactions = array();
$xactions[] = id(new PhabricatorEditEngineConfigurationTransaction())
->setTransactionType($type)
->setNewValue(!$config->getIsDisabled());
$editor = id(new PhabricatorEditEngineConfigurationEditor())
->setActor($viewer)
->setContentSourceFromRequest($request)
->setContinueOnMissingFields(true)
->setContinueOnNoEffect(true);
$editor->applyTransactions($config, $xactions);
return id(new AphrontRedirectResponse())
->setURI($cancel_uri);
}
if ($config->getIsDisabled()) {
$title = pht('Enable Form');
$body = pht(
'Enable this form? Users who can see it will be able to use it to '.
'create objects.');
$button = pht('Enable Form');
} else {
$title = pht('Disable Form');
$body = pht(
'Disable this form? Users will no longer be able to use it.');
$button = pht('Disable Form');
}
return $this->newDialog()
->setTitle($title)
->appendParagraph($body)
->addSubmitButton($button)
->addCancelbutton($cancel_uri);
}
}

View file

@ -17,16 +17,16 @@ final class PhabricatorEditEngineConfigurationListController
}
protected function buildApplicationCrumbs() {
$viewer = $this->getViewer();
$crumbs = parent::buildApplicationCrumbs();
$engine_key = $this->getEngineKey();
$edit_uri = "/transactions/editengine/{$engine_key}/edit/";
$target_key = $this->getEngineKey();
$target_engine = PhabricatorEditEngine::getByKey($viewer, $target_key);
$crumbs->addAction(
id(new PHUIListItemView())
->setName(pht('New Form'))
->setHref($edit_uri)
->setIcon('fa-plus-square'));
id(new PhabricatorEditEngineConfigurationEditEngine())
->setTargetEngine($target_engine)
->setViewer($viewer)
->addActionToCrumbs($crumbs);
return $crumbs;
}

View file

@ -8,17 +8,9 @@ final class PhabricatorEditEngineConfigurationViewController
}
public function handleRequest(AphrontRequest $request) {
$engine_key = $request->getURIData('engineKey');
$this->setEngineKey($engine_key);
$key = $request->getURIData('key');
$viewer = $this->getViewer();
$config = id(new PhabricatorEditEngineConfigurationQuery())
->setViewer($viewer)
->withEngineKeys(array($engine_key))
->withIdentifiers(array($key))
->executeOne();
$config = $this->loadConfigForEdit();
if (!$config) {
return id(new Aphront404Response());
}
@ -149,6 +141,42 @@ final class PhabricatorEditEngineConfigurationViewController
->setWorkflow(true)
->setDisabled(!$can_edit));
$disable_uri = "{$base_uri}/disable/{$form_key}/";
if ($config->getIsDisabled()) {
$disable_name = pht('Enable Form');
$disable_icon = 'fa-check';
} else {
$disable_name = pht('Disable Form');
$disable_icon = 'fa-ban';
}
$view->addAction(
id(new PhabricatorActionView())
->setName($disable_name)
->setIcon($disable_icon)
->setHref($disable_uri)
->setWorkflow(true)
->setDisabled(!$can_edit));
$defaultcreate_uri = "{$base_uri}/defaultcreate/{$form_key}/";
if ($config->getIsDefault()) {
$defaultcreate_name = pht('Remove from "Create" Menu');
$defaultcreate_icon = 'fa-minus';
} else {
$defaultcreate_name = pht('Add to "Create" Menu');
$defaultcreate_icon = 'fa-plus';
}
$view->addAction(
id(new PhabricatorActionView())
->setName($defaultcreate_name)
->setIcon($defaultcreate_icon)
->setHref($defaultcreate_uri)
->setWorkflow(true)
->setDisabled(!$can_edit));
return $view;
}

View file

@ -34,4 +34,39 @@ abstract class PhabricatorEditEngineController
return $crumbs;
}
protected function loadConfigForEdit() {
$request = $this->getRequest();
$viewer = $this->getViewer();
$engine_key = $request->getURIData('engineKey');
$this->setEngineKey($engine_key);
$key = $request->getURIData('key');
$config = id(new PhabricatorEditEngineConfigurationQuery())
->setViewer($viewer)
->withEngineKeys(array($engine_key))
->withIdentifiers(array($key))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
if ($config) {
$engine = $config->getEngine();
// TODO: When we're editing the meta-engine, we need to set the engine
// itself as its own target. This is hacky and it would be nice to find
// a cleaner approach later.
if ($engine instanceof PhabricatorEditEngineConfigurationEditEngine) {
$engine->setTargetEngine($engine);
}
}
return $config;
}
}

View file

@ -352,7 +352,9 @@ abstract class PhabricatorEditEngine
if (!$has_default) {
$first = head($configurations);
if (!$first->getBuiltinKey()) {
$first->setBuiltinKey(self::EDITENGINECONFIG_DEFAULT);
$first
->setBuiltinKey(self::EDITENGINECONFIG_DEFAULT)
->setIsDefault(true);
if (!strlen($first->getName())) {
$first->setName($this->getObjectCreateShortText());
@ -629,6 +631,8 @@ abstract class PhabricatorEditEngine
switch ($action) {
case 'parameters':
return $this->buildParametersResponse($object);
case 'nodefault':
return $this->buildNoDefaultResponse($object);
default:
return $this->buildEditResponse($object);
}
@ -820,6 +824,74 @@ abstract class PhabricatorEditEngine
return $actions;
}
final public function addActionToCrumbs(PHUICrumbsView $crumbs) {
$viewer = $this->getViewer();
$configs = id(new PhabricatorEditEngineConfigurationQuery())
->setViewer($viewer)
->withEngineKeys(array($this->getEngineKey()))
->withIsDefault(true)
->withIsDisabled(false)
->execute();
$dropdown = null;
$disabled = false;
$workflow = false;
$menu_icon = 'fa-plus-square';
if (!$configs) {
if ($viewer->isLoggedIn()) {
$disabled = true;
} else {
// If the viewer isn't logged in, assume they'll get hit with a login
// dialog and are likely able to create objects after they log in.
$disabled = false;
}
$workflow = true;
$create_uri = $this->getEditURI(null, 'nodefault/');
} else {
$config = head($configs);
$form_key = $config->getIdentifier();
$create_uri = $this->getEditURI(null, "form/{$form_key}/");
if (count($configs) > 1) {
$configs = msort($configs, 'getDisplayName');
$menu_icon = 'fa-caret-square-o-down';
$dropdown = id(new PhabricatorActionListView())
->setUser($viewer);
foreach ($configs as $config) {
$form_key = $config->getIdentifier();
$config_uri = $this->getEditURI(null, "form/{$form_key}/");
$item_icon = 'fa-plus';
$dropdown->addAction(
id(new PhabricatorActionView())
->setName($config->getDisplayName())
->setIcon($item_icon)
->setHref($config_uri));
}
}
}
$action = id(new PHUIListItemView())
->setName($this->getObjectCreateShortText())
->setHref($create_uri)
->setIcon($menu_icon)
->setWorkflow($workflow)
->setDisabled($disabled);
if ($dropdown) {
$action->setDropdownMenu($dropdown);
}
$crumbs->addAction($action);
}
/* -( Responding to HTTP Parameter Requests )------------------------------ */
@ -864,6 +936,19 @@ abstract class PhabricatorEditEngine
}
private function buildNoDefaultResponse($object) {
$cancel_uri = $this->getObjectCreateCancelURI($object);
return $this->getController()
->newDialog()
->setTitle(pht('No Default Create Forms'))
->appendParagraph(
pht(
'This application is not configured with any visible, enabled '.
'forms for creating objects.'))
->addCancelButton($cancel_uri);
}
/* -( Conduit )------------------------------------------------------------ */

View file

@ -13,6 +13,9 @@ final class PhabricatorEditEngineConfigurationEditEngine
}
public function getTargetEngine() {
if (!$this->targetEngine) {
throw new PhutilInvalidStateException('setTargetEngine');
}
return $this->targetEngine;
}

View file

@ -22,6 +22,10 @@ final class PhabricatorEditEngineConfigurationEditor
$types[] = PhabricatorEditEngineConfigurationTransaction::TYPE_ORDER;
$types[] = PhabricatorEditEngineConfigurationTransaction::TYPE_DEFAULT;
$types[] = PhabricatorEditEngineConfigurationTransaction::TYPE_LOCKS;
$types[] =
PhabricatorEditEngineConfigurationTransaction::TYPE_DEFAULTCREATE;
$types[] = PhabricatorEditEngineConfigurationTransaction::TYPE_DISABLE;
return $types;
}
@ -70,6 +74,10 @@ final class PhabricatorEditEngineConfigurationEditor
return $object->getFieldDefault($field_key);
case PhabricatorEditEngineConfigurationTransaction::TYPE_LOCKS:
return $object->getFieldLocks();
case PhabricatorEditEngineConfigurationTransaction::TYPE_DEFAULTCREATE:
return (int)$object->getIsDefault();
case PhabricatorEditEngineConfigurationTransaction::TYPE_DISABLE:
return (int)$object->getIsDisabled();
}
}
@ -84,6 +92,9 @@ final class PhabricatorEditEngineConfigurationEditor
case PhabricatorEditEngineConfigurationTransaction::TYPE_DEFAULT:
case PhabricatorEditEngineConfigurationTransaction::TYPE_LOCKS:
return $xaction->getNewValue();
case PhabricatorEditEngineConfigurationTransaction::TYPE_DEFAULTCREATE:
case PhabricatorEditEngineConfigurationTransaction::TYPE_DISABLE:
return (int)$xaction->getNewValue();
}
}
@ -108,6 +119,12 @@ final class PhabricatorEditEngineConfigurationEditor
case PhabricatorEditEngineConfigurationTransaction::TYPE_LOCKS:
$object->setFieldLocks($xaction->getNewValue());
return;
case PhabricatorEditEngineConfigurationTransaction::TYPE_DEFAULTCREATE:
$object->setIsDefault($xaction->getNewValue());
return;
case PhabricatorEditEngineConfigurationTransaction::TYPE_DISABLE:
$object->setIsDisabled($xaction->getNewValue());
return;
}
return parent::applyCustomInternalTransaction($object, $xaction);
@ -123,6 +140,8 @@ final class PhabricatorEditEngineConfigurationEditor
case PhabricatorEditEngineConfigurationTransaction::TYPE_ORDER;
case PhabricatorEditEngineConfigurationTransaction::TYPE_DEFAULT:
case PhabricatorEditEngineConfigurationTransaction::TYPE_LOCKS:
case PhabricatorEditEngineConfigurationTransaction::TYPE_DEFAULTCREATE:
case PhabricatorEditEngineConfigurationTransaction::TYPE_DISABLE:
return;
}

View file

@ -8,6 +8,8 @@ final class PhabricatorEditEngineConfigurationQuery
private $engineKeys;
private $builtinKeys;
private $identifiers;
private $default;
private $disabled;
public function withIDs(array $ids) {
$this->ids = $ids;
@ -34,6 +36,16 @@ final class PhabricatorEditEngineConfigurationQuery
return $this;
}
public function withIsDefault($default) {
$this->default = $default;
return $this;
}
public function withIsDisabled($disabled) {
$this->disabled = $disabled;
return $this;
}
public function newResultObject() {
return new PhabricatorEditEngineConfiguration();
}
@ -118,6 +130,22 @@ final class PhabricatorEditEngineConfigurationQuery
}
}
if ($this->default !== null) {
foreach ($page as $key => $config) {
if ($config->getIsDefault() != $this->default) {
unset($page[$key]);
}
}
}
if ($this->disabled !== null) {
foreach ($page as $key => $config) {
if ($config->getIsDisabled() != $this->disabled) {
unset($page[$key]);
}
}
}
if ($this->identifiers !== null) {
$identifiers = array_fuse($this->identifiers);
foreach ($page as $key => $config) {

View file

@ -92,6 +92,13 @@ final class PhabricatorEditEngineConfigurationSearchEngine
}
$item->setHref("/transactions/editengine/{$engine_key}/view/{$key}/");
if ($config->getIsDefault()) {
$item->addIcon('fa-plus', pht('Default'));
}
if ($config->getIsDisabled()) {
$item->addIcon('fa-ban', pht('Disabled'));
}
$list->addItem($item);
}

View file

@ -29,7 +29,7 @@ final class PhabricatorEditEngineConfiguration
PhabricatorUser $actor,
PhabricatorEditEngine $engine) {
// TODO: This should probably be controlled by a new defualt capability.
// TODO: This should probably be controlled by a new default capability.
$edit_policy = PhabricatorPolicies::POLICY_ADMIN;
return id(new PhabricatorEditEngineConfiguration())

View file

@ -8,6 +8,8 @@ final class PhabricatorEditEngineConfigurationTransaction
const TYPE_ORDER = 'editengine.config.order';
const TYPE_DEFAULT = 'editengine.config.default';
const TYPE_LOCKS = 'editengine.config.locks';
const TYPE_DEFAULTCREATE = 'editengine.config.default.create';
const TYPE_DISABLE = 'editengine.config.disable';
public function getApplicationName() {
return 'search';
@ -60,6 +62,26 @@ final class PhabricatorEditEngineConfigurationTransaction
return pht(
'%s changed locked and hidden fields.',
$this->renderHandleLink($author_phid));
case self::TYPE_DEFAULTCREATE:
if ($new) {
return pht(
'%s added this form to the "Create" menu.',
$this->renderHandleLink($author_phid));
} else {
return pht(
'%s removed this form from the "Create" menu.',
$this->renderHandleLink($author_phid));
}
case self::TYPE_DISABLE:
if ($new) {
return pht(
'%s disabled this form.',
$this->renderHandleLink($author_phid));
} else {
return pht(
'%s enabled this form.',
$this->renderHandleLink($author_phid));
}
}
return parent::getTitle();