From 804be81f5dbbe08059c2ebe1a6ee96b89c32968f Mon Sep 17 00:00:00 2001 From: epriestley Date: Sun, 10 Mar 2019 22:56:54 -0700 Subject: [PATCH] Provide better UI feedback about cards that can't be dragged or edited Summary: Depends on D20273. Fixes T10722. Currently, we don't make it very clear when a card can't be edited. Long ago, some code made a weak attempt to do this (by hiding the "grip" on the card), but later UI changes hid the "grip" unconditionally so that mooted things. Instead: - Replace the edit pencil with a red lock. - Provide cursor hints for grabbable / not grabbable. - Don't let users pick up cards they can't edit. Test Plan: On a workboard with a mixture of editable and not-editable cards, hovered over the different cards and was able to figure out which ones I could drag or not drag pretty easily. Picked up cards I could pick up, wasn't able to drag cards I can't edit. Reviewers: amckinley Reviewed By: amckinley Maniphest Tasks: T10722 Differential Revision: https://secure.phabricator.com/D20274 --- resources/celerity/map.php | 52 +++++++++---------- .../project/view/ProjectBoardTaskCard.php | 30 +++++++---- .../css/phui/workboards/phui-workcard.css | 35 ++++++++++--- .../js/application/projects/WorkboardBoard.js | 2 +- webroot/rsrc/js/core/DraggableList.js | 2 + 5 files changed, 77 insertions(+), 44 deletions(-) diff --git a/resources/celerity/map.php b/resources/celerity/map.php index efa2e80f17..33d8b09bc8 100644 --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -10,7 +10,7 @@ return array( 'conpherence.pkg.css' => '3c8a0668', 'conpherence.pkg.js' => '020aebcf', 'core.pkg.css' => '34ce1741', - 'core.pkg.js' => 'b96c872e', + 'core.pkg.js' => '200a0a61', 'differential.pkg.css' => '8d8360fb', 'differential.pkg.js' => '67e02996', 'diffusion.pkg.css' => '42c75c37', @@ -177,7 +177,7 @@ return array( 'rsrc/css/phui/phui-two-column-view.css' => '01e6991e', 'rsrc/css/phui/workboards/phui-workboard-color.css' => 'e86de308', 'rsrc/css/phui/workboards/phui-workboard.css' => '74fc9d98', - 'rsrc/css/phui/workboards/phui-workcard.css' => '8c536f90', + 'rsrc/css/phui/workboards/phui-workcard.css' => '9e9eb0df', 'rsrc/css/phui/workboards/phui-workpanel.css' => 'bc16cf33', 'rsrc/css/sprite-login.css' => '18b368a6', 'rsrc/css/sprite-tokens.css' => 'f1896dc5', @@ -408,7 +408,7 @@ return array( 'rsrc/js/application/phortune/phortune-credit-card-form.js' => 'd12d214f', 'rsrc/js/application/policy/behavior-policy-control.js' => '0eaa33a9', 'rsrc/js/application/policy/behavior-policy-rule-editor.js' => '9347f172', - 'rsrc/js/application/projects/WorkboardBoard.js' => 'fc1664ff', + 'rsrc/js/application/projects/WorkboardBoard.js' => 'eb55f7e8', 'rsrc/js/application/projects/WorkboardCard.js' => '0392a5d8', 'rsrc/js/application/projects/WorkboardCardTemplate.js' => '2a61f8d4', 'rsrc/js/application/projects/WorkboardColumn.js' => 'fd4c2069', @@ -436,7 +436,7 @@ return array( 'rsrc/js/application/uiexample/notification-example.js' => '29819b75', 'rsrc/js/core/Busy.js' => '5202e831', 'rsrc/js/core/DragAndDropFileUpload.js' => '4370900d', - 'rsrc/js/core/DraggableList.js' => '8437c663', + 'rsrc/js/core/DraggableList.js' => '91f40fbf', 'rsrc/js/core/Favicon.js' => '7930776a', 'rsrc/js/core/FileUpload.js' => 'ab85e184', 'rsrc/js/core/Hovercard.js' => '074f0783', @@ -728,7 +728,7 @@ return array( 'javelin-view-renderer' => '9aae2b66', 'javelin-view-visitor' => '308f9fe4', 'javelin-websocket' => 'fdc13e4e', - 'javelin-workboard-board' => 'fc1664ff', + 'javelin-workboard-board' => 'eb55f7e8', 'javelin-workboard-card' => '0392a5d8', 'javelin-workboard-card-template' => '2a61f8d4', 'javelin-workboard-column' => 'fd4c2069', @@ -759,7 +759,7 @@ return array( 'phabricator-diff-changeset-list' => '04023d82', 'phabricator-diff-inline' => 'a4a14a94', 'phabricator-drag-and-drop-file-upload' => '4370900d', - 'phabricator-draggable-list' => '8437c663', + 'phabricator-draggable-list' => '91f40fbf', 'phabricator-fatal-config-template-css' => '20babf50', 'phabricator-favicon' => '7930776a', 'phabricator-feed-css' => 'd8b6e3f8', @@ -857,7 +857,7 @@ return array( 'phui-two-column-view-css' => '01e6991e', 'phui-workboard-color-css' => 'e86de308', 'phui-workboard-view-css' => '74fc9d98', - 'phui-workcard-view-css' => '8c536f90', + 'phui-workcard-view-css' => '9e9eb0df', 'phui-workpanel-view-css' => 'bc16cf33', 'phuix-action-list-view' => 'c68f183f', 'phuix-action-view' => 'aaa08f3b', @@ -1557,14 +1557,6 @@ return array( 'javelin-dom', 'javelin-vector', ), - '8437c663' => array( - 'javelin-install', - 'javelin-dom', - 'javelin-stratcom', - 'javelin-util', - 'javelin-vector', - 'javelin-magical-init', - ), '87428eb2' => array( 'javelin-behavior', 'javelin-diffusion-locate-file-source', @@ -1643,6 +1635,14 @@ return array( 'javelin-workflow', 'javelin-stratcom', ), + '91f40fbf' => array( + 'javelin-install', + 'javelin-dom', + 'javelin-stratcom', + 'javelin-util', + 'javelin-vector', + 'javelin-magical-init', + ), '92388bae' => array( 'javelin-behavior', 'javelin-scrollbar', @@ -2051,6 +2051,17 @@ return array( 'javelin-install', 'javelin-event', ), + 'eb55f7e8' => array( + 'javelin-install', + 'javelin-dom', + 'javelin-util', + 'javelin-stratcom', + 'javelin-workflow', + 'phabricator-draggable-list', + 'javelin-workboard-column', + 'javelin-workboard-header-template', + 'javelin-workboard-card-template', + ), 'ec4e31c0' => array( 'phui-timeline-view-css', ), @@ -2118,17 +2129,6 @@ return array( 'phabricator-keyboard-shortcut', 'conpherence-thread-manager', ), - 'fc1664ff' => array( - 'javelin-install', - 'javelin-dom', - 'javelin-util', - 'javelin-stratcom', - 'javelin-workflow', - 'phabricator-draggable-list', - 'javelin-workboard-column', - 'javelin-workboard-header-template', - 'javelin-workboard-card-template', - ), 'fce5d170' => array( 'javelin-magical-init', 'javelin-util', diff --git a/src/applications/project/view/ProjectBoardTaskCard.php b/src/applications/project/view/ProjectBoardTaskCard.php index 3a7016ca74..bb1c8ca8c5 100644 --- a/src/applications/project/view/ProjectBoardTaskCard.php +++ b/src/applications/project/view/ProjectBoardTaskCard.php @@ -82,20 +82,32 @@ final class ProjectBoardTaskCard extends Phobject { $card = id(new PHUIObjectItemView()) ->setObject($task) ->setUser($viewer) - ->setObjectName('T'.$task->getID()) + ->setObjectName($task->getMonogram()) ->setHeader($task->getTitle()) - ->setGrippable($can_edit) - ->setHref('/T'.$task->getID()) + ->setHref($task->getURI()) ->addSigil('project-card') ->setDisabled($task->isClosed()) - ->addAction( - id(new PHUIListItemView()) - ->setName(pht('Edit')) - ->setIcon('fa-pencil') - ->addSigil('edit-project-card') - ->setHref('/maniphest/task/edit/'.$task->getID().'/')) ->setBarColor($bar_color); + if ($can_edit) { + $card + ->addSigil('draggable-card') + ->addClass('draggable-card'); + $edit_icon = 'fa-pencil'; + } else { + $card + ->addClass('not-editable') + ->addClass('undraggable-card'); + $edit_icon = 'fa-lock red'; + } + + $card->addAction( + id(new PHUIListItemView()) + ->setName(pht('Edit')) + ->setIcon($edit_icon) + ->addSigil('edit-project-card') + ->setHref('/maniphest/task/edit/'.$task->getID().'/')); + if ($owner) { $card->addHandleIcon($owner, $owner->getName()); } diff --git a/webroot/rsrc/css/phui/workboards/phui-workcard.css b/webroot/rsrc/css/phui/workboards/phui-workcard.css index e137e962bc..3c6a798fc8 100644 --- a/webroot/rsrc/css/phui/workboards/phui-workcard.css +++ b/webroot/rsrc/css/phui/workboards/phui-workcard.css @@ -59,14 +59,6 @@ vertical-align: top; } -.phui-workcard.phui-oi-grippable .phui-oi-frame { - padding-left: 0; -} - -.phui-workcard .phui-oi-grip { - display: none; -} - .device-desktop .phui-workcard .phui-list-item-icon { display: none; } @@ -88,6 +80,33 @@ opacity: 1; } +.device-desktop .phui-workcard.draggable-card { + cursor: grab; +} + +.jx-dragging .phui-workcard.draggable-card { + cursor: grabbing; +} + +.device-desktop .phui-workcard.undraggable-card { + cursor: not-allowed; +} + +.device-desktop .phui-workcard.phui-oi.not-editable:hover { + background: {$sh-redbackground}; +} + +.device-desktop .phui-workcard.phui-oi.not-editable:hover + .phui-list-item-href { + border-radius: 3px; + background: {$red}; +} + +.device-desktop .phui-workcard.phui-oi.not-editable:hover + .phui-list-item-href .phui-icon-view { + color: #fff; +} + .phui-workcard.phui-oi:hover .phui-list-item-icon { display: block; } diff --git a/webroot/rsrc/js/application/projects/WorkboardBoard.js b/webroot/rsrc/js/application/projects/WorkboardBoard.js index cda48bde11..a05777e2f2 100644 --- a/webroot/rsrc/js/application/projects/WorkboardBoard.js +++ b/webroot/rsrc/js/application/projects/WorkboardBoard.js @@ -138,7 +138,7 @@ JX.install('WorkboardBoard', { for (var k in columns) { var column = columns[k]; - var list = new JX.DraggableList('project-card', column.getRoot()) + var list = new JX.DraggableList('draggable-card', column.getRoot()) .setOuterContainer(this.getRoot()) .setFindItemsHandler(JX.bind(column, column.getDropTargetNodes)) .setCanDragX(true) diff --git a/webroot/rsrc/js/core/DraggableList.js b/webroot/rsrc/js/core/DraggableList.js index 598856581f..1c7ca766f2 100644 --- a/webroot/rsrc/js/core/DraggableList.js +++ b/webroot/rsrc/js/core/DraggableList.js @@ -240,6 +240,7 @@ JX.install('DraggableList', { frame.appendChild(clone); document.body.appendChild(frame); + JX.DOM.alterClass(document.body, 'jx-dragging', true); this._dragging = drag; this._clone = clone; @@ -618,6 +619,7 @@ JX.install('DraggableList', { this._autoscroller = null; JX.DOM.remove(this._frame); + JX.DOM.alterClass(document.body, 'jx-dragging', false); this._frame = null; this._clone = null;