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=<parent>" 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
This commit is contained in:
		| @@ -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/'); | ||||
|   | ||||
| @@ -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') | ||||
|   | ||||
| @@ -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'); | ||||
|   | ||||
| @@ -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); | ||||
| } | ||||
|   | ||||
							
								
								
									
										
											BIN
										
									
								
								webroot/rsrc/image/icon/fatcow/arrow_branch.png
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								webroot/rsrc/image/icon/fatcow/arrow_branch.png
									
									
									
									
									
										Executable file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 655 B | 
		Reference in New Issue
	
	Block a user
	 epriestley
					epriestley