1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-09 16:32:39 +01:00

Add a "WorkboardCardTemplate" class to make workboard client code easier to reason about

Summary:
Depends on D20266. Boards currently have several `whateverMap<cardPHID => stuff>` properties, but we can just move these all down into a `CardTemplate`, similar to the recently introduced `HeaderTemplate`.

The `CardTemplate` holds all the global information for a card, and then `Card` is specific for a particular copy in a column. Today, each `CardTemplate` has one `Card`, but a `CardTemplate` may have more than one card in the future (when we add subproject columns).

Test Plan: Viewed workboards in different sort orders and dragged stuff around, grepped for all affected symbols.

Reviewers: amckinley

Reviewed By: amckinley

Differential Revision: https://secure.phabricator.com/D20267
This commit is contained in:
epriestley 2019-03-10 19:53:25 -07:00
parent 4bad6bc42a
commit 7d849afd16
6 changed files with 140 additions and 88 deletions

View file

@ -408,13 +408,14 @@ 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' => '902a1551', 'rsrc/js/application/projects/WorkboardBoard.js' => '2181739b',
'rsrc/js/application/projects/WorkboardCard.js' => '887ef74f', 'rsrc/js/application/projects/WorkboardCard.js' => 'bc92741f',
'rsrc/js/application/projects/WorkboardColumn.js' => '01ea93b3', 'rsrc/js/application/projects/WorkboardCardTemplate.js' => 'b0b5f90a',
'rsrc/js/application/projects/WorkboardColumn.js' => '6461f58b',
'rsrc/js/application/projects/WorkboardController.js' => '42c7a5a7', 'rsrc/js/application/projects/WorkboardController.js' => '42c7a5a7',
'rsrc/js/application/projects/WorkboardHeader.js' => '6e75daea', 'rsrc/js/application/projects/WorkboardHeader.js' => '6e75daea',
'rsrc/js/application/projects/WorkboardHeaderTemplate.js' => '2d641f7d', 'rsrc/js/application/projects/WorkboardHeaderTemplate.js' => '2d641f7d',
'rsrc/js/application/projects/behavior-project-boards.js' => 'e2730b90', 'rsrc/js/application/projects/behavior-project-boards.js' => 'cca3f5f8',
'rsrc/js/application/projects/behavior-project-create.js' => '34c53422', 'rsrc/js/application/projects/behavior-project-create.js' => '34c53422',
'rsrc/js/application/projects/behavior-reorder-columns.js' => '8ac32fd9', 'rsrc/js/application/projects/behavior-reorder-columns.js' => '8ac32fd9',
'rsrc/js/application/releeph/releeph-preview-branch.js' => '75184d68', 'rsrc/js/application/releeph/releeph-preview-branch.js' => '75184d68',
@ -655,7 +656,7 @@ return array(
'javelin-behavior-phuix-example' => 'c2c500a7', 'javelin-behavior-phuix-example' => 'c2c500a7',
'javelin-behavior-policy-control' => '0eaa33a9', 'javelin-behavior-policy-control' => '0eaa33a9',
'javelin-behavior-policy-rule-editor' => '9347f172', 'javelin-behavior-policy-rule-editor' => '9347f172',
'javelin-behavior-project-boards' => 'e2730b90', 'javelin-behavior-project-boards' => 'cca3f5f8',
'javelin-behavior-project-create' => '34c53422', 'javelin-behavior-project-create' => '34c53422',
'javelin-behavior-quicksand-blacklist' => '5a6f6a06', 'javelin-behavior-quicksand-blacklist' => '5a6f6a06',
'javelin-behavior-read-only-warning' => 'b9109f8f', 'javelin-behavior-read-only-warning' => 'b9109f8f',
@ -727,9 +728,10 @@ 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' => '902a1551', 'javelin-workboard-board' => '2181739b',
'javelin-workboard-card' => '887ef74f', 'javelin-workboard-card' => 'bc92741f',
'javelin-workboard-column' => '01ea93b3', 'javelin-workboard-card-template' => 'b0b5f90a',
'javelin-workboard-column' => '6461f58b',
'javelin-workboard-controller' => '42c7a5a7', 'javelin-workboard-controller' => '42c7a5a7',
'javelin-workboard-header' => '6e75daea', 'javelin-workboard-header' => '6e75daea',
'javelin-workboard-header-template' => '2d641f7d', 'javelin-workboard-header-template' => '2d641f7d',
@ -889,11 +891,6 @@ return array(
'javelin-uri', 'javelin-uri',
'phabricator-notification', 'phabricator-notification',
), ),
'01ea93b3' => array(
'javelin-install',
'javelin-workboard-card',
'javelin-workboard-header',
),
'022516b4' => array( '022516b4' => array(
'javelin-install', 'javelin-install',
'javelin-util', 'javelin-util',
@ -1051,6 +1048,17 @@ return array(
'javelin-behavior', 'javelin-behavior',
'javelin-request', 'javelin-request',
), ),
'2181739b' => 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',
),
'225bbb98' => array( '225bbb98' => array(
'javelin-install', 'javelin-install',
'javelin-reactor', 'javelin-reactor',
@ -1419,6 +1427,11 @@ return array(
'60cd9241' => array( '60cd9241' => array(
'javelin-behavior', 'javelin-behavior',
), ),
'6461f58b' => array(
'javelin-install',
'javelin-workboard-card',
'javelin-workboard-header',
),
'65bb0011' => array( '65bb0011' => array(
'javelin-behavior', 'javelin-behavior',
'javelin-dom', 'javelin-dom',
@ -1568,9 +1581,6 @@ return array(
'javelin-install', 'javelin-install',
'javelin-dom', 'javelin-dom',
), ),
'887ef74f' => array(
'javelin-install',
),
'89a1ae3a' => array( '89a1ae3a' => array(
'javelin-dom', 'javelin-dom',
'javelin-util', 'javelin-util',
@ -1620,16 +1630,6 @@ return array(
'javelin-workflow', 'javelin-workflow',
'javelin-stratcom', 'javelin-stratcom',
), ),
'902a1551' => array(
'javelin-install',
'javelin-dom',
'javelin-util',
'javelin-stratcom',
'javelin-workflow',
'phabricator-draggable-list',
'javelin-workboard-column',
'javelin-workboard-header-template',
),
91863989 => array( 91863989 => array(
'javelin-install', 'javelin-install',
'javelin-stratcom', 'javelin-stratcom',
@ -1839,6 +1839,9 @@ return array(
'javelin-behavior-device', 'javelin-behavior-device',
'javelin-vector', 'javelin-vector',
), ),
'b0b5f90a' => array(
'javelin-install',
),
'b105a3a6' => array( 'b105a3a6' => array(
'javelin-behavior', 'javelin-behavior',
'javelin-stratcom', 'javelin-stratcom',
@ -1893,6 +1896,9 @@ return array(
'bc16cf33' => array( 'bc16cf33' => array(
'phui-workcard-view-css', 'phui-workcard-view-css',
), ),
'bc92741f' => array(
'javelin-install',
),
'bdce4d78' => array( 'bdce4d78' => array(
'javelin-install', 'javelin-install',
'javelin-util', 'javelin-util',
@ -1962,6 +1968,15 @@ return array(
'javelin-util', 'javelin-util',
'phabricator-keyboard-shortcut-manager', 'phabricator-keyboard-shortcut-manager',
), ),
'cca3f5f8' => array(
'javelin-behavior',
'javelin-dom',
'javelin-util',
'javelin-vector',
'javelin-stratcom',
'javelin-workflow',
'javelin-workboard-controller',
),
'cf32921f' => array( 'cf32921f' => array(
'javelin-behavior', 'javelin-behavior',
'javelin-dom', 'javelin-dom',
@ -2022,15 +2037,6 @@ return array(
'javelin-dom', 'javelin-dom',
'javelin-history', 'javelin-history',
), ),
'e2730b90' => array(
'javelin-behavior',
'javelin-dom',
'javelin-util',
'javelin-vector',
'javelin-stratcom',
'javelin-workflow',
'javelin-workboard-controller',
),
'e562708c' => array( 'e562708c' => array(
'javelin-install', 'javelin-install',
), ),

View file

@ -8,6 +8,7 @@
* phabricator-draggable-list * phabricator-draggable-list
* javelin-workboard-column * javelin-workboard-column
* javelin-workboard-header-template * javelin-workboard-header-template
* javelin-workboard-card-template
* @javelin * @javelin
*/ */
@ -18,10 +19,9 @@ JX.install('WorkboardBoard', {
this._phid = phid; this._phid = phid;
this._root = root; this._root = root;
this._templates = {};
this._orderMaps = {};
this._propertiesMap = {};
this._headers = {}; this._headers = {};
this._cards = {};
this._buildColumns(); this._buildColumns();
}, },
@ -35,10 +35,8 @@ JX.install('WorkboardBoard', {
_phid: null, _phid: null,
_root: null, _root: null,
_columns: null, _columns: null,
_templates: null,
_orderMaps: null,
_propertiesMap: null,
_headers: null, _headers: null,
_cards: null,
getRoot: function() { getRoot: function() {
return this._root; return this._root;
@ -56,9 +54,12 @@ JX.install('WorkboardBoard', {
return this._phid; return this._phid;
}, },
setCardTemplate: function(phid, template) { getCardTemplate: function(phid) {
this._templates[phid] = template; if (!this._cards[phid]) {
return this; this._cards[phid] = new JX.WorkboardCardTemplate(phid);
}
return this._cards[phid];
}, },
getHeaderTemplate: function(header_key) { getHeaderTemplate: function(header_key) {
@ -91,32 +92,10 @@ JX.install('WorkboardBoard', {
return this.compareVectors(u.getVector(), v.getVector()); 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() { getController: function() {
return this._controller; return this._controller;
}, },
setOrderMap: function(phid, map) {
this._orderMaps[phid] = map;
return this;
},
getOrderVector: function(phid, key) {
return this._orderMaps[phid][key];
},
compareVectors: function(u_vec, v_vec) { compareVectors: function(u_vec, v_vec) {
for (var ii = 0; ii < u_vec.length; ii++) { for (var ii = 0; ii < u_vec.length; ii++) {
if (u_vec[ii] > v_vec[ii]) { if (u_vec[ii] > v_vec[ii]) {
@ -310,25 +289,29 @@ JX.install('WorkboardBoard', {
var columns = this.getColumns(); var columns = this.getColumns();
var phid = response.objectPHID; var phid = response.objectPHID;
var card = this.getCardTemplate(phid);
if (!this._templates[phid]) { for (var add_phid in response.columnMaps) {
for (var add_phid in response.columnMaps) { var target_column = this.getColumn(add_phid);
var target_column = this.getColumn(add_phid);
if (!target_column) { if (!target_column) {
// If the column isn't visible, don't try to add a card to it. // If the column isn't visible, don't try to add a card to it.
continue; continue;
}
target_column.newCard(phid);
} }
target_column.newCard(phid);
} }
this.setCardTemplate(phid, response.cardHTML); card.setNodeHTMLTemplate(response.cardHTML);
var order_maps = response.orderMaps; var order_maps = response.orderMaps;
for (var order_phid in order_maps) { for (var order_phid in order_maps) {
this.setOrderMap(order_phid, order_maps[order_phid]); var card_template = this.getCardTemplate(order_phid);
for (var order_key in order_maps[order_phid]) {
card_template.setSortVector(
order_key,
order_maps[order_phid][order_key]);
}
} }
var column_maps = response.columnMaps; var column_maps = response.columnMaps;
@ -348,7 +331,8 @@ JX.install('WorkboardBoard', {
var property_maps = response.propertyMaps; var property_maps = response.propertyMaps;
for (var property_phid in property_maps) { for (var property_phid in property_maps) {
this.setObjectProperties(property_phid, property_maps[property_phid]); this.getCardTemplate(property_phid)
.setObjectProperties(property_maps[property_phid]);
} }
for (var column_phid in columns) { for (var column_phid in columns) {

View file

@ -29,7 +29,8 @@ JX.install('WorkboardCard', {
}, },
getProperties: function() { getProperties: function() {
return this.getColumn().getBoard().getObjectProperties(this.getPHID()); return this.getColumn().getBoard().getCardTemplate(this.getPHID())
.getObjectProperties();
}, },
getPoints: function() { getPoints: function() {
@ -47,11 +48,16 @@ JX.install('WorkboardCard', {
getNode: function() { getNode: function() {
if (!this._root) { if (!this._root) {
var phid = this.getPHID(); var phid = this.getPHID();
var template = this.getColumn().getBoard().getCardTemplate(phid);
this._root = JX.$H(template).getFragment().firstChild;
JX.Stratcom.getData(this._root).objectPHID = this.getPHID(); var root = this.getColumn().getBoard()
.getCardTemplate(phid)
.newNode();
JX.Stratcom.getData(root).objectPHID = phid;
this._root = root;
} }
return this._root; return this._root;
}, },

View file

@ -0,0 +1,47 @@
/**
* @provides javelin-workboard-card-template
* @requires javelin-install
* @javelin
*/
JX.install('WorkboardCardTemplate', {
construct: function(phid) {
this._phid = phid;
this._vectors = {};
this.setObjectProperties({});
},
properties: {
objectProperties: null
},
members: {
_phid: null,
_vectors: null,
getPHID: function() {
return this._phid;
},
setNodeHTMLTemplate: function(html) {
this._html = html;
return this;
},
setSortVector: function(order, vector) {
this._vectors[order] = vector;
return this;
},
getSortVector: function(order) {
return this._vectors[order];
},
newNode: function() {
return JX.$H(this._html).getFragment().firstChild;
}
}
});

View file

@ -319,18 +319,21 @@ JX.install('WorkboardColumn', {
}, },
_getOrderVector: function(phid, order) { _getOrderVector: function(phid, order) {
var board = this.getBoard();
if (!this._orderVectors) { if (!this._orderVectors) {
this._orderVectors = {}; this._orderVectors = {};
} }
if (!this._orderVectors[order]) { if (!this._orderVectors[order]) {
var board = this.getBoard();
var cards = this.getCards(); var cards = this.getCards();
var vectors = {}; var vectors = {};
for (var k in cards) { for (var k in cards) {
var card_phid = cards[k].getPHID(); var card_phid = cards[k].getPHID();
var vector = board.getOrderVector(card_phid, order); var vector = board.getCardTemplate(card_phid)
.getSortVector(order);
vectors[card_phid] = [].concat(vector); vectors[card_phid] = [].concat(vector);
// Push a "card" type, so cards always sort after headers; headers // Push a "card" type, so cards always sort after headers; headers
@ -352,7 +355,8 @@ JX.install('WorkboardColumn', {
// In this case, we're comparing a card being dragged in from another // In this case, we're comparing a card being dragged in from another
// column to the cards already in this column. We're just going to // column to the cards already in this column. We're just going to
// build a temporary vector for it. // build a temporary vector for it.
var incoming_vector = this.getBoard().getOrderVector(phid, order); var incoming_vector = board.getCardTemplate(phid)
.getSortVector(order);
incoming_vector = [].concat(incoming_vector); incoming_vector = [].concat(incoming_vector);
// Add a "card" type to sort this after headers. // Add a "card" type to sort this after headers.

View file

@ -83,7 +83,8 @@ JX.behavior('project-boards', function(config, statics) {
var templates = config.templateMap; var templates = config.templateMap;
for (var k in templates) { for (var k in templates) {
board.setCardTemplate(k, templates[k]); board.getCardTemplate(k)
.setNodeHTMLTemplate(templates[k]);
} }
var column_maps = config.columnMaps; var column_maps = config.columnMaps;
@ -97,12 +98,16 @@ JX.behavior('project-boards', function(config, statics) {
var order_maps = config.orderMaps; var order_maps = config.orderMaps;
for (var object_phid in order_maps) { for (var object_phid in order_maps) {
board.setOrderMap(object_phid, order_maps[object_phid]); var order_card = board.getCardTemplate(object_phid);
for (var order_key in order_maps[object_phid]) {
order_card.setSortVector(order_key, order_maps[object_phid][order_key]);
}
} }
var property_maps = config.propertyMaps; var property_maps = config.propertyMaps;
for (var property_phid in property_maps) { for (var property_phid in property_maps) {
board.setObjectProperties(property_phid, property_maps[property_phid]); board.getCardTemplate(property_phid)
.setObjectProperties(property_maps[property_phid]);
} }
var headers = config.headers; var headers = config.headers;