Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F13248804
D14706.id35580.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
15 KB
Referenced Files
None
Subscribers
None
D14706.id35580.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
@@ -120,6 +120,7 @@
'AphrontFormDateControlValue' => 'view/form/control/AphrontFormDateControlValue.php',
'AphrontFormDividerControl' => 'view/form/control/AphrontFormDividerControl.php',
'AphrontFormFileControl' => 'view/form/control/AphrontFormFileControl.php',
+ 'AphrontFormHandlesControl' => 'view/form/control/AphrontFormHandlesControl.php',
'AphrontFormMarkupControl' => 'view/form/control/AphrontFormMarkupControl.php',
'AphrontFormPasswordControl' => 'view/form/control/AphrontFormPasswordControl.php',
'AphrontFormPolicyControl' => 'view/form/control/AphrontFormPolicyControl.php',
@@ -1310,9 +1311,11 @@
'ManiphestTaskHeraldField' => 'applications/maniphest/herald/ManiphestTaskHeraldField.php',
'ManiphestTaskHeraldFieldGroup' => 'applications/maniphest/herald/ManiphestTaskHeraldFieldGroup.php',
'ManiphestTaskListController' => 'applications/maniphest/controller/ManiphestTaskListController.php',
+ 'ManiphestTaskListHTTPParameterType' => 'applications/maniphest/httpparametertype/ManiphestTaskListHTTPParameterType.php',
'ManiphestTaskListView' => 'applications/maniphest/view/ManiphestTaskListView.php',
'ManiphestTaskMailReceiver' => 'applications/maniphest/mail/ManiphestTaskMailReceiver.php',
'ManiphestTaskOpenStatusDatasource' => 'applications/maniphest/typeahead/ManiphestTaskOpenStatusDatasource.php',
+ 'ManiphestTaskPHIDResolver' => 'applications/maniphest/httpparametertype/ManiphestTaskPHIDResolver.php',
'ManiphestTaskPHIDType' => 'applications/maniphest/phid/ManiphestTaskPHIDType.php',
'ManiphestTaskPriority' => 'applications/maniphest/constants/ManiphestTaskPriority.php',
'ManiphestTaskPriorityDatasource' => 'applications/maniphest/typeahead/ManiphestTaskPriorityDatasource.php',
@@ -2306,6 +2309,7 @@
'PhabricatorHandlePool' => 'applications/phid/handle/pool/PhabricatorHandlePool.php',
'PhabricatorHandlePoolTestCase' => 'applications/phid/handle/pool/__tests__/PhabricatorHandlePoolTestCase.php',
'PhabricatorHandleQuery' => 'applications/phid/query/PhabricatorHandleQuery.php',
+ 'PhabricatorHandlesEditField' => 'applications/transactions/editfield/PhabricatorHandlesEditField.php',
'PhabricatorHarbormasterApplication' => 'applications/harbormaster/application/PhabricatorHarbormasterApplication.php',
'PhabricatorHarbormasterConfigOptions' => 'applications/harbormaster/config/PhabricatorHarbormasterConfigOptions.php',
'PhabricatorHash' => 'infrastructure/util/PhabricatorHash.php',
@@ -3941,6 +3945,7 @@
'AphrontFormDateControlValue' => 'Phobject',
'AphrontFormDividerControl' => 'AphrontFormControl',
'AphrontFormFileControl' => 'AphrontFormControl',
+ 'AphrontFormHandlesControl' => 'AphrontFormControl',
'AphrontFormMarkupControl' => 'AphrontFormControl',
'AphrontFormPasswordControl' => 'AphrontFormControl',
'AphrontFormPolicyControl' => 'AphrontFormControl',
@@ -5308,9 +5313,11 @@
'ManiphestTaskHeraldField' => 'HeraldField',
'ManiphestTaskHeraldFieldGroup' => 'HeraldFieldGroup',
'ManiphestTaskListController' => 'ManiphestController',
+ 'ManiphestTaskListHTTPParameterType' => 'AphrontListHTTPParameterType',
'ManiphestTaskListView' => 'ManiphestView',
'ManiphestTaskMailReceiver' => 'PhabricatorObjectMailReceiver',
'ManiphestTaskOpenStatusDatasource' => 'PhabricatorTypeaheadDatasource',
+ 'ManiphestTaskPHIDResolver' => 'PhabricatorPHIDResolver',
'ManiphestTaskPHIDType' => 'PhabricatorPHIDType',
'ManiphestTaskPriority' => 'ManiphestConstants',
'ManiphestTaskPriorityDatasource' => 'PhabricatorTypeaheadDatasource',
@@ -6471,6 +6478,7 @@
'PhabricatorHandlePool' => 'Phobject',
'PhabricatorHandlePoolTestCase' => 'PhabricatorTestCase',
'PhabricatorHandleQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
+ 'PhabricatorHandlesEditField' => 'PhabricatorPHIDListEditField',
'PhabricatorHarbormasterApplication' => 'PhabricatorApplication',
'PhabricatorHarbormasterConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorHash' => 'Phobject',
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
@@ -134,8 +134,6 @@
$task,
PhabricatorPolicyCapability::CAN_EDIT);
- $can_create = $viewer->isLoggedIn();
-
$view = id(new PhabricatorActionListView())
->setUser($viewer)
->setObject($task)
@@ -158,10 +156,26 @@
->setDisabled(!$can_edit)
->setWorkflow(true));
+ $edit_config = id(new ManiphestEditEngine())
+ ->setViewer($viewer)
+ ->loadDefaultEditConfiguration();
+
+ $can_create = (bool)$edit_config;
+ if ($can_create) {
+ $form_key = $edit_config->getIdentifier();
+ $edit_uri = "/editpro/form/{$form_key}/?parent={$id}&template={$id}";
+ $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 = "/editpro/{$id}/";
+ $edit_uri = $this->getApplicationURI($edit_uri);
+ }
+
$view->addAction(
id(new PhabricatorActionView())
->setName(pht('Create Subtask'))
- ->setHref($this->getApplicationURI("/task/create/?parent={$id}"))
+ ->setHref($edit_uri)
->setIcon('fa-level-down')
->setDisabled(!$can_create)
->setWorkflow(!$can_create));
diff --git a/src/applications/maniphest/editor/ManiphestEditEngine.php b/src/applications/maniphest/editor/ManiphestEditEngine.php
--- a/src/applications/maniphest/editor/ManiphestEditEngine.php
+++ b/src/applications/maniphest/editor/ManiphestEditEngine.php
@@ -69,6 +69,13 @@
}
return array(
+ id(new PhabricatorHandlesEditField())
+ ->setKey('parent')
+ ->setLabel(pht('Parent Task'))
+ ->setDescription(pht('Task to make this a subtask of.'))
+ ->setAliases(array('parentPHID'))
+ ->setTransactionType(ManiphestTransaction::TYPE_PARENT)
+ ->setSingleValue(null),
id(new PhabricatorTextEditField())
->setKey('title')
->setLabel(pht('Title'))
diff --git a/src/applications/maniphest/editor/ManiphestTransactionEditor.php b/src/applications/maniphest/editor/ManiphestTransactionEditor.php
--- a/src/applications/maniphest/editor/ManiphestTransactionEditor.php
+++ b/src/applications/maniphest/editor/ManiphestTransactionEditor.php
@@ -26,6 +26,7 @@
$types[] = ManiphestTransaction::TYPE_MERGED_INTO;
$types[] = ManiphestTransaction::TYPE_MERGED_FROM;
$types[] = ManiphestTransaction::TYPE_UNBLOCK;
+ $types[] = ManiphestTransaction::TYPE_PARENT;
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
$types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
@@ -67,6 +68,8 @@
case ManiphestTransaction::TYPE_MERGED_INTO:
case ManiphestTransaction::TYPE_MERGED_FROM:
return null;
+ case ManiphestTransaction::TYPE_PARENT:
+ return null;
}
}
@@ -88,6 +91,8 @@
case ManiphestTransaction::TYPE_MERGED_FROM:
case ManiphestTransaction::TYPE_UNBLOCK:
return $xaction->getNewValue();
+ case ManiphestTransaction::TYPE_PARENT:
+ return $xaction->getNewValue();
}
}
@@ -155,6 +160,8 @@
return;
case ManiphestTransaction::TYPE_MERGED_FROM:
return;
+ case ManiphestTransaction::TYPE_PARENT:
+ return;
}
}
@@ -163,6 +170,15 @@
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
+ case ManiphestTransaction::TYPE_PARENT:
+ $parent_phid = $xaction->getNewValue();
+ $parent_type = ManiphestTaskDependsOnTaskEdgeType::EDGECONST;
+ $task_phid = $object->getPHID();
+
+ id(new PhabricatorEdgeEditor())
+ ->addEdge($parent_phid, $parent_type, $task_phid)
+ ->save();
+ break;
case ManiphestTransaction::TYPE_PROJECT_COLUMN:
$board_phid = idx($xaction->getNewValue(), 'projectPHID');
if (!$board_phid) {
@@ -740,6 +756,17 @@
$errors[] = $error;
}
break;
+ case ManiphestTransaction::TYPE_PARENT:
+ if ($xactions && !$this->getIsNewObject()) {
+ $error = new PhabricatorApplicationTransactionValidationError(
+ $type,
+ pht('Invalid'),
+ pht(
+ 'You can only select a parent task when creating a '.
+ 'transaction for the first time.'),
+ last($xactions));
+ }
+ break;
}
return $errors;
diff --git a/src/applications/maniphest/httpparametertype/ManiphestTaskListHTTPParameterType.php b/src/applications/maniphest/httpparametertype/ManiphestTaskListHTTPParameterType.php
new file mode 100644
--- /dev/null
+++ b/src/applications/maniphest/httpparametertype/ManiphestTaskListHTTPParameterType.php
@@ -0,0 +1,47 @@
+<?php
+
+final class ManiphestTaskListHTTPParameterType
+ extends AphrontListHTTPParameterType {
+
+ protected function getParameterValue(AphrontRequest $request, $key) {
+ $type = new AphrontStringListHTTPParameterType();
+ $list = $this->getValueWithType($type, $request, $key);
+
+ return id(new ManiphestTaskPHIDResolver())
+ ->setViewer($this->getViewer())
+ ->resolvePHIDs($list);
+ }
+
+ protected function getParameterTypeName() {
+ return 'list<task>';
+ }
+
+ protected function getParameterFormatDescriptions() {
+ return array(
+ pht('Comma-separated list of task PHIDs.'),
+ pht('List of task PHIDs, as array.'),
+ pht('Comma-separated list of task IDs.'),
+ pht('List of task IDs, as array.'),
+ pht('Comma-separated list of task monograms.'),
+ pht('List of task monograms, as array.'),
+ pht('Mixture of PHIDs, IDs and monograms.'),
+ );
+ }
+
+ protected function getParameterExamples() {
+ return array(
+ 'v=PHID-TASK-1111',
+ 'v=PHID-TASK-1111,PHID-TASK-2222',
+ 'v[]=PHID-TASK-1111&v[]=PHID-TASK-2222',
+ 'v=123',
+ 'v=123,124',
+ 'v[]=123&v[]=124',
+ 'v=T123',
+ 'v=T123,T124',
+ 'v[]=T123&v[]=T124',
+ 'v=PHID-TASK-1111,123,T124',
+ 'v[]=PHID-TASK-1111&v[]=123&v[]=T124',
+ );
+ }
+
+}
diff --git a/src/applications/maniphest/httpparametertype/ManiphestTaskPHIDResolver.php b/src/applications/maniphest/httpparametertype/ManiphestTaskPHIDResolver.php
new file mode 100644
--- /dev/null
+++ b/src/applications/maniphest/httpparametertype/ManiphestTaskPHIDResolver.php
@@ -0,0 +1,30 @@
+<?php
+
+final class ManiphestTaskPHIDResolver
+ extends PhabricatorPHIDResolver {
+
+ protected function getResolutionMap(array $names) {
+ foreach ($names as $key => $name) {
+ if (ctype_digit($name)) {
+ $names[$key] = 'T'.$name;
+ }
+ }
+
+ $query = id(new PhabricatorObjectQuery())
+ ->setViewer($this->getViewer());
+
+ $tasks = id(new ManiphestTaskPHIDType())
+ ->loadNamedObjects($query, $names);
+
+
+ $results = array();
+ foreach ($tasks as $task) {
+ $task_phid = $task->getPHID();
+ $results[$task->getID()] = $task_phid;
+ $results[$task->getMonogram()] = $task_phid;
+ }
+
+ return $results;
+ }
+
+}
diff --git a/src/applications/maniphest/storage/ManiphestTransaction.php b/src/applications/maniphest/storage/ManiphestTransaction.php
--- a/src/applications/maniphest/storage/ManiphestTransaction.php
+++ b/src/applications/maniphest/storage/ManiphestTransaction.php
@@ -14,6 +14,7 @@
const TYPE_MERGED_INTO = 'mergedinto';
const TYPE_MERGED_FROM = 'mergedfrom';
const TYPE_UNBLOCK = 'unblock';
+ const TYPE_PARENT = 'parent';
// NOTE: this type is deprecated. Keep it around for legacy installs
// so any transactions render correctly.
@@ -147,6 +148,7 @@
}
break;
case self::TYPE_SUBPRIORITY:
+ case self::TYPE_PARENT:
return true;
case self::TYPE_PROJECT_COLUMN:
$old_cols = idx($this->getOldValue(), 'columnPHIDs');
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
@@ -252,7 +252,7 @@
'getCreateSortKey');
}
- private function loadDefaultEditConfiguration() {
+ public function loadDefaultEditConfiguration() {
$query = $this->newConfigurationQuery()
->withIsEdit(true)
->withIsDisabled(false);
diff --git a/src/applications/transactions/editfield/PhabricatorHandlesEditField.php b/src/applications/transactions/editfield/PhabricatorHandlesEditField.php
new file mode 100644
--- /dev/null
+++ b/src/applications/transactions/editfield/PhabricatorHandlesEditField.php
@@ -0,0 +1,14 @@
+<?php
+
+final class PhabricatorHandlesEditField
+ extends PhabricatorPHIDListEditField {
+
+ protected function newControl() {
+ return id(new AphrontFormHandlesControl());
+ }
+
+ protected function newHTTPParameterType() {
+ return new ManiphestTaskListHTTPParameterType();
+ }
+
+}
diff --git a/src/applications/transactions/editfield/PhabricatorPHIDListEditField.php b/src/applications/transactions/editfield/PhabricatorPHIDListEditField.php
--- a/src/applications/transactions/editfield/PhabricatorPHIDListEditField.php
+++ b/src/applications/transactions/editfield/PhabricatorPHIDListEditField.php
@@ -52,6 +52,14 @@
return parent::readValueFromComment($value);
}
+ protected function getValueFromRequest(AphrontRequest $request, $key) {
+ $value = parent::getValueFromRequest($request, $key);
+ if ($this->getIsSingleValue()) {
+ $value = array_slice($value, 0, 1);
+ }
+ return $value;
+ }
+
public function getValueForTransaction() {
$new = parent::getValueForTransaction();
diff --git a/src/view/form/control/AphrontFormHandlesControl.php b/src/view/form/control/AphrontFormHandlesControl.php
new file mode 100644
--- /dev/null
+++ b/src/view/form/control/AphrontFormHandlesControl.php
@@ -0,0 +1,36 @@
+<?php
+
+final class AphrontFormHandlesControl extends AphrontFormControl {
+
+ protected function getCustomControlClass() {
+ return 'aphront-form-control-handles';
+ }
+
+ protected function shouldRender() {
+ return (bool)$this->getValue();
+ }
+
+ protected function renderInput() {
+ $value = $this->getValue();
+ $viewer = $this->getUser();
+
+ $list = $viewer->renderHandleList($value);
+ $list = id(new PHUIBoxView())
+ ->addPadding(PHUI::PADDING_SMALL_TOP)
+ ->appendChild($list);
+
+ $inputs = array();
+ foreach ($value as $phid) {
+ $inputs[] = phutil_tag(
+ 'input',
+ array(
+ 'type' => 'hidden',
+ 'name' => $this->getName().'[]',
+ 'value' => $phid,
+ ));
+ }
+
+ return array($list, $inputs);
+ }
+
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
May 25 2024, 4:10 AM (4 w, 3 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6274755
Default Alt Text
D14706.id35580.diff (15 KB)
Attached To
Mode
D14706: Make "Create Subtask" work properly in EditEngine
Attached
Detach File
Event Timeline
Log In to Comment