@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Replace workboard task creation with EditEngine

Summary: Ref T9908. This is the last of the things that need to swap over.

Test Plan:
- Created tasks from a workboard.
- Created tasks in different columns.
- Edited tasks.
- Used `?parent=..`.
- Verified that default edit form config now affects comment actions.
- No more weird comment thing on forms, at least for now.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T9908

Differential Revision: https://secure.phabricator.com/D14715

+233 -21
+1 -1
src/applications/config/controller/PhabricatorConfigWelcomeController.php
··· 265 265 266 266 267 267 $maniphest_uri = PhabricatorEnv::getURI('/maniphest/'); 268 - $maniphest_create_uri = PhabricatorEnv::getURI('/maniphest/task/create/'); 268 + $maniphest_create_uri = PhabricatorEnv::getURI('/maniphest/editpro/'); 269 269 $maniphest_all_uri = PhabricatorEnv::getURI('/maniphest/query/all/'); 270 270 $quick[] = $this->newItem( 271 271 $request,
+17 -2
src/applications/maniphest/editor/ManiphestEditEngine.php
··· 75 75 ->setDescription(pht('Task to make this a subtask of.')) 76 76 ->setAliases(array('parentPHID')) 77 77 ->setTransactionType(ManiphestTransaction::TYPE_PARENT) 78 - ->setSingleValue(null), 78 + ->setHandleParameterType(new ManiphestTaskListHTTPParameterType()) 79 + ->setSingleValue(null) 80 + ->setIsReorderable(false) 81 + ->setIsDefaultable(false) 82 + ->setIsLockable(false), 83 + id(new PhabricatorHandlesEditField()) 84 + ->setKey('column') 85 + ->setLabel(pht('Column')) 86 + ->setDescription(pht('Workboard column to create this task into.')) 87 + ->setAliases(array('columnPHID')) 88 + ->setTransactionType(ManiphestTransaction::TYPE_COLUMN) 89 + ->setSingleValue(null) 90 + ->setIsInvisible(true) 91 + ->setIsReorderable(false) 92 + ->setIsDefaultable(false) 93 + ->setIsLockable(false), 79 94 id(new PhabricatorTextEditField()) 80 95 ->setKey('title') 81 96 ->setLabel(pht('Title')) ··· 213 228 214 229 } 215 230 216 - return parent::newEditResponse(); 231 + return parent::newEditResponse($request, $object, $xactions); 217 232 } 218 233 219 234 private function buildListResponse(ManiphestTask $task) {
+93 -4
src/applications/maniphest/editor/ManiphestTransactionEditor.php
··· 27 27 $types[] = ManiphestTransaction::TYPE_MERGED_FROM; 28 28 $types[] = ManiphestTransaction::TYPE_UNBLOCK; 29 29 $types[] = ManiphestTransaction::TYPE_PARENT; 30 + $types[] = ManiphestTransaction::TYPE_COLUMN; 30 31 $types[] = PhabricatorTransactions::TYPE_VIEW_POLICY; 31 32 $types[] = PhabricatorTransactions::TYPE_EDIT_POLICY; 32 33 ··· 69 70 case ManiphestTransaction::TYPE_MERGED_FROM: 70 71 return null; 71 72 case ManiphestTransaction::TYPE_PARENT: 73 + case ManiphestTransaction::TYPE_COLUMN: 72 74 return null; 73 75 } 74 76 } ··· 92 94 case ManiphestTransaction::TYPE_UNBLOCK: 93 95 return $xaction->getNewValue(); 94 96 case ManiphestTransaction::TYPE_PARENT: 97 + case ManiphestTransaction::TYPE_COLUMN: 95 98 return $xaction->getNewValue(); 96 99 } 97 100 } ··· 159 162 $object->setStatus(ManiphestTaskStatus::getDuplicateStatus()); 160 163 return; 161 164 case ManiphestTransaction::TYPE_MERGED_FROM: 162 - return; 163 165 case ManiphestTransaction::TYPE_PARENT: 166 + case ManiphestTransaction::TYPE_COLUMN: 164 167 return; 165 168 } 166 169 } ··· 757 760 } 758 761 break; 759 762 case ManiphestTransaction::TYPE_PARENT: 760 - if ($xactions && !$this->getIsNewObject()) { 761 - $error = new PhabricatorApplicationTransactionValidationError( 763 + $with_effect = array(); 764 + foreach ($xactions as $xaction) { 765 + $task_phid = $xaction->getNewValue(); 766 + if (!$task_phid) { 767 + continue; 768 + } 769 + 770 + $with_effect[] = $xaction; 771 + 772 + $task = id(new ManiphestTaskQuery()) 773 + ->setViewer($this->getActor()) 774 + ->withPHIDs(array($task_phid)) 775 + ->executeOne(); 776 + if (!$task) { 777 + $errors[] = new PhabricatorApplicationTransactionValidationError( 778 + $type, 779 + pht('Invalid'), 780 + pht( 781 + 'Parent task identifier "%s" does not identify a visible '. 782 + 'task.', 783 + $task_phid), 784 + $xaction); 785 + } 786 + } 787 + 788 + if ($with_effect && !$this->getIsNewObject()) { 789 + $errors[] = new PhabricatorApplicationTransactionValidationError( 762 790 $type, 763 791 pht('Invalid'), 764 792 pht( 765 793 'You can only select a parent task when creating a '. 766 794 'transaction for the first time.'), 767 - last($xactions)); 795 + last($with_effect)); 796 + } 797 + break; 798 + case ManiphestTransaction::TYPE_COLUMN: 799 + $with_effect = array(); 800 + foreach ($xactions as $xaction) { 801 + $column_phid = $xaction->getNewValue(); 802 + if (!$column_phid) { 803 + continue; 804 + } 805 + 806 + $with_effect[] = $xaction; 807 + 808 + $column = $this->loadProjectColumn($column_phid); 809 + if (!$column) { 810 + $errors[] = new PhabricatorApplicationTransactionValidationError( 811 + $type, 812 + pht('Invalid'), 813 + pht( 814 + 'Column PHID "%s" does not identify a visible column.', 815 + $column_phid), 816 + $xaction); 817 + } 818 + } 819 + 820 + if ($with_effect && !$this->getIsNewObject()) { 821 + $errors[] = new PhabricatorApplicationTransactionValidationError( 822 + $type, 823 + pht('Invalid'), 824 + pht( 825 + 'You can only put a task into an initial column during task '. 826 + 'creation.'), 827 + last($with_effect)); 768 828 } 769 829 break; 770 830 } ··· 841 901 $results = parent::expandTransaction($object, $xaction); 842 902 843 903 switch ($xaction->getTransactionType()) { 904 + case ManiphestTransaction::TYPE_COLUMN: 905 + $column_phid = $xaction->getNewValue(); 906 + if (!$column_phid) { 907 + break; 908 + } 909 + 910 + // When a task is created into a column, we also generate a transaction 911 + // to actually put it in that column. 912 + $column = $this->loadProjectColumn($column_phid); 913 + $results[] = id(new ManiphestTransaction()) 914 + ->setTransactionType(ManiphestTransaction::TYPE_PROJECT_COLUMN) 915 + ->setOldValue( 916 + array( 917 + 'projectPHID' => $column->getProjectPHID(), 918 + 'columnPHIDs' => array(), 919 + )) 920 + ->setNewValue( 921 + array( 922 + 'projectPHID' => $column->getProjectPHID(), 923 + 'columnPHIDs' => array($column->getPHID()), 924 + )); 925 + break; 844 926 case ManiphestTransaction::TYPE_OWNER: 845 927 // When a task is reassigned, move the old owner to the subscriber 846 928 // list so they're still in the loop. ··· 858 940 } 859 941 860 942 return $results; 943 + } 944 + 945 + private function loadProjectColumn($column_phid) { 946 + return id(new PhabricatorProjectColumnQuery()) 947 + ->setViewer($this->getActor()) 948 + ->withPHIDs(array($column_phid)) 949 + ->executeOne(); 861 950 } 862 951 863 952
+2
src/applications/maniphest/storage/ManiphestTransaction.php
··· 15 15 const TYPE_MERGED_FROM = 'mergedfrom'; 16 16 const TYPE_UNBLOCK = 'unblock'; 17 17 const TYPE_PARENT = 'parent'; 18 + const TYPE_COLUMN = 'column'; 18 19 19 20 // NOTE: this type is deprecated. Keep it around for legacy installs 20 21 // so any transactions render correctly. ··· 149 150 break; 150 151 case self::TYPE_SUBPRIORITY: 151 152 case self::TYPE_PARENT: 153 + case self::TYPE_COLUMN: 152 154 return true; 153 155 case self::TYPE_PROJECT_COLUMN: 154 156 $old_cols = idx($this->getOldValue(), 'columnPHIDs');
+20 -2
src/applications/project/controller/PhabricatorProjectBoardViewController.php
··· 276 276 'boardID' => $board_id, 277 277 'projectPHID' => $project->getPHID(), 278 278 'moveURI' => $this->getApplicationURI('move/'.$project->getID().'/'), 279 - 'createURI' => '/maniphest/task/create/', 279 + 'createURI' => $this->getCreateURI(), 280 280 'order' => $this->sortKey, 281 281 ); 282 282 $this->initBehavior( ··· 630 630 $column_items[] = id(new PhabricatorActionView()) 631 631 ->setIcon('fa-plus') 632 632 ->setName(pht('Create Task...')) 633 - ->setHref('/maniphest/task/create/') 633 + ->setHref($this->getCreateURI()) 634 634 ->addSigil('column-add-task') 635 635 ->setMetadata( 636 636 array( ··· 766 766 $base->setQueryParam('hidden', $this->showHidden ? 'true' : null); 767 767 768 768 return $base; 769 + } 770 + 771 + private function getCreateURI() { 772 + $viewer = $this->getViewer(); 773 + 774 + // TODO: This should be cleaned up, but maybe we're going to make options 775 + // for each column or board? 776 + $edit_config = id(new ManiphestEditEngine()) 777 + ->setViewer($viewer) 778 + ->loadDefaultEditConfiguration(); 779 + if ($edit_config) { 780 + $form_key = $edit_config->getIdentifier(); 781 + $create_uri = "/maniphest/editpro/form/{$form_key}/"; 782 + } else { 783 + $create_uri = '/maniphest/editpro/'; 784 + } 785 + 786 + return $create_uri; 769 787 } 770 788 771 789 }
+1 -1
src/applications/search/engine/PhabricatorJumpNavHandler.php
··· 66 66 return id(new AphrontRedirectResponse())->setURI($uri); 67 67 case 'create-task': 68 68 return id(new AphrontRedirectResponse()) 69 - ->setURI('/maniphest/task/create/?title=' 69 + ->setURI('/maniphest/editpro/?title=' 70 70 .phutil_escape_uri($matches[1])); 71 71 default: 72 72 throw new Exception(pht("Unknown jump effect '%s'!", $effect));
+26 -3
src/applications/transactions/editengine/PhabricatorEditEngine.php
··· 1137 1137 1138 1138 $all_types = array(); 1139 1139 foreach ($fields as $field) { 1140 - // TODO: Load draft stuff. 1140 + if (!$this->isCommentField($field)) { 1141 + continue; 1142 + } 1143 + 1141 1144 $types = $field->getCommentEditTypes(); 1142 1145 foreach ($types as $type) { 1143 1146 $all_types[] = $type; ··· 1329 1332 $viewer->getPHID(), 1330 1333 $current_version); 1331 1334 1332 - // TODO: This is just a proof of concept. 1333 1335 $draft 1334 - ->setProperty('temporary.comment', $comment_text) 1336 + ->setProperty('comment', $comment_text) 1335 1337 ->setProperty('actions', $actions) 1336 1338 ->save(); 1337 1339 } ··· 1342 1344 if ($actions) { 1343 1345 $type_map = array(); 1344 1346 foreach ($fields as $field) { 1347 + if (!$this->isCommentField($field)) { 1348 + continue; 1349 + } 1350 + 1345 1351 $types = $field->getCommentEditTypes(); 1346 1352 foreach ($types as $type) { 1347 1353 $type_map[$type->getEditType()] = array( ··· 1684 1690 $this->getViewer(), 1685 1691 $this, 1686 1692 PhabricatorPolicyCapability::CAN_EDIT); 1693 + } 1694 + 1695 + private function isCommentField(PhabricatorEditField $field) { 1696 + // TODO: This is a little bit hacky. 1697 + if ($field->getKey() == 'comment') { 1698 + return true; 1699 + } 1700 + 1701 + if ($field->getIsLocked()) { 1702 + return false; 1703 + } 1704 + 1705 + if ($field->getIsHidden()) { 1706 + return false; 1707 + } 1708 + 1709 + return true; 1687 1710 } 1688 1711 1689 1712
+3
src/applications/transactions/editengineextension/PhabricatorCommentEditEngineExtension.php
··· 44 44 ->setDescription(pht('Add comments.')) 45 45 ->setAliases(array('comments')) 46 46 ->setIsHidden(true) 47 + ->setIsReorderable(false) 48 + ->setIsDefaultable(false) 49 + ->setIsLockable(false) 47 50 ->setTransactionType($comment_type) 48 51 ->setValue(null); 49 52
+35 -2
src/applications/transactions/editfield/PhabricatorHandlesEditField.php
··· 3 3 final class PhabricatorHandlesEditField 4 4 extends PhabricatorPHIDListEditField { 5 5 6 + private $handleParameterType; 7 + private $isInvisible; 8 + 9 + public function setHandleParameterType(AphrontHTTPParameterType $type) { 10 + $this->handleParameterType = $type; 11 + return $this; 12 + } 13 + 14 + public function getHandleParameterType() { 15 + return $this->handleParameterType; 16 + } 17 + 18 + public function setIsInvisible($is_invisible) { 19 + $this->isInvisible = $is_invisible; 20 + return $this; 21 + } 22 + 23 + public function getIsInvisible() { 24 + return $this->isInvisible; 25 + } 26 + 6 27 protected function newControl() { 7 - return id(new AphrontFormHandlesControl()); 28 + $control = id(new AphrontFormHandlesControl()); 29 + 30 + if ($this->getIsInvisible()) { 31 + $control->setIsInvisible(true); 32 + } 33 + 34 + return $control; 8 35 } 9 36 10 37 protected function newHTTPParameterType() { 11 - return new ManiphestTaskListHTTPParameterType(); 38 + $type = $this->getHandleParameterType(); 39 + 40 + if ($type) { 41 + return $type; 42 + } 43 + 44 + return new AphrontPHIDListHTTPParameterType(); 12 45 } 13 46 14 47 }
+1 -1
src/applications/transactions/view/PhabricatorApplicationTransactionCommentView.php
··· 196 196 197 197 $versioned_draft = $this->getVersionedDraft(); 198 198 if ($versioned_draft) { 199 - $draft_comment = $versioned_draft->getProperty('temporary.comment', ''); 199 + $draft_comment = $versioned_draft->getProperty('comment', ''); 200 200 } 201 201 202 202 if (!$this->getObjectPHID()) {
+34 -5
src/view/form/control/AphrontFormHandlesControl.php
··· 2 2 3 3 final class AphrontFormHandlesControl extends AphrontFormControl { 4 4 5 + private $isInvisible; 6 + 5 7 protected function getCustomControlClass() { 6 8 return 'aphront-form-control-handles'; 7 9 } 8 10 11 + public function setIsInvisible($is_invisible) { 12 + $this->isInvisible = $is_invisible; 13 + return $this; 14 + } 15 + 16 + public function getIsInvisible() { 17 + return $this->isInvisible; 18 + } 19 + 9 20 protected function shouldRender() { 10 21 return (bool)$this->getValue(); 11 22 } 12 23 24 + public function getLabel() { 25 + // TODO: This is a bit funky and still rendering a few pixels of padding 26 + // on the form, but there's currently no way to get a control to only emit 27 + // hidden inputs. Clean this up eventually. 28 + 29 + if ($this->getIsInvisible()) { 30 + return null; 31 + } 32 + 33 + return parent::getLabel(); 34 + } 35 + 13 36 protected function renderInput() { 14 37 $value = $this->getValue(); 15 38 $viewer = $this->getUser(); 16 39 17 - $list = $viewer->renderHandleList($value); 18 - $list = id(new PHUIBoxView()) 19 - ->addPadding(PHUI::PADDING_SMALL_TOP) 20 - ->appendChild($list); 40 + $out = array(); 41 + 42 + if (!$this->getIsInvisible()) { 43 + $list = $viewer->renderHandleList($value); 44 + $list = id(new PHUIBoxView()) 45 + ->addPadding(PHUI::PADDING_SMALL_TOP) 46 + ->appendChild($list); 47 + $out[] = $list; 48 + } 21 49 22 50 $inputs = array(); 23 51 foreach ($value as $phid) { ··· 29 57 'value' => $phid, 30 58 )); 31 59 } 60 + $out[] = $inputs; 32 61 33 - return array($list, $inputs); 62 + return $out; 34 63 } 35 64 36 65 }