Page MenuHomePhabricator

D19853.diff
No OneTemporary

D19853.diff

diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -1760,6 +1760,7 @@
'ManiphestTaskStatusTestCase' => 'applications/maniphest/constants/__tests__/ManiphestTaskStatusTestCase.php',
'ManiphestTaskStatusTransaction' => 'applications/maniphest/xaction/ManiphestTaskStatusTransaction.php',
'ManiphestTaskSubpriorityTransaction' => 'applications/maniphest/xaction/ManiphestTaskSubpriorityTransaction.php',
+ 'ManiphestTaskSubtaskController' => 'applications/maniphest/controller/ManiphestTaskSubtaskController.php',
'ManiphestTaskSubtypeDatasource' => 'applications/maniphest/typeahead/ManiphestTaskSubtypeDatasource.php',
'ManiphestTaskTestCase' => 'applications/maniphest/__tests__/ManiphestTaskTestCase.php',
'ManiphestTaskTitleHeraldField' => 'applications/maniphest/herald/ManiphestTaskTitleHeraldField.php',
@@ -7347,6 +7348,7 @@
'ManiphestTaskStatusTestCase' => 'PhabricatorTestCase',
'ManiphestTaskStatusTransaction' => 'ManiphestTaskTransactionType',
'ManiphestTaskSubpriorityTransaction' => 'ManiphestTaskTransactionType',
+ 'ManiphestTaskSubtaskController' => 'ManiphestController',
'ManiphestTaskSubtypeDatasource' => 'PhabricatorTypeaheadDatasource',
'ManiphestTaskTestCase' => 'PhabricatorTestCase',
'ManiphestTaskTitleHeraldField' => 'ManiphestTaskHeraldField',
diff --git a/src/applications/maniphest/application/PhabricatorManiphestApplication.php b/src/applications/maniphest/application/PhabricatorManiphestApplication.php
--- a/src/applications/maniphest/application/PhabricatorManiphestApplication.php
+++ b/src/applications/maniphest/application/PhabricatorManiphestApplication.php
@@ -52,6 +52,7 @@
'task/' => array(
$this->getEditRoutePattern('edit/')
=> 'ManiphestTaskEditController',
+ 'subtask/(?P<id>[1-9]\d*)/' => 'ManiphestTaskSubtaskController',
),
'subpriority/' => 'ManiphestSubpriorityController',
),
diff --git a/src/applications/maniphest/controller/ManiphestTaskDetailController.php b/src/applications/maniphest/controller/ManiphestTaskDetailController.php
--- a/src/applications/maniphest/controller/ManiphestTaskDetailController.php
+++ b/src/applications/maniphest/controller/ManiphestTaskDetailController.php
@@ -281,29 +281,39 @@
->setDisabled(!$can_edit)
->setWorkflow($workflow_edit));
- $edit_config = $edit_engine->loadDefaultEditConfiguration($task);
- $can_create = (bool)$edit_config;
+ $subtype_map = $task->newEditEngineSubtypeMap();
+ $subtask_options = $subtype_map->getCreateFormsForSubtype(
+ $edit_engine,
+ $task);
+
+ // If no forms are available, we want to show the user an error.
+ // If one form is available, we take them user directly to the form.
+ // If two or more forms are available, we give the user a choice.
+
+ // The "subtask" controller handles the first case (no forms) and the
+ // third case (more than one form). In the case of one form, we link
+ // directly to the form.
+ $subtask_uri = "/task/subtask/{$id}/";
+ $subtask_workflow = true;
- if ($can_create) {
- $form_key = $edit_config->getIdentifier();
- $edit_uri = id(new PhutilURI("/task/edit/form/{$form_key}/"))
+ if (count($subtask_options) == 1) {
+ $subtask_form = head($subtask_options);
+ $form_key = $subtask_form->getIdentifier();
+ $subtask_uri = id(new PhutilURI("/task/edit/form/{$form_key}/"))
->setQueryParam('parent', $id)
->setQueryParam('template', $id)
->setQueryParam('status', ManiphestTaskStatus::getDefaultStatus());
- $edit_uri = $this->getApplicationURI($edit_uri);
- } else {
- // TODO: This will usually give us a somewhat-reasonable error page, but
- // could be a bit cleaner.
- $edit_uri = "/task/edit/{$id}/";
- $edit_uri = $this->getApplicationURI($edit_uri);
+ $subtask_workflow = false;
}
+ $subtask_uri = $this->getApplicationURI($subtask_uri);
+
$subtask_item = id(new PhabricatorActionView())
->setName(pht('Create Subtask'))
- ->setHref($edit_uri)
+ ->setHref($subtask_uri)
->setIcon('fa-level-down')
- ->setDisabled(!$can_create)
- ->setWorkflow(!$can_create);
+ ->setDisabled(!$subtask_options)
+ ->setWorkflow($subtask_workflow);
$relationship_list = PhabricatorObjectRelationshipList::newForObject(
$viewer,
diff --git a/src/applications/maniphest/controller/ManiphestTaskSubtaskController.php b/src/applications/maniphest/controller/ManiphestTaskSubtaskController.php
new file mode 100644
--- /dev/null
+++ b/src/applications/maniphest/controller/ManiphestTaskSubtaskController.php
@@ -0,0 +1,76 @@
+<?php
+
+final class ManiphestTaskSubtaskController
+ extends ManiphestController {
+
+ public function handleRequest(AphrontRequest $request) {
+ $viewer = $this->getViewer();
+ $id = $request->getURIData('id');
+
+ $task = id(new ManiphestTaskQuery())
+ ->setViewer($viewer)
+ ->withIDs(array($id))
+ ->executeOne();
+ if (!$task) {
+ return new Aphront404Response();
+ }
+
+ $cancel_uri = $task->getURI();
+
+ $edit_engine = id(new ManiphestEditEngine())
+ ->setViewer($viewer)
+ ->setTargetObject($task);
+
+ $subtype_map = $task->newEditEngineSubtypeMap();
+
+ $subtype_options = $subtype_map->getCreateFormsForSubtype(
+ $edit_engine,
+ $task);
+
+ if (!$subtype_options) {
+ return $this->newDialog()
+ ->setTitle(pht('No Forms'))
+ ->appendParagraph(
+ pht(
+ 'You do not have access to any forms which can be used to '.
+ 'create a subtask.'))
+ ->addCancelButton($cancel_uri, pht('Close'));
+ }
+
+ if ($request->isFormPost()) {
+ $form_key = $request->getStr('formKey');
+ if (isset($subtype_options[$form_key])) {
+ $subtask_uri = id(new PhutilURI("/task/edit/form/{$form_key}/"))
+ ->setQueryParam('parent', $id)
+ ->setQueryParam('template', $id)
+ ->setQueryParam('status', ManiphestTaskStatus::getDefaultStatus());
+ $subtask_uri = $this->getApplicationURI($subtask_uri);
+
+ return id(new AphrontRedirectResponse())
+ ->setURI($subtask_uri);
+ }
+ }
+
+ $control = id(new AphrontFormRadioButtonControl())
+ ->setName('formKey')
+ ->setLabel(pht('Subtype'));
+
+ foreach ($subtype_options as $key => $subtype_form) {
+ $control->addButton(
+ $key,
+ $subtype_form->getDisplayName(),
+ null);
+ }
+
+ $form = id(new AphrontFormView())
+ ->setViewer($viewer)
+ ->appendControl($control);
+
+ return $this->newDialog()
+ ->setTitle(pht('Choose Subtype'))
+ ->appendForm($form)
+ ->addSubmitButton(pht('Continue'))
+ ->addCancelButton($cancel_uri);
+ }
+
+}
diff --git a/src/applications/transactions/editengine/PhabricatorEditEngine.php b/src/applications/transactions/editengine/PhabricatorEditEngine.php
--- a/src/applications/transactions/editengine/PhabricatorEditEngine.php
+++ b/src/applications/transactions/editengine/PhabricatorEditEngine.php
@@ -358,7 +358,7 @@
return $this->editEngineConfiguration;
}
- private function newConfigurationQuery() {
+ public function newConfigurationQuery() {
return id(new PhabricatorEditEngineConfigurationQuery())
->setViewer($this->getViewer())
->withEngineKeys(array($this->getEngineKey()));
diff --git a/src/applications/transactions/editengine/PhabricatorEditEngineSubtypeMap.php b/src/applications/transactions/editengine/PhabricatorEditEngineSubtypeMap.php
--- a/src/applications/transactions/editengine/PhabricatorEditEngineSubtypeMap.php
+++ b/src/applications/transactions/editengine/PhabricatorEditEngineSubtypeMap.php
@@ -39,4 +39,47 @@
return $this->subtypes[$subtype_key];
}
+ public function getCreateFormsForSubtype(
+ PhabricatorEditEngine $edit_engine,
+ PhabricatorEditEngineSubtypeInterface $object) {
+
+ $subtype_key = $object->getEditEngineSubtype();
+ $subtype = $this->getSubtype($subtype_key);
+
+ // TODO: Allow subtype configuration to specify that children should be
+ // created from particular forms or subtypes.
+ $select_ids = array();
+ $select_subtypes = array();
+
+ $query = $edit_engine->newConfigurationQuery()
+ ->withIsDisabled(false);
+
+ if ($select_ids) {
+ $query->withIDs($select_ids);
+ } else {
+ // If we're selecting by subtype rather than selecting specific forms,
+ // only select create forms.
+ $query->withIsDefault(true);
+
+ if ($select_subtypes) {
+ $query->withSubtypes($select_subtypes);
+ } else {
+ $query->withSubtypes(array($subtype_key));
+ }
+ }
+
+ $forms = $query->execute();
+ $forms = mpull($forms, null, 'getIdentifier');
+
+ // If we're selecting by ID, respect the order specified in the
+ // constraint. Otherwise, use the create form sort order.
+ if ($select_ids) {
+ $forms = array_select_keys($forms, $select_ids) + $forms;
+ } else {
+ $forms = msort($forms, 'getCreateSortKey');
+ }
+
+ return $forms;
+ }
+
}

File Metadata

Mime Type
text/plain
Expires
Wed, Mar 19, 8:43 AM (4 d, 4 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7324765
Default Alt Text
D19853.diff (9 KB)

Event Timeline