Merge pull request #1208 from taigaio/improve-board-load

request tasks and attachments only if the zoom level need it
stable
David Barragán Merino 2017-01-18 14:32:39 +01:00 committed by GitHub
commit ffc6f898a0
13 changed files with 113 additions and 33 deletions

View File

@ -170,9 +170,14 @@ class KanbanUserstoriesService extends taiga.Service
userstories = @.userstoriesRaw userstories = @.userstoriesRaw
userstories = _.map userstories, (usModel) => userstories = _.map userstories, (usModel) =>
us = {} us = {}
model = usModel.getAttrs()
us.foldStatusChanged = @.foldStatusChanged[usModel.id] us.foldStatusChanged = @.foldStatusChanged[usModel.id]
us.model = usModel.getAttrs()
us.images = _.filter usModel.attachments, (it) -> return !!it.thumbnail_card_url us.model = model
us.images = _.filter model.attachments, (it) -> return !!it.thumbnail_card_url
us.id = usModel.id us.id = usModel.id
us.assigned_to = @.usersById[usModel.assigned_to] us.assigned_to = @.usersById[usModel.assigned_to]
us.colorized_tags = _.map us.model.tags, (tag) => us.colorized_tags = _.map us.model.tags, (tag) =>

View File

@ -77,6 +77,10 @@ class KanbanController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
@scope.sectionName = @translate.instant("KANBAN.SECTION_NAME") @scope.sectionName = @translate.instant("KANBAN.SECTION_NAME")
@.initializeEventHandlers() @.initializeEventHandlers()
taiga.defineImmutableProperty @.scope, "usByStatus", () =>
return @kanbanUserstoriesService.usByStatus
firstLoad: () ->
promise = @.loadInitialData() promise = @.loadInitialData()
# On Success # On Success
@ -91,16 +95,29 @@ class KanbanController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
# On Error # On Error
promise.then null, @.onInitialDataError.bind(@) promise.then null, @.onInitialDataError.bind(@)
taiga.defineImmutableProperty @.scope, "usByStatus", () =>
return @kanbanUserstoriesService.usByStatus
setZoom: (zoomLevel, zoom) -> setZoom: (zoomLevel, zoom) ->
if @.zoomLevel != zoomLevel if @.zoomLevel == zoomLevel
@kanbanUserstoriesService.resetFolds() return null
@.isFirstLoad = !@.zoomLevel
previousZoomLevel = @.zoomLevel
@.zoomLevel = zoomLevel @.zoomLevel = zoomLevel
@.zoom = zoom @.zoom = zoom
if @.isFirstLoad
@.firstLoad().then () =>
@.isFirstLoad = false
@kanbanUserstoriesService.resetFolds()
else if @.zoomLevel > 1 && previousZoomLevel <= 1
@.zoomLoading = true
@.loadUserstories().then () =>
@.zoomLoading = false
@kanbanUserstoriesService.resetFolds()
filtersReloadContent: () -> filtersReloadContent: () ->
@.loadUserstories().then () => @.loadUserstories().then () =>
openArchived = _.difference(@kanbanUserstoriesService.archivedStatus, openArchived = _.difference(@kanbanUserstoriesService.archivedStatus,
@ -182,13 +199,15 @@ class KanbanController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
return @rs.projects.tagsColors(@scope.projectId).then (tags_colors) => return @rs.projects.tagsColors(@scope.projectId).then (tags_colors) =>
@scope.project.tags_colors = tags_colors._attrs @scope.project.tags_colors = tags_colors._attrs
loadUserstories: -> loadUserstories: () ->
params = { params = {
status__is_archived: false, status__is_archived: false
include_attachments: true,
include_tasks: true
} }
if @.zoomLevel > 1
params.include_attachments = 1
params.include_tasks = 1
params = _.merge params, @location.search() params = _.merge params, @location.search()
promise = @rs.userstories.listAll(@scope.projectId, params).then (userstories) => promise = @rs.userstories.listAll(@scope.projectId, params).then (userstories) =>
@ -423,14 +442,19 @@ KanbanSquishColumnDirective = (rs, projectService) ->
return 40 return 40
else else
return 310 return 310
totalWidth = _.reduce columnWidths, (total, width) -> totalWidth = _.reduce columnWidths, (total, width) ->
return total + width return total + width
$el.find('.kanban-table-inner').css("width", totalWidth) $el.find('.kanban-table-inner').css("width", totalWidth)
unwatch = $scope.$watch 'usByStatus', (usByStatus) ->
if usByStatus.size
$scope.folds = rs.kanban.getStatusColumnModes(projectService.project.get('id')) $scope.folds = rs.kanban.getStatusColumnModes(projectService.project.get('id'))
updateTableWidth() updateTableWidth()
unwatch()
return {link: link} return {link: link}
module.directive("tgKanbanSquishColumn", ["$tgResources", "tgProjectService", KanbanSquishColumnDirective]) module.directive("tgKanbanSquishColumn", ["$tgResources", "tgProjectService", KanbanSquishColumnDirective])

View File

@ -33,9 +33,12 @@ resourceProvider = ($repo, $http, $urls, $storage) ->
hashSuffixStatusColumnModes = "tasks-statuscolumnmodels" hashSuffixStatusColumnModes = "tasks-statuscolumnmodels"
hashSuffixUsRowModes = "tasks-usrowmodels" hashSuffixUsRowModes = "tasks-usrowmodels"
service.get = (projectId, taskId) -> service.get = (projectId, taskId, extraParams) ->
params = service.getQueryParams(projectId) params = service.getQueryParams(projectId)
params.project = projectId params.project = projectId
params = _.extend({}, params, extraParams)
return $repo.queryOne("tasks", taskId, params) return $repo.queryOne("tasks", taskId, params)
service.getByRef = (projectId, ref, extraParams) -> service.getByRef = (projectId, ref, extraParams) ->

View File

@ -30,9 +30,12 @@ resourceProvider = ($repo, $http, $urls, $storage, $q) ->
service = {} service = {}
hashSuffix = "userstories-queryparams" hashSuffix = "userstories-queryparams"
service.get = (projectId, usId) -> service.get = (projectId, usId, extraParams) ->
params = service.getQueryParams(projectId) params = service.getQueryParams(projectId)
params.project = projectId params.project = projectId
params = _.extend({}, params, extraParams)
return $repo.queryOne("userstories", usId, params) return $repo.queryOne("userstories", usId, params)
service.getByRef = (projectId, ref, extraParams = {}) -> service.getByRef = (projectId, ref, extraParams = {}) ->
@ -64,6 +67,7 @@ resourceProvider = ($repo, $http, $urls, $storage, $q) ->
params = {"project": projectId} params = {"project": projectId}
params = _.extend({}, params, filters or {}) params = _.extend({}, params, filters or {})
service.storeQueryParams(projectId, params) service.storeQueryParams(projectId, params)
return $repo.queryMany("userstories", params) return $repo.queryMany("userstories", params)
service.bulkCreate = (projectId, status, bulk) -> service.bulkCreate = (projectId, status, bulk) ->

View File

@ -72,6 +72,10 @@ class TaskboardController extends mixOf(taiga.Controller, taiga.PageMixin, taiga
@scope.sectionName = @translate.instant("TASKBOARD.SECTION_NAME") @scope.sectionName = @translate.instant("TASKBOARD.SECTION_NAME")
@.initializeEventHandlers() @.initializeEventHandlers()
taiga.defineImmutableProperty @.scope, "usTasks", () =>
return @taskboardTasksService.usTasks
firstLoad: () ->
promise = @.loadInitialData() promise = @.loadInitialData()
# On Success # On Success
@ -79,16 +83,28 @@ class TaskboardController extends mixOf(taiga.Controller, taiga.PageMixin, taiga
# On Error # On Error
promise.then null, @.onInitialDataError.bind(@) promise.then null, @.onInitialDataError.bind(@)
taiga.defineImmutableProperty @.scope, "usTasks", () =>
return @taskboardTasksService.usTasks
setZoom: (zoomLevel, zoom) -> setZoom: (zoomLevel, zoom) ->
if @.zoomLevel != zoomLevel if @.zoomLevel == zoomLevel
@taskboardTasksService.resetFolds() return null
@.isFirstLoad = !@.zoomLevel
previousZoomLevel = @.zoomLevel
@.zoomLevel = zoomLevel @.zoomLevel = zoomLevel
@.zoom = zoom @.zoom = zoom
if @.isFirstLoad
@.firstLoad().then () =>
@.isFirstLoad = false
@taskboardTasksService.resetFolds()
else if @.zoomLevel > 1 && previousZoomLevel <= 1
@.zoomLoading = true
@.loadTasks().then () =>
@.zoomLoading = false
@taskboardTasksService.resetFolds()
if @.zoomLevel == '0' if @.zoomLevel == '0'
@rootscope.$broadcast("sprint:zoom0") @rootscope.$broadcast("sprint:zoom0")
@ -342,9 +358,10 @@ class TaskboardController extends mixOf(taiga.Controller, taiga.PageMixin, taiga
return sprint return sprint
loadTasks: -> loadTasks: ->
params = { params = {}
include_attachments: true,
} if @.zoomLevel > 1
params.include_attachments = 1
params = _.merge params, @location.search() params = _.merge params, @location.search()

View File

@ -157,9 +157,12 @@ class TaskboardTasksService extends taiga.Service
for taskModel in tasks for taskModel in tasks
if usTasks[taskModel.user_story]? and usTasks[taskModel.user_story][taskModel.status]? if usTasks[taskModel.user_story]? and usTasks[taskModel.user_story][taskModel.status]?
task = {} task = {}
model = taskModel.getAttrs()
task.foldStatusChanged = @.foldStatusChanged[taskModel.id] task.foldStatusChanged = @.foldStatusChanged[taskModel.id]
task.model = taskModel.getAttrs() task.model = model
task.images = _.filter taskModel.attachments, (it) -> return !!it.thumbnail_card_url task.images = _.filter model.attachments, (it) -> return !!it.thumbnail_card_url
task.id = taskModel.id task.id = taskModel.id
task.assigned_to = @.usersById[taskModel.assigned_to] task.assigned_to = @.usersById[taskModel.assigned_to]
task.colorized_tags = _.map task.model.tags, (tag) => task.colorized_tags = _.map task.model.tags, (tag) =>

View File

@ -36,6 +36,7 @@ $contrast: 2;
.range-slider { .range-slider {
-webkit-appearance: none; -webkit-appearance: none;
display: block;
margin: $thumb-height / 2 0; margin: $thumb-height / 2 0;
width: $track-width; width: $track-width;

View File

@ -1,6 +1,11 @@
.card-unfold.ng-animate-disabled( .card-unfold.ng-animate-disabled(
ng-click="vm.toggleFold()" ng-click="vm.toggleFold()"
ng-if="vm.visible('unfold') && (vm.item.getIn(['model', 'tasks']).size || vm.item.get('images').size)" ng-if="vm.visible('unfold')"
role="button" role="button"
) )
tg-svg(svg-icon="icon-view-more") tg-svg(svg-icon="icon-view-more")
.loading-extra(
tg-loading="vm.item.get('loading-extra')"
)

View File

@ -5,6 +5,10 @@
margin: 0 .6rem .6rem; margin: 0 .6rem .6rem;
overflow: hidden; overflow: hidden;
transition: box-shadow .2s ease-in; transition: box-shadow .2s ease-in;
.loading-extra.loading {
padding: .2rem;
text-align: center;
}
&:hover { &:hover {
box-shadow: 3px 3px 6px darken($whitish, 10%); box-shadow: 3px 3px 6px darken($whitish, 10%);
} }

View File

@ -1,7 +1,10 @@
doctype html doctype html
div.wrapper(tg-kanban, ng-controller="KanbanController as ctrl" div.wrapper(
ng-init="section='kanban'") tg-kanban,
ng-controller="KanbanController as ctrl"
ng-init="section='kanban'"
)
tg-project-menu tg-project-menu
section.main.kanban section.main.kanban
@ -23,8 +26,8 @@ div.wrapper(tg-kanban, ng-controller="KanbanController as ctrl"
.kanban-header .kanban-header
include ../includes/components/mainTitle include ../includes/components/mainTitle
.taskboard-actions .taskboard-actions
.zoom-loading(tg-loading="ctrl.zoomLoading")
tg-kanban-board-zoom( tg-kanban-board-zoom(
ng-if="usByStatus.size",
on-zoom-change="ctrl.setZoom(zoomLevel, zoom)" on-zoom-change="ctrl.setZoom(zoomLevel, zoom)"
) )

View File

@ -1,7 +1,10 @@
doctype html doctype html
div.wrapper(tg-taskboard, ng-controller="TaskboardController as ctrl", div.wrapper(
ng-init="section='backlog'") tg-taskboard,
ng-controller="TaskboardController as ctrl",
ng-init="section='backlog'"
)
tg-project-menu tg-project-menu
section.main.taskboard section.main.taskboard
tg-filter( tg-filter(
@ -24,8 +27,8 @@ div.wrapper(tg-taskboard, ng-controller="TaskboardController as ctrl",
span.green(tg-bo-bind="sprint.name") span.green(tg-bo-bind="sprint.name")
span.date(tg-date-range="sprint.estimated_start,sprint.estimated_finish") span.date(tg-date-range="sprint.estimated_start,sprint.estimated_finish")
.taskboard-actions .taskboard-actions
.zoom-loading(tg-loading="ctrl.zoomLoading")
tg-taskboard-zoom( tg-taskboard-zoom(
ng-if="usTasks.size",
on-zoom-change="ctrl.setZoom(zoomLevel, zoom)" on-zoom-change="ctrl.setZoom(zoomLevel, zoom)"
) )
button.button-filter.e2e-open-filter( button.button-filter.e2e-open-filter(

View File

@ -14,6 +14,10 @@
.burndown-container { .burndown-container {
display: none; display: none;
} }
.zoom-loading img {
display: block;
margin-right: 1rem;
}
} }
.kanban-header { .kanban-header {

View File

@ -10,6 +10,10 @@
.graphics-container { .graphics-container {
@include slide(300px, hidden); @include slide(300px, hidden);
} }
.zoom-loading img {
display: block;
margin-right: 1rem;
}
} }
.taskboard-header { .taskboard-header {