diff --git a/resources/celerity/map.php b/resources/celerity/map.php --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -412,9 +412,9 @@ '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' => '46573d65', + 'rsrc/js/application/projects/WorkboardBoard.js' => '50147a89', 'rsrc/js/application/projects/WorkboardCard.js' => '0392a5d8', - 'rsrc/js/application/projects/WorkboardCardTemplate.js' => '2a61f8d4', + 'rsrc/js/application/projects/WorkboardCardTemplate.js' => '84f82dad', 'rsrc/js/application/projects/WorkboardColumn.js' => 'c3d24e63', 'rsrc/js/application/projects/WorkboardController.js' => 'b9d0c2f3', 'rsrc/js/application/projects/WorkboardDropEffect.js' => '8e0aa661', @@ -743,9 +743,9 @@ 'javelin-view-renderer' => '9aae2b66', 'javelin-view-visitor' => '308f9fe4', 'javelin-websocket' => 'fdc13e4e', - 'javelin-workboard-board' => '46573d65', + 'javelin-workboard-board' => '50147a89', 'javelin-workboard-card' => '0392a5d8', - 'javelin-workboard-card-template' => '2a61f8d4', + 'javelin-workboard-card-template' => '84f82dad', 'javelin-workboard-column' => 'c3d24e63', 'javelin-workboard-controller' => 'b9d0c2f3', 'javelin-workboard-drop-effect' => '8e0aa661', @@ -1133,9 +1133,6 @@ 'javelin-stratcom', 'javelin-behavior', ), - '2a61f8d4' => array( - 'javelin-install', - ), '2a8b62d9' => array( 'multirow-row-manager', 'javelin-install', @@ -1292,18 +1289,6 @@ 'javelin-util', 'phabricator-busy', ), - '46573d65' => 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', - ), '47a0728b' => array( 'javelin-behavior', 'javelin-dom', @@ -1372,6 +1357,18 @@ '4feea7d3' => array( 'trigger-rule-control', ), + '50147a89' => 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', + ), '506aa3f4' => array( 'javelin-behavior', 'javelin-stratcom', @@ -1619,6 +1616,9 @@ 'javelin-resource', 'javelin-routable', ), + '84f82dad' => array( + 'javelin-install', + ), '87428eb2' => array( 'javelin-behavior', 'javelin-diffusion-locate-file-source', diff --git a/src/applications/project/controller/PhabricatorProjectBoardReloadController.php b/src/applications/project/controller/PhabricatorProjectBoardReloadController.php --- a/src/applications/project/controller/PhabricatorProjectBoardReloadController.php +++ b/src/applications/project/controller/PhabricatorProjectBoardReloadController.php @@ -20,13 +20,42 @@ $board_phid = $project->getPHID(); $objects = $state->getObjects(); - $object_phids = mpull($objects, 'getPHID'); + $objects = mpull($objects, null, 'getPHID'); + + try { + $client_state = $request->getStr('state'); + $client_state = phutil_json_decode($client_state); + } catch (PhutilJSONParserException $ex) { + $client_state = array(); + } + + // Figure out which objects need to be updated: either the client has an + // out-of-date version of them (objects which have been edited); or they + // exist on the client but not on the server (objects which have been + // removed from the board); or they exist on the server but not on the + // client (objects which have been added to the board). + + $update_objects = array(); + foreach ($objects as $object_phid => $object) { + + // TODO: For now, this is always hard-coded. + $object_version = 2; + + $client_version = idx($client_state, $object_phid, 0); + if ($object_version > $client_version) { + $update_objects[$object_phid] = $object; + } + } + + $update_phids = array_keys($update_objects); + $visible_phids = array_keys($client_state); $engine = id(new PhabricatorBoardResponseEngine()) ->setViewer($viewer) ->setBoardPHID($board_phid) ->setObjects($objects) - ->setUpdatePHIDs($object_phids); + ->setUpdatePHIDs($update_phids) + ->setVisiblePHIDs($visible_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 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 @@ -734,7 +734,20 @@ }, _reloadCards: function() { - var data = {}; + var state = {}; + + var columns = this.getColumns(); + for (var column_phid in columns) { + var cards = columns[column_phid].getCards(); + for (var card_phid in cards) { + state[card_phid] = this.getCardTemplate(card_phid).getVersion(); + } + } + + var data = { + state: JX.JSON.stringify(state), + }; + var on_reload = JX.bind(this, this._onReloadResponse); new JX.Request(this.getController().getReloadURI(), on_reload) diff --git a/webroot/rsrc/js/application/projects/WorkboardCardTemplate.js b/webroot/rsrc/js/application/projects/WorkboardCardTemplate.js --- a/webroot/rsrc/js/application/projects/WorkboardCardTemplate.js +++ b/webroot/rsrc/js/application/projects/WorkboardCardTemplate.js @@ -28,6 +28,11 @@ return this._phid; }, + getVersion: function() { + // TODO: For now, just return a constant version number. + return 1; + }, + setNodeHTMLTemplate: function(html) { this._html = html; return this;