mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-14 02:42:40 +01:00
Make workboard columns fixed-height and internally scrollable
Summary: Ref T5240. - Columns are fixed height. - Columns scroll internally. - Drag behaviors generally align with these column behaviors. Test Plan: {F1099061} Reviewers: chad Reviewed By: chad Maniphest Tasks: T5240 Differential Revision: https://secure.phabricator.com/D15209
This commit is contained in:
parent
4dd6a1224d
commit
ca83eb1ca6
4 changed files with 80 additions and 35 deletions
|
@ -8,7 +8,7 @@
|
||||||
return array(
|
return array(
|
||||||
'names' => array(
|
'names' => array(
|
||||||
'core.pkg.css' => 'b4a7e275',
|
'core.pkg.css' => 'b4a7e275',
|
||||||
'core.pkg.js' => '808ae845',
|
'core.pkg.js' => '771b0e84',
|
||||||
'darkconsole.pkg.js' => 'e7393ebb',
|
'darkconsole.pkg.js' => 'e7393ebb',
|
||||||
'differential.pkg.css' => '2de124c9',
|
'differential.pkg.css' => '2de124c9',
|
||||||
'differential.pkg.js' => 'd0cd0df6',
|
'differential.pkg.js' => 'd0cd0df6',
|
||||||
|
@ -154,7 +154,7 @@ return array(
|
||||||
'rsrc/css/phui/phui-tag-view.css' => '9d5d4400',
|
'rsrc/css/phui/phui-tag-view.css' => '9d5d4400',
|
||||||
'rsrc/css/phui/phui-timeline-view.css' => '2efceff8',
|
'rsrc/css/phui/phui-timeline-view.css' => '2efceff8',
|
||||||
'rsrc/css/phui/phui-two-column-view.css' => 'c75bfc5b',
|
'rsrc/css/phui/phui-two-column-view.css' => 'c75bfc5b',
|
||||||
'rsrc/css/phui/workboards/phui-workboard.css' => '2a04b1a8',
|
'rsrc/css/phui/workboards/phui-workboard.css' => 'f526057c',
|
||||||
'rsrc/css/phui/workboards/phui-workcard.css' => 'a869098a',
|
'rsrc/css/phui/workboards/phui-workcard.css' => 'a869098a',
|
||||||
'rsrc/css/phui/workboards/phui-workpanel.css' => 'e1bd8d04',
|
'rsrc/css/phui/workboards/phui-workpanel.css' => 'e1bd8d04',
|
||||||
'rsrc/css/sprite-login.css' => '60e8560e',
|
'rsrc/css/sprite-login.css' => '60e8560e',
|
||||||
|
@ -447,7 +447,7 @@ return array(
|
||||||
'rsrc/js/application/uiexample/notification-example.js' => '8ce821c5',
|
'rsrc/js/application/uiexample/notification-example.js' => '8ce821c5',
|
||||||
'rsrc/js/core/Busy.js' => '59a7976a',
|
'rsrc/js/core/Busy.js' => '59a7976a',
|
||||||
'rsrc/js/core/DragAndDropFileUpload.js' => '81f182b5',
|
'rsrc/js/core/DragAndDropFileUpload.js' => '81f182b5',
|
||||||
'rsrc/js/core/DraggableList.js' => '8905523d',
|
'rsrc/js/core/DraggableList.js' => '8199fb41',
|
||||||
'rsrc/js/core/FileUpload.js' => '680ea2c8',
|
'rsrc/js/core/FileUpload.js' => '680ea2c8',
|
||||||
'rsrc/js/core/Hovercard.js' => '1bd28176',
|
'rsrc/js/core/Hovercard.js' => '1bd28176',
|
||||||
'rsrc/js/core/KeyboardShortcut.js' => '1ae869f2',
|
'rsrc/js/core/KeyboardShortcut.js' => '1ae869f2',
|
||||||
|
@ -742,7 +742,7 @@ return array(
|
||||||
'phabricator-countdown-css' => 'e7544472',
|
'phabricator-countdown-css' => 'e7544472',
|
||||||
'phabricator-dashboard-css' => 'eb458607',
|
'phabricator-dashboard-css' => 'eb458607',
|
||||||
'phabricator-drag-and-drop-file-upload' => '81f182b5',
|
'phabricator-drag-and-drop-file-upload' => '81f182b5',
|
||||||
'phabricator-draggable-list' => '8905523d',
|
'phabricator-draggable-list' => '8199fb41',
|
||||||
'phabricator-fatal-config-template-css' => '8e6c6fcd',
|
'phabricator-fatal-config-template-css' => '8e6c6fcd',
|
||||||
'phabricator-feed-css' => 'ecd4ec57',
|
'phabricator-feed-css' => 'ecd4ec57',
|
||||||
'phabricator-file-upload' => '680ea2c8',
|
'phabricator-file-upload' => '680ea2c8',
|
||||||
|
@ -831,7 +831,7 @@ return array(
|
||||||
'phui-theme-css' => 'ab7b848c',
|
'phui-theme-css' => 'ab7b848c',
|
||||||
'phui-timeline-view-css' => '2efceff8',
|
'phui-timeline-view-css' => '2efceff8',
|
||||||
'phui-two-column-view-css' => 'c75bfc5b',
|
'phui-two-column-view-css' => 'c75bfc5b',
|
||||||
'phui-workboard-view-css' => '2a04b1a8',
|
'phui-workboard-view-css' => 'f526057c',
|
||||||
'phui-workcard-view-css' => 'a869098a',
|
'phui-workcard-view-css' => 'a869098a',
|
||||||
'phui-workpanel-view-css' => 'e1bd8d04',
|
'phui-workpanel-view-css' => 'e1bd8d04',
|
||||||
'phuix-action-list-view' => 'b5c256b8',
|
'phuix-action-list-view' => 'b5c256b8',
|
||||||
|
@ -1451,6 +1451,14 @@ return array(
|
||||||
'javelin-vector',
|
'javelin-vector',
|
||||||
'javelin-stratcom',
|
'javelin-stratcom',
|
||||||
),
|
),
|
||||||
|
'8199fb41' => array(
|
||||||
|
'javelin-install',
|
||||||
|
'javelin-dom',
|
||||||
|
'javelin-stratcom',
|
||||||
|
'javelin-util',
|
||||||
|
'javelin-vector',
|
||||||
|
'javelin-magical-init',
|
||||||
|
),
|
||||||
'81f182b5' => array(
|
'81f182b5' => array(
|
||||||
'javelin-install',
|
'javelin-install',
|
||||||
'javelin-util',
|
'javelin-util',
|
||||||
|
@ -1496,14 +1504,6 @@ return array(
|
||||||
'javelin-stratcom',
|
'javelin-stratcom',
|
||||||
'javelin-dom',
|
'javelin-dom',
|
||||||
),
|
),
|
||||||
'8905523d' => array(
|
|
||||||
'javelin-install',
|
|
||||||
'javelin-dom',
|
|
||||||
'javelin-stratcom',
|
|
||||||
'javelin-util',
|
|
||||||
'javelin-vector',
|
|
||||||
'javelin-magical-init',
|
|
||||||
),
|
|
||||||
'8a41885b' => array(
|
'8a41885b' => array(
|
||||||
'javelin-install',
|
'javelin-install',
|
||||||
'javelin-dom',
|
'javelin-dom',
|
||||||
|
|
|
@ -25,12 +25,13 @@ final class PHUIWorkboardView extends AphrontTagView {
|
||||||
$view->addColumn($panel);
|
$view->addColumn($panel);
|
||||||
}
|
}
|
||||||
|
|
||||||
$board = phutil_tag(
|
$board = javelin_tag(
|
||||||
'div',
|
'div',
|
||||||
array(
|
array(
|
||||||
'class' => 'phui-workboard-view-shadow',
|
'class' => 'phui-workboard-view-shadow',
|
||||||
),
|
'sigil' => 'lock-scroll-while-dragging',
|
||||||
$view);
|
),
|
||||||
|
$view);
|
||||||
|
|
||||||
return $board;
|
return $board;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
.device-desktop .phui-workboard-view-shadow {
|
.device-desktop .phui-workboard-view-shadow {
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
|
overflow-y: hidden;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 79px;
|
top: 79px;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
|
@ -70,3 +71,9 @@
|
||||||
.device .project-board-wrapper {
|
.device .project-board-wrapper {
|
||||||
margin: 16px;
|
margin: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.device-desktop .phui-workpanel-body {
|
||||||
|
max-height: calc(100vh - 170px);
|
||||||
|
overflow-y: scroll;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
|
|
@ -310,6 +310,10 @@ JX.install('DraggableList', {
|
||||||
return target_list;
|
return target_list;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_getTarget: function() {
|
||||||
|
return this._target;
|
||||||
|
},
|
||||||
|
|
||||||
_setTarget : function(cur_target) {
|
_setTarget : function(cur_target) {
|
||||||
var ghost = this.getGhostNode();
|
var ghost = this.getGhostNode();
|
||||||
var target = this._target;
|
var target = this._target;
|
||||||
|
@ -433,8 +437,6 @@ JX.install('DraggableList', {
|
||||||
this._cursorOrigin.y - (this._cursorScroll.y - s.y));
|
this._cursorOrigin.y - (this._cursorScroll.y - s.y));
|
||||||
}
|
}
|
||||||
|
|
||||||
this._updateAutoscroll(this._cursorPosition);
|
|
||||||
|
|
||||||
var p = JX.$V(this._cursorPosition.x, this._cursorPosition.y);
|
var p = JX.$V(this._cursorPosition.x, this._cursorPosition.y);
|
||||||
|
|
||||||
var group = this._group;
|
var group = this._group;
|
||||||
|
@ -459,6 +461,8 @@ JX.install('DraggableList', {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._updateAutoscroll(this._cursorPosition);
|
||||||
|
|
||||||
var f = JX.$V(this._frame);
|
var f = JX.$V(this._frame);
|
||||||
p.x -= f.x;
|
p.x -= f.x;
|
||||||
p.y -= f.y;
|
p.y -= f.y;
|
||||||
|
@ -475,7 +479,7 @@ JX.install('DraggableList', {
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateAutoscroll: function(p) {
|
_updateAutoscroll: function(p) {
|
||||||
var container = this._dragging.parentNode;
|
var container = this._getScrollAnchor().parentNode;
|
||||||
var autoscroll = {};
|
var autoscroll = {};
|
||||||
|
|
||||||
var outer = this.getOuterContainer();
|
var outer = this.getOuterContainer();
|
||||||
|
@ -595,6 +599,22 @@ JX.install('DraggableList', {
|
||||||
this.invoke('didEndDrag', dragging);
|
this.invoke('didEndDrag', dragging);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_getScrollAnchor: function() {
|
||||||
|
// If you drag an item from column "A" into column "B", then move the
|
||||||
|
// mouse to the top or bottom of the screen, we need to scroll the target
|
||||||
|
// column (column "B"), not the original column.
|
||||||
|
|
||||||
|
var group = this._group;
|
||||||
|
for (var ii = 0; ii < group.length; ii++) {
|
||||||
|
var target = group[ii]._getTarget();
|
||||||
|
if (target) {
|
||||||
|
return group[ii]._ghostNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._dragging;
|
||||||
|
},
|
||||||
|
|
||||||
_onautoscroll: function() {
|
_onautoscroll: function() {
|
||||||
var u = this._autoscroll.up;
|
var u = this._autoscroll.up;
|
||||||
var d = this._autoscroll.down;
|
var d = this._autoscroll.down;
|
||||||
|
@ -613,20 +633,22 @@ JX.install('DraggableList', {
|
||||||
|
|
||||||
var amount = 12 * (delta / 10);
|
var amount = 12 * (delta / 10);
|
||||||
|
|
||||||
|
var anchor = this._getScrollAnchor();
|
||||||
|
|
||||||
if (u && (u != d)) {
|
if (u && (u != d)) {
|
||||||
this._tryScroll(this._dragging, u, 'scrollTop', amount);
|
this._tryScroll(anchor, u, 'scrollTop', amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d && (d != u)) {
|
if (d && (d != u)) {
|
||||||
this._tryScroll(this._dragging, d, 'scrollTop', -amount);
|
this._tryScroll(anchor, d, 'scrollTop', -amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (l && (l != r)) {
|
if (l && (l != r)) {
|
||||||
this._tryScroll(this._dragging, l, 'scrollLeft', amount);
|
this._tryScroll(anchor, l, 'scrollLeft', amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r && (r != l)) {
|
if (r && (r != l)) {
|
||||||
this._tryScroll(this._dragging, r, 'scrollLeft', -amount);
|
this._tryScroll(anchor, r, 'scrollLeft', -amount);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -639,19 +661,34 @@ JX.install('DraggableList', {
|
||||||
|
|
||||||
var container = from.parentNode;
|
var container = from.parentNode;
|
||||||
while (container) {
|
while (container) {
|
||||||
// Read the current scroll value.
|
|
||||||
value = container[property];
|
|
||||||
|
|
||||||
// Try to scroll.
|
// In Safari, we'll eventually reach `window.document`, which is not
|
||||||
container[property] -= amount;
|
// sufficently node-like to support sigil tests.
|
||||||
|
var lock;
|
||||||
// If we scrolled it, we're all done.
|
if (container === window.document) {
|
||||||
if (container[property] != value) {
|
lock = false;
|
||||||
break;
|
} else {
|
||||||
|
// Some elements may respond to, e.g., `scrollTop` adjustment, even
|
||||||
|
// though they are not scrollable. This sigil disables adjustment
|
||||||
|
// for them.
|
||||||
|
lock = JX.Stratcom.hasSigil(container, 'lock-scroll-while-dragging');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (container == to) {
|
if (!lock) {
|
||||||
break;
|
// Read the current scroll value.
|
||||||
|
value = container[property];
|
||||||
|
|
||||||
|
// Try to scroll.
|
||||||
|
container[property] -= amount;
|
||||||
|
|
||||||
|
// If we scrolled it, we're all done.
|
||||||
|
if (container[property] != value) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (container == to) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
container = container.parentNode;
|
container = container.parentNode;
|
||||||
|
|
Loading…
Reference in a new issue