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

Implement a rough optgroup-based "Move on Workboard" stacked action

Summary:
Ref T6027. Try this out and see how it feels? Clear issues:

- This definitely shouldn't be at the top.
- You should probably be able to select it multiple times?
- Some of the "which columns show up" rules might need adjustment?
- Diamond marker maybe not great?

Not sure I love this but it doesn't feel //terrible//...

Test Plan: {F1207891}

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T6027

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

+171 -7
+6 -6
resources/celerity/map.php
··· 515 515 'rsrc/js/phuix/PHUIXActionView.js' => '8cf6d262', 516 516 'rsrc/js/phuix/PHUIXAutocomplete.js' => '9196fb06', 517 517 'rsrc/js/phuix/PHUIXDropdownMenu.js' => 'bd4c8dca', 518 - 'rsrc/js/phuix/PHUIXFormControl.js' => 'a7763e11', 518 + 'rsrc/js/phuix/PHUIXFormControl.js' => 'e15869a8', 519 519 'rsrc/js/phuix/PHUIXIconView.js' => 'bff6884b', 520 520 ), 521 521 'symbols' => array( ··· 855 855 'phuix-action-view' => '8cf6d262', 856 856 'phuix-autocomplete' => '9196fb06', 857 857 'phuix-dropdown-menu' => 'bd4c8dca', 858 - 'phuix-form-control-view' => 'a7763e11', 858 + 'phuix-form-control-view' => 'e15869a8', 859 859 'phuix-icon-view' => 'bff6884b', 860 860 'policy-css' => '957ea14c', 861 861 'policy-edit-css' => '815c66f7', ··· 1659 1659 'javelin-uri', 1660 1660 'phabricator-notification', 1661 1661 ), 1662 - 'a7763e11' => array( 1663 - 'javelin-install', 1664 - 'javelin-dom', 1665 - ), 1666 1662 'a80d0378' => array( 1667 1663 'javelin-behavior', 1668 1664 'javelin-stratcom', ··· 1963 1959 'javelin-behavior', 1964 1960 'javelin-dom', 1965 1961 'phabricator-prefab', 1962 + ), 1963 + 'e15869a8' => array( 1964 + 'javelin-install', 1965 + 'javelin-dom', 1966 1966 ), 1967 1967 'e1d25dfb' => array( 1968 1968 'javelin-behavior',
+2
src/__phutil_library_map__.php
··· 2278 2278 'PhabricatorEdgesDestructionEngineExtension' => 'infrastructure/edges/engineextension/PhabricatorEdgesDestructionEngineExtension.php', 2279 2279 'PhabricatorEditEngine' => 'applications/transactions/editengine/PhabricatorEditEngine.php', 2280 2280 'PhabricatorEditEngineAPIMethod' => 'applications/transactions/editengine/PhabricatorEditEngineAPIMethod.php', 2281 + 'PhabricatorEditEngineColumnsCommentAction' => 'applications/transactions/commentaction/PhabricatorEditEngineColumnsCommentAction.php', 2281 2282 'PhabricatorEditEngineCommentAction' => 'applications/transactions/commentaction/PhabricatorEditEngineCommentAction.php', 2282 2283 'PhabricatorEditEngineConfiguration' => 'applications/transactions/storage/PhabricatorEditEngineConfiguration.php', 2283 2284 'PhabricatorEditEngineConfigurationDefaultCreateController' => 'applications/transactions/controller/PhabricatorEditEngineConfigurationDefaultCreateController.php', ··· 6723 6724 'PhabricatorPolicyInterface', 6724 6725 ), 6725 6726 'PhabricatorEditEngineAPIMethod' => 'ConduitAPIMethod', 6727 + 'PhabricatorEditEngineColumnsCommentAction' => 'PhabricatorEditEngineCommentAction', 6726 6728 'PhabricatorEditEngineCommentAction' => 'Phobject', 6727 6729 'PhabricatorEditEngineConfiguration' => array( 6728 6730 'PhabricatorSearchDAO',
+80 -1
src/applications/maniphest/editor/ManiphestEditEngine.php
··· 132 132 EODOCS 133 133 ); 134 134 135 + $column_map = $this->getColumnMap($object); 136 + 135 137 $fields = array( 136 138 id(new PhabricatorHandlesEditField()) 137 139 ->setKey('parent') ··· 159 161 ->setTransactionType(PhabricatorTransactions::TYPE_COLUMNS) 160 162 ->setIsReorderable(false) 161 163 ->setIsDefaultable(false) 162 - ->setIsLockable(false), 164 + ->setIsLockable(false) 165 + ->setCommentActionLabel(pht('Move on Workboard')) 166 + ->setColumnMap($column_map), 163 167 id(new PhabricatorTextEditField()) 164 168 ->setKey('title') 165 169 ->setLabel(pht('Title')) ··· 368 372 ->setObjectPHID($object_phid) 369 373 ->setVisiblePHIDs($visible_phids) 370 374 ->buildResponse(); 375 + } 376 + 377 + private function getColumnMap(ManiphestTask $task) { 378 + $phid = $task->getPHID(); 379 + if (!$phid) { 380 + return array(); 381 + } 382 + 383 + $board_phids = PhabricatorEdgeQuery::loadDestinationPHIDs( 384 + $phid, 385 + PhabricatorProjectObjectHasProjectEdgeType::EDGECONST); 386 + if (!$board_phids) { 387 + return array(); 388 + } 389 + 390 + $viewer = $this->getViewer(); 391 + 392 + $layout_engine = id(new PhabricatorBoardLayoutEngine()) 393 + ->setViewer($viewer) 394 + ->setBoardPHIDs($board_phids) 395 + ->setObjectPHIDs(array($task->getPHID())) 396 + ->setFetchAllBoards(true) 397 + ->executeLayout(); 398 + 399 + $map = array(); 400 + foreach ($board_phids as $board_phid) { 401 + $in_columns = $layout_engine->getObjectColumns($board_phid, $phid); 402 + $in_columns = mpull($in_columns, null, 'getPHID'); 403 + 404 + $all_columns = $layout_engine->getColumns($board_phid); 405 + $options = array(); 406 + foreach ($all_columns as $column) { 407 + $name = $column->getDisplayName(); 408 + 409 + $is_hidden = $column->isHidden(); 410 + $is_selected = isset($in_columns[$column->getPHID()]); 411 + 412 + // Don't show hidden, subproject or milestone columns in this map 413 + // unless the object is currently in the column. 414 + $skip_column = ($is_hidden || $column->getProxyPHID()); 415 + if ($skip_column) { 416 + if (!$is_selected) { 417 + continue; 418 + } 419 + } 420 + 421 + if ($is_hidden) { 422 + $name = pht('(%s)', $name); 423 + } 424 + 425 + if ($is_selected) { 426 + $name = pht("\xE2\x97\x8F %s", $name); 427 + } else { 428 + $name = pht("\xE2\x97\x8B %s", $name); 429 + } 430 + 431 + $option = array( 432 + 'key' => $column->getPHID(), 433 + 'label' => $name, 434 + 'selected' => (bool)$is_selected, 435 + ); 436 + 437 + $options[] = $option; 438 + } 439 + 440 + $map[] = array( 441 + 'label' => head($all_columns)->getProject()->getDisplayName(), 442 + 'options' => $options, 443 + ); 444 + } 445 + 446 + $map = isort($map, 'label'); 447 + $map = array_values($map); 448 + 449 + return $map; 371 450 } 372 451 373 452
+27
src/applications/transactions/commentaction/PhabricatorEditEngineColumnsCommentAction.php
··· 1 + <?php 2 + 3 + final class PhabricatorEditEngineColumnsCommentAction 4 + extends PhabricatorEditEngineCommentAction { 5 + 6 + private $columnMap; 7 + 8 + public function setColumnMap(array $column_map) { 9 + $this->columnMap = $column_map; 10 + return $this; 11 + } 12 + 13 + public function getColumnMap() { 14 + return $this->columnMap; 15 + } 16 + 17 + public function getPHUIXControlType() { 18 + return 'optgroups'; 19 + } 20 + 21 + public function getPHUIXControlSpecification() { 22 + return array( 23 + 'groups' => $this->getColumnMap(), 24 + ); 25 + } 26 + 27 + }
+21
src/applications/transactions/editfield/PhabricatorColumnsEditField.php
··· 3 3 final class PhabricatorColumnsEditField 4 4 extends PhabricatorPHIDListEditField { 5 5 6 + private $columnMap; 7 + 8 + public function setColumnMap(array $column_map) { 9 + $this->columnMap = $column_map; 10 + return $this; 11 + } 12 + 13 + public function getColumnMap() { 14 + return $this->columnMap; 15 + } 16 + 6 17 protected function newControl() { 7 18 $control = id(new AphrontFormHandlesControl()); 8 19 $control->setIsInvisible(true); ··· 16 27 17 28 protected function newConduitParameterType() { 18 29 return new ConduitColumnsParameterType(); 30 + } 31 + 32 + protected function newCommentAction() { 33 + $column_map = $this->getColumnMap(); 34 + if (!$column_map) { 35 + return null; 36 + } 37 + 38 + return id(new PhabricatorEditEngineColumnsCommentAction()) 39 + ->setColumnMap($this->getColumnMap()); 19 40 } 20 41 21 42 }
+35
webroot/rsrc/js/phuix/PHUIXFormControl.js
··· 38 38 case 'points': 39 39 input = this._newPoints(spec); 40 40 break; 41 + case 'optgroups': 42 + input = this._newOptgroups(spec); 43 + break; 41 44 default: 42 45 // TODO: Default or better error? 43 46 JX.$E('Bad Input Type'); ··· 170 173 }; 171 174 172 175 var node = JX.$N('input', attrs); 176 + 177 + return { 178 + node: node, 179 + get: function() { 180 + return node.value; 181 + }, 182 + set: function(value) { 183 + node.value = value; 184 + } 185 + }; 186 + }, 187 + 188 + _newOptgroups: function(spec) { 189 + var value = spec.value || null; 190 + 191 + var optgroups = []; 192 + for (var ii = 0; ii < spec.groups.length; ii++) { 193 + var group = spec.groups[ii]; 194 + var options = []; 195 + for (var jj = 0; jj < group.options.length; jj++) { 196 + var option = group.options[jj]; 197 + options.push(JX.$N('option', {value: option.key}, option.label)); 198 + 199 + if (option.selected && (value === null)) { 200 + value = option.key; 201 + } 202 + } 203 + optgroups.push(JX.$N('optgroup', {label: group.label}, options)); 204 + } 205 + 206 + var node = JX.$N('select', {}, optgroups); 207 + node.value = value; 173 208 174 209 return { 175 210 node: node,