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

Allow EditEngine forms to have defaults assigned

Summary: Ref T9132. Allow form configurations to include defaults (like default projects, spaces, policies, etc).

Test Plan:
Defaulted "Language" to "Rainbow", plus other adjustments:

{F975746}

{F975747}

{F975748}

{F975749}

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T9132

Differential Revision: https://secure.phabricator.com/D14508
This commit is contained in:
epriestley 2015-11-18 10:38:12 -08:00
parent 9aee90f8c1
commit 53d5cd3950
9 changed files with 234 additions and 3 deletions

View file

@ -2112,6 +2112,7 @@ phutil_register_library_map(array(
'PhabricatorEditEngine' => 'applications/transactions/editengine/PhabricatorEditEngine.php', 'PhabricatorEditEngine' => 'applications/transactions/editengine/PhabricatorEditEngine.php',
'PhabricatorEditEngineAPIMethod' => 'applications/transactions/editengine/PhabricatorEditEngineAPIMethod.php', 'PhabricatorEditEngineAPIMethod' => 'applications/transactions/editengine/PhabricatorEditEngineAPIMethod.php',
'PhabricatorEditEngineConfiguration' => 'applications/transactions/storage/PhabricatorEditEngineConfiguration.php', 'PhabricatorEditEngineConfiguration' => 'applications/transactions/storage/PhabricatorEditEngineConfiguration.php',
'PhabricatorEditEngineConfigurationDefaultsController' => 'applications/transactions/controller/PhabricatorEditEngineConfigurationDefaultsController.php',
'PhabricatorEditEngineConfigurationEditController' => 'applications/transactions/controller/PhabricatorEditEngineConfigurationEditController.php', 'PhabricatorEditEngineConfigurationEditController' => 'applications/transactions/controller/PhabricatorEditEngineConfigurationEditController.php',
'PhabricatorEditEngineConfigurationEditEngine' => 'applications/transactions/editor/PhabricatorEditEngineConfigurationEditEngine.php', 'PhabricatorEditEngineConfigurationEditEngine' => 'applications/transactions/editor/PhabricatorEditEngineConfigurationEditEngine.php',
'PhabricatorEditEngineConfigurationEditor' => 'applications/transactions/editor/PhabricatorEditEngineConfigurationEditor.php', 'PhabricatorEditEngineConfigurationEditor' => 'applications/transactions/editor/PhabricatorEditEngineConfigurationEditor.php',
@ -6205,6 +6206,7 @@ phutil_register_library_map(array(
'PhabricatorApplicationTransactionInterface', 'PhabricatorApplicationTransactionInterface',
'PhabricatorPolicyInterface', 'PhabricatorPolicyInterface',
), ),
'PhabricatorEditEngineConfigurationDefaultsController' => 'PhabricatorEditEngineController',
'PhabricatorEditEngineConfigurationEditController' => 'PhabricatorEditEngineController', 'PhabricatorEditEngineConfigurationEditController' => 'PhabricatorEditEngineController',
'PhabricatorEditEngineConfigurationEditEngine' => 'PhabricatorEditEngine', 'PhabricatorEditEngineConfigurationEditEngine' => 'PhabricatorEditEngine',
'PhabricatorEditEngineConfigurationEditor' => 'PhabricatorApplicationTransactionEditor', 'PhabricatorEditEngineConfigurationEditor' => 'PhabricatorApplicationTransactionEditor',

View file

@ -47,6 +47,8 @@ final class PhabricatorTransactionsApplication extends PhabricatorApplication {
'PhabricatorEditEngineConfigurationSaveController', 'PhabricatorEditEngineConfigurationSaveController',
'reorder/(?P<key>[^/]+)/' => 'reorder/(?P<key>[^/]+)/' =>
'PhabricatorEditEngineConfigurationReorderController', 'PhabricatorEditEngineConfigurationReorderController',
'defaults/(?P<key>[^/]+)/' =>
'PhabricatorEditEngineConfigurationDefaultsController',
), ),
), ),
), ),

View file

