Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15404713
D19853.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
9 KB
Referenced Files
None
Subscribers
None
D19853.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D19853: Allow the "Create Subtask" workflow to prompt for a subtype selection, and prepare for customizable options
Attached
Detach File
Event Timeline
Log In to Comment