1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-22 13:30:55 +01:00

Restore column point counts to workboards

Summary: Ref T4427.

Test Plan:
  - Dragged a 17 XP task from "Hunting" to "Slain".
  - Saw 17 XP move.
  - Level up!

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T4427

Differential Revision: https://secure.phabricator.com/D15237
This commit is contained in:
epriestley 2016-02-10 13:53:36 -08:00
parent 888ea4e4fe
commit 1fb76655df
7 changed files with 212 additions and 82 deletions

View file

@ -221,6 +221,13 @@ final class ManiphestTask extends ManiphestDAO
); );
} }
public function getWorkboardProperties() {
return array(
'status' => $this->getStatus(),
'points' => (double)$this->getPoints(),
);
}
/* -( PhabricatorSubscribableInterface )----------------------------------- */ /* -( PhabricatorSubscribableInterface )----------------------------------- */

View file

@ -318,14 +318,17 @@ final class PhabricatorProjectBoardViewController
$column_menu = $this->buildColumnMenu($project, $column); $column_menu = $this->buildColumnMenu($project, $column);
$panel->addHeaderAction($column_menu); $panel->addHeaderAction($column_menu);
$tag_id = celerity_generate_unique_node_id();
$tag_content_id = celerity_generate_unique_node_id();
$count_tag = id(new PHUITagView()) $count_tag = id(new PHUITagView())
->setType(PHUITagView::TYPE_SHADE) ->setType(PHUITagView::TYPE_SHADE)
->setShade(PHUITagView::COLOR_BLUE) ->setShade(PHUITagView::COLOR_BLUE)
->setID($tag_id) ->addSigil('column-points')
->setName(phutil_tag('span', array('id' => $tag_content_id), '-')) ->setName(
javelin_tag(
'span',
array(
'sigil' => 'column-points-content',
),
pht('-')))
->setStyle('display: none'); ->setStyle('display: none');
$panel->setHeaderTag($count_tag); $panel->setHeaderTag($count_tag);
@ -339,8 +342,6 @@ final class PhabricatorProjectBoardViewController
->setMetadata( ->setMetadata(
array( array(
'columnPHID' => $column->getPHID(), 'columnPHID' => $column->getPHID(),
'countTagID' => $tag_id,
'countTagContentID' => $tag_content_id,
'pointLimit' => $column->getPointLimit(), 'pointLimit' => $column->getPointLimit(),
)); ));
@ -359,17 +360,22 @@ final class PhabricatorProjectBoardViewController
} }
$behavior_config = array( $behavior_config = array(
'boardID' => $board_id,
'projectPHID' => $project->getPHID(),
'moveURI' => $this->getApplicationURI('move/'.$project->getID().'/'), 'moveURI' => $this->getApplicationURI('move/'.$project->getID().'/'),
'createURI' => $this->getCreateURI(), 'createURI' => $this->getCreateURI(),
'uploadURI' => '/file/dropupload/', 'uploadURI' => '/file/dropupload/',
'coverURI' => $this->getApplicationURI('cover/'), 'coverURI' => $this->getApplicationURI('cover/'),
'chunkThreshold' => PhabricatorFileStorageEngine::getChunkThreshold(), 'chunkThreshold' => PhabricatorFileStorageEngine::getChunkThreshold(),
'pointsEnabled' => ManiphestTaskPoints::getIsEnabled(),
'boardPHID' => $project->getPHID(),
'order' => $this->sortKey, 'order' => $this->sortKey,
'templateMap' => $templates, 'templateMap' => $templates,
'columnMaps' => $column_maps, 'columnMaps' => $column_maps,
'orderMaps' => mpull($all_tasks, 'getWorkboardOrderVectors'), 'orderMaps' => mpull($all_tasks, 'getWorkboardOrderVectors'),
'propertyMaps' => mpull($all_tasks, 'getWorkboardProperties'),
'boardID' => $board_id,
'projectPHID' => $project->getPHID(),
); );
$this->initBehavior('project-boards', $behavior_config); $this->initBehavior('project-boards', $behavior_config);

