From c0ce76abb8b2421eee07f15ded460dc014efaf0a Mon Sep 17 00:00:00 2001 From: epriestley Date: Wed, 3 Aug 2011 08:48:42 -0700 Subject: [PATCH] Add a "Create Subtask" operation to Maniphest Summary: Add a new "Create Subtask" action that allows you to quickly split a task into dependent subtasks, using the parent task as a template. Followups: - Cause "workflow=" to change "Create Another Task" into "Create Another Subtask" (after D736). - Show parent tasks (requires some schema stuff). Test Plan: - Created a new task. - Created a new subtask. Reviewed By: codeblock Reviewers: hunterbridges, codeblock, jungejason, tuomaspelkonen, aran CC: aran, codeblock Differential Revision: 774 --- .../ManiphestTaskDetailController.php | 7 +++ .../taskedit/ManiphestTaskEditController.php | 54 ++++++++++++++++-- .../controller/taskedit/__init__.php | 1 + .../css/aphront/headsup-action-list-view.css | 4 ++ .../rsrc/image/icon/fatcow/arrow_branch.png | Bin 0 -> 655 bytes 5 files changed, 62 insertions(+), 4 deletions(-) create mode 100755 webroot/rsrc/image/icon/fatcow/arrow_branch.png diff --git a/src/applications/maniphest/controller/taskdetail/ManiphestTaskDetailController.php b/src/applications/maniphest/controller/taskdetail/ManiphestTaskDetailController.php index ca713ed339..4e209f066f 100644 --- a/src/applications/maniphest/controller/taskdetail/ManiphestTaskDetailController.php +++ b/src/applications/maniphest/controller/taskdetail/ManiphestTaskDetailController.php @@ -220,6 +220,13 @@ class ManiphestTaskDetailController extends ManiphestController { $action->setClass('action-merge'); $actions[] = $action; + $action = new AphrontHeadsupActionView(); + $action->setName('Create Subtask'); + $action->setURI('/maniphest/task/create/?parent='.$task->getID()); + $action->setClass('action-branch'); + $actions[] = $action; + + $action = new AphrontHeadsupActionView(); $action->setName('Edit Dependencies'); $action->setURI('/search/attach/'.$task->getPHID().'/TASK/dependencies/'); diff --git a/src/applications/maniphest/controller/taskedit/ManiphestTaskEditController.php b/src/applications/maniphest/controller/taskedit/ManiphestTaskEditController.php index e3c9d5d426..2059bf89a7 100644 --- a/src/applications/maniphest/controller/taskedit/ManiphestTaskEditController.php +++ b/src/applications/maniphest/controller/taskedit/ManiphestTaskEditController.php @@ -33,6 +33,8 @@ class ManiphestTaskEditController extends ManiphestController { $user = $request->getUser(); $files = array(); + $parent_task = null; + $template_id = null; if ($this->id) { $task = id(new ManiphestTask())->load($this->id); @@ -70,9 +72,15 @@ class ManiphestTaskEditController extends ManiphestController { 'phid IN (%Ls)', $file_phids); } - } - $template_id = $request->getStr('template'); + $template_id = $request->getInt('template'); + + // You can only have a parent task if you're creating a new task. + $parent_id = $request->getInt('parent'); + if ($parent_id) { + $parent_task = id(new ManiphestTask())->load($parent_id); + } + } $errors = array(); $e_title = true; @@ -197,7 +205,26 @@ class ManiphestTaskEditController extends ManiphestController { $aux_field->getValueForStorage() ); } - + + if ($parent_task) { + $type_task = PhabricatorPHIDConstants::PHID_TYPE_TASK; + + // NOTE: It's safe to simply apply this transaction without doing + // cycle detection because we know the new task has no children. + $new_value = $parent_task->getAttached(); + $new_value[$type_task][$task->getPHID()] = true; + + $parent_xaction = clone $template; + $attach_type = ManiphestTransactionType::TYPE_ATTACH; + $parent_xaction->setTransactionType($attach_type); + $parent_xaction->setNewValue($new_value); + + $editor = new ManiphestTransactionEditor(); + $editor->applyTransactions($parent_task, array($parent_xaction)); + + $workflow = $parent_task->getID(); + } + $redirect_uri = '/T'.$task->getID(); if ($workflow) { @@ -228,6 +255,10 @@ class ManiphestTaskEditController extends ManiphestController { $task->getCCPHIDs(), $task->getProjectPHIDs()); + if ($parent_task) { + $phids[] = $parent_task->getPHID(); + } + $phids = array_filter($phids); $phids = array_unique($phids); @@ -275,6 +306,10 @@ class ManiphestTaskEditController extends ManiphestController { if ($task->getID()) { $button_name = 'Save Task'; $header_name = 'Edit Task'; + } else if ($parent_task) { + $cancel_uri = '/T'.$parent_task->getID(); + $button_name = 'Create Task'; + $header_name = 'Create New Subtask'; } else { $button_name = 'Create Task'; $header_name = 'Create New Task'; @@ -286,7 +321,18 @@ class ManiphestTaskEditController extends ManiphestController { $form ->setUser($user) ->setAction($request->getRequestURI()->getPath()) - ->addHiddenInput('template', $template_id) + ->addHiddenInput('template', $template_id); + + if ($parent_task) { + $form + ->appendChild( + id(new AphrontFormStaticControl()) + ->setLabel('Parent Task') + ->setValue($handles[$parent_task->getPHID()]->getFullName())) + ->addHiddenInput('parent', $parent_task->getID()); + } + + $form ->appendChild( id(new AphrontFormTextAreaControl()) ->setLabel('Title') diff --git a/src/applications/maniphest/controller/taskedit/__init__.php b/src/applications/maniphest/controller/taskedit/__init__.php index 92a2a49dbd..ff0eea8157 100644 --- a/src/applications/maniphest/controller/taskedit/__init__.php +++ b/src/applications/maniphest/controller/taskedit/__init__.php @@ -26,6 +26,7 @@ phutil_require_module('phabricator', 'infrastructure/javelin/markup'); phutil_require_module('phabricator', 'view/form/base'); phutil_require_module('phabricator', 'view/form/control/markup'); phutil_require_module('phabricator', 'view/form/control/select'); +phutil_require_module('phabricator', 'view/form/control/static'); phutil_require_module('phabricator', 'view/form/control/submit'); phutil_require_module('phabricator', 'view/form/control/textarea'); phutil_require_module('phabricator', 'view/form/control/tokenizer'); diff --git a/webroot/rsrc/css/aphront/headsup-action-list-view.css b/webroot/rsrc/css/aphront/headsup-action-list-view.css index 80a0d0eedf..752aad4dab 100644 --- a/webroot/rsrc/css/aphront/headsup-action-list-view.css +++ b/webroot/rsrc/css/aphront/headsup-action-list-view.css @@ -66,6 +66,10 @@ background-image: url(/rsrc/image/icon/fatcow/arrow_merge.png); } +.aphront-headsup-action-list .action-branch { + background-image: url(/rsrc/image/icon/fatcow/arrow_branch.png); +} + .aphront-headsup-action-list .action-dependencies { background-image: url(/rsrc/image/icon/fatcow/link.png); } diff --git a/webroot/rsrc/image/icon/fatcow/arrow_branch.png b/webroot/rsrc/image/icon/fatcow/arrow_branch.png new file mode 100755 index 0000000000000000000000000000000000000000..d1fe71753d9ee95a71fda3a22c80b2e689e54acc GIT binary patch literal 655 zcmV;A0&x9_P)b~3AjO`9_7DU?D54;WAF)Mi5e2~<6?$n8N>wb{L;V72sy!%F z1Gb7445)0d*VV7M*w;V`{3r|5pZ1fB5|krsF% zzK-c!7$`#DcSUF|c%7LgQ+Ov-DV9Y{^$SDPH|2;!V`L4ner>0=qD$YcqxVSN9Z;<` zk+| zfkZ6kH1fIpES}i;Z-ZPulIHy68D)hTlo1AEdv~szq=#J&8bWP?i(j-)xrAbnl_PEn0_XN93BbyxJ>DDy?|pgmw7PR zJ5vK2;TAMaqs2k40a1zmSmAaUtiLDcI3{L;#Ip_N`ZemW;$h49+G@q@>0vfYZmro{ p2;a(tZnNg=X)XT8Yv!*20|51~?XpgJ{&4^R002ovPDHLkV1nPpGCcqQ literal 0 HcmV?d00001