mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-22 14:52:41 +01:00
Make pressing "R" on your keyboard reload the card state on workboards
Summary: Depends on D20638. Ref T4900. This is an incremental step toward proper workboard updates. Currently, the client can mostly update its view because we do updates when you edit or move a card, and the client and server know how to send lists of card updates, so a lot of the work is already done. However, the code assumes we're only updating/redrawing one card at a time. Make the client accept and process multiple card updates. In future changes, I'll add versioning (so we only update cards that have actually changed), fix the "TODO" around ordering, and move toward actual Aphlict-based real-time updates. Test Plan: - Opened the same workboard in two windows. - Edited cards in one window, pressed "R" (capital letter, with no modifier keys) to reload the second window. - Saw edits and moves reflected accurately after sync, except for some special cases of header/order interaction (see "TODO"). Reviewers: amckinley Reviewed By: amckinley Maniphest Tasks: T4900 Differential Revision: https://secure.phabricator.com/D20639
This commit is contained in:
parent
97c1699756
commit
db69686927
9 changed files with 283 additions and 129 deletions
|
@ -412,16 +412,16 @@ return array(
|
|||
'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-rule-editor.js' => '9347f172',
|
||||
'rsrc/js/application/projects/WorkboardBoard.js' => '44f71637',
|
||||
'rsrc/js/application/projects/WorkboardBoard.js' => '34c2f539',
|
||||
'rsrc/js/application/projects/WorkboardCard.js' => '0392a5d8',
|
||||
'rsrc/js/application/projects/WorkboardCardTemplate.js' => '2a61f8d4',
|
||||
'rsrc/js/application/projects/WorkboardColumn.js' => 'c3d24e63',
|
||||
'rsrc/js/application/projects/WorkboardController.js' => '42c7a5a7',
|
||||
'rsrc/js/application/projects/WorkboardController.js' => 'b9d0c2f3',
|
||||
'rsrc/js/application/projects/WorkboardDropEffect.js' => '8e0aa661',
|
||||
'rsrc/js/application/projects/WorkboardHeader.js' => '111bfd2d',
|
||||
'rsrc/js/application/projects/WorkboardHeaderTemplate.js' => 'ebe83a6b',
|
||||
'rsrc/js/application/projects/WorkboardOrderTemplate.js' => '03e8891f',
|
||||
'rsrc/js/application/projects/behavior-project-boards.js' => 'aad45445',
|
||||
'rsrc/js/application/projects/behavior-project-boards.js' => '58cb6a88',
|
||||
'rsrc/js/application/projects/behavior-project-create.js' => '34c53422',
|
||||
'rsrc/js/application/projects/behavior-reorder-columns.js' => '8ac32fd9',
|
||||
'rsrc/js/application/releeph/releeph-preview-branch.js' => '75184d68',
|
||||
|
@ -667,7 +667,7 @@ return array(
|
|||
'javelin-behavior-phuix-example' => 'c2c500a7',
|
||||
'javelin-behavior-policy-control' => '0eaa33a9',
|
||||
'javelin-behavior-policy-rule-editor' => '9347f172',
|
||||
'javelin-behavior-project-boards' => 'aad45445',
|
||||
'javelin-behavior-project-boards' => '58cb6a88',
|
||||
'javelin-behavior-project-create' => '34c53422',
|
||||
'javelin-behavior-quicksand-blacklist' => '5a6f6a06',
|
||||
'javelin-behavior-read-only-warning' => 'b9109f8f',
|
||||
|
@ -743,11 +743,11 @@ return array(
|
|||
'javelin-view-renderer' => '9aae2b66',
|
||||
'javelin-view-visitor' => '308f9fe4',
|
||||
'javelin-websocket' => 'fdc13e4e',
|
||||
'javelin-workboard-board' => '44f71637',
|
||||
'javelin-workboard-board' => '34c2f539',
|
||||
'javelin-workboard-card' => '0392a5d8',
|
||||
'javelin-workboard-card-template' => '2a61f8d4',
|
||||
'javelin-workboard-column' => 'c3d24e63',
|
||||
'javelin-workboard-controller' => '42c7a5a7',
|
||||
'javelin-workboard-controller' => 'b9d0c2f3',
|
||||
'javelin-workboard-drop-effect' => '8e0aa661',
|
||||
'javelin-workboard-header' => '111bfd2d',
|
||||
'javelin-workboard-header-template' => 'ebe83a6b',
|
||||
|
@ -1202,6 +1202,18 @@ return array(
|
|||
'javelin-install',
|
||||
'javelin-util',
|
||||
),
|
||||
'34c2f539' => 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',
|
||||
'javelin-workboard-order-template',
|
||||
),
|
||||
'34c53422' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-dom',
|
||||
|
@ -1264,16 +1276,6 @@ return array(
|
|||
'4234f572' => array(
|
||||
'syntax-default-css',
|
||||
),
|
||||
'42c7a5a7' => array(
|
||||
'javelin-install',
|
||||
'javelin-dom',
|
||||
'javelin-util',
|
||||
'javelin-vector',
|
||||
'javelin-stratcom',
|
||||
'javelin-workflow',
|
||||
'phabricator-drag-and-drop-file-upload',
|
||||
'javelin-workboard-board',
|
||||
),
|
||||
'4370900d' => array(
|
||||
'javelin-install',
|
||||
'javelin-util',
|
||||
|
@ -1294,18 +1296,6 @@ return array(
|
|||
'43bc9360' => array(
|
||||
'javelin-install',
|
||||
),
|
||||
'44f71637' => 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',
|
||||
'javelin-workboard-order-template',
|
||||
),
|
||||
'46116c01' => array(
|
||||
'javelin-request',
|
||||
'javelin-behavior',
|
||||
|
@ -1424,6 +1414,16 @@ return array(
|
|||
'javelin-vector',
|
||||
'javelin-typeahead-static-source',
|
||||
),
|
||||
'58cb6a88' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-dom',
|
||||
'javelin-util',
|
||||
'javelin-vector',
|
||||
'javelin-stratcom',
|
||||
'javelin-workflow',
|
||||
'javelin-workboard-controller',
|
||||
'javelin-workboard-drop-effect',
|
||||
),
|
||||
'5902260c' => array(
|
||||
'javelin-util',
|
||||
'javelin-magical-init',
|
||||
|
@ -1852,16 +1852,6 @@ return array(
|
|||
'javelin-dom',
|
||||
'javelin-util',
|
||||
),
|
||||
'aad45445' => array(
|
||||
'javelin-behavior',
|
||||
'javelin-dom',
|
||||
'javelin-util',
|
||||
'javelin-vector',
|
||||
'javelin-stratcom',
|
||||
'javelin-workflow',
|
||||
'javelin-workboard-controller',
|
||||
'javelin-workboard-drop-effect',
|
||||
),
|
||||
'ab85e184' => array(
|
||||
'javelin-install',
|
||||
'javelin-dom',
|
||||
|
@ -1952,6 +1942,16 @@ return array(
|
|||
'javelin-uri',
|
||||
'phabricator-notification',
|
||||
),
|
||||
'b9d0c2f3' => array(
|
||||
'javelin-install',
|
||||
'javelin-dom',
|
||||
'javelin-util',
|
||||
'javelin-vector',
|
||||
'javelin-stratcom',
|
||||
'javelin-workflow',
|
||||
'phabricator-drag-and-drop-file-upload',
|
||||
'javelin-workboard-board',
|
||||
),
|
||||
'bde53589' => array(
|
||||
'phui-inline-comment-view-css',
|
||||
),
|
||||
|
|
|
@ -4163,6 +4163,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorProjectBoardFilterController' => 'applications/project/controller/PhabricatorProjectBoardFilterController.php',
|
||||
'PhabricatorProjectBoardImportController' => 'applications/project/controller/PhabricatorProjectBoardImportController.php',
|
||||
'PhabricatorProjectBoardManageController' => 'applications/project/controller/PhabricatorProjectBoardManageController.php',
|
||||
'PhabricatorProjectBoardReloadController' => 'applications/project/controller/PhabricatorProjectBoardReloadController.php',
|
||||
'PhabricatorProjectBoardReorderController' => 'applications/project/controller/PhabricatorProjectBoardReorderController.php',
|
||||
'PhabricatorProjectBoardViewController' => 'applications/project/controller/PhabricatorProjectBoardViewController.php',
|
||||
'PhabricatorProjectBuiltinsExample' => 'applications/uiexample/examples/PhabricatorProjectBuiltinsExample.php',
|
||||
|
@ -10431,6 +10432,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorProjectBoardFilterController' => 'PhabricatorProjectBoardController',
|
||||
'PhabricatorProjectBoardImportController' => 'PhabricatorProjectBoardController',
|
||||
'PhabricatorProjectBoardManageController' => 'PhabricatorProjectBoardController',
|
||||
'PhabricatorProjectBoardReloadController' => 'PhabricatorProjectBoardController',
|
||||
'PhabricatorProjectBoardReorderController' => 'PhabricatorProjectBoardController',
|
||||
'PhabricatorProjectBoardViewController' => 'PhabricatorProjectBoardController',
|
||||
'PhabricatorProjectBuiltinsExample' => 'PhabricatorUIExample',
|
||||
|
|
|
@ -99,6 +99,8 @@ final class PhabricatorProjectApplication extends PhabricatorApplication {
|
|||
=> 'PhabricatorProjectBoardDefaultController',
|
||||
'filter/(?:query/(?P<queryKey>[^/]+)/)?'
|
||||
=> 'PhabricatorProjectBoardFilterController',
|
||||
'reload/'
|
||||
=> 'PhabricatorProjectBoardReloadController',
|
||||
),
|
||||
'column/' => array(
|
||||
'remove/(?P<id>\d+)/' =>
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorProjectBoardReloadController
|
||||
extends PhabricatorProjectBoardController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->getViewer();
|
||||
|
||||
$response = $this->loadProject();
|
||||
if ($response) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
$project = $this->getProject();
|
||||
$state = $this->getViewState();
|
||||
$board_uri = $state->newWorkboardURI();
|
||||
|
||||
$layout_engine = $state->getLayoutEngine();
|
||||
|
||||
$board_phid = $project->getPHID();
|
||||
|
||||
$objects = $state->getObjects();
|
||||
$object_phids = mpull($objects, 'getPHID');
|
||||
|
||||
$engine = id(new PhabricatorBoardResponseEngine())
|
||||
->setViewer($viewer)
|
||||
->setBoardPHID($board_phid)
|
||||
->setUpdatePHIDs($object_phids);
|
||||
|
||||
// TODO: We don't currently process "order" properly. If a user is viewing
|
||||
// a board grouped by "Owner", and another user changes a task to be owned
|
||||
// by a user who currently owns nothing on the board, the new header won't
|
||||
// generate correctly if the first user presses "R".
|
||||
|
||||
return $engine->buildResponse();
|
||||
}
|
||||
|
||||
}
|
|
@ -286,6 +286,7 @@ final class PhabricatorProjectBoardViewController
|
|||
'moveURI' => $this->getApplicationURI('move/'.$project->getID().'/'),
|
||||
'uploadURI' => '/file/dropupload/',
|
||||
'coverURI' => $this->getApplicationURI('cover/'),
|
||||
'reloadURI' => phutil_string_cast($state->newWorkboardURI('reload/')),
|
||||
'chunkThreshold' => PhabricatorFileStorageEngine::getChunkThreshold(),
|
||||
'pointsEnabled' => ManiphestTaskPoints::getIsEnabled(),
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ final class PhabricatorBoardResponseEngine extends Phobject {
|
|||
private $boardPHID;
|
||||
private $objectPHID;
|
||||
private $visiblePHIDs;
|
||||
private $updatePHIDs = array();
|
||||
private $ordering;
|
||||
private $sounds;
|
||||
|
||||
|
@ -45,6 +46,15 @@ final class PhabricatorBoardResponseEngine extends Phobject {
|
|||
return $this->visiblePHIDs;
|
||||
}
|
||||
|
||||
public function setUpdatePHIDs(array $update_phids) {
|
||||
$this->updatePHIDs = $update_phids;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getUpdatePHIDs() {
|
||||
return $this->updatePHIDs;
|
||||
}
|
||||
|
||||
public function setOrdering(PhabricatorProjectColumnOrder $ordering) {
|
||||
$this->ordering = $ordering;
|
||||
return $this;
|
||||
|
@ -71,36 +81,41 @@ final class PhabricatorBoardResponseEngine extends Phobject {
|
|||
|
||||
// Load all the other tasks that are visible in the affected columns and
|
||||
// perform layout for them.
|
||||
$visible_phids = $this->getAllVisiblePHIDs();
|
||||
$all_phids = $this->getAllVisiblePHIDs();
|
||||
|
||||
$layout_engine = id(new PhabricatorBoardLayoutEngine())
|
||||
->setViewer($viewer)
|
||||
->setBoardPHIDs(array($board_phid))
|
||||
->setObjectPHIDs($visible_phids)
|
||||
->setObjectPHIDs($all_phids)
|
||||
->executeLayout();
|
||||
|
||||
$object_columns = $layout_engine->getObjectColumns(
|
||||
$board_phid,
|
||||
$object_phid);
|
||||
|
||||
$natural = array();
|
||||
foreach ($object_columns as $column_phid => $column) {
|
||||
|
||||
$update_phids = $this->getAllUpdatePHIDs();
|
||||
$update_columns = array();
|
||||
foreach ($update_phids as $update_phid) {
|
||||
$update_columns += $layout_engine->getObjectColumns(
|
||||
$board_phid,
|
||||
$update_phid);
|
||||
}
|
||||
|
||||
foreach ($update_columns as $column_phid => $column) {
|
||||
$column_object_phids = $layout_engine->getColumnObjectPHIDs(
|
||||
$board_phid,
|
||||
$column_phid);
|
||||
$natural[$column_phid] = array_values($column_object_phids);
|
||||
}
|
||||
|
||||
$all_visible = id(new ManiphestTaskQuery())
|
||||
$all_objects = id(new ManiphestTaskQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs($visible_phids)
|
||||
->withPHIDs($all_phids)
|
||||
->execute();
|
||||
$all_visible = mpull($all_visible, null, 'getPHID');
|
||||
$all_objects = mpull($all_objects, null, 'getPHID');
|
||||
|
||||
if ($ordering) {
|
||||
$vectors = $ordering->getSortVectorsForObjects($all_visible);
|
||||
$header_keys = $ordering->getHeaderKeysForObjects($all_visible);
|
||||
$headers = $ordering->getHeadersForObjects($all_visible);
|
||||
$vectors = $ordering->getSortVectorsForObjects($all_objects);
|
||||
$header_keys = $ordering->getHeaderKeysForObjects($all_objects);
|
||||
$headers = $ordering->getHeadersForObjects($all_objects);
|
||||
$headers = mpull($headers, 'toDictionary');
|
||||
} else {
|
||||
$vectors = array();
|
||||
|
@ -108,19 +123,10 @@ final class PhabricatorBoardResponseEngine extends Phobject {
|
|||
$headers = array();
|
||||
}
|
||||
|
||||
$object = id(new ManiphestTaskQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs(array($object_phid))
|
||||
->needProjectPHIDs(true)
|
||||
->executeOne();
|
||||
if (!$object) {
|
||||
return new Aphront404Response();
|
||||
}
|
||||
|
||||
$template = $this->buildTemplate($object);
|
||||
$templates = $this->newCardTemplates();
|
||||
|
||||
$cards = array();
|
||||
foreach ($all_visible as $card_phid => $object) {
|
||||
foreach ($all_objects as $card_phid => $object) {
|
||||
$card = array(
|
||||
'vectors' => array(),
|
||||
'headers' => array(),
|
||||
|
@ -144,8 +150,11 @@ final class PhabricatorBoardResponseEngine extends Phobject {
|
|||
$card['properties'] = self::newTaskProperties($object);
|
||||
}
|
||||
|
||||
if ($card_phid === $object_phid) {
|
||||
$card['nodeHTMLTemplate'] = hsprintf('%s', $template);
|
||||
if (isset($templates[$card_phid])) {
|
||||
$card['nodeHTMLTemplate'] = hsprintf('%s', $templates[$card_phid]);
|
||||
$card['update'] = true;
|
||||
} else {
|
||||
$card['update'] = false;
|
||||
}
|
||||
|
||||
$card['vectors'] = (object)$card['vectors'];
|
||||
|
@ -156,7 +165,6 @@ final class PhabricatorBoardResponseEngine extends Phobject {
|
|||
}
|
||||
|
||||
$payload = array(
|
||||
'objectPHID' => $object_phid,
|
||||
'columnMaps' => $natural,
|
||||
'cards' => $cards,
|
||||
'headers' => $headers,
|
||||
|
@ -176,22 +184,6 @@ final class PhabricatorBoardResponseEngine extends Phobject {
|
|||
);
|
||||
}
|
||||
|
||||
private function buildTemplate($object) {
|
||||
$viewer = $this->getViewer();
|
||||
$object_phid = $this->getObjectPHID();
|
||||
|
||||
$excluded_phids = $this->loadExcludedProjectPHIDs();
|
||||
|
||||
$rendering_engine = id(new PhabricatorBoardRenderingEngine())
|
||||
->setViewer($viewer)
|
||||
->setObjects(array($object))
|
||||
->setExcludedProjectPHIDs($excluded_phids);
|
||||
|
||||
$card = $rendering_engine->renderCard($object_phid);
|
||||
|
||||
return hsprintf('%s', $card->getItem());
|
||||
}
|
||||
|
||||
private function loadExcludedProjectPHIDs() {
|
||||
$viewer = $this->getViewer();
|
||||
$board_phid = $this->getBoardPHID();
|
||||
|
@ -211,10 +203,67 @@ final class PhabricatorBoardResponseEngine extends Phobject {
|
|||
}
|
||||
|
||||
private function getAllVisiblePHIDs() {
|
||||
$visible_phids = $this->getVisiblePHIDs();
|
||||
$visible_phids[] = $this->getObjectPHID();
|
||||
$visible_phids = array_fuse($visible_phids);
|
||||
return $visible_phids;
|
||||
$phids = $this->getAllUpdatePHIDs();
|
||||
|
||||
foreach ($this->getVisiblePHIDs() as $phid) {
|
||||
$phids[] = $phid;
|
||||
}
|
||||
|
||||
$phids = array_fuse($phids);
|
||||
|
||||
return $phids;
|
||||
}
|
||||
|
||||
private function getAllUpdatePHIDs() {
|
||||
$phids = $this->getUpdatePHIDs();
|
||||
|
||||
$object_phid = $this->getObjectPHID();
|
||||
if ($object_phid) {
|
||||
$phids[] = $object_phid;
|
||||
}
|
||||
|
||||
$phids = array_fuse($phids);
|
||||
|
||||
return $phids;
|
||||
}
|
||||
|
||||
private function newCardTemplates() {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$update_phids = $this->getAllUpdatePHIDs();
|
||||
if (!$update_phids) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$objects = id(new ManiphestTaskQuery())
|
||||
->setViewer($viewer)
|
||||
->withPHIDs($update_phids)
|
||||
->needProjectPHIDs(true)
|
||||
->execute();
|
||||
|
||||
if (!$objects) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$excluded_phids = $this->loadExcludedProjectPHIDs();
|
||||
|
||||
$rendering_engine = id(new PhabricatorBoardRenderingEngine())
|
||||
->setViewer($viewer)
|
||||
->setObjects($objects)
|
||||
->setExcludedProjectPHIDs($excluded_phids);
|
||||
|
||||
$templates = array();
|
||||
foreach ($objects as $object) {
|
||||
$object_phid = $object->getPHID();
|
||||
|
||||
$card = $rendering_engine->renderCard($object_phid);
|
||||
$item = $card->getItem();
|
||||
$template = hsprintf('%s', $item);
|
||||
|
||||
$templates[$object_phid] = $template;
|
||||
}
|
||||
|
||||
return $templates;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -129,6 +129,13 @@ JX.install('WorkboardBoard', {
|
|||
start: function() {
|
||||
this._setupDragHandlers();
|
||||
|
||||
// TODO: This is temporary code to make it easier to debug this workflow
|
||||
// by pressing the "R" key.
|
||||
var on_reload = JX.bind(this, this._reloadCards);
|
||||
new JX.KeyboardShortcut('R', 'Reload Card State (Prototype)')
|
||||
.setHandler(on_reload)
|
||||
.register();
|
||||
|
||||
for (var k in this._columns) {
|
||||
this._columns[k].redraw();
|
||||
}
|
||||
|
@ -551,15 +558,6 @@ JX.install('WorkboardBoard', {
|
|||
},
|
||||
|
||||
_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);
|
||||
|
||||
var sounds = response.sounds || [];
|
||||
|
@ -572,37 +570,51 @@ JX.install('WorkboardBoard', {
|
|||
|
||||
updateCard: function(response) {
|
||||
var columns = this.getColumns();
|
||||
var column_phid;
|
||||
var card_phid;
|
||||
var card_data;
|
||||
|
||||
var phid = response.objectPHID;
|
||||
// The server may send us a full or partial update for a card. If we've
|
||||
// received a full update, we're going to redraw the entire card and may
|
||||
// need to change which columns it appears in.
|
||||
|
||||
for (var add_phid in response.columnMaps) {
|
||||
var target_column = this.getColumn(add_phid);
|
||||
// For a partial update, we've just received supplemental sorting or
|
||||
// property information and do not need to perform a full redraw.
|
||||
|
||||
// When we reload card state, edit a card, or move a card, we get a full
|
||||
// update for the card.
|
||||
|
||||
// Ween we move a card in a column, we may get a partial update for other
|
||||
// visible cards in the column.
|
||||
|
||||
|
||||
// Figure out which columns each card now appears in. For cards that
|
||||
// have received a full update, we'll use this map to move them into
|
||||
// the correct columns.
|
||||
var update_map = {};
|
||||
for (column_phid in response.columnMaps) {
|
||||
var target_column = this.getColumn(column_phid);
|
||||
|
||||
if (!target_column) {
|
||||
// If the column isn't visible, don't try to add a card to it.
|
||||
continue;
|
||||
}
|
||||
|
||||
target_column.newCard(phid);
|
||||
}
|
||||
var column_map = response.columnMaps[column_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;
|
||||
for (var ii = 0; ii < column_map.length; ii++) {
|
||||
card_phid = column_map[ii];
|
||||
if (!update_map[card_phid]) {
|
||||
update_map[card_phid] = {};
|
||||
}
|
||||
update_map[card_phid][column_phid] = true;
|
||||
}
|
||||
|
||||
natural_column.setNaturalOrder(column_maps[natural_phid]);
|
||||
}
|
||||
|
||||
for (var card_phid in response.cards) {
|
||||
var card_data = response.cards[card_phid];
|
||||
// Process partial updates for cards. This is supplemental data which
|
||||
// we can just merge in without any special handling.
|
||||
for (card_phid in response.cards) {
|
||||
card_data = response.cards[card_phid];
|
||||
var card_template = this.getCardTemplate(card_phid);
|
||||
|
||||
if (card_data.nodeHTMLTemplate) {
|
||||
|
@ -623,6 +635,57 @@ JX.install('WorkboardBoard', {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// Process full updates for cards which we have a full update for. This
|
||||
// may involve moving them between columns.
|
||||
for (card_phid in response.cards) {
|
||||
card_data = response.cards[card_phid];
|
||||
|
||||
if (!card_data.update) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (column_phid in columns) {
|
||||
var column = columns[column_phid];
|
||||
var card = column.getCard(card_phid);
|
||||
|
||||
if (card) {
|
||||
card.redraw();
|
||||
column.markForRedraw();
|
||||
}
|
||||
|
||||
// Compare the server state to the client state, and add or remove
|
||||
// cards on the client as necessary to synchronize them.
|
||||
|
||||
if (update_map[card_phid][column_phid]) {
|
||||
if (!card) {
|
||||
column.newCard(card_phid);
|
||||
column.markForRedraw();
|
||||
}
|
||||
} else {
|
||||
if (card) {
|
||||
column.removeCard(card_phid);
|
||||
column.markForRedraw();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 headers = response.headers;
|
||||
for (var jj = 0; jj < headers.length; jj++) {
|
||||
var header = headers[jj];
|
||||
|
@ -634,22 +697,6 @@ JX.install('WorkboardBoard', {
|
|||
.setEditProperties(header.editProperties);
|
||||
}
|
||||
|
||||
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();
|
||||
},
|
||||
|
||||
|
@ -660,6 +707,19 @@ JX.install('WorkboardBoard', {
|
|||
columns[k].redraw();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_reloadCards: function() {
|
||||
var data = {};
|
||||
var on_reload = JX.bind(this, this._onReloadResponse);
|
||||
|
||||
new JX.Request(this.getController().getReloadURI(), on_reload)
|
||||
.setData(data)
|
||||
.send();
|
||||
},
|
||||
|
||||
_onReloadResponse: function(response) {
|
||||
this.updateCard(response);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ JX.install('WorkboardController', {
|
|||
uploadURI: null,
|
||||
coverURI: null,
|
||||
moveURI: null,
|
||||
reloadURI: null,
|
||||
chunkThreshold: null
|
||||
},
|
||||
|
||||
|
|
|
@ -71,6 +71,7 @@ JX.behavior('project-boards', function(config, statics) {
|
|||
.setUploadURI(config.uploadURI)
|
||||
.setCoverURI(config.coverURI)
|
||||
.setMoveURI(config.moveURI)
|
||||
.setReloadURI(config.reloadURI)
|
||||
.setChunkThreshold(config.chunkThreshold)
|
||||
.start();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue