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

Provide "Change Projects" and "Change Subscribers" (instead of "Add ...") in comment actions

Summary:
Ref T9908. Fixes T6205.

This is largely some refactoring to improve the code. The new structure is:

- Each EditField has zero or one "submit" (normal edit form) controls.
- Each EditField has zero or one "comment" (stacked actions) controls.
- If we want more than one in the future, we'd just add two fields.
- Each EditField can have multiple EditTypes which provide Conduit transactions.
- EditTypes are now lower-level and less involved on the Submit/Comment pathways.

Test Plan:
- Added and removed projects and subscribers.
- Changed task statuses.
- In two windows: added some subscribers in one, removed different ones in the other. The changes did not conflict.
- Applied changes via Conduit.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T6205, T9908

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

+412 -316
+10 -10
resources/celerity/map.php
··· 426 426 'rsrc/js/application/repository/repository-crossreference.js' => 'e5339c43', 427 427 'rsrc/js/application/search/behavior-reorder-queries.js' => 'e9581f08', 428 428 'rsrc/js/application/slowvote/behavior-slowvote-embed.js' => '887ad43f', 429 - 'rsrc/js/application/transactions/behavior-comment-actions.js' => '6de53e91', 429 + 'rsrc/js/application/transactions/behavior-comment-actions.js' => 'bb0d2d0c', 430 430 'rsrc/js/application/transactions/behavior-reorder-configs.js' => 'd7a74243', 431 431 'rsrc/js/application/transactions/behavior-reorder-fields.js' => 'b59e1e96', 432 432 'rsrc/js/application/transactions/behavior-show-older-transactions.js' => 'dbbf48b6', ··· 571 571 'javelin-behavior-audit-preview' => 'd835b03a', 572 572 'javelin-behavior-bulk-job-reload' => 'edf8a145', 573 573 'javelin-behavior-choose-control' => '6153c708', 574 - 'javelin-behavior-comment-actions' => '6de53e91', 574 + 'javelin-behavior-comment-actions' => 'bb0d2d0c', 575 575 'javelin-behavior-config-reorder-fields' => 'b6993408', 576 576 'javelin-behavior-conpherence-drag-and-drop-photo' => 'cf86d16a', 577 577 'javelin-behavior-conpherence-menu' => '1d45c74d', ··· 1335 1335 'phabricator-drag-and-drop-file-upload', 1336 1336 'phabricator-textareautils', 1337 1337 ), 1338 - '6de53e91' => array( 1339 - 'javelin-behavior', 1340 - 'javelin-stratcom', 1341 - 'javelin-workflow', 1342 - 'javelin-dom', 1343 - 'phuix-form-control-view', 1344 - 'phuix-icon-view', 1345 - ), 1346 1338 '6eff08aa' => array( 1347 1339 'javelin-install', 1348 1340 'javelin-util', ··· 1738 1730 'javelin-stratcom', 1739 1731 'javelin-workflow', 1740 1732 'phabricator-draggable-list', 1733 + ), 1734 + 'bb0d2d0c' => array( 1735 + 'javelin-behavior', 1736 + 'javelin-stratcom', 1737 + 'javelin-workflow', 1738 + 'javelin-dom', 1739 + 'phuix-form-control-view', 1740 + 'phuix-icon-view', 1741 1741 ), 1742 1742 'bd4c8dca' => array( 1743 1743 'javelin-install',
+6
src/__phutil_library_map__.php
··· 2150 2150 'PhabricatorEdgeTypeTestCase' => 'infrastructure/edges/type/__tests__/PhabricatorEdgeTypeTestCase.php', 2151 2151 'PhabricatorEditEngine' => 'applications/transactions/editengine/PhabricatorEditEngine.php', 2152 2152 'PhabricatorEditEngineAPIMethod' => 'applications/transactions/editengine/PhabricatorEditEngineAPIMethod.php', 2153 + 'PhabricatorEditEngineCommentAction' => 'applications/transactions/commentaction/PhabricatorEditEngineCommentAction.php', 2153 2154 'PhabricatorEditEngineConfiguration' => 'applications/transactions/storage/PhabricatorEditEngineConfiguration.php', 2154 2155 'PhabricatorEditEngineConfigurationDefaultCreateController' => 'applications/transactions/controller/PhabricatorEditEngineConfigurationDefaultCreateController.php', 2155 2156 'PhabricatorEditEngineConfigurationDefaultsController' => 'applications/transactions/controller/PhabricatorEditEngineConfigurationDefaultsController.php', ··· 2175 2176 'PhabricatorEditEngineListController' => 'applications/transactions/controller/PhabricatorEditEngineListController.php', 2176 2177 'PhabricatorEditEngineQuery' => 'applications/transactions/query/PhabricatorEditEngineQuery.php', 2177 2178 'PhabricatorEditEngineSearchEngine' => 'applications/transactions/query/PhabricatorEditEngineSearchEngine.php', 2179 + 'PhabricatorEditEngineSelectCommentAction' => 'applications/transactions/commentaction/PhabricatorEditEngineSelectCommentAction.php', 2180 + 'PhabricatorEditEngineTokenizerCommentAction' => 'applications/transactions/commentaction/PhabricatorEditEngineTokenizerCommentAction.php', 2178 2181 'PhabricatorEditField' => 'applications/transactions/editfield/PhabricatorEditField.php', 2179 2182 'PhabricatorEditType' => 'applications/transactions/edittype/PhabricatorEditType.php', 2180 2183 'PhabricatorEditor' => 'infrastructure/PhabricatorEditor.php', ··· 6308 6311 'PhabricatorPolicyInterface', 6309 6312 ), 6310 6313 'PhabricatorEditEngineAPIMethod' => 'ConduitAPIMethod', 6314 + 'PhabricatorEditEngineCommentAction' => 'Phobject', 6311 6315 'PhabricatorEditEngineConfiguration' => array( 6312 6316 'PhabricatorSearchDAO', 6313 6317 'PhabricatorApplicationTransactionInterface', ··· 6337 6341 'PhabricatorEditEngineListController' => 'PhabricatorEditEngineController', 6338 6342 'PhabricatorEditEngineQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 6339 6343 'PhabricatorEditEngineSearchEngine' => 'PhabricatorApplicationSearchEngine', 6344 + 'PhabricatorEditEngineSelectCommentAction' => 'PhabricatorEditEngineCommentAction', 6345 + 'PhabricatorEditEngineTokenizerCommentAction' => 'PhabricatorEditEngineCommentAction', 6340 6346 'PhabricatorEditField' => 'Phobject', 6341 6347 'PhabricatorEditType' => 'Phobject', 6342 6348 'PhabricatorEditor' => 'Phobject',
+2 -2
src/applications/maniphest/editor/ManiphestEditEngine.php
··· 110 110 ->setIsCopyable(true) 111 111 ->setSingleValue($object->getOwnerPHID()) 112 112 ->setCommentActionLabel(pht('Assign / Claim')) 113 - ->setCommentActionDefaultValue($owner_value), 113 + ->setCommentActionValue($owner_value), 114 114 id(new PhabricatorSelectEditField()) 115 115 ->setKey('status') 116 116 ->setLabel(pht('Status')) ··· 120 120 ->setValue($object->getStatus()) 121 121 ->setOptions($status_map) 122 122 ->setCommentActionLabel(pht('Change Status')) 123 - ->setCommentActionDefaultValue($default_status), 123 + ->setCommentActionValue($default_status), 124 124 id(new PhabricatorSelectEditField()) 125 125 ->setKey('priority') 126 126 ->setLabel(pht('Priority'))
+1 -1
src/applications/project/engineextension/PhabricatorProjectsEditEngineExtension.php
··· 54 54 pht('Add projects.'), 55 55 pht('Remove projects.'), 56 56 pht('Set associated projects, overwriting current value.')) 57 - ->setCommentActionLabel(pht('Add Projects')) 57 + ->setCommentActionLabel(pht('Change Projects')) 58 58 ->setTransactionType($edge_type) 59 59 ->setMetadataValue('edge:type', $project_edge_type) 60 60 ->setValue($project_phids);
+1 -1
src/applications/subscriptions/engineextension/PhabricatorSubscriptionsEditEngineExtension.php
··· 49 49 pht('Add subscribers.'), 50 50 pht('Remove subscribers.'), 51 51 pht('Set subscribers, overwriting current value.')) 52 - ->setCommentActionLabel(pht('Add Subscribers')) 52 + ->setCommentActionLabel(pht('Change Subscribers')) 53 53 ->setTransactionType($subscribers_type) 54 54 ->setValue($sub_phids); 55 55
+49
src/applications/transactions/commentaction/PhabricatorEditEngineCommentAction.php
··· 1 + <?php 2 + 3 + abstract class PhabricatorEditEngineCommentAction extends Phobject { 4 + 5 + private $key; 6 + private $label; 7 + private $value; 8 + private $initialValue; 9 + 10 + abstract public function getPHUIXControlType(); 11 + abstract public function getPHUIXControlSpecification(); 12 + 13 + public function setKey($key) { 14 + $this->key = $key; 15 + return $this; 16 + } 17 + 18 + public function getKey() { 19 + return $this->key; 20 + } 21 + 22 + public function setLabel($label) { 23 + $this->label = $label; 24 + return $this; 25 + } 26 + 27 + public function getLabel() { 28 + return $this->label; 29 + } 30 + 31 + public function setValue($value) { 32 + $this->value = $value; 33 + return $this; 34 + } 35 + 36 + public function getValue() { 37 + return $this->value; 38 + } 39 + 40 + public function setInitialValue($initial_value) { 41 + $this->initialValue = $initial_value; 42 + return $this; 43 + } 44 + 45 + public function getInitialValue() { 46 + return $this->initialValue; 47 + } 48 + 49 + }
+29
src/applications/transactions/commentaction/PhabricatorEditEngineSelectCommentAction.php
··· 1 + <?php 2 + 3 + final class PhabricatorEditEngineSelectCommentAction 4 + extends PhabricatorEditEngineCommentAction { 5 + 6 + private $options; 7 + 8 + public function setOptions(array $options) { 9 + $this->options = $options; 10 + return $this; 11 + } 12 + 13 + public function getOptions() { 14 + return $this->options; 15 + } 16 + 17 + public function getPHUIXControlType() { 18 + return 'select'; 19 + } 20 + 21 + public function getPHUIXControlSpecification() { 22 + return array( 23 + 'options' => $this->getOptions(), 24 + 'order' => array_keys($this->getOptions()), 25 + 'value' => $this->getValue(), 26 + ); 27 + } 28 + 29 + }
+55
src/applications/transactions/commentaction/PhabricatorEditEngineTokenizerCommentAction.php
··· 1 + <?php 2 + 3 + final class PhabricatorEditEngineTokenizerCommentAction 4 + extends PhabricatorEditEngineCommentAction { 5 + 6 + private $datasource; 7 + private $limit; 8 + 9 + public function setDatasource(PhabricatorTypeaheadDatasource $datasource) { 10 + $this->datasource = $datasource; 11 + return $this; 12 + } 13 + 14 + public function getDatasource() { 15 + return $this->datasource; 16 + } 17 + 18 + public function setLimit($limit) { 19 + $this->limit = $limit; 20 + return $this; 21 + } 22 + 23 + public function getLimit() { 24 + return $this->limit; 25 + } 26 + 27 + public function getPHUIXControlType() { 28 + return 'tokenizer'; 29 + } 30 + 31 + public function getPHUIXControlSpecification() { 32 + $template = new AphrontTokenizerTemplateView(); 33 + 34 + $datasource = $this->getDatasource(); 35 + $limit = $this->getLimit(); 36 + 37 + $value = $this->getValue(); 38 + if (!$value) { 39 + $value = array(); 40 + } 41 + $value = $datasource->getWireTokens($value); 42 + 43 + return array( 44 + 'markup' => $template->render(), 45 + 'config' => array( 46 + 'src' => $datasource->getDatasourceURI(), 47 + 'browseURI' => $datasource->getBrowseURI(), 48 + 'placeholder' => $datasource->getPlaceholderText(), 49 + 'limit' => $limit, 50 + ), 51 + 'value' => $value, 52 + ); 53 + } 54 + 55 + }
+51 -62
src/applications/transactions/editengine/PhabricatorEditEngine.php
··· 792 792 793 793 $validation_exception = null; 794 794 if ($request->isFormPost()) { 795 - foreach ($fields as $field) { 795 + $submit_fields = $fields; 796 + 797 + foreach ($submit_fields as $key => $field) { 798 + if (!$field->shouldGenerateTransactionsFromSubmit()) { 799 + unset($submit_fields[$key]); 800 + continue; 801 + } 802 + 796 803 $field->setIsSubmittedForm(true); 797 804 798 - if ($field->getIsLocked() || $field->getIsHidden()) { 805 + if (!$field->shouldReadValueFromSubmit()) { 799 806 continue; 800 807 } 801 808 ··· 803 810 } 804 811 805 812 $xactions = array(); 806 - foreach ($fields as $field) { 807 - $types = $field->getWebEditTypes(); 808 - foreach ($types as $type) { 809 - $type_xactions = $type->generateTransactions( 810 - clone $template, 811 - array( 812 - 'value' => $field->getValueForTransaction(), 813 - )); 813 + foreach ($submit_fields as $field) { 814 + $type_xactions = $field->generateTransactions( 815 + clone $template, 816 + array( 817 + 'value' => $field->getValueForTransaction(), 818 + )); 814 819 815 - if (!$type_xactions) { 816 - continue; 817 - } 818 - 819 - foreach ($type_xactions as $type_xaction) { 820 - $xactions[] = $type_xaction; 821 - } 820 + foreach ($type_xactions as $type_xaction) { 821 + $xactions[] = $type_xaction; 822 822 } 823 823 } 824 824 ··· 879 879 } 880 880 881 881 foreach ($fields as $field) { 882 - if ($field->getIsLocked() || $field->getIsHidden()) { 882 + if (!$field->shouldReadValueFromRequest()) { 883 883 continue; 884 884 } 885 885 ··· 1171 1171 1172 1172 $fields = $this->buildEditFields($object); 1173 1173 1174 - $all_types = array(); 1174 + $comment_actions = array(); 1175 1175 foreach ($fields as $field) { 1176 - if (!$this->isCommentField($field)) { 1176 + if (!$field->shouldGenerateTransactionsFromComment()) { 1177 1177 continue; 1178 1178 } 1179 1179 1180 - $types = $field->getCommentEditTypes(); 1181 - foreach ($types as $type) { 1182 - $all_types[] = $type; 1180 + $comment_action = $field->getCommentAction(); 1181 + if (!$comment_action) { 1182 + continue; 1183 1183 } 1184 + 1185 + $key = $comment_action->getKey(); 1186 + 1187 + // TODO: Validate these better. 1188 + 1189 + $comment_actions[$key] = $comment_action; 1184 1190 } 1185 1191 1186 - $view->setEditTypes($all_types); 1192 + $view->setCommentActions($comment_actions); 1187 1193 1188 1194 return $view; 1189 1195 } ··· 1378 1384 $xactions = array(); 1379 1385 1380 1386 if ($actions) { 1381 - $type_map = array(); 1382 - foreach ($fields as $field) { 1383 - if (!$this->isCommentField($field)) { 1387 + $action_map = array(); 1388 + foreach ($actions as $action) { 1389 + $type = idx($action, 'type'); 1390 + if (!$type) { 1384 1391 continue; 1385 1392 } 1386 1393 1387 - $types = $field->getCommentEditTypes(); 1388 - foreach ($types as $type) { 1389 - $type_map[$type->getEditType()] = array( 1390 - 'type' => $type, 1391 - 'field' => $field, 1392 - ); 1394 + if (empty($fields[$type])) { 1395 + continue; 1393 1396 } 1397 + 1398 + $action_map[$type] = $action; 1394 1399 } 1395 1400 1396 - foreach ($actions as $action) { 1397 - $type = idx($action, 'type'); 1398 - if (!$type) { 1401 + foreach ($action_map as $type => $action) { 1402 + $field = $fields[$type]; 1403 + 1404 + if (!$field->shouldGenerateTransactionsFromComment()) { 1399 1405 continue; 1400 1406 } 1401 1407 1402 - $spec = idx($type_map, $type); 1403 - if (!$spec) { 1404 - continue; 1408 + if (array_key_exists('initialValue', $action)) { 1409 + $field->setInitialValue($action['initialValue']); 1405 1410 } 1406 1411 1407 - $edit_type = $spec['type']; 1408 - $field = $spec['field']; 1409 - 1410 - $field->readValueFromComment($action); 1412 + $field->readValueFromComment(idx($action, 'value')); 1411 1413 1412 - $type_xactions = $edit_type->generateTransactions( 1413 - $template, 1414 + $type_xactions = $field->generateTransactions( 1415 + clone $template, 1414 1416 array( 1415 1417 'value' => $field->getValueForTransaction(), 1416 1418 )); ··· 1508 1510 ->setActor($viewer) 1509 1511 ->setContentSourceFromConduitRequest($request) 1510 1512 ->setContinueOnNoEffect(true); 1513 + 1514 + if (!$this->getIsCreate()) { 1515 + $editor->setContinueOnMissingFields(true); 1516 + } 1511 1517 1512 1518 $xactions = $editor->applyTransactions($object, $xactions); 1513 1519 ··· 1727 1733 $this->getViewer(), 1728 1734 $this, 1729 1735 PhabricatorPolicyCapability::CAN_EDIT); 1730 - } 1731 - 1732 - private function isCommentField(PhabricatorEditField $field) { 1733 - // TODO: This is a little bit hacky. 1734 - if ($field->getKey() == 'comment') { 1735 - return true; 1736 - } 1737 - 1738 - if ($field->getIsLocked()) { 1739 - return false; 1740 - } 1741 - 1742 - if ($field->getIsHidden()) { 1743 - return false; 1744 - } 1745 - 1746 - return true; 1747 1736 } 1748 1737 1749 1738
+4
src/applications/transactions/editfield/PhabricatorCommentEditField.php
··· 11 11 return new PhabricatorCommentEditType(); 12 12 } 13 13 14 + public function shouldGenerateTransactionsFromComment() { 15 + return true; 16 + } 17 + 14 18 }
+120 -9
src/applications/transactions/editfield/PhabricatorEditField.php
··· 15 15 private $description; 16 16 private $editTypeKey; 17 17 private $isRequired; 18 + 18 19 private $commentActionLabel; 20 + private $commentActionValue; 21 + private $hasCommentActionValue; 19 22 20 23 private $isLocked; 21 24 private $isHidden; ··· 202 205 return $this->commentActionLabel; 203 206 } 204 207 208 + public function setCommentActionValue($comment_action_value) { 209 + $this->hasCommentActionValue = true; 210 + $this->commentActionValue = $comment_action_value; 211 + return $this; 212 + } 213 + 214 + public function getCommentActionValue() { 215 + return $this->commentActionValue; 216 + } 217 + 205 218 protected function newControl() { 206 219 throw new PhutilMethodNotImplementedException(); 207 220 } ··· 345 358 return $this; 346 359 } 347 360 348 - public function readValueFromComment($action) { 349 - $this->value = $this->getValueFromComment(idx($action, 'value')); 361 + public function readValueFromComment($value) { 362 + $this->value = $this->getValueFromComment($value); 350 363 return $this; 351 364 } 352 365 ··· 424 437 return $this->initialValue; 425 438 } 426 439 440 + public function setInitialValue($initial_value) { 441 + $this->initialValue = $initial_value; 442 + return $this; 443 + } 444 + 427 445 public function readValueFromSubmit(AphrontRequest $request) { 428 446 $key = $this->getKey(); 429 447 if ($this->getValueExistsInSubmit($request, $key)) { ··· 548 566 return array($edit_type); 549 567 } 550 568 551 - public function getWebEditTypes() { 569 + public function getCommentAction() { 570 + $label = $this->getCommentActionLabel(); 571 + if ($label === null) { 572 + return null; 573 + } 574 + 575 + $action = $this->newCommentAction(); 576 + if ($action === null) { 577 + return null; 578 + } 579 + 580 + if ($this->hasCommentActionValue) { 581 + $value = $this->getCommentActionValue(); 582 + } else { 583 + $value = $this->getValue(); 584 + } 585 + 586 + $action 587 + ->setKey($this->getKey()) 588 + ->setLabel($label) 589 + ->setValue($this->getValueForCommentAction($value)); 590 + 591 + return $action; 592 + } 593 + 594 + protected function newCommentAction() { 595 + return null; 596 + } 597 + 598 + protected function getValueForCommentAction($value) { 599 + return $value; 600 + } 601 + 602 + public function shouldGenerateTransactionsFromSubmit() { 552 603 if ($this->getIsConduitOnly()) { 553 - return array(); 604 + return false; 554 605 } 555 606 556 607 $edit_type = $this->getEditType(); 608 + if (!$edit_type) { 609 + return false; 610 + } 611 + 612 + return true; 613 + } 557 614 558 - if ($edit_type === null) { 559 - return array(); 615 + public function shouldReadValueFromRequest() { 616 + if ($this->getIsConduitOnly()) { 617 + return false; 560 618 } 561 619 562 - return array($edit_type); 620 + if ($this->getIsLocked()) { 621 + return false; 622 + } 623 + 624 + if ($this->getIsHidden()) { 625 + return false; 626 + } 627 + 628 + return true; 563 629 } 564 630 565 - public function getCommentEditTypes() { 566 - return array(); 631 + public function shouldReadValueFromSubmit() { 632 + if ($this->getIsConduitOnly()) { 633 + return false; 634 + } 635 + 636 + if ($this->getIsLocked()) { 637 + return false; 638 + } 639 + 640 + if ($this->getIsHidden()) { 641 + return false; 642 + } 643 + 644 + return true; 645 + } 646 + 647 + public function shouldGenerateTransactionsFromComment() { 648 + if ($this->getIsConduitOnly()) { 649 + return false; 650 + } 651 + 652 + if ($this->getIsLocked()) { 653 + return false; 654 + } 655 + 656 + if ($this->getIsHidden()) { 657 + return false; 658 + } 659 + 660 + return true; 661 + } 662 + 663 + public function generateTransactions( 664 + PhabricatorApplicationTransaction $template, 665 + array $spec) { 666 + 667 + $edit_type = $this->getEditType(); 668 + if (!$edit_type) { 669 + throw new Exception( 670 + pht( 671 + 'EditField (with key "%s", of class "%s") is generating '. 672 + 'transactions, but has no EditType.', 673 + $this->getKey(), 674 + get_class($this))); 675 + } 676 + 677 + return $edit_type->generateTransactions($template, $spec); 567 678 } 568 679 569 680 }
-8
src/applications/transactions/editfield/PhabricatorPHIDListEditField.php
··· 44 44 return new AphrontPHIDListHTTPParameterType(); 45 45 } 46 46 47 - public function readValueFromComment($value) { 48 - // TODO: This is really hacky -- make sure we pass a plain PHID list to 49 - // the edit type. This method probably needs to move down to EditType, and 50 - // maybe more additional logic does too. 51 - $this->setUseEdgeTransactions(false); 52 - return parent::readValueFromComment($value); 53 - } 54 - 55 47 protected function getValueFromRequest(AphrontRequest $request, $key) { 56 48 $value = parent::getValueFromRequest($request, $key); 57 49 if ($this->getIsSingleValue()) {
+3 -32
src/applications/transactions/editfield/PhabricatorSelectEditField.php
··· 4 4 extends PhabricatorEditField { 5 5 6 6 private $options; 7 - private $commentActionDefaultValue; 8 7 9 8 public function setOptions(array $options) { 10 9 $this->options = $options; ··· 18 17 return $this->options; 19 18 } 20 19 21 - public function setCommentActionDefaultValue($default) { 22 - $this->commentActionDefaultValue = $default; 23 - return $this; 24 - } 25 - 26 - public function getCommentActionDefaultValue() { 27 - return $this->commentActionDefaultValue; 28 - } 29 - 30 20 protected function newControl() { 31 21 return id(new AphrontFormSelectControl()) 32 22 ->setOptions($this->getOptions()); ··· 36 26 return new AphrontSelectHTTPParameterType(); 37 27 } 38 28 39 - public function getCommentEditTypes() { 40 - $label = $this->getCommentActionLabel(); 41 - if ($label === null) { 42 - return array(); 43 - } 44 - 45 - $default_value = $this->getCommentActionDefaultValue(); 46 - if ($default_value === null) { 47 - $default_value = $this->getValue(); 48 - } 49 - 50 - $edit = $this->getEditType() 51 - ->setLabel($label) 52 - ->setPHUIXControlType('select') 53 - ->setPHUIXControlSpecification( 54 - array( 55 - 'options' => $this->getOptions(), 56 - 'order' => array_keys($this->getOptions()), 57 - 'value' => $default_value, 58 - )); 59 - 60 - return array($edit); 29 + protected function newCommentAction() { 30 + return id(new PhabricatorEditEngineSelectCommentAction()) 31 + ->setOptions($this->getOptions()); 61 32 } 62 33 63 34 }
+14 -38
src/applications/transactions/editfield/PhabricatorTokenizerEditField.php
··· 3 3 abstract class PhabricatorTokenizerEditField 4 4 extends PhabricatorPHIDListEditField { 5 5 6 - private $commentActionDefaultValue; 7 - 8 6 abstract protected function newDatasource(); 9 7 10 - public function setCommentActionDefaultValue(array $default) { 11 - $this->commentActionDefaultValue = $default; 12 - return $this; 13 - } 14 - 15 - public function getCommentActionDefaultValue() { 16 - return $this->commentActionDefaultValue; 17 - } 18 - 19 8 protected function newControl() { 20 9 $control = id(new AphrontFormTokenizerControl()) 21 10 ->setDatasource($this->newDatasource()); 22 11 23 12 $initial_value = $this->getInitialValue(); 24 13 if ($initial_value !== null) { 25 - $control->setOriginalValue($initial_value); 14 + $control->setInitialValue($initial_value); 26 15 } 27 16 28 17 if ($this->getIsSingleValue()) { ··· 33 22 } 34 23 35 24 protected function getInitialValueFromSubmit(AphrontRequest $request, $key) { 36 - return $request->getArr($key.'.original'); 25 + return $request->getArr($key.'.initial'); 37 26 } 38 27 39 28 protected function newEditType() { ··· 46 35 return $type; 47 36 } 48 37 49 - public function getCommentEditTypes() { 50 - $label = $this->getCommentActionLabel(); 51 - if ($label === null) { 52 - return array(); 53 - } 54 - 55 - $transaction_type = $this->getTransactionType(); 56 - if ($transaction_type === null) { 57 - return array(); 58 - } 38 + protected function newCommentAction() { 39 + $viewer = $this->getViewer(); 59 40 60 - if ($this->getUseEdgeTransactions()) { 61 - $type_key = $this->getEditTypeKey(); 62 - $base = $this->getEditType(); 41 + $datasource = $this->newDatasource() 42 + ->setViewer($viewer); 63 43 64 - $add = id(clone $base) 65 - ->setEditType($type_key.'.add') 66 - ->setEdgeOperation('+') 67 - ->setLabel($label); 44 + $action = id(new PhabricatorEditEngineTokenizerCommentAction()) 45 + ->setDatasource($datasource); 68 46 69 - return array($add); 47 + if ($this->getIsSingleValue()) { 48 + $action->setLimit(1); 70 49 } 71 50 72 - $edit = $this->getEditType() 73 - ->setLabel($label); 74 - 75 - $default = $this->getCommentActionDefaultValue(); 76 - if ($default) { 77 - $edit->setDefaultValue($default); 51 + $initial_value = $this->getInitialValue(); 52 + if ($initial_value !== null) { 53 + $action->setInitialValue($initial_value); 78 54 } 79 55 80 - return array($edit); 56 + return $action; 81 57 } 82 58 83 59 }
-12
src/applications/transactions/edittype/PhabricatorEditType.php
··· 96 96 return $xaction; 97 97 } 98 98 99 - public function getPHUIXControlType() { 100 - return null; 101 - } 102 - 103 - public function getPHUIXControlSpecification() { 104 - return null; 105 - } 106 - 107 - public function getCommentActionValueFromDraftValue($value) { 108 - return $value; 109 - } 110 - 111 99 }
-59
src/applications/transactions/edittype/PhabricatorPHIDListEditType.php
··· 42 42 } 43 43 } 44 44 45 - public function getPHUIXControlType() { 46 - $datasource = $this->getDatasource(); 47 - 48 - if (!$datasource) { 49 - return null; 50 - } 51 - 52 - return 'tokenizer'; 53 - } 54 - 55 - public function getPHUIXControlSpecification() { 56 - $datasource = $this->getDatasource(); 57 - 58 - if (!$datasource) { 59 - return null; 60 - } 61 - 62 - $template = new AphrontTokenizerTemplateView(); 63 - 64 - if ($this->getIsSingleValue()) { 65 - $limit = 1; 66 - } else { 67 - $limit = null; 68 - } 69 - 70 - $default = $this->getDefaultValue(); 71 - if ($default) { 72 - $value = $datasource->getWireTokens($default); 73 - } else { 74 - $value = array(); 75 - } 76 - 77 - return array( 78 - 'markup' => $template->render(), 79 - 'config' => array( 80 - 'src' => $datasource->getDatasourceURI(), 81 - 'browseURI' => $datasource->getBrowseURI(), 82 - 'placeholder' => $datasource->getPlaceholderText(), 83 - 'limit' => $limit, 84 - ), 85 - 'value' => $value, 86 - ); 87 - } 88 - 89 - public function getCommentActionValueFromDraftValue($value) { 90 - $datasource = $this->getDatasource(); 91 - 92 - if (!$datasource) { 93 - return array(); 94 - } 95 - 96 - if (!is_array($value)) { 97 - return array(); 98 - } 99 - 100 - return $datasource->getWireTokens($value); 101 - } 102 - 103 - 104 45 }
-18
src/applications/transactions/edittype/PhabricatorSimpleEditType.php
··· 35 35 return $this->valueDescription; 36 36 } 37 37 38 - public function setPHUIXControlType($type) { 39 - $this->phuixControlType = $type; 40 - return $this; 41 - } 42 - 43 - public function getPHUIXControlType() { 44 - return $this->phuixControlType; 45 - } 46 - 47 - public function setPHUIXControlSpecification(array $spec) { 48 - $this->phuixControlSpecification = $spec; 49 - return $this; 50 - } 51 - 52 - public function getPHUIXControlSpecification() { 53 - return $this->phuixControlSpecification; 54 - } 55 - 56 38 }
+43 -40
src/applications/transactions/view/PhabricatorApplicationTransactionCommentView.php
··· 20 20 private $headerText; 21 21 private $noPermission; 22 22 23 - 24 - 25 23 private $currentVersion; 26 24 private $versionedDraft; 27 - private $editTypes; 25 + private $commentActions; 28 26 private $transactionTimeline; 29 27 30 28 public function setObjectPHID($object_phid) { ··· 104 102 return $this; 105 103 } 106 104 107 - public function setEditTypes($edit_types) { 108 - $this->editTypes = $edit_types; 105 + public function setCommentActions(array $comment_actions) { 106 + assert_instances_of($comment_actions, 'PhabricatorEditEngineCommentAction'); 107 + $this->commentActions = $comment_actions; 109 108 return $this; 110 109 } 111 110 112 - public function getEditTypes() { 113 - return $this->editTypes; 111 + public function getCommentActions() { 112 + return $this->commentActions; 114 113 } 115 114 116 115 public function setNoPermission($no_permission) { ··· 166 165 $preview = null; 167 166 } 168 167 169 - if (!$this->getEditTypes()) { 168 + if (!$this->getCommentActions()) { 170 169 Javelin::initBehavior( 171 170 'phabricator-transaction-comment-form', 172 171 array( ··· 219 218 ->addHiddenInput('__draft__', $draft_key) 220 219 ->addHiddenInput($version_key, $version_value); 221 220 222 - $edit_types = $this->getEditTypes(); 223 - if ($edit_types) { 224 - 221 + $comment_actions = $this->getCommentActions(); 222 + if ($comment_actions) { 225 223 $action_map = array(); 226 224 $type_map = array(); 227 - foreach ($edit_types as $edit_type) { 228 - $key = $edit_type->getEditType(); 225 + 226 + $comment_actions = mpull($comment_actions, null, 'getKey'); 227 + 228 + $draft_actions = array(); 229 + $draft_keys = array(); 230 + if ($versioned_draft) { 231 + $draft_actions = $versioned_draft->getProperty('actions', array()); 232 + 233 + if (!is_array($draft_actions)) { 234 + $draft_actions = array(); 235 + } 236 + 237 + foreach ($draft_actions as $action) { 238 + $type = idx($action, 'type'); 239 + $comment_action = idx($comment_actions, $type); 240 + if (!$comment_action) { 241 + continue; 242 + } 243 + 244 + $value = idx($action, 'value'); 245 + $comment_action->setValue($value); 246 + 247 + $draft_keys[] = $type; 248 + } 249 + } 250 + 251 + foreach ($comment_actions as $key => $comment_action) { 252 + $key = $comment_action->getKey(); 229 253 $action_map[$key] = array( 230 254 'key' => $key, 231 - 'label' => $edit_type->getLabel(), 232 - 'type' => $edit_type->getPHUIXControlType(), 233 - 'spec' => $edit_type->getPHUIXControlSpecification(), 255 + 'label' => $comment_action->getLabel(), 256 + 'type' => $comment_action->getPHUIXControlType(), 257 + 'spec' => $comment_action->getPHUIXControlSpecification(), 258 + 'initialValue' => $comment_action->getInitialValue(), 234 259 ); 235 260 236 - $type_map[$key] = $edit_type; 261 + $type_map[$key] = $comment_action; 237 262 } 238 263 239 264 $options = array(); ··· 270 295 'id' => $place_id, 271 296 ))); 272 297 273 - $draft_actions = array(); 274 - if ($versioned_draft) { 275 - $draft_actions = $versioned_draft->getProperty('actions', array()); 276 - foreach ($draft_actions as $key => $action) { 277 - $type = idx($action, 'type'); 278 - if (!$type) { 279 - unset($draft_actions[$key]); 280 - continue; 281 - } 282 - 283 - $edit_type = idx($type_map, $type); 284 - if (!$edit_type) { 285 - unset($draft_actions[$key]); 286 - continue; 287 - } 288 - 289 - $value = idx($action, 'value'); 290 - $value = $edit_type->getCommentActionValueFromDraftValue($value); 291 - $draft_actions[$key]['value'] = $value; 292 - } 293 - } 294 - 295 298 Javelin::initBehavior( 296 299 'comment-actions', 297 300 array( ··· 304 307 'actions' => $action_map, 305 308 'showPreview' => $this->getShowPreview(), 306 309 'actionURI' => $this->getAction(), 307 - 'drafts' => $draft_actions, 310 + 'drafts' => $draft_keys, 308 311 )); 309 312 } 310 313
+12 -12
src/view/control/AphrontTokenizerTemplateView.php
··· 6 6 private $name; 7 7 private $id; 8 8 private $browseURI; 9 - private $originalValue; 9 + private $initialValue; 10 10 11 11 public function setBrowseURI($browse_uri) { 12 12 $this->browseURI = $browse_uri; ··· 37 37 return $this->name; 38 38 } 39 39 40 - public function setOriginalValue(array $original_value) { 41 - $this->originalValue = $original_value; 40 + public function setInitialValue(array $initial_value) { 41 + $this->initialValue = $initial_value; 42 42 return $this; 43 43 } 44 44 45 - public function getOriginalValue() { 46 - return $this->originalValue; 45 + public function getInitialValue() { 46 + return $this->initialValue; 47 47 } 48 48 49 49 public function render() { ··· 95 95 $classes[] = 'has-browse'; 96 96 } 97 97 98 - $original = array(); 99 - $original_value = $this->getOriginalValue(); 100 - if ($original_value) { 101 - foreach ($this->getOriginalValue() as $value) { 102 - $original[] = phutil_tag( 98 + $initial = array(); 99 + $initial_value = $this->getInitialValue(); 100 + if ($initial_value) { 101 + foreach ($this->getInitialValue() as $value) { 102 + $initial[] = phutil_tag( 103 103 'input', 104 104 array( 105 105 'type' => 'hidden', 106 - 'name' => $name.'.original[]', 106 + 'name' => $name.'.initial[]', 107 107 'value' => $value, 108 108 )); 109 109 } ··· 118 118 array( 119 119 $container, 120 120 $browse, 121 - $original, 121 + $initial, 122 122 )); 123 123 124 124 return $frame;
+8 -8
src/view/form/control/AphrontFormTokenizerControl.php
··· 7 7 private $limit; 8 8 private $placeholder; 9 9 private $handles; 10 - private $originalValue; 10 + private $initialValue; 11 11 12 12 public function setDatasource(PhabricatorTypeaheadDatasource $datasource) { 13 13 $this->datasource = $datasource; ··· 33 33 return $this; 34 34 } 35 35 36 - public function setOriginalValue(array $original_value) { 37 - $this->originalValue = $original_value; 36 + public function setInitialValue(array $initial_value) { 37 + $this->initialValue = $initial_value; 38 38 return $this; 39 39 } 40 40 41 - public function getOriginalValue() { 42 - return $this->originalValue; 41 + public function getInitialValue() { 42 + return $this->initialValue; 43 43 } 44 44 45 45 public function willRender() { ··· 84 84 ->setID($id) 85 85 ->setValue($tokens); 86 86 87 - $original_value = $this->getOriginalValue(); 88 - if ($original_value !== null) { 89 - $template->setOriginalValue($original_value); 87 + $initial_value = $this->getInitialValue(); 88 + if ($initial_value !== null) { 89 + $template->setInitialValue($initial_value); 90 90 } 91 91 92 92 $username = null;
+4 -4
webroot/rsrc/js/application/transactions/behavior-comment-actions.js
··· 80 80 for (var k in rows) { 81 81 data.push({ 82 82 type: k, 83 - value: rows[k].getValue() 83 + value: rows[k].getValue(), 84 + initialValue: action_map[k].initialValue || null 84 85 }); 85 86 } 86 87 ··· 104 105 for (var ii = 0; ii < drafts.length; ii++) { 105 106 draft = drafts[ii]; 106 107 107 - option = find_option(draft.type); 108 + option = find_option(draft); 108 109 if (!option) { 109 110 continue; 110 111 } 111 112 112 113 control = add_row(option); 113 - control.setValue(draft.value); 114 114 } 115 115 } 116 116 ··· 133 133 input_node.value = serialize_actions(); 134 134 }); 135 135 136 + 136 137 if (config.showPreview) { 137 138 var request = new JX.PhabricatorShapedRequest( 138 139 config.actionURI, ··· 154 155 } 155 156 156 157 restore_draft_actions(config.drafts || []); 157 - 158 158 });