Page MenuHomePhabricator

D14706.id35580.diff
No OneTemporary

D14706.id35580.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
@@ -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

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)

Event Timeline