Page MenuHomePhabricator

D15237.diff
No OneTemporary

D15237.diff

diff --git a/src/applications/maniphest/storage/ManiphestTask.php b/src/applications/maniphest/storage/ManiphestTask.php
--- a/src/applications/maniphest/storage/ManiphestTask.php
+++ b/src/applications/maniphest/storage/ManiphestTask.php
@@ -221,6 +221,13 @@
);
}
+ public function getWorkboardProperties() {
+ return array(
+ 'status' => $this->getStatus(),
+ 'points' => (double)$this->getPoints(),
+ );
+ }
+
/* -( PhabricatorSubscribableInterface )----------------------------------- */
diff --git a/src/applications/project/controller/PhabricatorProjectBoardViewController.php b/src/applications/project/controller/PhabricatorProjectBoardViewController.php
--- a/src/applications/project/controller/PhabricatorProjectBoardViewController.php
+++ b/src/applications/project/controller/PhabricatorProjectBoardViewController.php
@@ -318,14 +318,17 @@
$column_menu = $this->buildColumnMenu($project, $column);
$panel->addHeaderAction($column_menu);
- $tag_id = celerity_generate_unique_node_id();
- $tag_content_id = celerity_generate_unique_node_id();
-
$count_tag = id(new PHUITagView())
->setType(PHUITagView::TYPE_SHADE)
->setShade(PHUITagView::COLOR_BLUE)
- ->setID($tag_id)
- ->setName(phutil_tag('span', array('id' => $tag_content_id), '-'))
+ ->addSigil('column-points')
+ ->setName(
+ javelin_tag(
+ 'span',
+ array(
+ 'sigil' => 'column-points-content',
+ ),
+ pht('-')))
->setStyle('display: none');
$panel->setHeaderTag($count_tag);
@@ -339,8 +342,6 @@
->setMetadata(
array(
'columnPHID' => $column->getPHID(),
- 'countTagID' => $tag_id,
- 'countTagContentID' => $tag_content_id,
'pointLimit' => $column->getPointLimit(),
));
@@ -359,17 +360,22 @@
}
$behavior_config = array(
- 'boardID' => $board_id,
- 'projectPHID' => $project->getPHID(),
'moveURI' => $this->getApplicationURI('move/'.$project->getID().'/'),
'createURI' => $this->getCreateURI(),
'uploadURI' => '/file/dropupload/',
'coverURI' => $this->getApplicationURI('cover/'),
'chunkThreshold' => PhabricatorFileStorageEngine::getChunkThreshold(),
+ 'pointsEnabled' => ManiphestTaskPoints::getIsEnabled(),
+
+ 'boardPHID' => $project->getPHID(),
'order' => $this->sortKey,
'templateMap' => $templates,
'columnMaps' => $column_maps,
'orderMaps' => mpull($all_tasks, 'getWorkboardOrderVectors'),
+ 'propertyMaps' => mpull($all_tasks, 'getWorkboardProperties'),
+
+ 'boardID' => $board_id,
+ 'projectPHID' => $project->getPHID(),
);
$this->initBehavior('project-boards', $behavior_config);
diff --git a/src/applications/project/engine/PhabricatorBoardResponseEngine.php b/src/applications/project/engine/PhabricatorBoardResponseEngine.php
--- a/src/applications/project/engine/PhabricatorBoardResponseEngine.php
+++ b/src/applications/project/engine/PhabricatorBoardResponseEngine.php
@@ -80,34 +80,37 @@
$order_maps[$visible->getPHID()] = $visible->getWorkboardOrderVectors();
}
- $template = $this->buildTemplate();
+ $object = id(new ManiphestTaskQuery())
+ ->setViewer($viewer)
+ ->withPHIDs(array($object_phid))
+ ->needProjectPHIDs(true)
+ ->executeOne();
+ if (!$object) {
+ 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() {
+ private function buildTemplate($object) {
$viewer = $this->getViewer();
$object_phid = $this->getObjectPHID();
$excluded_phids = $this->loadExcludedProjectPHIDs();
- $object = id(new ManiphestTaskQuery())
- ->setViewer($viewer)
- ->withPHIDs(array($object_phid))
- ->needProjectPHIDs(true)
- ->executeOne();
- if (!$object) {
- return new Aphront404Response();
- }
-
$rendering_engine = id(new PhabricatorBoardRenderingEngine())
->setViewer($viewer)
->setObjects(array($object))
diff --git a/webroot/rsrc/js/application/projects/WorkboardBoard.js b/webroot/rsrc/js/application/projects/WorkboardBoard.js
--- a/webroot/rsrc/js/application/projects/WorkboardBoard.js
+++ b/webroot/rsrc/js/application/projects/WorkboardBoard.js
@@ -19,11 +19,13 @@
this._templates = {};
this._orderMaps = {};
+ this._propertiesMap = {};
this._buildColumns();
},
properties: {
order: null,
+ pointsEnabled: false
},
members: {
@@ -33,6 +35,7 @@
_columns: null,
_templates: null,
_orderMaps: null,
+ _propertiesMap: null,
getRoot: function() {
return this._root;
@@ -55,6 +58,15 @@
return this;
},
+ setObjectProperties: function(phid, properties) {
+ this._propertiesMap[phid] = properties;
+ return this;
+ },
+
+ getObjectProperties: function(phid) {
+ return this._propertiesMap[phid];
+ },
+
getCardTemplate: function(phid) {
return this._templates[phid];
},
@@ -174,12 +186,18 @@
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) {
+ updateCard: function(response, options) {
+ options = options || {};
+ options.dirtyColumns = options.dirtyColumns || {};
+
var columns = this.getColumns();
var phid = response.objectPHID;
@@ -202,8 +220,15 @@
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) {
- var cards = columns[column_phid].getCards();
+ var column = columns[column_phid];
+
+ var cards = column.getCards();
for (var object_phid in cards) {
if (object_phid !== phid) {
continue;
@@ -211,8 +236,20 @@
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();
}
- columns[column_phid].redraw();
}
}
diff --git a/webroot/rsrc/js/application/projects/WorkboardCard.js b/webroot/rsrc/js/application/projects/WorkboardCard.js
--- a/webroot/rsrc/js/application/projects/WorkboardCard.js
+++ b/webroot/rsrc/js/application/projects/WorkboardCard.js
@@ -28,6 +28,18 @@
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() {
if (!this._root) {
var phid = this.getPHID();
diff --git a/webroot/rsrc/js/application/projects/WorkboardColumn.js b/webroot/rsrc/js/application/projects/WorkboardColumn.js
--- a/webroot/rsrc/js/application/projects/WorkboardColumn.js
+++ b/webroot/rsrc/js/application/projects/WorkboardColumn.js
@@ -12,6 +12,14 @@
this._phid = phid;
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._naturalOrder = [];
},
@@ -22,6 +30,10 @@
_board: null,
_cards: null,
_naturalOrder: null,
+ _panel: null,
+ _pointsNode: null,
+ _pointsContentNode: null,
+ _dirty: true,
getPHID: function() {
return this._phid;
@@ -48,6 +60,18 @@
return this;
},
+ getPointsNode: function() {
+ return this._pointsNode;
+ },
+
+ getPointsContentNode: function() {
+ return this._pointsContentNode;
+ },
+
+ getWorkpanelNode: function() {
+ return this._panel;
+ },
+
newCard: function(phid) {
var card = new JX.WorkboardCard(this, phid);
@@ -112,8 +136,21 @@
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() {
- var order = this.getBoard().getOrder();
+ var board = this.getBoard();
+ var order = board.getOrder();
var list;
if (order == 'natural') {
@@ -124,11 +161,18 @@
var content = [];
for (var ii = 0; ii < list.length; ii++) {
- var node = list[ii].getNode();
+ var card = list[ii];
+
+ var node = card.getNode();
content.push(node);
+
}
JX.DOM.setContent(this.getRoot(), content);
+
+ this._redrawFrame();
+
+ this._dirty = false;
},
_getCardsSortedNaturally: function() {
@@ -170,6 +214,69 @@
}
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);
}
}
diff --git a/webroot/rsrc/js/application/projects/behavior-project-boards.js b/webroot/rsrc/js/application/projects/behavior-project-boards.js
--- a/webroot/rsrc/js/application/projects/behavior-project-boards.js
+++ b/webroot/rsrc/js/application/projects/behavior-project-boards.js
@@ -11,54 +11,6 @@
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) {
statics.boardID = update_config.boardID;
statics.projectPHID = update_config.projectPHID;
@@ -135,7 +87,8 @@
var board_node = JX.$(config.boardID);
var board = statics.workboard.newBoard(board_phid, board_node)
- .setOrder(config.order);
+ .setOrder(config.order)
+ .setPointsEnabled(config.pointsEnabled);
var templates = config.templateMap;
for (var k in templates) {
@@ -156,6 +109,11 @@
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();
});

File Metadata

Mime Type
text/plain
Expires
Sat, Dec 28, 11:36 AM (6 h, 45 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6937961
Default Alt Text
D15237.diff (13 KB)

Event Timeline