1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-10-24 01:28:52 +02:00
phorge-phorge/webroot/rsrc/js/application/projects/WorkboardBoard.js

328 lines
7.9 KiB
JavaScript
Raw Normal View History

/**
* @provides javelin-workboard-board
* @requires javelin-install
* javelin-dom
* javelin-util
* javelin-stratcom
* javelin-workflow
* phabricator-draggable-list
* javelin-workboard-column
Add priority group headers to workboard columns (display only) Summary: Ref T10333. When workboards are ordered (for example, by priority), add headers to the various groups. Major goals are: - Allow users to drag-and-drop to set values that no cards currently have: for example, you can change a card priority to "normal" by dragging it under the "normal" header, even if no other cards in the column are currently "Normal". - Make future orderings more useful, particularly "order by assignee". We don't really have room to put the username on every card and it would create a fair amount of clutter, but we can put usernames in these headers and then reference them with just the profile picture. This also allows you to assign to users who are not currently assigned anything in a given column. - Make the drag-and-drop behavior more obvious by showing what it will do more clearly (see T8135). - Make things a little easier to scan in general: because space on cards is limited, some information isn't conveyed very clearly (for example, priority information is currently conveyed //only// through color, which can be hard to pick out visually and is probably not functional for users who need vision accommodations). - Maybe do "swimlanes": this is pretty much a "swimlanes" UI if we add whitespace at the bottom of each group so that the headers line up across all the columns (e.g., "Normal" is at the same y-axis position in every column as you scroll down the page). Not sold on this being useful, but it's just a UI adjustment if we do want to try it. NOTE: This only makes these headers work for display. They aren't yet recognized as targets by the drag list UI, so you can't drag cards into an empty group. I'll tackle that in a followup. Test Plan: {F6257686} Reviewers: amckinley Reviewed By: amckinley Maniphest Tasks: T10333 Differential Revision: https://secure.phabricator.com/D20247
2019-03-05 15:00:12 +01:00
* javelin-workboard-header-template
* @javelin
*/
JX.install('WorkboardBoard', {
construct: function(controller, phid, root) {
this._controller = controller;
this._phid = phid;
this._root = root;
this._templates = {};
this._orderMaps = {};
this._propertiesMap = {};
Add priority group headers to workboard columns (display only) Summary: Ref T10333. When workboards are ordered (for example, by priority), add headers to the various groups. Major goals are: - Allow users to drag-and-drop to set values that no cards currently have: for example, you can change a card priority to "normal" by dragging it under the "normal" header, even if no other cards in the column are currently "Normal". - Make future orderings more useful, particularly "order by assignee". We don't really have room to put the username on every card and it would create a fair amount of clutter, but we can put usernames in these headers and then reference them with just the profile picture. This also allows you to assign to users who are not currently assigned anything in a given column. - Make the drag-and-drop behavior more obvious by showing what it will do more clearly (see T8135). - Make things a little easier to scan in general: because space on cards is limited, some information isn't conveyed very clearly (for example, priority information is currently conveyed //only// through color, which can be hard to pick out visually and is probably not functional for users who need vision accommodations). - Maybe do "swimlanes": this is pretty much a "swimlanes" UI if we add whitespace at the bottom of each group so that the headers line up across all the columns (e.g., "Normal" is at the same y-axis position in every column as you scroll down the page). Not sold on this being useful, but it's just a UI adjustment if we do want to try it. NOTE: This only makes these headers work for display. They aren't yet recognized as targets by the drag list UI, so you can't drag cards into an empty group. I'll tackle that in a followup. Test Plan: {F6257686} Reviewers: amckinley Reviewed By: amckinley Maniphest Tasks: T10333 Differential Revision: https://secure.phabricator.com/D20247
2019-03-05 15:00:12 +01:00
this._headers = {};
this._buildColumns();
},
properties: {
order: null,
pointsEnabled: false
},
members: {
_controller: null,
_phid: null,
_root: null,
_columns: null,
_templates: null,
_orderMaps: null,
_propertiesMap: null,
Add priority group headers to workboard columns (display only) Summary: Ref T10333. When workboards are ordered (for example, by priority), add headers to the various groups. Major goals are: - Allow users to drag-and-drop to set values that no cards currently have: for example, you can change a card priority to "normal" by dragging it under the "normal" header, even if no other cards in the column are currently "Normal". - Make future orderings more useful, particularly "order by assignee". We don't really have room to put the username on every card and it would create a fair amount of clutter, but we can put usernames in these headers and then reference them with just the profile picture. This also allows you to assign to users who are not currently assigned anything in a given column. - Make the drag-and-drop behavior more obvious by showing what it will do more clearly (see T8135). - Make things a little easier to scan in general: because space on cards is limited, some information isn't conveyed very clearly (for example, priority information is currently conveyed //only// through color, which can be hard to pick out visually and is probably not functional for users who need vision accommodations). - Maybe do "swimlanes": this is pretty much a "swimlanes" UI if we add whitespace at the bottom of each group so that the headers line up across all the columns (e.g., "Normal" is at the same y-axis position in every column as you scroll down the page). Not sold on this being useful, but it's just a UI adjustment if we do want to try it. NOTE: This only makes these headers work for display. They aren't yet recognized as targets by the drag list UI, so you can't drag cards into an empty group. I'll tackle that in a followup. Test Plan: {F6257686} Reviewers: amckinley Reviewed By: amckinley Maniphest Tasks: T10333 Differential Revision: https://secure.phabricator.com/D20247
2019-03-05 15:00:12 +01:00
_headers: null,
getRoot: function() {
return this._root;
},
getColumns: function() {
return this._columns;
},
getColumn: function(k) {
return this._columns[k];
},
getPHID: function() {
return this._phid;
},
setCardTemplate: function(phid, template) {
this._templates[phid] = template;
return this;
},
Add priority group headers to workboard columns (display only) Summary: Ref T10333. When workboards are ordered (for example, by priority), add headers to the various groups. Major goals are: - Allow users to drag-and-drop to set values that no cards currently have: for example, you can change a card priority to "normal" by dragging it under the "normal" header, even if no other cards in the column are currently "Normal". - Make future orderings more useful, particularly "order by assignee". We don't really have room to put the username on every card and it would create a fair amount of clutter, but we can put usernames in these headers and then reference them with just the profile picture. This also allows you to assign to users who are not currently assigned anything in a given column. - Make the drag-and-drop behavior more obvious by showing what it will do more clearly (see T8135). - Make things a little easier to scan in general: because space on cards is limited, some information isn't conveyed very clearly (for example, priority information is currently conveyed //only// through color, which can be hard to pick out visually and is probably not functional for users who need vision accommodations). - Maybe do "swimlanes": this is pretty much a "swimlanes" UI if we add whitespace at the bottom of each group so that the headers line up across all the columns (e.g., "Normal" is at the same y-axis position in every column as you scroll down the page). Not sold on this being useful, but it's just a UI adjustment if we do want to try it. NOTE: This only makes these headers work for display. They aren't yet recognized as targets by the drag list UI, so you can't drag cards into an empty group. I'll tackle that in a followup. Test Plan: {F6257686} Reviewers: amckinley Reviewed By: amckinley Maniphest Tasks: T10333 Differential Revision: https://secure.phabricator.com/D20247
2019-03-05 15:00:12 +01:00
getHeaderTemplate: function(header_key) {
if (!this._headers[header_key]) {
this._headers[header_key] = new JX.WorkboardHeaderTemplate(header_key);
}
return this._headers[header_key];
},
getHeaderTemplatesForOrder: function(order) {
var templates = [];
for (var k in this._headers) {
var header = this._headers[k];
if (header.getOrder() !== order) {
continue;
}
templates.push(header);
}
templates.sort(JX.bind(this, this._sortHeaderTemplates));
return templates;
},
_sortHeaderTemplates: function(u, v) {
return this.compareVectors(u.getVector(), v.getVector());
},
setObjectProperties: function(phid, properties) {
this._propertiesMap[phid] = properties;
return this;
},
getObjectProperties: function(phid) {
return this._propertiesMap[phid];
},
getCardTemplate: function(phid) {
return this._templates[phid];
},
getController: function() {
return this._controller;
},
setOrderMap: function(phid, map) {
this._orderMaps[phid] = map;
return this;
},
getOrderVector: function(phid, key) {
return this._orderMaps[phid][key];
},
Add priority group headers to workboard columns (display only) Summary: Ref T10333. When workboards are ordered (for example, by priority), add headers to the various groups. Major goals are: - Allow users to drag-and-drop to set values that no cards currently have: for example, you can change a card priority to "normal" by dragging it under the "normal" header, even if no other cards in the column are currently "Normal". - Make future orderings more useful, particularly "order by assignee". We don't really have room to put the username on every card and it would create a fair amount of clutter, but we can put usernames in these headers and then reference them with just the profile picture. This also allows you to assign to users who are not currently assigned anything in a given column. - Make the drag-and-drop behavior more obvious by showing what it will do more clearly (see T8135). - Make things a little easier to scan in general: because space on cards is limited, some information isn't conveyed very clearly (for example, priority information is currently conveyed //only// through color, which can be hard to pick out visually and is probably not functional for users who need vision accommodations). - Maybe do "swimlanes": this is pretty much a "swimlanes" UI if we add whitespace at the bottom of each group so that the headers line up across all the columns (e.g., "Normal" is at the same y-axis position in every column as you scroll down the page). Not sold on this being useful, but it's just a UI adjustment if we do want to try it. NOTE: This only makes these headers work for display. They aren't yet recognized as targets by the drag list UI, so you can't drag cards into an empty group. I'll tackle that in a followup. Test Plan: {F6257686} Reviewers: amckinley Reviewed By: amckinley Maniphest Tasks: T10333 Differential Revision: https://secure.phabricator.com/D20247
2019-03-05 15:00:12 +01:00
compareVectors: function(u_vec, v_vec) {
for (var ii = 0; ii < u_vec.length; ii++) {
if (u_vec[ii] > v_vec[ii]) {
return 1;
}
if (u_vec[ii] < v_vec[ii]) {
return -1;
}
}
return 0;
},
start: function() {
this._setupDragHandlers();
for (var k in this._columns) {
this._columns[k].redraw();
}
},
_buildColumns: function() {
var nodes = JX.DOM.scry(this.getRoot(), 'ul', 'project-column');
this._columns = {};
for (var ii = 0; ii < nodes.length; ii++) {
var node = nodes[ii];
var data = JX.Stratcom.getData(node);
var phid = data.columnPHID;
this._columns[phid] = new JX.WorkboardColumn(this, phid, node);
}
},
_setupDragHandlers: function() {
var columns = this.getColumns();
var lists = [];
for (var k in columns) {
var column = columns[k];
var list = new JX.DraggableList('project-card', column.getRoot())
.setOuterContainer(this.getRoot())
.setFindItemsHandler(JX.bind(column, column.getCardNodes))
.setCanDragX(true)
.setHasInfiniteHeight(true)
.setIsDropTargetHandler(JX.bind(column, column.setIsDropTarget));
When dragging nodes between different columns on an ordered board, don't reorder them by making secondary edits Summary: Ref T10334. When a workboard is ordered by priority, dragging from column "A" to a particular place in column "B" currently means "move this task to column B, and adjust its priority so that it naturally sorts into the location under my mouse cursor". Users frequently find this confusing / undesirable. To begin improving this, make "drag from column A to column B" and "drag from somewhere in column A to somewhere else in column A" into different operations. The first operation, a movement between columns, no longer implies an ordering change. The second action still does. So if you actually want to change the priority of a task, you drag it within its current column. If you just want to move it to a different column, you drag it between columns. This creates some possible problems: - Some users may love the current behavior and just not be very vocal about it. I doubt it, but presumably we'll hear from them if we break it. - If you actualy want to move + reorder, it's a bit more cumbersome now. We could possibly add something like "shift + drag" for this if there's feedback. - The new behavior is probably less surprising, but may not be much more obvious. Future changes (for example, in T10335) should help make it more clear. - When you mouse cursor goes over column B, the card dashed-rectangle preview target thing jumps to the correct position in the column -- but that may not be under your mouse cursor. This feels pretty much fine if the whole column fits on screen. It may not be so great if the column does not fit on screen and the dashed-rectangle-thing has vanished. This is just a UI feedback issue and we could refine this later (scroll/highlight the column). Test Plan: - Created several tasks at different priority levels, sorted a board by priority, dragged tasks between columns. Dragging from "A" to "B" no longer causes a priority edit. - Also, dragged within a column. This still performs priority edits. Reviewers: amckinley Reviewed By: amckinley Maniphest Tasks: T10334 Differential Revision: https://secure.phabricator.com/D20242
2019-03-02 00:13:25 +01:00
if (this.getOrder() !== 'natural') {
list.setCompareHandler(JX.bind(column, column.compareHandler));
}
list.listen('didDrop', JX.bind(this, this._onmovecard, list));
lists.push(list);
}
for (var ii = 0; ii < lists.length; ii++) {
lists[ii].setGroup(lists);
}
},
_findCardsInColumn: function(column_node) {
return JX.DOM.scry(column_node, 'li', 'project-card');
},
_onmovecard: function(list, item, after_node, src_list) {
list.lock();
JX.DOM.alterClass(item, 'drag-sending', true);
var src_phid = JX.Stratcom.getData(src_list.getRootNode()).columnPHID;
var dst_phid = JX.Stratcom.getData(list.getRootNode()).columnPHID;
var item_phid = JX.Stratcom.getData(item).objectPHID;
var data = {
objectPHID: item_phid,
columnPHID: dst_phid,
order: this.getOrder()
};
if (after_node) {
data.afterPHID = JX.Stratcom.getData(after_node).objectPHID;
}
var before_node = item.nextSibling;
if (before_node) {
var before_phid = JX.Stratcom.getData(before_node).objectPHID;
if (before_phid) {
data.beforePHID = before_phid;
}
}
var visible_phids = [];
var column = this.getColumn(dst_phid);
for (var object_phid in column.getCards()) {
visible_phids.push(object_phid);
}
data.visiblePHIDs = visible_phids.join(',');
var onupdate = JX.bind(
this,
this._oncardupdate,
list,
src_phid,
dst_phid,
data.afterPHID);
new JX.Workflow(this.getController().getMoveURI(), data)
.setHandler(onupdate)
.start();
},
_oncardupdate: function(list, src_phid, dst_phid, after_phid, response) {
var src_column = this.getColumn(src_phid);
var dst_column = this.getColumn(dst_phid);
var card = src_column.removeCard(response.objectPHID);
dst_column.addCard(card, after_phid);
src_column.markForRedraw();
dst_column.markForRedraw();
this.updateCard(response);
list.unlock();
},
updateCard: function(response, options) {
options = options || {};
options.dirtyColumns = options.dirtyColumns || {};
var columns = this.getColumns();
var phid = response.objectPHID;
if (!this._templates[phid]) {
for (var add_phid in response.columnMaps) {
var target_column = this.getColumn(add_phid);
if (!target_column) {
// If the column isn't visible, don't try to add a card to it.
continue;
}
target_column.newCard(phid);
}
}
this.setCardTemplate(phid, response.cardHTML);
var order_maps = response.orderMaps;
for (var order_phid in order_maps) {
this.setOrderMap(order_phid, order_maps[order_phid]);
}
var column_maps = response.columnMaps;
var natural_column;
for (var natural_phid in column_maps) {
natural_column = this.getColumn(natural_phid);
if (!natural_column) {
// Our view of the board may be out of date, so we might get back
// information about columns that aren't visible. Just ignore the
// position information for any columns we aren't displaying on the
// client.
continue;
}
natural_column.setNaturalOrder(column_maps[natural_phid]);
}
var property_maps = response.propertyMaps;
for (var property_phid in property_maps) {
this.setObjectProperties(property_phid, property_maps[property_phid]);
}
for (var column_phid in columns) {
var column = columns[column_phid];
var cards = column.getCards();
for (var object_phid in cards) {
if (object_phid !== phid) {
continue;
}
var card = cards[object_phid];
card.redraw();
column.markForRedraw();
}
}
this._redrawColumns();
},
_redrawColumns: function() {
var columns = this.getColumns();
for (var k in columns) {
if (columns[k].isMarkedForRedraw()) {
columns[k].redraw();
}
}
}
}
});