@ -0,0 +1,111 @@
<?php
final class PhabricatorEditEngineConfigurationDefaultsController
extends PhabricatorEditEngineController {
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))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
if (!$config) {
return id(new Aphront404Response());
}
$cancel_uri = "/transactions/editengine/{$engine_key}/view/{$key}/";
$engine = $config->getEngine();
$fields = $engine->getFieldsForConfig($config);
foreach ($fields as $key => $field) {
if (!$field->getIsDefaultable()) {
unset($fields[$key]);
continue;
}
}
foreach ($fields as $field) {
$field->setIsEditDefaults(true);
}
if ($request->isFormPost()) {
$xactions = array();
foreach ($fields as $field) {
$field->readValueFromSubmit($request);
}
$type = PhabricatorEditEngineConfigurationTransaction::TYPE_DEFAULT;
$xactions = array();
foreach ($fields as $field) {
$new_value = $field->getValueForDefaults();
$xactions[] = id(new PhabricatorEditEngineConfigurationTransaction())
->setTransactionType($type)
->setMetadataValue('field.key', $field->getKey())
->setNewValue($new_value);
}
$editor = id(new PhabricatorEditEngineConfigurationEditor())
->setActor($viewer)
->setContentSourceFromRequest($request)
->setContinueOnMissingFields(true)
->setContinueOnNoEffect(true);
$editor->applyTransactions($config, $xactions);
return id(new AphrontRedirectResponse())
->setURI($cancel_uri);
}
$title = pht('Edit Form Defaults');
$form = id(new AphrontFormView())
->setUser($viewer);
foreach ($fields as $field) {
$field->appendToForm($form);
}
$form
->appendControl(
id(new AphrontFormSubmitControl())
->setValue(pht('Save Defaults'))
->addCancelButton($cancel_uri));
$info = id(new PHUIInfoView())
->setSeverity(PHUIInfoView::SEVERITY_NOTICE)
->setErrors(
array(
pht('You are editing the default values for this form.'),
));
$box = id(new PHUIObjectBoxView())
->setHeaderText($title)
->setInfoView($info)
->setForm($form);
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(pht('Form %d', $config->getID()), $cancel_uri);
$crumbs->addTextCrumb(pht('Edit Defaults'));
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->appendChild($box);
}
}

View file

@ -119,11 +119,21 @@ final class PhabricatorEditEngineConfigurationViewController
->setIcon('fa-th-list') ->setIcon('fa-th-list')
->setHref($use_uri)); ->setHref($use_uri));
$defaults_uri = "{$base_uri}/defaults/{$form_key}/";
$view->addAction(
id(new PhabricatorActionView())
->setName(pht('Change Default Values'))
->setIcon('fa-paint-brush')
->setHref($defaults_uri)
->setWorkflow(!$can_edit)
->setDisabled(!$can_edit));
$reorder_uri = "{$base_uri}/reorder/{$form_key}/"; $reorder_uri = "{$base_uri}/reorder/{$form_key}/";
$view->addAction( $view->addAction(
id(new PhabricatorActionView()) id(new PhabricatorActionView())
->setName(pht('Reorder Fields')) ->setName(pht('Change Field Order'))
->setIcon('fa-sort-alpha-asc') ->setIcon('fa-sort-alpha-asc')
->setHref($reorder_uri) ->setHref($reorder_uri)
->setWorkflow(true) ->setWorkflow(true)

View file

@ -62,8 +62,12 @@ abstract class PhabricatorEditEngine
PhabricatorEditEngineConfiguration $config) { PhabricatorEditEngineConfiguration $config) {
$object = $this->newEditableObject(); $object = $this->newEditableObject();
$this->editEngineConfiguration = $config; $this->editEngineConfiguration = $config;
// This is mostly making sure that we fill in default values.
$this->setIsCreate(true);
return $this->buildEditFields($object); return $this->buildEditFields($object);
} }

View file

