diff --git a/resources/celerity/map.php b/resources/celerity/map.php index f8d15a1af0..c45f8f5346 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -419,6 +419,7 @@ return array( 'rsrc/js/application/repository/repository-crossreference.js' => 'e5339c43', 'rsrc/js/application/search/behavior-reorder-queries.js' => 'e9581f08', 'rsrc/js/application/slowvote/behavior-slowvote-embed.js' => '887ad43f', + 'rsrc/js/application/transactions/behavior-reorder-fields.js' => 'b59e1e96', 'rsrc/js/application/transactions/behavior-show-older-transactions.js' => 'dbbf48b6', 'rsrc/js/application/transactions/behavior-transaction-comment-form.js' => 'b23b49e6', 'rsrc/js/application/transactions/behavior-transaction-list.js' => '13c739ea', @@ -591,6 +592,7 @@ return array( 'javelin-behavior-doorkeeper-tag' => 'e5822781', 'javelin-behavior-drydock-live-operation-status' => '901935ef', 'javelin-behavior-durable-column' => 'c72aa091', + 'javelin-behavior-editengine-reorder-fields' => 'b59e1e96', 'javelin-behavior-error-log' => '6882e80a', 'javelin-behavior-event-all-day' => '38dcf3c8', 'javelin-behavior-fancy-datepicker' => '8ae55229', @@ -1714,6 +1716,13 @@ return array( 'javelin-typeahead-preloaded-source', 'javelin-util', ), + 'b59e1e96' => array( + 'javelin-behavior', + 'javelin-stratcom', + 'javelin-workflow', + 'javelin-dom', + 'phabricator-draggable-list', + ), 'b5c256b8' => array( 'javelin-install', 'javelin-dom', diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 87c661c4a5..0f239ea0ad 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -2118,6 +2118,7 @@ phutil_register_library_map(array( 'PhabricatorEditEngineConfigurationListController' => 'applications/transactions/controller/PhabricatorEditEngineConfigurationListController.php', 'PhabricatorEditEngineConfigurationPHIDType' => 'applications/transactions/phid/PhabricatorEditEngineConfigurationPHIDType.php', 'PhabricatorEditEngineConfigurationQuery' => 'applications/transactions/query/PhabricatorEditEngineConfigurationQuery.php', + 'PhabricatorEditEngineConfigurationReorderController' => 'applications/transactions/controller/PhabricatorEditEngineConfigurationReorderController.php', 'PhabricatorEditEngineConfigurationSaveController' => 'applications/transactions/controller/PhabricatorEditEngineConfigurationSaveController.php', 'PhabricatorEditEngineConfigurationSearchEngine' => 'applications/transactions/query/PhabricatorEditEngineConfigurationSearchEngine.php', 'PhabricatorEditEngineConfigurationTransaction' => 'applications/transactions/storage/PhabricatorEditEngineConfigurationTransaction.php', @@ -2810,6 +2811,7 @@ phutil_register_library_map(array( 'PhabricatorRemarkupCowsayBlockInterpreter' => 'infrastructure/markup/interpreter/PhabricatorRemarkupCowsayBlockInterpreter.php', 'PhabricatorRemarkupCustomBlockRule' => 'infrastructure/markup/rule/PhabricatorRemarkupCustomBlockRule.php', 'PhabricatorRemarkupCustomInlineRule' => 'infrastructure/markup/rule/PhabricatorRemarkupCustomInlineRule.php', + 'PhabricatorRemarkupEditField' => 'applications/transactions/editfield/PhabricatorRemarkupEditField.php', 'PhabricatorRemarkupFigletBlockInterpreter' => 'infrastructure/markup/interpreter/PhabricatorRemarkupFigletBlockInterpreter.php', 'PhabricatorRemarkupUIExample' => 'applications/uiexample/examples/PhabricatorRemarkupUIExample.php', 'PhabricatorRepositoriesSetupCheck' => 'applications/config/check/PhabricatorRepositoriesSetupCheck.php', @@ -6209,6 +6211,7 @@ phutil_register_library_map(array( 'PhabricatorEditEngineConfigurationListController' => 'PhabricatorEditEngineController', 'PhabricatorEditEngineConfigurationPHIDType' => 'PhabricatorPHIDType', 'PhabricatorEditEngineConfigurationQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', + 'PhabricatorEditEngineConfigurationReorderController' => 'PhabricatorEditEngineController', 'PhabricatorEditEngineConfigurationSaveController' => 'PhabricatorEditEngineController', 'PhabricatorEditEngineConfigurationSearchEngine' => 'PhabricatorApplicationSearchEngine', 'PhabricatorEditEngineConfigurationTransaction' => 'PhabricatorApplicationTransaction', @@ -7021,6 +7024,7 @@ phutil_register_library_map(array( 'PhabricatorRemarkupCowsayBlockInterpreter' => 'PhutilRemarkupBlockInterpreter', 'PhabricatorRemarkupCustomBlockRule' => 'PhutilRemarkupBlockRule', 'PhabricatorRemarkupCustomInlineRule' => 'PhutilRemarkupRule', + 'PhabricatorRemarkupEditField' => 'PhabricatorEditField', 'PhabricatorRemarkupFigletBlockInterpreter' => 'PhutilRemarkupBlockInterpreter', 'PhabricatorRemarkupUIExample' => 'PhabricatorUIExample', 'PhabricatorRepositoriesSetupCheck' => 'PhabricatorSetupCheck', diff --git a/src/applications/base/PhabricatorApplication.php b/src/applications/base/PhabricatorApplication.php index 8dce30290d..f4b43a0ed1 100644 --- a/src/applications/base/PhabricatorApplication.php +++ b/src/applications/base/PhabricatorApplication.php @@ -636,7 +636,15 @@ abstract class PhabricatorApplication } protected function getEditRoutePattern($base = null) { - return $base.'(?:(?P[0-9]\d*)/)?(?:(?Pparameters)/)?'; + return $base.'(?:'. + '(?P[0-9]\d*)/)?'. + '(?:'. + '(?:'. + '(?Pparameters)'. + '|'. + '(?:form/(?P[^/]+))'. + ')'. + '/)?'; } protected function getQueryRoutePattern($base = null) { diff --git a/src/applications/transactions/application/PhabricatorTransactionsApplication.php b/src/applications/transactions/application/PhabricatorTransactionsApplication.php index 260fa889b4..1f78c71bd2 100644 --- a/src/applications/transactions/application/PhabricatorTransactionsApplication.php +++ b/src/applications/transactions/application/PhabricatorTransactionsApplication.php @@ -45,6 +45,8 @@ final class PhabricatorTransactionsApplication extends PhabricatorApplication { 'PhabricatorEditEngineConfigurationViewController', 'save/(?P[^/]+)/' => 'PhabricatorEditEngineConfigurationSaveController', + 'reorder/(?P[^/]+)/' => + 'PhabricatorEditEngineConfigurationReorderController', ), ), ), diff --git a/src/applications/transactions/controller/PhabricatorEditEngineConfigurationReorderController.php b/src/applications/transactions/controller/PhabricatorEditEngineConfigurationReorderController.php new file mode 100644 index 0000000000..15eb9530fd --- /dev/null +++ b/src/applications/transactions/controller/PhabricatorEditEngineConfigurationReorderController.php @@ -0,0 +1,123 @@ +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}/"; + $reorder_uri = "/transactions/editengine/{$engine_key}/reorder/{$key}/"; + + if ($request->isFormPost()) { + $xactions = array(); + $key_order = $request->getStrList('keyOrder'); + + $type_order = PhabricatorEditEngineConfigurationTransaction::TYPE_ORDER; + + $xactions[] = id(new PhabricatorEditEngineConfigurationTransaction()) + ->setTransactionType($type_order) + ->setNewValue($key_order); + + $editor = id(new PhabricatorEditEngineConfigurationEditor()) + ->setActor($viewer) + ->setContentSourceFromRequest($request) + ->setContinueOnMissingFields(true) + ->setContinueOnNoEffect(true); + + $editor->applyTransactions($config, $xactions); + + return id(new AphrontRedirectResponse()) + ->setURI($cancel_uri); + } + + $engine = $config->getEngine(); + $fields = $engine->getFieldsForConfig($config); + + $list_id = celerity_generate_unique_node_id(); + $input_id = celerity_generate_unique_node_id(); + + $list = id(new PHUIObjectItemListView()) + ->setUser($viewer) + ->setID($list_id) + ->setFlush(true); + + $key_order = array(); + foreach ($fields as $field) { + if (!$field->getIsReorderable()) { + continue; + } + + $label = $field->getLabel(); + $key = $field->getKey(); + + if ($label !== null) { + $header = $label; + } else { + $header = $key; + } + + $item = id(new PHUIObjectItemView()) + ->setHeader($header) + ->setGrippable(true) + ->addSigil('editengine-form-field') + ->setMetadata( + array( + 'fieldKey' => $key, + )); + + $list->addItem($item); + + $key_order[] = $key; + } + + Javelin::initBehavior( + 'editengine-reorder-fields', + array( + 'listID' => $list_id, + 'inputID' => $input_id, + 'reorderURI' => $reorder_uri, + )); + + $note = id(new PHUIInfoView()) + ->appendChild(pht('Drag and drop fields to reorder them.')) + ->setSeverity(PHUIInfoView::SEVERITY_NOTICE); + + $input = phutil_tag( + 'input', + array( + 'type' => 'hidden', + 'name' => 'keyOrder', + 'value' => implode(', ', $key_order), + 'id' => $input_id, + )); + + return $this->newDialog() + ->setTitle(pht('Reorder Fields')) + ->setWidth(AphrontDialogView::WIDTH_FORM) + ->appendChild($note) + ->appendChild($list) + ->appendChild($input) + ->addSubmitButton(pht('Save Changes')) + ->addCancelButton($cancel_uri); + } + +} diff --git a/src/applications/transactions/controller/PhabricatorEditEngineConfigurationViewController.php b/src/applications/transactions/controller/PhabricatorEditEngineConfigurationViewController.php index f65eed1746..deeed6252a 100644 --- a/src/applications/transactions/controller/PhabricatorEditEngineConfigurationViewController.php +++ b/src/applications/transactions/controller/PhabricatorEditEngineConfigurationViewController.php @@ -39,6 +39,8 @@ final class PhabricatorEditEngineConfigurationViewController ->setHeader($header) ->addPropertyList($properties); + $field_list = $this->buildFieldList($config); + $crumbs = $this->buildApplicationCrumbs(); if ($is_concrete) { @@ -62,6 +64,7 @@ final class PhabricatorEditEngineConfigurationViewController ->appendChild( array( $box, + $field_list, $timeline, )); } @@ -69,7 +72,8 @@ final class PhabricatorEditEngineConfigurationViewController private function buildActionView( PhabricatorEditEngineConfiguration $config) { $viewer = $this->getViewer(); - $engine_key = $this->getEngineKey(); + $engine = $config->getEngine(); + $engine_key = $engine->getEngineKey(); $can_edit = PhabricatorPolicyFilter::hasCapability( $viewer, @@ -79,13 +83,13 @@ final class PhabricatorEditEngineConfigurationViewController $view = id(new PhabricatorActionListView()) ->setUser($viewer); - $key = $config->getIdentifier(); + $form_key = $config->getIdentifier(); $base_uri = "/transactions/editengine/{$engine_key}"; $is_concrete = (bool)$config->getID(); if (!$is_concrete) { - $save_uri = "{$base_uri}/save/{$key}/"; + $save_uri = "{$base_uri}/save/{$form_key}/"; $view->addAction( id(new PhabricatorActionView()) @@ -97,7 +101,7 @@ final class PhabricatorEditEngineConfigurationViewController $can_edit = false; } else { - $edit_uri = "{$base_uri}/edit/{$key}/"; + $edit_uri = "{$base_uri}/edit/{$form_key}/"; $view->addAction( id(new PhabricatorActionView()) ->setName(pht('Edit Form Configuration')) @@ -107,6 +111,24 @@ final class PhabricatorEditEngineConfigurationViewController ->setHref($edit_uri)); } + $use_uri = $engine->getEditURI(null, "form/{$form_key}/"); + + $view->addAction( + id(new PhabricatorActionView()) + ->setName(pht('Use Form')) + ->setIcon('fa-th-list') + ->setHref($use_uri)); + + $reorder_uri = "{$base_uri}/reorder/{$form_key}/"; + + $view->addAction( + id(new PhabricatorActionView()) + ->setName(pht('Reorder Fields')) + ->setIcon('fa-sort-alpha-asc') + ->setHref($reorder_uri) + ->setWorkflow(true) + ->setDisabled(!$can_edit)); + return $view; } @@ -121,5 +143,35 @@ final class PhabricatorEditEngineConfigurationViewController return $properties; } + private function buildFieldList(PhabricatorEditEngineConfiguration $config) { + $viewer = $this->getViewer(); + $engine = $config->getEngine(); + + $fields = $engine->getFieldsForConfig($config); + + $form = id(new AphrontFormView()) + ->setUser($viewer) + ->setAction(null); + + foreach ($fields as $field) { + $field->setIsPreview(true); + + $field->appendToForm($form); + } + + $info = id(new PHUIInfoView()) + ->setSeverity(PHUIInfoView::SEVERITY_NOTICE) + ->setErrors( + array( + pht('This is a preview of the current form configuration.'), + )); + + $box = id(new PHUIObjectBoxView()) + ->setHeaderText(pht('Form Preview')) + ->setInfoView($info) + ->setForm($form); + + return $box; + } } diff --git a/src/applications/transactions/editengine/PhabricatorEditEngine.php b/src/applications/transactions/editengine/PhabricatorEditEngine.php index 13c2b3e017..f195664702 100644 --- a/src/applications/transactions/editengine/PhabricatorEditEngine.php +++ b/src/applications/transactions/editengine/PhabricatorEditEngine.php @@ -46,6 +46,11 @@ abstract class PhabricatorEditEngine return $this->getPhobjectClassConstant('ENGINECONST', 64); } + final public function getApplication() { + $app_class = $this->getEngineApplicationClass(); + return PhabricatorApplication::getByClass($app_class); + } + /* -( Managing Fields )---------------------------------------------------- */ @@ -53,6 +58,15 @@ abstract class PhabricatorEditEngine abstract public function getEngineApplicationClass(); abstract protected function buildCustomEditFields($object); + public function getFieldsForConfig( + PhabricatorEditEngineConfiguration $config) { + + $object = $this->newEditableObject(); + $this->editEngineConfiguration = $config; + + return $this->buildEditFields($object); + } + final protected function buildEditFields($object) { $viewer = $this->getViewer(); $editor = $object->getApplicationTransactionEditor(); @@ -129,6 +143,7 @@ abstract class PhabricatorEditEngine ->setEditTypeKey('space') ->setDescription( pht('Shifts the object in the Spaces application.')) + ->setIsReorderable(false) ->setAliases(array('space', 'policy.space')) ->setTransactionType($type_space) ->setValue($object->getSpacePHID()); @@ -222,6 +237,13 @@ abstract class PhabricatorEditEngine */ abstract protected function getObjectCreateTitleText($object); + /** + * @task text + */ + protected function getFormHeaderText($object) { + $config = $this->getEditEngineConfiguration(); + return $config->getName(); + } /** * @task text @@ -384,16 +406,16 @@ abstract class PhabricatorEditEngine /** * @task uri */ - protected function getObjectEditURI($object) { - return $this->getController()->getApplicationURI('edit/'); + protected function getObjectCreateCancelURI($object) { + return $this->getApplication()->getApplicationURI(); } /** * @task uri */ - protected function getObjectCreateCancelURI($object) { - return $this->getController()->getApplicationURI(); + protected function getEditorURI() { + return $this->getApplication()->getApplicationURI('edit/'); } @@ -408,12 +430,12 @@ abstract class PhabricatorEditEngine /** * @task uri */ - protected function getEditURI($object, $path = null) { - $parts = array( - $this->getObjectEditURI($object), - ); + public function getEditURI($object = null, $path = null) { + $parts = array(); - if (!$this->getIsCreate()) { + $parts[] = $this->getEditorURI(); + + if ($object && $object->getID()) { $parts[] = $object->getID().'/'; } @@ -563,7 +585,8 @@ abstract class PhabricatorEditEngine $controller = $this->getController(); $request = $controller->getRequest(); - $config = $this->loadEditEngineConfiguration($request->getURIData('form')); + $form_key = $request->getURIData('formKey'); + $config = $this->loadEditEngineConfiguration($form_key); if (!$config) { return new Aphront404Response(); } @@ -668,7 +691,7 @@ abstract class PhabricatorEditEngine $action_button = $this->buildEditFormActionButton($object); if ($this->getIsCreate()) { - $header_text = $this->getObjectCreateTitleText($object); + $header_text = $this->getFormHeaderText($object); } else { $header_text = $this->getObjectEditTitleText($object); } diff --git a/src/applications/transactions/editengine/PhabricatorEditEngineAPIMethod.php b/src/applications/transactions/editengine/PhabricatorEditEngineAPIMethod.php index cb7662c7ba..ca6b9fe370 100644 --- a/src/applications/transactions/editengine/PhabricatorEditEngineAPIMethod.php +++ b/src/applications/transactions/editengine/PhabricatorEditEngineAPIMethod.php @@ -39,7 +39,7 @@ abstract class PhabricatorEditEngineAPIMethod final public function getMethodDescription() { // TODO: We don't currently have a real viewer in this method. - $viewer = new PhabricatorUser(); + $viewer = PhabricatorUser::getOmnipotentUser(); $engine = $this->newEditEngine() ->setViewer($viewer); diff --git a/src/applications/transactions/editfield/PhabricatorEditField.php b/src/applications/transactions/editfield/PhabricatorEditField.php index 55815c3c4d..58a1435c0c 100644 --- a/src/applications/transactions/editfield/PhabricatorEditField.php +++ b/src/applications/transactions/editfield/PhabricatorEditField.php @@ -14,6 +14,8 @@ abstract class PhabricatorEditField extends Phobject { private $description; private $editTypeKey; private $isLocked; + private $isPreview; + private $isReorderable = true; public function setKey($key) { $this->key = $key; @@ -78,6 +80,24 @@ abstract class PhabricatorEditField extends Phobject { return $this->isLocked; } + public function setIsPreview($preview) { + $this->isPreview = $preview; + return $this; + } + + public function getIsPreview() { + return $this->isPreview; + } + + public function setIsReorderable($is_reorderable) { + $this->isReorderable = $is_reorderable; + return $this; + } + + public function getIsReorderable() { + return $this->isReorderable; + } + protected function newControl() { throw new PhutilMethodNotImplementedException(); } @@ -96,7 +116,7 @@ abstract class PhabricatorEditField extends Phobject { $control->setLabel($this->getLabel()); } - if ($this->getIsLocked()) { + if ($this->getIsLocked() || $this->getIsPreview()) { $control->setDisabled(true); } @@ -149,9 +169,6 @@ abstract class PhabricatorEditField extends Phobject { } public function getTransactionType() { - if (!$this->transactionType) { - throw new PhutilInvalidStateException('setTransactionType'); - } return $this->transactionType; } @@ -257,6 +274,10 @@ abstract class PhabricatorEditField extends Phobject { public function getEditTransactionTypes() { $transaction_type = $this->getTransactionType(); + if ($transaction_type === null) { + return array(); + } + $type_key = $this->getEditTypeKey(); // TODO: This is a pretty big pile of hard-coded hacks for now. diff --git a/src/applications/transactions/editfield/PhabricatorRemarkupEditField.php b/src/applications/transactions/editfield/PhabricatorRemarkupEditField.php new file mode 100644 index 0000000000..ff0621830f --- /dev/null +++ b/src/applications/transactions/editfield/PhabricatorRemarkupEditField.php @@ -0,0 +1,10 @@ +getTargetEngine()->getEngineKey(); $id = $object->getID(); - return "/transactions/editengine/{$engine_key}/view/{$id}/"; + return $this->getURI("view/{$id}/"); } - protected function getObjectEditURI($object) { - $engine_key = $this->getTargetEngine()->getEngineKey(); - $id = $object->getID(); - return "/transactions/editengine/{$engine_key}/edit/{$id}/"; + protected function getEditorURI() { + return $this->getURI('edit/'); } protected function getObjectCreateCancelURI($object) { + return $this->getURI(); + } + + private function getURI($path = null) { $engine_key = $this->getTargetEngine()->getEngineKey(); - return "/transactions/editengine/{$engine_key}/"; + return "/transactions/editengine/{$engine_key}/{$path}"; } protected function buildCustomEditFields($object) { @@ -76,6 +77,13 @@ final class PhabricatorEditEngineConfigurationEditEngine ->setTransactionType( PhabricatorEditEngineConfigurationTransaction::TYPE_NAME) ->setValue($object->getName()), + id(new PhabricatorRemarkupEditField()) + ->setKey('preamble') + ->setLabel(pht('Preamble')) + ->setDescription(pht('Optional instructions, shown above the form.')) + ->setTransactionType( + PhabricatorEditEngineConfigurationTransaction::TYPE_PREAMBLE) + ->setValue($object->getPreamble()), ); } diff --git a/src/applications/transactions/editor/PhabricatorEditEngineConfigurationEditor.php b/src/applications/transactions/editor/PhabricatorEditEngineConfigurationEditor.php index 4736e89efa..626e63f852 100644 --- a/src/applications/transactions/editor/PhabricatorEditEngineConfigurationEditor.php +++ b/src/applications/transactions/editor/PhabricatorEditEngineConfigurationEditor.php @@ -18,6 +18,8 @@ final class PhabricatorEditEngineConfigurationEditor $types[] = PhabricatorTransactions::TYPE_EDIT_POLICY; $types[] = PhabricatorEditEngineConfigurationTransaction::TYPE_NAME; + $types[] = PhabricatorEditEngineConfigurationTransaction::TYPE_PREAMBLE; + $types[] = PhabricatorEditEngineConfigurationTransaction::TYPE_ORDER; return $types; } @@ -57,6 +59,10 @@ final class PhabricatorEditEngineConfigurationEditor switch ($xaction->getTransactionType()) { case PhabricatorEditEngineConfigurationTransaction::TYPE_NAME: return $object->getName(); + case PhabricatorEditEngineConfigurationTransaction::TYPE_PREAMBLE; + return $object->getPreamble(); + case PhabricatorEditEngineConfigurationTransaction::TYPE_ORDER: + return $object->getFieldOrder(); } } @@ -66,6 +72,8 @@ final class PhabricatorEditEngineConfigurationEditor switch ($xaction->getTransactionType()) { case PhabricatorEditEngineConfigurationTransaction::TYPE_NAME: + case PhabricatorEditEngineConfigurationTransaction::TYPE_PREAMBLE; + case PhabricatorEditEngineConfigurationTransaction::TYPE_ORDER: return $xaction->getNewValue(); } } @@ -78,6 +86,12 @@ final class PhabricatorEditEngineConfigurationEditor case PhabricatorEditEngineConfigurationTransaction::TYPE_NAME: $object->setName($xaction->getNewValue()); return; + case PhabricatorEditEngineConfigurationTransaction::TYPE_PREAMBLE; + $object->setPreamble($xaction->getNewValue()); + return; + case PhabricatorEditEngineConfigurationTransaction::TYPE_ORDER: + $object->setFieldOrder($xaction->getNewValue()); + return; } return parent::applyCustomInternalTransaction($object, $xaction); @@ -89,6 +103,8 @@ final class PhabricatorEditEngineConfigurationEditor switch ($xaction->getTransactionType()) { case PhabricatorEditEngineConfigurationTransaction::TYPE_NAME: + case PhabricatorEditEngineConfigurationTransaction::TYPE_PREAMBLE; + case PhabricatorEditEngineConfigurationTransaction::TYPE_ORDER; return; } diff --git a/src/applications/transactions/query/PhabricatorEditEngineConfigurationQuery.php b/src/applications/transactions/query/PhabricatorEditEngineConfigurationQuery.php index b1c573f775..6fc91dffbc 100644 --- a/src/applications/transactions/query/PhabricatorEditEngineConfigurationQuery.php +++ b/src/applications/transactions/query/PhabricatorEditEngineConfigurationQuery.php @@ -134,6 +134,31 @@ final class PhabricatorEditEngineConfigurationQuery return $page; } + protected function willFilterPage(array $configs) { + $engine_keys = mpull($configs, 'getEngineKey'); + + $engines = id(new PhabricatorEditEngineQuery()) + ->setParentQuery($this) + ->setViewer($this->getViewer()) + ->withEngineKeys($engine_keys) + ->execute(); + $engines = mpull($engines, null, 'getEngineKey'); + + foreach ($configs as $key => $config) { + $engine = idx($engines, $config->getEngineKey()); + + if (!$engine) { + $this->didRejectResult($config); + unset($configs[$key]); + continue; + } + + $config->attachEngine($engine); + } + + return $configs; + } + protected function buildWhereClauseParts(AphrontDatabaseConnection $conn) { $where = parent::buildWhereClauseParts($conn); diff --git a/src/applications/transactions/query/PhabricatorEditEngineQuery.php b/src/applications/transactions/query/PhabricatorEditEngineQuery.php index 62d5f38c99..ffdbd88535 100644 --- a/src/applications/transactions/query/PhabricatorEditEngineQuery.php +++ b/src/applications/transactions/query/PhabricatorEditEngineQuery.php @@ -20,6 +20,28 @@ final class PhabricatorEditEngineQuery return $engines; } + protected function willFilterPage(array $engines) { + $viewer = $this->getViewer(); + + foreach ($engines as $key => $engine) { + $app_class = $engine->getEngineApplicationClass(); + if ($app_class === null) { + continue; + } + + $can_see = PhabricatorApplication::isClassInstalledForViewer( + $app_class, + $viewer); + if (!$can_see) { + $this->didRejectResult($engine); + unset($engines[$key]); + continue; + } + } + + return $engines; + } + public function getQueryApplicationClass() { return 'PhabricatorTransactionsApplication'; } diff --git a/src/applications/transactions/storage/PhabricatorEditEngineConfiguration.php b/src/applications/transactions/storage/PhabricatorEditEngineConfiguration.php index aed81bd8a3..a95375c53e 100644 --- a/src/applications/transactions/storage/PhabricatorEditEngineConfiguration.php +++ b/src/applications/transactions/storage/PhabricatorEditEngineConfiguration.php @@ -99,12 +99,13 @@ final class PhabricatorEditEngineConfiguration $fields = $this->reorderFields($fields); - $head_instructions = $this->getProperty('instructions.head'); - if (strlen($head_instructions)) { + $preamble = $this->getPreamble(); + if (strlen($preamble)) { $fields = array( - 'config.instructions.head' => id(new PhabricatorInstructionsEditField()) - ->setKey('config.instructions.head') - ->setValue($head_instructions), + 'config.preamble' => id(new PhabricatorInstructionsEditField()) + ->setKey('config.preamble') + ->setIsReorderable(false) + ->setValue($preamble), ) + $fields; } @@ -112,7 +113,7 @@ final class PhabricatorEditEngineConfiguration } private function reorderFields(array $fields) { - $keys = array(); + $keys = $this->getFieldOrder(); $fields = array_select_keys($fields, $keys) + $fields; // Now, move locked fields to the bottom. @@ -158,6 +159,22 @@ final class PhabricatorEditEngineConfiguration return pht('Untitled Form'); } + public function getPreamble() { + return $this->getProperty('preamble'); + } + + public function setPreamble($preamble) { + return $this->setProperty('preamble', $preamble); + } + + public function setFieldOrder(array $field_order) { + return $this->setProperty('order', $field_order); + } + + public function getFieldOrder() { + return $this->getProperty('order', array()); + } + /* -( PhabricatorPolicyInterface )----------------------------------------- */ diff --git a/src/applications/transactions/storage/PhabricatorEditEngineConfigurationTransaction.php b/src/applications/transactions/storage/PhabricatorEditEngineConfigurationTransaction.php index cbc7d2b911..77f5b4ef20 100644 --- a/src/applications/transactions/storage/PhabricatorEditEngineConfigurationTransaction.php +++ b/src/applications/transactions/storage/PhabricatorEditEngineConfigurationTransaction.php @@ -4,6 +4,8 @@ final class PhabricatorEditEngineConfigurationTransaction extends PhabricatorApplicationTransaction { const TYPE_NAME = 'editengine.config.name'; + const TYPE_PREAMBLE = 'editengine.config.preamble'; + const TYPE_ORDER = 'editengine.config.order'; public function getApplicationName() { return 'search'; diff --git a/webroot/rsrc/js/application/transactions/behavior-reorder-fields.js b/webroot/rsrc/js/application/transactions/behavior-reorder-fields.js new file mode 100644 index 0000000000..bfb31f35af --- /dev/null +++ b/webroot/rsrc/js/application/transactions/behavior-reorder-fields.js @@ -0,0 +1,32 @@ +/** + * @provides javelin-behavior-editengine-reorder-fields + * @requires javelin-behavior + * javelin-stratcom + * javelin-workflow + * javelin-dom + * phabricator-draggable-list + */ + +JX.behavior('editengine-reorder-fields', function(config) { + + var root = JX.$(config.listID); + + var list = new JX.DraggableList('editengine-form-field', root) + .setFindItemsHandler(function() { + return JX.DOM.scry(root, 'li', 'editengine-form-field'); + }); + + list.listen('didDrop', function() { + var nodes = list.findItems(); + + var data; + var keys = []; + for (var ii = 0; ii < nodes.length; ii++) { + data = JX.Stratcom.getData(nodes[ii]); + keys.push(data.fieldKey); + } + + JX.$(config.inputID).value = keys.join(','); + }); + +});