diff --git a/resources/celerity/map.php b/resources/celerity/map.php --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -412,7 +412,7 @@ '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' => '34c2f539', + 'rsrc/js/application/projects/WorkboardBoard.js' => '46573d65', 'rsrc/js/application/projects/WorkboardCard.js' => '0392a5d8', 'rsrc/js/application/projects/WorkboardCardTemplate.js' => '2a61f8d4', 'rsrc/js/application/projects/WorkboardColumn.js' => 'c3d24e63', @@ -743,7 +743,7 @@ 'javelin-view-renderer' => '9aae2b66', 'javelin-view-visitor' => '308f9fe4', 'javelin-websocket' => 'fdc13e4e', - 'javelin-workboard-board' => '34c2f539', + 'javelin-workboard-board' => '46573d65', 'javelin-workboard-card' => '0392a5d8', 'javelin-workboard-card-template' => '2a61f8d4', 'javelin-workboard-column' => 'c3d24e63', @@ -1202,18 +1202,6 @@ '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', @@ -1304,6 +1292,18 @@ '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', diff --git a/src/applications/maniphest/editor/ManiphestEditEngine.php b/src/applications/maniphest/editor/ManiphestEditEngine.php --- a/src/applications/maniphest/editor/ManiphestEditEngine.php +++ b/src/applications/maniphest/editor/ManiphestEditEngine.php @@ -434,7 +434,7 @@ $engine = id(new PhabricatorBoardResponseEngine()) ->setViewer($viewer) ->setBoardPHID($board_phid) - ->setObjectPHID($object_phid) + ->setUpdatePHIDs(array($object_phid)) ->setVisiblePHIDs($visible_phids); if ($ordering) { 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 @@ -25,6 +25,7 @@ $engine = id(new PhabricatorBoardResponseEngine()) ->setViewer($viewer) ->setBoardPHID($board_phid) + ->setObjects($objects) ->setUpdatePHIDs($object_phids); // TODO: We don't currently process "order" properly. If a user is viewing diff --git a/src/applications/project/controller/PhabricatorProjectController.php b/src/applications/project/controller/PhabricatorProjectController.php --- a/src/applications/project/controller/PhabricatorProjectController.php +++ b/src/applications/project/controller/PhabricatorProjectController.php @@ -184,7 +184,7 @@ $engine = id(new PhabricatorBoardResponseEngine()) ->setViewer($viewer) ->setBoardPHID($board_phid) - ->setObjectPHID($object_phid) + ->setUpdatePHIDs(array($object_phid)) ->setVisiblePHIDs($visible_phids) ->setSounds($sounds); 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 @@ -3,9 +3,9 @@ final class PhabricatorBoardResponseEngine extends Phobject { private $viewer; + private $objects; private $boardPHID; - private $objectPHID; - private $visiblePHIDs; + private $visiblePHIDs = array(); private $updatePHIDs = array(); private $ordering; private $sounds; @@ -28,13 +28,13 @@ return $this->boardPHID; } - public function setObjectPHID($object_phid) { - $this->objectPHID = $object_phid; + public function setObjects(array $objects) { + $this->objects = $objects; return $this; } - public function getObjectPHID() { - return $this->objectPHID; + public function getObjects() { + return $this->objects; } public function setVisiblePHIDs(array $visible_phids) { @@ -75,13 +75,30 @@ public function buildResponse() { $viewer = $this->getViewer(); - $object_phid = $this->getObjectPHID(); $board_phid = $this->getBoardPHID(); $ordering = $this->getOrdering(); + $update_phids = $this->getUpdatePHIDs(); + $update_phids = array_fuse($update_phids); + + $visible_phids = $this->getVisiblePHIDs(); + $visible_phids = array_fuse($visible_phids); + + $all_phids = $update_phids + $visible_phids; + // Load all the other tasks that are visible in the affected columns and // perform layout for them. - $all_phids = $this->getAllVisiblePHIDs(); + + if ($this->objects !== null) { + $all_objects = $this->getObjects(); + $all_objects = mpull($all_objects, null, 'getPHID'); + } else { + $all_objects = id(new ManiphestTaskQuery()) + ->setViewer($viewer) + ->withPHIDs($all_phids) + ->execute(); + $all_objects = mpull($all_objects, null, 'getPHID'); + } $layout_engine = id(new PhabricatorBoardLayoutEngine()) ->setViewer($viewer) @@ -91,7 +108,6 @@ $natural = array(); - $update_phids = $this->getAllUpdatePHIDs(); $update_columns = array(); foreach ($update_phids as $update_phid) { $update_columns += $layout_engine->getObjectColumns( @@ -106,12 +122,6 @@ $natural[$column_phid] = array_values($column_object_phids); } - $all_objects = id(new ManiphestTaskQuery()) - ->setViewer($viewer) - ->withPHIDs($all_phids) - ->execute(); - $all_objects = mpull($all_objects, null, 'getPHID'); - if ($ordering) { $vectors = $ordering->getSortVectorsForObjects($all_objects); $header_keys = $ordering->getHeaderKeysForObjects($all_objects); @@ -164,6 +174,17 @@ $cards[$card_phid] = $card; } + // Mark cards which are currently visible on the client but not visible + // on the board on the server for removal from the client view of the + // board state. + foreach ($visible_phids as $card_phid) { + if (!isset($cards[$card_phid])) { + $cards[$card_phid] = array( + 'remove' => true, + ); + } + } + $payload = array( 'columnMaps' => $natural, 'cards' => $cards, @@ -202,44 +223,26 @@ return array_fuse($exclude_phids); } - private function getAllVisiblePHIDs() { - $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(); + $update_phids = $this->getUpdatePHIDs(); if (!$update_phids) { return array(); } - - $objects = id(new ManiphestTaskQuery()) - ->setViewer($viewer) - ->withPHIDs($update_phids) - ->needProjectPHIDs(true) - ->execute(); + $update_phids = array_fuse($update_phids); + + if ($this->objects === null) { + $objects = id(new ManiphestTaskQuery()) + ->setViewer($viewer) + ->withPHIDs($update_phids) + ->needProjectPHIDs(true) + ->execute(); + } else { + $objects = $this->getObjects(); + $objects = mpull($objects, null, 'getPHID'); + $objects = array_select_keys($objects, $update_phids); + } if (!$objects) { return array(); 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 @@ -611,10 +611,35 @@ } } + // Process card removals. These are cases where the client still sees + // a particular card on a board but it has been removed on the server. + for (card_phid in response.cards) { + card_data = response.cards[card_phid]; + + if (!card_data.remove) { + continue; + } + + for (column_phid in columns) { + var column = columns[column_phid]; + + var card = column.getCard(card_phid); + if (card) { + column.removeCard(card_phid); + column.markForRedraw(); + } + } + } + // 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]; + + if (card_data.remove) { + continue; + } + var card_template = this.getCardTemplate(card_phid); if (card_data.nodeHTMLTemplate) { @@ -635,7 +660,6 @@ } } - // 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) {