@ -16,6 +16,8 @@ abstract class PhabricatorEditField extends Phobject {
private $isLocked; private $isLocked;
private $isPreview; private $isPreview;
private $isReorderable = true; private $isReorderable = true;
private $isEditDefaults;
private $isDefaultable = true;
public function setKey($key) { public function setKey($key) {
$this->key = $key; $this->key = $key;
@ -98,6 +100,24 @@ abstract class PhabricatorEditField extends Phobject {
return $this->isReorderable; return $this->isReorderable;
} }
public function setIsEditDefaults($is_edit_defaults) {
$this->isEditDefaults = $is_edit_defaults;
return $this;
}
public function getIsEditDefaults() {
return $this->isEditDefaults;
}
public function setIsDefaultable($is_defaultable) {
$this->isDefaultable = $is_defaultable;
return $this;
}
public function getIsDefaultable() {
return $this->isDefaultable;
}
protected function newControl() { protected function newControl() {
throw new PhutilMethodNotImplementedException(); throw new PhutilMethodNotImplementedException();
} }
@ -116,10 +136,16 @@ abstract class PhabricatorEditField extends Phobject {
$control->setLabel($this->getLabel()); $control->setLabel($this->getLabel());
} }
if ($this->getIsLocked() || $this->getIsPreview()) { if ($this->getIsPreview()) {
$control->setDisabled(true); $disabled = true;
} else if ($this->getIsEditDefaults()) {
$disabled = false;
} else {
$disabled = $this->getIsLocked();
} }
$control->setDisabled($disabled);
return $control; return $control;
} }
@ -135,6 +161,19 @@ abstract class PhabricatorEditField extends Phobject {
return $this->getValue(); return $this->getValue();
} }
public function getValueForDefaults() {
$value = $this->getValue();
// By default, just treat the empty string like `null` since they're
// equivalent for almost all fields and this reduces the number of
// meaningless transactions we generate when adjusting defaults.
if ($value === '') {
return null;
}
return $value;
}
protected function getValue() { protected function getValue() {
return $this->value; return $this->value;
} }

View file

@ -20,6 +20,7 @@ final class PhabricatorEditEngineConfigurationEditor
$types[] = PhabricatorEditEngineConfigurationTransaction::TYPE_NAME; $types[] = PhabricatorEditEngineConfigurationTransaction::TYPE_NAME;
$types[] = PhabricatorEditEngineConfigurationTransaction::TYPE_PREAMBLE; $types[] = PhabricatorEditEngineConfigurationTransaction::TYPE_PREAMBLE;
$types[] = PhabricatorEditEngineConfigurationTransaction::TYPE_ORDER; $types[] = PhabricatorEditEngineConfigurationTransaction::TYPE_ORDER;
$types[] = PhabricatorEditEngineConfigurationTransaction::TYPE_DEFAULT;
return $types; return $types;
} }
@ -63,6 +64,9 @@ final class PhabricatorEditEngineConfigurationEditor
return $object->getPreamble(); return $object->getPreamble();
case PhabricatorEditEngineConfigurationTransaction::TYPE_ORDER: case PhabricatorEditEngineConfigurationTransaction::TYPE_ORDER:
return $object->getFieldOrder(); return $object->getFieldOrder();
case PhabricatorEditEngineConfigurationTransaction::TYPE_DEFAULT:
$field_key = $xaction->getMetadataValue('field.key');
return $object->getFieldDefault($field_key);
} }
} }
@ -74,6 +78,7 @@ final class PhabricatorEditEngineConfigurationEditor
case PhabricatorEditEngineConfigurationTransaction::TYPE_NAME: case PhabricatorEditEngineConfigurationTransaction::TYPE_NAME:
case PhabricatorEditEngineConfigurationTransaction::TYPE_PREAMBLE; case PhabricatorEditEngineConfigurationTransaction::TYPE_PREAMBLE;
case PhabricatorEditEngineConfigurationTransaction::TYPE_ORDER: case PhabricatorEditEngineConfigurationTransaction::TYPE_ORDER:
case PhabricatorEditEngineConfigurationTransaction::TYPE_DEFAULT:
return $xaction->getNewValue(); return $xaction->getNewValue();
} }
} }
@ -92,6 +97,10 @@ final class PhabricatorEditEngineConfigurationEditor
case PhabricatorEditEngineConfigurationTransaction::TYPE_ORDER: case PhabricatorEditEngineConfigurationTransaction::TYPE_ORDER:
$object->setFieldOrder($xaction->getNewValue()); $object->setFieldOrder($xaction->getNewValue());
return; return;
case PhabricatorEditEngineConfigurationTransaction::TYPE_DEFAULT:
$field_key = $xaction->getMetadataValue('field.key');
$object->setFieldDefault($field_key, $xaction->getNewValue());
return;
} }
return parent::applyCustomInternalTransaction($object, $xaction); return parent::applyCustomInternalTransaction($object, $xaction);
@ -105,6 +114,7 @@ final class PhabricatorEditEngineConfigurationEditor
case PhabricatorEditEngineConfigurationTransaction::TYPE_NAME: case PhabricatorEditEngineConfigurationTransaction::TYPE_NAME:
case PhabricatorEditEngineConfigurationTransaction::TYPE_PREAMBLE; case PhabricatorEditEngineConfigurationTransaction::TYPE_PREAMBLE;
case PhabricatorEditEngineConfigurationTransaction::TYPE_ORDER; case PhabricatorEditEngineConfigurationTransaction::TYPE_ORDER;
case PhabricatorEditEngineConfigurationTransaction::TYPE_DEFAULT:
return; return;
} }

