Remember scroll offset of lanes when refreshing board view
When the board object in the board detail view is reloaded (which is quite a regular occurrence to help prevent stale data being used), the scroll position of lanes is lost. This is a minor inconvenience for small boards with only a few cards and a short distance to scroll, but is frustrating for large boards with many cards per lane, since it can be hard to find the old scroll location. The issue is compounded by long load times of large boards making it seem like the lane scrollbars reset with no apparent reason. This commit solves this issue by adding support to remember the scroll position of each lane when updating the board object, and re-scrolling the newly rendered lanes to the correct position. Change-Id: I75a6703b2f43bed8cdc4643f6a103f95e1fa61ae
This commit is contained in:
parent
884ca37c39
commit
1c048042ed
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2016 Codethink Limited
|
||||
* Copyright (c) 2019 Adam Coldrick
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License. You may obtain
|
||||
@ -22,6 +23,8 @@ angular.module('sb.board').controller('BoardDetailController',
|
||||
BoardHelper, DueDate, $document, User, $q, moment) {
|
||||
'use strict';
|
||||
|
||||
$scope.board = new Board();
|
||||
|
||||
/**
|
||||
* Load the board. If onlyContents is true then assume $scope.board
|
||||
* is a board and reload its contents.
|
||||
@ -35,6 +38,7 @@ angular.module('sb.board').controller('BoardDetailController',
|
||||
};
|
||||
});
|
||||
Board.get(params, function(board) {
|
||||
var offsets = BoardHelper.recordLaneScrollbars($scope.board);
|
||||
$scope.board = board;
|
||||
$scope.owners = [];
|
||||
$scope.users = [];
|
||||
@ -44,6 +48,7 @@ angular.module('sb.board').controller('BoardDetailController',
|
||||
angular.forEach(board.users, function(id) {
|
||||
$scope.users.push(User.get({id: id}));
|
||||
});
|
||||
BoardHelper.scrollLanes(board, offsets);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
* A service to help with use of a kanban board.
|
||||
*/
|
||||
angular.module('sb.board').factory('BoardHelper',
|
||||
function($document, $window, Worklist) {
|
||||
function($document, $window, $timeout, Worklist) {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
@ -73,9 +73,47 @@ angular.module('sb.board').factory('BoardHelper',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to record scrollbar positions for the lanes of a board.
|
||||
*
|
||||
* This is used to track where a user has scrolled each lane to before
|
||||
* refreshing the board UI. It returns a mapping of lane IDs to scroll
|
||||
* offsets which can later be used to re-scroll to the correct point.
|
||||
*/
|
||||
function recordLaneScrollbars(board) {
|
||||
var scrollbars = {};
|
||||
angular.forEach(board.lanes, function(lane) {
|
||||
var elem = $document[0].getElementById('lane-' + lane.id);
|
||||
if (!!elem) {
|
||||
scrollbars[lane.id] = elem.scrollTop;
|
||||
}
|
||||
});
|
||||
return scrollbars;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to scroll lanes to a previously recorded position.
|
||||
*
|
||||
* Takes a board and a mapping of lane IDs to scroll offsets as
|
||||
* produced by `recordLaneScrollbars` and scrolls the corresponding
|
||||
* lane containers by the given offsets.
|
||||
*/
|
||||
function scrollLanes(board, scrollbars) {
|
||||
angular.forEach(board.lanes, function(lane) {
|
||||
$timeout(function() {
|
||||
var elem = $document[0].getElementById('lane-' + lane.id);
|
||||
if (!!elem) {
|
||||
elem.scrollTop = scrollbars[lane.id];
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
maybeScrollContainer: scrollFunction,
|
||||
moveCard: moveCard
|
||||
moveCard: moveCard,
|
||||
recordLaneScrollbars: recordLaneScrollbars,
|
||||
scrollLanes: scrollLanes
|
||||
};
|
||||
}
|
||||
);
|
||||
|
@ -15,7 +15,8 @@
|
||||
-->
|
||||
<div as-sortable="cardsSortable"
|
||||
ng-model="lane.worklist.items"
|
||||
class="kanban-lane-contents">
|
||||
class="kanban-lane-contents"
|
||||
id="lane-{{ lane.id }}">
|
||||
<div class="kanban-card"
|
||||
ng-class="{'kanban-card-due': isDue(item), 'kanban-card-late': isLate(item)}"
|
||||
as-sortable-item
|
||||
|
@ -13,7 +13,8 @@
|
||||
~ License for the specific language governing permissions and limitations
|
||||
~ under the License.
|
||||
-->
|
||||
<div class="kanban-lane-contents-readonly">
|
||||
<div class="kanban-lane-contents-readonly"
|
||||
id="lane-{{ lane.id }}">
|
||||
<div class="kanban-card-readonly"
|
||||
ng-class="{'kanban-card-due': isDue(item), 'kanban-card-late': isLate(item)}"
|
||||
ng-repeat="item in lane.worklist.items"
|
||||
|
Loading…
x
Reference in New Issue
Block a user