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
This commit is contained in:
		| @@ -10,7 +10,7 @@ return array( | |||||||
|     'conpherence.pkg.css' => '3c8a0668', |     'conpherence.pkg.css' => '3c8a0668', | ||||||
|     'conpherence.pkg.js' => '020aebcf', |     'conpherence.pkg.js' => '020aebcf', | ||||||
|     'core.pkg.css' => '34ce1741', |     'core.pkg.css' => '34ce1741', | ||||||
|     'core.pkg.js' => 'b96c872e', |     'core.pkg.js' => '200a0a61', | ||||||
|     'differential.pkg.css' => '8d8360fb', |     'differential.pkg.css' => '8d8360fb', | ||||||
|     'differential.pkg.js' => '67e02996', |     'differential.pkg.js' => '67e02996', | ||||||
|     'diffusion.pkg.css' => '42c75c37', |     'diffusion.pkg.css' => '42c75c37', | ||||||
| @@ -177,7 +177,7 @@ return array( | |||||||
|     'rsrc/css/phui/phui-two-column-view.css' => '01e6991e', |     'rsrc/css/phui/phui-two-column-view.css' => '01e6991e', | ||||||
|     'rsrc/css/phui/workboards/phui-workboard-color.css' => 'e86de308', |     'rsrc/css/phui/workboards/phui-workboard-color.css' => 'e86de308', | ||||||
|     'rsrc/css/phui/workboards/phui-workboard.css' => '74fc9d98', |     '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/phui/workboards/phui-workpanel.css' => 'bc16cf33', | ||||||
|     'rsrc/css/sprite-login.css' => '18b368a6', |     'rsrc/css/sprite-login.css' => '18b368a6', | ||||||
|     'rsrc/css/sprite-tokens.css' => 'f1896dc5', |     '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/phortune/phortune-credit-card-form.js' => 'd12d214f', | ||||||
|     'rsrc/js/application/policy/behavior-policy-control.js' => '0eaa33a9', |     'rsrc/js/application/policy/behavior-policy-control.js' => '0eaa33a9', | ||||||
|     'rsrc/js/application/policy/behavior-policy-rule-editor.js' => '9347f172', |     '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/WorkboardCard.js' => '0392a5d8', | ||||||
|     'rsrc/js/application/projects/WorkboardCardTemplate.js' => '2a61f8d4', |     'rsrc/js/application/projects/WorkboardCardTemplate.js' => '2a61f8d4', | ||||||
|     'rsrc/js/application/projects/WorkboardColumn.js' => 'fd4c2069', |     'rsrc/js/application/projects/WorkboardColumn.js' => 'fd4c2069', | ||||||
| @@ -436,7 +436,7 @@ return array( | |||||||
|     'rsrc/js/application/uiexample/notification-example.js' => '29819b75', |     'rsrc/js/application/uiexample/notification-example.js' => '29819b75', | ||||||
|     'rsrc/js/core/Busy.js' => '5202e831', |     'rsrc/js/core/Busy.js' => '5202e831', | ||||||
|     'rsrc/js/core/DragAndDropFileUpload.js' => '4370900d', |     '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/Favicon.js' => '7930776a', | ||||||
|     'rsrc/js/core/FileUpload.js' => 'ab85e184', |     'rsrc/js/core/FileUpload.js' => 'ab85e184', | ||||||
|     'rsrc/js/core/Hovercard.js' => '074f0783', |     'rsrc/js/core/Hovercard.js' => '074f0783', | ||||||
| @@ -728,7 +728,7 @@ return array( | |||||||
|     'javelin-view-renderer' => '9aae2b66', |     'javelin-view-renderer' => '9aae2b66', | ||||||
|     'javelin-view-visitor' => '308f9fe4', |     'javelin-view-visitor' => '308f9fe4', | ||||||
|     'javelin-websocket' => 'fdc13e4e', |     'javelin-websocket' => 'fdc13e4e', | ||||||
|     'javelin-workboard-board' => 'fc1664ff', |     'javelin-workboard-board' => 'eb55f7e8', | ||||||
|     'javelin-workboard-card' => '0392a5d8', |     'javelin-workboard-card' => '0392a5d8', | ||||||
|     'javelin-workboard-card-template' => '2a61f8d4', |     'javelin-workboard-card-template' => '2a61f8d4', | ||||||
|     'javelin-workboard-column' => 'fd4c2069', |     'javelin-workboard-column' => 'fd4c2069', | ||||||
| @@ -759,7 +759,7 @@ return array( | |||||||
|     'phabricator-diff-changeset-list' => '04023d82', |     'phabricator-diff-changeset-list' => '04023d82', | ||||||
|     'phabricator-diff-inline' => 'a4a14a94', |     'phabricator-diff-inline' => 'a4a14a94', | ||||||
|     'phabricator-drag-and-drop-file-upload' => '4370900d', |     'phabricator-drag-and-drop-file-upload' => '4370900d', | ||||||
|     'phabricator-draggable-list' => '8437c663', |     'phabricator-draggable-list' => '91f40fbf', | ||||||
|     'phabricator-fatal-config-template-css' => '20babf50', |     'phabricator-fatal-config-template-css' => '20babf50', | ||||||
|     'phabricator-favicon' => '7930776a', |     'phabricator-favicon' => '7930776a', | ||||||
|     'phabricator-feed-css' => 'd8b6e3f8', |     'phabricator-feed-css' => 'd8b6e3f8', | ||||||
| @@ -857,7 +857,7 @@ return array( | |||||||
|     'phui-two-column-view-css' => '01e6991e', |     'phui-two-column-view-css' => '01e6991e', | ||||||
|     'phui-workboard-color-css' => 'e86de308', |     'phui-workboard-color-css' => 'e86de308', | ||||||
|     'phui-workboard-view-css' => '74fc9d98', |     'phui-workboard-view-css' => '74fc9d98', | ||||||
|     'phui-workcard-view-css' => '8c536f90', |     'phui-workcard-view-css' => '9e9eb0df', | ||||||
|     'phui-workpanel-view-css' => 'bc16cf33', |     'phui-workpanel-view-css' => 'bc16cf33', | ||||||
|     'phuix-action-list-view' => 'c68f183f', |     'phuix-action-list-view' => 'c68f183f', | ||||||
|     'phuix-action-view' => 'aaa08f3b', |     'phuix-action-view' => 'aaa08f3b', | ||||||
| @@ -1557,14 +1557,6 @@ return array( | |||||||
|       'javelin-dom', |       'javelin-dom', | ||||||
|       'javelin-vector', |       'javelin-vector', | ||||||
|     ), |     ), | ||||||
|     '8437c663' => array( |  | ||||||
|       'javelin-install', |  | ||||||
|       'javelin-dom', |  | ||||||
|       'javelin-stratcom', |  | ||||||
|       'javelin-util', |  | ||||||
|       'javelin-vector', |  | ||||||
|       'javelin-magical-init', |  | ||||||
|     ), |  | ||||||
|     '87428eb2' => array( |     '87428eb2' => array( | ||||||
|       'javelin-behavior', |       'javelin-behavior', | ||||||
|       'javelin-diffusion-locate-file-source', |       'javelin-diffusion-locate-file-source', | ||||||
| @@ -1643,6 +1635,14 @@ return array( | |||||||
|       'javelin-workflow', |       'javelin-workflow', | ||||||
|       'javelin-stratcom', |       'javelin-stratcom', | ||||||
|     ), |     ), | ||||||
|  |     '91f40fbf' => array( | ||||||
|  |       'javelin-install', | ||||||
|  |       'javelin-dom', | ||||||
|  |       'javelin-stratcom', | ||||||
|  |       'javelin-util', | ||||||
|  |       'javelin-vector', | ||||||
|  |       'javelin-magical-init', | ||||||
|  |     ), | ||||||
|     '92388bae' => array( |     '92388bae' => array( | ||||||
|       'javelin-behavior', |       'javelin-behavior', | ||||||
|       'javelin-scrollbar', |       'javelin-scrollbar', | ||||||
| @@ -2051,6 +2051,17 @@ return array( | |||||||
|       'javelin-install', |       'javelin-install', | ||||||
|       'javelin-event', |       '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( |     'ec4e31c0' => array( | ||||||
|       'phui-timeline-view-css', |       'phui-timeline-view-css', | ||||||
|     ), |     ), | ||||||
| @@ -2118,17 +2129,6 @@ return array( | |||||||
|       'phabricator-keyboard-shortcut', |       'phabricator-keyboard-shortcut', | ||||||
|       'conpherence-thread-manager', |       '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( |     'fce5d170' => array( | ||||||
|       'javelin-magical-init', |       'javelin-magical-init', | ||||||
|       'javelin-util', |       'javelin-util', | ||||||
|   | |||||||
| @@ -82,19 +82,31 @@ final class ProjectBoardTaskCard extends Phobject { | |||||||
|     $card = id(new PHUIObjectItemView()) |     $card = id(new PHUIObjectItemView()) | ||||||
|       ->setObject($task) |       ->setObject($task) | ||||||
|       ->setUser($viewer) |       ->setUser($viewer) | ||||||
|       ->setObjectName('T'.$task->getID()) |       ->setObjectName($task->getMonogram()) | ||||||
|       ->setHeader($task->getTitle()) |       ->setHeader($task->getTitle()) | ||||||
|       ->setGrippable($can_edit) |       ->setHref($task->getURI()) | ||||||
|       ->setHref('/T'.$task->getID()) |  | ||||||
|       ->addSigil('project-card') |       ->addSigil('project-card') | ||||||
|       ->setDisabled($task->isClosed()) |       ->setDisabled($task->isClosed()) | ||||||
|       ->addAction( |       ->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()) |       id(new PHUIListItemView()) | ||||||
|         ->setName(pht('Edit')) |         ->setName(pht('Edit')) | ||||||
|         ->setIcon('fa-pencil') |         ->setIcon($edit_icon) | ||||||
|         ->addSigil('edit-project-card') |         ->addSigil('edit-project-card') | ||||||
|         ->setHref('/maniphest/task/edit/'.$task->getID().'/')) |         ->setHref('/maniphest/task/edit/'.$task->getID().'/')); | ||||||
|       ->setBarColor($bar_color); |  | ||||||
|  |  | ||||||
|     if ($owner) { |     if ($owner) { | ||||||
|       $card->addHandleIcon($owner, $owner->getName()); |       $card->addHandleIcon($owner, $owner->getName()); | ||||||
|   | |||||||
| @@ -59,14 +59,6 @@ | |||||||
|   vertical-align: top; |   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 { | .device-desktop .phui-workcard .phui-list-item-icon { | ||||||
|   display: none; |   display: none; | ||||||
| } | } | ||||||
| @@ -88,6 +80,33 @@ | |||||||
|     opacity: 1; |     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 { | .phui-workcard.phui-oi:hover .phui-list-item-icon { | ||||||
|   display: block; |   display: block; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -138,7 +138,7 @@ JX.install('WorkboardBoard', { | |||||||
|       for (var k in columns) { |       for (var k in columns) { | ||||||
|         var column = columns[k]; |         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()) |           .setOuterContainer(this.getRoot()) | ||||||
|           .setFindItemsHandler(JX.bind(column, column.getDropTargetNodes)) |           .setFindItemsHandler(JX.bind(column, column.getDropTargetNodes)) | ||||||
|           .setCanDragX(true) |           .setCanDragX(true) | ||||||
|   | |||||||
| @@ -240,6 +240,7 @@ JX.install('DraggableList', { | |||||||
|       frame.appendChild(clone); |       frame.appendChild(clone); | ||||||
|  |  | ||||||
|       document.body.appendChild(frame); |       document.body.appendChild(frame); | ||||||
|  |       JX.DOM.alterClass(document.body, 'jx-dragging', true); | ||||||
|  |  | ||||||
|       this._dragging = drag; |       this._dragging = drag; | ||||||
|       this._clone = clone; |       this._clone = clone; | ||||||
| @@ -618,6 +619,7 @@ JX.install('DraggableList', { | |||||||
|       this._autoscroller = null; |       this._autoscroller = null; | ||||||
|  |  | ||||||
|       JX.DOM.remove(this._frame); |       JX.DOM.remove(this._frame); | ||||||
|  |       JX.DOM.alterClass(document.body, 'jx-dragging', false); | ||||||
|       this._frame = null; |       this._frame = null; | ||||||
|       this._clone = null; |       this._clone = null; | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 epriestley
					epriestley