View file

@ -105,6 +105,7 @@ final class PhabricatorEditEngineConfiguration
'config.preamble' => id(new PhabricatorInstructionsEditField()) 'config.preamble' => id(new PhabricatorInstructionsEditField())
->setKey('config.preamble') ->setKey('config.preamble')
->setIsReorderable(false) ->setIsReorderable(false)
->setIsDefaultable(false)
->setValue($preamble), ->setValue($preamble),
) + $fields; ) + $fields;
} }
@ -175,6 +176,17 @@ final class PhabricatorEditEngineConfiguration
return $this->getProperty('order', array()); return $this->getProperty('order', array());
} }
public function getFieldDefault($key) {
$defaults = $this->getProperty('defaults', array());
return idx($defaults, $key);
}
public function setFieldDefault($key, $value) {
$defaults = $this->getProperty('defaults', array());
$defaults[$key] = $value;
return $this->setProperty('defaults', $defaults);
}
/* -( PhabricatorPolicyInterface )----------------------------------------- */ /* -( PhabricatorPolicyInterface )----------------------------------------- */

View file

@ -6,6 +6,7 @@ final class PhabricatorEditEngineConfigurationTransaction
const TYPE_NAME = 'editengine.config.name'; const TYPE_NAME = 'editengine.config.name';
const TYPE_PREAMBLE = 'editengine.config.preamble'; const TYPE_PREAMBLE = 'editengine.config.preamble';
const TYPE_ORDER = 'editengine.config.order'; const TYPE_ORDER = 'editengine.config.order';
const TYPE_DEFAULT = 'editengine.config.default';
public function getApplicationName() { public function getApplicationName() {
return 'search'; return 'search';
@ -19,4 +20,44 @@ final class PhabricatorEditEngineConfigurationTransaction
return null; return null;
} }
public function getTitle() {
$author_phid = $this->getAuthorPHID();
$old = $this->getOldValue();
$new = $this->getNewValue();
$type = $this->getTransactionType();
switch ($type) {
case self::TYPE_NAME:
if (strlen($old)) {
return pht(
'%s renamed this form from "%s" to "%s".',
$this->renderHandleLink($author_phid),
$old,
$new);
} else {
return pht(
'%s named this form "%s".',
$this->renderHandleLink($author_phid),
$new);
}
case self::TYPE_PREAMBLE:
return pht(
'%s updated the preamble for this form.',
$this->renderHandleLink($author_phid));
case self::TYPE_ORDER:
return pht(
'%s reordered the fields in this form.',
$this->renderHandleLink($author_phid));
case self::TYPE_DEFAULT:
$key = $this->getMetadataValue('field.key');
return pht(
'%s changed the default value for field "%s".',
$this->renderHandleLink($author_phid),
$key);
}
return parent::getTitle();
}
} }