diff --git a/resources/celerity/map.php b/resources/celerity/map.php index 64455ce942..1c4d121db1 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -515,7 +515,7 @@ return array( 'rsrc/js/phuix/PHUIXActionView.js' => '8cf6d262', 'rsrc/js/phuix/PHUIXAutocomplete.js' => '9196fb06', 'rsrc/js/phuix/PHUIXDropdownMenu.js' => 'bd4c8dca', - 'rsrc/js/phuix/PHUIXFormControl.js' => 'a7763e11', + 'rsrc/js/phuix/PHUIXFormControl.js' => 'e15869a8', 'rsrc/js/phuix/PHUIXIconView.js' => 'bff6884b', ), 'symbols' => array( @@ -855,7 +855,7 @@ return array( 'phuix-action-view' => '8cf6d262', 'phuix-autocomplete' => '9196fb06', 'phuix-dropdown-menu' => 'bd4c8dca', - 'phuix-form-control-view' => 'a7763e11', + 'phuix-form-control-view' => 'e15869a8', 'phuix-icon-view' => 'bff6884b', 'policy-css' => '957ea14c', 'policy-edit-css' => '815c66f7', @@ -1659,10 +1659,6 @@ return array( 'javelin-uri', 'phabricator-notification', ), - 'a7763e11' => array( - 'javelin-install', - 'javelin-dom', - ), 'a80d0378' => array( 'javelin-behavior', 'javelin-stratcom', @@ -1964,6 +1960,10 @@ return array( 'javelin-dom', 'phabricator-prefab', ), + 'e15869a8' => array( + 'javelin-install', + 'javelin-dom', + ), 'e1d25dfb' => array( 'javelin-behavior', 'javelin-stratcom', diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index b1e36442c3..671a8e8e26 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -2278,6 +2278,7 @@ phutil_register_library_map(array( 'PhabricatorEdgesDestructionEngineExtension' => 'infrastructure/edges/engineextension/PhabricatorEdgesDestructionEngineExtension.php', 'PhabricatorEditEngine' => 'applications/transactions/editengine/PhabricatorEditEngine.php', 'PhabricatorEditEngineAPIMethod' => 'applications/transactions/editengine/PhabricatorEditEngineAPIMethod.php', + 'PhabricatorEditEngineColumnsCommentAction' => 'applications/transactions/commentaction/PhabricatorEditEngineColumnsCommentAction.php', 'PhabricatorEditEngineCommentAction' => 'applications/transactions/commentaction/PhabricatorEditEngineCommentAction.php', 'PhabricatorEditEngineConfiguration' => 'applications/transactions/storage/PhabricatorEditEngineConfiguration.php', 'PhabricatorEditEngineConfigurationDefaultCreateController' => 'applications/transactions/controller/PhabricatorEditEngineConfigurationDefaultCreateController.php', @@ -6723,6 +6724,7 @@ phutil_register_library_map(array( 'PhabricatorPolicyInterface', ), 'PhabricatorEditEngineAPIMethod' => 'ConduitAPIMethod', + 'PhabricatorEditEngineColumnsCommentAction' => 'PhabricatorEditEngineCommentAction', 'PhabricatorEditEngineCommentAction' => 'Phobject', 'PhabricatorEditEngineConfiguration' => array( 'PhabricatorSearchDAO', diff --git a/src/applications/maniphest/editor/ManiphestEditEngine.php b/src/applications/maniphest/editor/ManiphestEditEngine.php index 42822868f3..d49851cdfd 100644 --- a/src/applications/maniphest/editor/ManiphestEditEngine.php +++ b/src/applications/maniphest/editor/ManiphestEditEngine.php @@ -132,6 +132,8 @@ priority-sorted boards. EODOCS ); + $column_map = $this->getColumnMap($object); + $fields = array( id(new PhabricatorHandlesEditField()) ->setKey('parent') @@ -159,7 +161,9 @@ EODOCS ->setTransactionType(PhabricatorTransactions::TYPE_COLUMNS) ->setIsReorderable(false) ->setIsDefaultable(false) - ->setIsLockable(false), + ->setIsLockable(false) + ->setCommentActionLabel(pht('Move on Workboard')) + ->setColumnMap($column_map), id(new PhabricatorTextEditField()) ->setKey('title') ->setLabel(pht('Title')) @@ -370,5 +374,80 @@ EODOCS ->buildResponse(); } + private function getColumnMap(ManiphestTask $task) { + $phid = $task->getPHID(); + if (!$phid) { + return array(); + } + + $board_phids = PhabricatorEdgeQuery::loadDestinationPHIDs( + $phid, + PhabricatorProjectObjectHasProjectEdgeType::EDGECONST); + if (!$board_phids) { + return array(); + } + + $viewer = $this->getViewer(); + + $layout_engine = id(new PhabricatorBoardLayoutEngine()) + ->setViewer($viewer) + ->setBoardPHIDs($board_phids) + ->setObjectPHIDs(array($task->getPHID())) + ->setFetchAllBoards(true) + ->executeLayout(); + + $map = array(); + foreach ($board_phids as $board_phid) { + $in_columns = $layout_engine->getObjectColumns($board_phid, $phid); + $in_columns = mpull($in_columns, null, 'getPHID'); + + $all_columns = $layout_engine->getColumns($board_phid); + $options = array(); + foreach ($all_columns as $column) { + $name = $column->getDisplayName(); + + $is_hidden = $column->isHidden(); + $is_selected = isset($in_columns[$column->getPHID()]); + + // Don't show hidden, subproject or milestone columns in this map + // unless the object is currently in the column. + $skip_column = ($is_hidden || $column->getProxyPHID()); + if ($skip_column) { + if (!$is_selected) { + continue; + } + } + + if ($is_hidden) { + $name = pht('(%s)', $name); + } + + if ($is_selected) { + $name = pht("\xE2\x97\x8F %s", $name); + } else { + $name = pht("\xE2\x97\x8B %s", $name); + } + + $option = array( + 'key' => $column->getPHID(), + 'label' => $name, + 'selected' => (bool)$is_selected, + ); + + $options[] = $option; + } + + $map[] = array( + 'label' => head($all_columns)->getProject()->getDisplayName(), + 'options' => $options, + ); + } + + $map = isort($map, 'label'); + $map = array_values($map); + + return $map; + } + } diff --git a/src/applications/transactions/commentaction/PhabricatorEditEngineColumnsCommentAction.php b/src/applications/transactions/commentaction/PhabricatorEditEngineColumnsCommentAction.php new file mode 100644 index 0000000000..bc68b7b642 --- /dev/null +++ b/src/applications/transactions/commentaction/PhabricatorEditEngineColumnsCommentAction.php @@ -0,0 +1,27 @@ +columnMap = $column_map; + return $this; + } + + public function getColumnMap() { + return $this->columnMap; + } + + public function getPHUIXControlType() { + return 'optgroups'; + } + + public function getPHUIXControlSpecification() { + return array( + 'groups' => $this->getColumnMap(), + ); + } + +} diff --git a/src/applications/transactions/editfield/PhabricatorColumnsEditField.php b/src/applications/transactions/editfield/PhabricatorColumnsEditField.php index 79fb25b86a..fef51e2864 100644 --- a/src/applications/transactions/editfield/PhabricatorColumnsEditField.php +++ b/src/applications/transactions/editfield/PhabricatorColumnsEditField.php @@ -3,6 +3,17 @@ final class PhabricatorColumnsEditField extends PhabricatorPHIDListEditField { + private $columnMap; + + public function setColumnMap(array $column_map) { + $this->columnMap = $column_map; + return $this; + } + + public function getColumnMap() { + return $this->columnMap; + } + protected function newControl() { $control = id(new AphrontFormHandlesControl()); $control->setIsInvisible(true); @@ -18,4 +29,14 @@ final class PhabricatorColumnsEditField return new ConduitColumnsParameterType(); } + protected function newCommentAction() { + $column_map = $this->getColumnMap(); + if (!$column_map) { + return null; + } + + return id(new PhabricatorEditEngineColumnsCommentAction()) + ->setColumnMap($this->getColumnMap()); + } + } diff --git a/webroot/rsrc/js/phuix/PHUIXFormControl.js b/webroot/rsrc/js/phuix/PHUIXFormControl.js index cd004b0e8f..5a53bafd7b 100644 --- a/webroot/rsrc/js/phuix/PHUIXFormControl.js +++ b/webroot/rsrc/js/phuix/PHUIXFormControl.js @@ -38,6 +38,9 @@ JX.install('PHUIXFormControl', { case 'points': input = this._newPoints(spec); break; + case 'optgroups': + input = this._newOptgroups(spec); + break; default: // TODO: Default or better error? JX.$E('Bad Input Type'); @@ -171,6 +174,38 @@ JX.install('PHUIXFormControl', { var node = JX.$N('input', attrs); + return { + node: node, + get: function() { + return node.value; + }, + set: function(value) { + node.value = value; + } + }; + }, + + _newOptgroups: function(spec) { + var value = spec.value || null; + + var optgroups = []; + for (var ii = 0; ii < spec.groups.length; ii++) { + var group = spec.groups[ii]; + var options = []; + for (var jj = 0; jj < group.options.length; jj++) { + var option = group.options[jj]; + options.push(JX.$N('option', {value: option.key}, option.label)); + + if (option.selected && (value === null)) { + value = option.key; + } + } + optgroups.push(JX.$N('optgroup', {label: group.label}, options)); + } + + var node = JX.$N('select', {}, optgroups); + node.value = value; + return { node: node, get: function() {