View file

@ -80,25 +80,6 @@ final class PhabricatorBoardResponseEngine extends Phobject {
$order_maps[$visible->getPHID()] = $visible->getWorkboardOrderVectors(); $order_maps[$visible->getPHID()] = $visible->getWorkboardOrderVectors();
} }
$template = $this->buildTemplate();
$payload = array(
'objectPHID' => $object_phid,
'cardHTML' => $template,
'columnMaps' => $natural,
'orderMaps' => $order_maps,
);
return id(new AphrontAjaxResponse())
->setContent($payload);
}
private function buildTemplate() {
$viewer = $this->getViewer();
$object_phid = $this->getObjectPHID();
$excluded_phids = $this->loadExcludedProjectPHIDs();
$object = id(new ManiphestTaskQuery()) $object = id(new ManiphestTaskQuery())
->setViewer($viewer) ->setViewer($viewer)
->withPHIDs(array($object_phid)) ->withPHIDs(array($object_phid))
@ -108,6 +89,28 @@ final class PhabricatorBoardResponseEngine extends Phobject {
return new Aphront404Response(); return new Aphront404Response();
} }
$template = $this->buildTemplate($object);
$payload = array(
'objectPHID' => $object_phid,
'cardHTML' => $template,
'columnMaps' => $natural,
'orderMaps' => $order_maps,
'propertyMaps' => array(
$object_phid => $object->getWorkboardProperties(),
),
);
return id(new AphrontAjaxResponse())
->setContent($payload);
}
private function buildTemplate($object) {
$viewer = $this->getViewer();
$object_phid = $this->getObjectPHID();
$excluded_phids = $this->loadExcludedProjectPHIDs();
$rendering_engine = id(new PhabricatorBoardRenderingEngine()) $rendering_engine = id(new PhabricatorBoardRenderingEngine())
->setViewer($viewer) ->setViewer($viewer)
->setObjects(array($object)) ->setObjects(array($object))

View file

@ -19,11 +19,13 @@ JX.install('WorkboardBoard', {
this._templates = {}; this._templates = {};
this._orderMaps = {}; this._orderMaps = {};
this._propertiesMap = {};
this._buildColumns(); this._buildColumns();
}, },
properties: { properties: {
order: null, order: null,
pointsEnabled: false
}, },
members: { members: {
@ -33,6 +35,7 @@ JX.install('WorkboardBoard', {
_columns: null, _columns: null,
_templates: null, _templates: null,
_orderMaps: null, _orderMaps: null,
_propertiesMap: null,
getRoot: function() { getRoot: function() {
return this._root; return this._root;
@ -55,6 +58,15 @@ JX.install('WorkboardBoard', {
return this; return this;
}, },
setObjectProperties: function(phid, properties) {
this._propertiesMap[phid] = properties;
return this;
},
getObjectProperties: function(phid) {
return this._propertiesMap[phid];
},
getCardTemplate: function(phid) { getCardTemplate: function(phid) {
return this._templates[phid]; return this._templates[phid];
}, },
@ -174,12 +186,18 @@ JX.install('WorkboardBoard', {
var card = src_column.removeCard(response.objectPHID); var card = src_column.removeCard(response.objectPHID);
dst_column.addCard(card, after_phid); dst_column.addCard(card, after_phid);
src_column.markForRedraw();
dst_column.markForRedraw();
this.updateCard(response); this.updateCard(response);
list.unlock(); list.unlock();
}, },
updateCard: function(response) { updateCard: function(response, options) {
options = options || {};
options.dirtyColumns = options.dirtyColumns || {};
var columns = this.getColumns(); var columns = this.getColumns();
var phid = response.objectPHID; var phid = response.objectPHID;
@ -202,8 +220,15 @@ JX.install('WorkboardBoard', {
this.getColumn(natural_phid).setNaturalOrder(column_maps[natural_phid]); this.getColumn(natural_phid).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) { for (var column_phid in columns) {
var cards = columns[column_phid].getCards(); var column = columns[column_phid];
var cards = column.getCards();
for (var object_phid in cards) { for (var object_phid in cards) {
if (object_phid !== phid) { if (object_phid !== phid) {
continue; continue;
@ -211,8 +236,20 @@ JX.install('WorkboardBoard', {
var card = cards[object_phid]; var card = cards[object_phid];
card.redraw(); card.redraw();
column.markForRedraw();
}
}
this._redrawColumns();
},
_redrawColumns: function() {
var columns = this.getColumns();
for (var k in columns) {
if (columns[k].isMarkedForRedraw()) {
columns[k].redraw();
} }
columns[column_phid].redraw();
} }
} }

View file

@ -28,6 +28,18 @@ JX.install('WorkboardCard', {
this._column = column; this._column = column;
}, },
getProperties: function() {
return this.getColumn().getBoard().getObjectProperties(this.getPHID());
},
getPoints: function() {
return this.getProperties().points;
},
getStatus: function() {
return this.getProperties().status;
},
getNode: function() { getNode: function() {
if (!this._root) { if (!this._root) {
var phid = this.getPHID(); var phid = this.getPHID();

View file

@ -12,6 +12,14 @@ JX.install('WorkboardColumn', {
this._phid = phid; this._phid = phid;
this._root = root; this._root = root;
this._panel = JX.DOM.findAbove(root, 'div', 'workpanel');
this._pointsNode = JX.DOM.find(this._panel, 'span', 'column-points');
this._pointsContentNode = JX.DOM.find(
this._panel,
'span',
'column-points-content');
this._cards = {}; this._cards = {};
this._naturalOrder = []; this._naturalOrder = [];
}, },
@ -22,6 +30,10 @@ JX.install('WorkboardColumn', {
_board: null, _board: null,
_cards: null, _cards: null,
_naturalOrder: null, _naturalOrder: null,
_panel: null,
_pointsNode: null,
_pointsContentNode: null,
_dirty: true,
getPHID: function() { getPHID: function() {
return this._phid; return this._phid;
@ -48,6 +60,18 @@ JX.install('WorkboardColumn', {
return this; return this;
}, },
getPointsNode: function() {
return this._pointsNode;
},
getPointsContentNode: function() {
return this._pointsContentNode;
},
getWorkpanelNode: function() {
return this._panel;
},
newCard: function(phid) { newCard: function(phid) {
var card = new JX.WorkboardCard(this, phid); var card = new JX.WorkboardCard(this, phid);
@ -112,8 +136,21 @@ JX.install('WorkboardColumn', {
return JX.keys(this.getCards()); return JX.keys(this.getCards());
}, },
getPointLimit: function() {
return JX.Stratcom.getData(this.getRoot()).pointLimit;
},
markForRedraw: function() {
this._dirty = true;
},
isMarkedForRedraw: function() {
return this._dirty;
},
redraw: function() { redraw: function() {
var order = this.getBoard().getOrder(); var board = this.getBoard();
var order = board.getOrder();
var list; var list;
if (order == 'natural') { if (order == 'natural') {
@ -124,11 +161,18 @@ JX.install('WorkboardColumn', {
var content = []; var content = [];
for (var ii = 0; ii < list.length; ii++) { for (var ii = 0; ii < list.length; ii++) {
var node = list[ii].getNode(); var card = list[ii];
var node = card.getNode();
content.push(node); content.push(node);
} }
JX.DOM.setContent(this.getRoot(), content); JX.DOM.setContent(this.getRoot(), content);
this._redrawFrame();
this._dirty = false;
}, },
_getCardsSortedNaturally: function() { _getCardsSortedNaturally: function() {
@ -170,6 +214,69 @@ JX.install('WorkboardColumn', {
} }
return 0; return 0;
},
_redrawFrame: function() {
var cards = this.getCards();
var board = this.getBoard();
var points = {};
for (var phid in cards) {
var card = cards[phid];
var card_points;
if (board.getPointsEnabled()) {
card_points = card.getPoints();
} else {
card_points = 1;
}
if (card_points !== null) {
var status = card.getStatus();
if (!points[status]) {
points[status] = 0;
}
points[status] += card_points;
}
}
var total_points = 0;
for (var k in points) {
total_points += points[k];
}
var limit = this.getPointLimit();
var display_value;
if (limit !== null && limit !== 0) {
display_value = total_points + ' / ' + limit;
} else {
display_value = total_points;
}
var over_limit = ((limit !== null) && (total_points > limit));
var content_node = this.getPointsContentNode();
var points_node = this.getPointsNode();
JX.DOM.setContent(content_node, display_value);
var is_empty = !this.getCardPHIDs().length;
var panel = JX.DOM.findAbove(this.getRoot(), 'div', 'workpanel');
JX.DOM.alterClass(panel, 'project-panel-empty', is_empty);
JX.DOM.alterClass(panel, 'project-panel-over-limit', over_limit);
var color_map = {
'phui-tag-shade-disabled': (total_points === 0),
'phui-tag-shade-blue': (total_points > 0 && !over_limit),
'phui-tag-shade-red': (over_limit)
};
for (var c in color_map) {
JX.DOM.alterClass(points_node, c, !!color_map[c]);
}
JX.DOM.show(points_node);
} }
} }

View file

@ -11,54 +11,6 @@
JX.behavior('project-boards', function(config, statics) { JX.behavior('project-boards', function(config, statics) {
function onupdate(col) {
var data = JX.Stratcom.getData(col);
var cards = finditems(col);
// Update the count of tasks in the column header.
if (!data.countTagNode) {
data.countTagNode = JX.$(data.countTagID);
JX.DOM.show(data.countTagNode);
}
var sum = 0;
for (var ii = 0; ii < cards.length; ii++) {
// TODO: Allow this to be computed in some more clever way.
sum += 1;
}
// TODO: This is a little bit hacky, but we don't have a PHUIX version of
// this element yet.
var over_limit = (data.pointLimit && (sum > data.pointLimit));
var display_value = sum;
if (data.pointLimit) {
display_value = sum + ' / ' + data.pointLimit;
}
JX.DOM.setContent(JX.$(data.countTagContentID), display_value);
var panel_map = {
'project-panel-empty': !cards.length,
'project-panel-over-limit': over_limit
};
var panel = JX.DOM.findAbove(col, 'div', 'workpanel');
for (var p in panel_map) {
JX.DOM.alterClass(panel, p, !!panel_map[p]);
}
var color_map = {
'phui-tag-shade-disabled': (sum === 0),
'phui-tag-shade-blue': (sum > 0 && !over_limit),
'phui-tag-shade-red': (over_limit)
};
for (var c in color_map) {
JX.DOM.alterClass(data.countTagNode, c, !!color_map[c]);
}
}
function update_statics(update_config) { function update_statics(update_config) {
statics.boardID = update_config.boardID; statics.boardID = update_config.boardID;
statics.projectPHID = update_config.projectPHID; statics.projectPHID = update_config.projectPHID;
@ -135,7 +87,8 @@ JX.behavior('project-boards', function(config, statics) {
var board_node = JX.$(config.boardID); var board_node = JX.$(config.boardID);
var board = statics.workboard.newBoard(board_phid, board_node) var board = statics.workboard.newBoard(board_phid, board_node)
.setOrder(config.order); .setOrder(config.order)
.setPointsEnabled(config.pointsEnabled);
var templates = config.templateMap; var templates = config.templateMap;
for (var k in templates) { for (var k in templates) {
@ -156,6 +109,11 @@ JX.behavior('project-boards', function(config, statics) {
board.setOrderMap(object_phid, order_maps[object_phid]); board.setOrderMap(object_phid, order_maps[object_phid]);
} }
var property_maps = config.propertyMaps;
for (var property_phid in property_maps) {
board.setObjectProperties(property_phid, property_maps[property_phid]);
}
board.start(); board.start();
}); });