Merge pull request #572 from taigaio/Issues/2648/fix-tag-filtering

same behavior for issues filters and backlog filters
stable
Alejandro 2015-07-28 08:58:47 +02:00
commit e86caf338f
11 changed files with 192 additions and 160 deletions

View File

@ -35,11 +35,13 @@ module = angular.module("taigaBacklog")
## Issues Filters Directive
#############################################################################
BacklogFiltersDirective = ($log, $location, $templates) ->
BacklogFiltersDirective = ($q, $log, $location, $templates) ->
template = $templates.get("backlog/filters.html", true)
templateSelected = $templates.get("backlog/filter-selected.html", true)
link = ($scope, $el, $attrs) ->
currentFiltersType = ''
$ctrl = $el.closest(".wrapper").controller()
selectedFilters = []
@ -50,16 +52,18 @@ BacklogFiltersDirective = ($log, $location, $templates) ->
$el.find("h2 a.subfilter span.title").html(title)
$el.find("h2 a.subfilter span.title").prop("data-type", type)
currentFiltersType = getFiltersType()
showCategories = ->
$el.find(".filters-cats").show()
$el.find(".filter-list").addClass("hidden")
$el.find("h2.breadcrumb").addClass("hidden")
initializeSelectedFilters = (filters) ->
initializeSelectedFilters = () ->
showCategories()
selectedFilters = []
for name, values of filters
for name, values of $scope.filters
for val in values
selectedFilters.push(val) if val.selected
@ -81,43 +85,62 @@ BacklogFiltersDirective = ($log, $location, $templates) ->
html = template({filters:filters})
$el.find(".filter-list").html(html)
getFiltersType = () ->
return $el.find("h2 a.subfilter span.title").prop('data-type')
reloadUserstories = () ->
currentFiltersType = getFiltersType()
$q.all([$ctrl.loadUserstories(), $ctrl.generateFilters()]).then () ->
currentFilters = $scope.filters[currentFiltersType]
renderFilters(_.reject(currentFilters, "selected"))
toggleFilterSelection = (type, id) ->
currentFiltersType = getFiltersType()
filters = $scope.filters[type]
filter = _.find(filters, {id: taiga.toString(id)})
filter = _.find(filters, {id: id})
filter.selected = (not filter.selected)
if filter.selected
selectedFilters.push(filter)
$scope.$apply ->
$ctrl.selectFilter(type, id)
else
selectedFilters = _.reject(selectedFilters, filter)
$scope.$apply ->
$ctrl.unselectFilter(type, id)
selectedFilters = _.reject selectedFilters, (selected) ->
return filter.type == selected.type && filter.id == selected.id
$ctrl.unselectFilter(type, id)
renderSelectedFilters(selectedFilters)
currentFiltersType = $el.find("h2 a.subfilter span.title").prop('data-type')
if type == currentFiltersType
renderFilters(_.reject(filters, "selected"))
$ctrl.loadUserstories()
reloadUserstories()
selectQFilter = debounceLeading 100, (value) ->
return if value is undefined
if value.length == 0
$ctrl.replaceFilter("q", null)
else
$ctrl.replaceFilter("q", value)
$ctrl.loadUserstories()
reloadUserstories()
$scope.$watch("filtersQ", selectQFilter)
## Angular Watchers
$scope.$on "filters:loaded", (ctx, filters) ->
initializeSelectedFilters(filters)
$scope.$on "backlog:loaded", (ctx) ->
initializeSelectedFilters()
$scope.$on "filters:update", (ctx, filters) ->
renderFilters(filters)
$scope.$on "filters:update", (ctx) ->
$ctrl.generateFilters().then () ->
filters = $scope.filters[currentFiltersType]
if currentFiltersType
renderFilters(_.reject(filters, "selected"))
## Dom Event Handlers
$el.on "click", ".filters-cats > ul > li > a", (event) ->
@ -126,7 +149,7 @@ BacklogFiltersDirective = ($log, $location, $templates) ->
tags = $scope.filters[target.data("type")]
renderFilters(_.reject(tags, "selected"))
showFilters(target.attr("title"), target.data("type"))
showFilters(target.attr("title"), target.data('type'))
$el.on "click", ".filters-inner > .filters-step-cat > .breadcrumb > .back", (event) ->
event.preventDefault()
@ -153,4 +176,4 @@ BacklogFiltersDirective = ($log, $location, $templates) ->
return {link:link}
module.directive("tgBacklogFilters", ["$log", "$tgLocation", "$tgTemplate", BacklogFiltersDirective])
module.directive("tgBacklogFilters", ["$q", "$log", "$tgLocation", "$tgTemplate", BacklogFiltersDirective])

View File

@ -96,6 +96,8 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F
@scope.$on "usform:new:success", =>
@.loadUserstories()
@.loadProjectStats()
@rootscope.$broadcast("filters:update")
@analytics.trackEvent("userstory", "create", "create userstory on backlog", 1)
@scope.$on "sprintform:edit:success", =>
@ -105,9 +107,11 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F
@.loadSprints()
@.loadProjectStats()
@.loadUserstories()
@rootscope.$broadcast("filters:update")
@scope.$on "usform:edit:success", =>
@.loadUserstories()
@rootscope.$broadcast("filters:update")
@scope.$on("sprint:us:move", @.moveUs)
@scope.$on("sprint:us:moved", @.loadSprints)
@ -145,10 +149,6 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F
return stats
refreshTagsColors: ->
return @rs.projects.tagsColors(@scope.projectId).then (tags_colors) =>
@scope.project.tags_colors = tags_colors
unloadClosedSprints: ->
@scope.$apply =>
@scope.closedSprints = []
@ -182,7 +182,7 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F
resetFilters: ->
selectedTags = _.filter(@scope.filters.tags, "selected")
selectedStatuses = _.filter(@scope.filters.statuses, "selected")
selectedStatuses = _.filter(@scope.filters.status, "selected")
@scope.filtersQ = ""
@ -195,23 +195,20 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F
@.unselectFilter(item.type, item.id)
@.loadUserstories()
@rootscope.$broadcast("filters:update")
loadUserstories: ->
@scope.httpParams = @.getUrlFilters()
@rs.userstories.storeQueryParams(@scope.projectId, @scope.httpParams)
promise = @q.all([@.refreshTagsColors(), @rs.userstories.listUnassigned(@scope.projectId, @scope.httpParams)])
promise = @rs.userstories.listUnassigned(@scope.projectId, @scope.httpParams)
return promise.then (data) =>
userstories = data[1]
return promise.then (userstories) =>
# NOTE: Fix order of USs because the filter orderBy does not work propertly in the partials files
@scope.userstories = _.sortBy(userstories, "backlog_order")
@.setSearchDataFilters()
@.filterVisibleUserstories()
@.generateFilters()
@rootscope.$broadcast("filters:loaded", @scope.filters)
# The broadcast must be executed when the DOM has been fully reloaded.
# We can't assure when this exactly happens so we need a defer
scopeDefer @scope, =>
@ -247,22 +244,10 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F
@.fillUsersAndRoles(project.members, project.roles)
@.initializeSubscription()
return promise.then(=> @.loadBacklog())
filterVisibleUserstories: ->
@scope.visibleUserstories = []
# Filter by tags
@scope.visibleUserstories = _.reject @scope.userstories, (us) =>
return _.some us.tags, (tag) =>
return @isFilterSelected("tag", tag)
# Filter by status
@scope.visibleUserstories = _.filter @scope.visibleUserstories, (us) =>
if @searchdata["statuses"] && Object.keys(@searchdata["statuses"]).length
return @isFilterSelected("statuses", taiga.toString(us.status))
return true
return promise
.then(=> @.loadBacklog())
.then(=> @.generateFilters())
.then(=> @scope.$emit("backlog:loaded"))
prepareBulkUpdateData: (uses, field="backlog_order") ->
return _.map(uses, (x) -> {"us_id": x.id, "order": x[field]})
@ -333,13 +318,8 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F
@scope.$apply =>
# Add new us to backlog userstories list
# @scope.userstories.splice(newUsIndex, 0, us)
# @scope.visibleUserstories.splice(newUsIndex, 0, us)
args = [newUsIndex, 0].concat(usList)
Array.prototype.splice.apply(@scope.userstories, args)
Array.prototype.splice.apply(@scope.visibleUserstories, args)
# Execute the prefiltering of user stories
@.filterVisibleUserstories()
# Remove the us from the sprint list.
sprint = @scope.sprintsById[oldSprintId]
@ -376,8 +356,8 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F
# Remove moving us from backlog userstories lists.
for us, key in usList
r = @scope.visibleUserstories.indexOf(us)
@scope.visibleUserstories.splice(r, 1)
r = @scope.userstories.indexOf(us)
@scope.userstories.splice(r, 1)
r = @scope.userstories.indexOf(us)
@scope.userstories.splice(r, 1)
@ -439,74 +419,77 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F
@searchdata[name][val] = true
getUrlFilters: ->
return _.pick(@location.search(), "statuses", "tags", "q")
return _.pick(@location.search(), "status", "tags", "q")
generateFilters: ->
urlfilters = @.getUrlFilters()
@scope.filters = {}
@scope.filters = {}
#tags
plainTags = _.flatten(_.filter(_.map(@scope.visibleUserstories, "tags")))
plainTags.sort()
loadFilters = {}
loadFilters.project = @scope.projectId
loadFilters.tags = urlfilters.tags
loadFilters.status = urlfilters.status
loadFilters.q = urlfilters.q
loadFilters.milestone = 'null'
if plainTags.length == 0 and urlfilters["tags"]
plainTags.push(urlfilters["tags"])
return @rs.userstories.filtersData(loadFilters).then (data) =>
choicesFiltersFormat = (choices, type, byIdObject) =>
_.map choices, (t) ->
t.type = type
return t
@scope.filters.tags = _.map _.countBy(plainTags), (v, k) =>
obj = {
id: k,
type: "tags",
name: k,
color: @scope.project.tags_colors[k],
count: v
}
obj.selected = true if @isFilterSelected("tags", obj.id)
return obj
tagsFilterFormat = (tags) =>
return _.map tags, (t) ->
t.id = t.name
t.type = 'tags'
return t
selectedTags = _.filter(@scope.filters.tags, "selected")
selectedTags = _.map(selectedTags, "name")
# Build filters data structure
@scope.filters.status = choicesFiltersFormat(data.statuses, "status", @scope.usStatusById)
@scope.filters.tags = tagsFilterFormat(data.tags)
#status
plainStatuses = _.map(@scope.visibleUserstories, "status")
selectedTags = _.filter(@scope.filters.tags, "selected")
selectedTags = _.map(selectedTags, "id")
plainStatuses = _.filter plainStatuses, (status) =>
if status
return status
selectedStatuses = _.filter(@scope.filters.status, "selected")
selectedStatuses = _.map(selectedStatuses, "id")
if plainStatuses.length == 0 and urlfilters["statuses"]
plainStatuses.push(urlfilters["statuses"])
@.markSelectedFilters(@scope.filters, urlfilters)
@scope.filters.statuses = _.map _.countBy(plainStatuses), (v, k) =>
obj = {
id: k,
type: "statuses",
name: @scope.usStatusById[k].name,
color: @scope.usStatusById[k].color,
count:v
}
obj.selected = true if @isFilterSelected("statuses", obj.id)
#store query params
@rs.userstories.storeQueryParams(@scope.projectId, {
"status": selectedStatuses,
"tags": selectedTags,
"project": @scope.projectId
"milestone": null
})
return obj
markSelectedFilters: (filters, urlfilters) ->
# Build selected filters (from url) fast lookup data structure
searchdata = {}
for name, value of _.omit(urlfilters, "page", "orderBy")
if not searchdata[name]?
searchdata[name] = {}
selectedStatuses = _.filter(@scope.filters.statuses, "selected")
selectedStatuses = _.map(selectedStatuses, "id")
for val in "#{value}".split(",")
searchdata[name][val] = true
#store query params
@rs.userstories.storeQueryParams(@scope.projectId, {
"status": selectedStatuses,
"tags": selectedTags,
"project": @scope.projectId
"milestone": null
})
isSelected = (type, id) ->
if searchdata[type]? and searchdata[type][id]
return true
return false
for key, value of filters
for obj in value
obj.selected = if isSelected(obj.type, obj.id) then true else undefined
## Template actions
updateUserStoryStatus: () ->
@.setSearchDataFilters()
@.filterVisibleUserstories()
@.generateFilters()
@rootscope.$broadcast("filters:update", @scope.filters['statuses'])
@.loadProjectStats()
@.generateFilters().then () ->
@rootscope.$broadcast("filters:update")
@.loadProjectStats()
editUserStory: (us) ->
@rootscope.$broadcast("usform:edit", us)
@ -519,7 +502,6 @@ class BacklogController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.F
@confirm.askOnDelete(title, message).then (finish) =>
# We modify the userstories in scope so the user doesn't see the removed US for a while
@scope.userstories = _.without(@scope.userstories, us)
@filterVisibleUserstories()
promise = @.repo.remove(us)
promise.then =>
finish()
@ -560,9 +542,9 @@ BacklogDirective = ($repo, $rootscope, $translate) ->
total_points = stats.total_points
current_sum = stats.assigned_points
return if not $scope.visibleUserstories
return if not $scope.userstories
for us, i in $scope.visibleUserstories
for us, i in $scope.userstories
current_sum += us.total_points
if current_sum > total_points
@ -603,7 +585,6 @@ BacklogDirective = ($repo, $rootscope, $translate) ->
# Update the total of points
$scope.sprints[0].total_points += totalExtraPoints
$ctrl.filterVisibleUserstories()
$repo.saveAll(selectedUss).then ->
$ctrl.loadSprints()
$ctrl.loadProjectStats()
@ -725,7 +706,7 @@ BacklogDirective = ($repo, $rootscope, $translate) ->
$el.find(".backlog-table-body").disableSelection()
filters = $ctrl.getUrlFilters()
if filters.statuses ||
if filters.status ||
filters.tags ||
filters.q
showHideFilter($scope, $el, $ctrl)

View File

@ -83,8 +83,6 @@ class IssuesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
@scope.$on "issueform:new:success", =>
@analytics.trackEvent("issue", "create", "create issue on issues list", 1)
@.loadIssues()
@.loadFilters()
initializeSubscription: ->
routingKey = "changes.project.#{@scope.projectId}.issues"
@ -115,9 +113,10 @@ class IssuesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
return project
getUrlFilters: ->
filters = _.pick(@location.search(), "page", "tags", "statuses", "types",
filters = _.pick(@location.search(), "page", "tags", "status", "types",
"q", "severities", "priorities",
"assignedTo", "createdBy", "orderBy")
filters.page = 1 if not filters.page
return filters
@ -180,20 +179,30 @@ class IssuesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
@scope.filters.myFilters = myFilters
return myFilters
loadFilters = {}
loadFilters.project = @scope.projectId
loadFilters.tags = urlfilters.tags
loadFilters.status = urlfilters.status
loadFilters.q = urlfilters.q
loadFilters.types = urlfilters.types
loadFilters.severities = urlfilters.severities
loadFilters.priorities = urlfilters.priorities
loadFilters.assigned_to = urlfilters.assignedTo
loadFilters.owner = urlfilters.createdBy
# Load default filters data
promise = promise.then =>
return @rs.issues.filtersData(@scope.projectId)
return @rs.issues.filtersData(loadFilters)
# Format filters and set them on scope
return promise.then (data) =>
usersFiltersFormat = (users, type, unknownOption) =>
reformatedUsers = _.map users, (t) =>
return {
id: t[0],
count: t[1],
type: type
name: if t[0] then @scope.usersById[t[0]].full_name_display else unknownOption
}
t.type = type
t.name = if t.full_name then t.full_name else unknownOption
return t
unknownItem = _.remove(reformatedUsers, (u) -> not u.id)
reformatedUsers = _.sortBy(reformatedUsers, (u) -> u.name.toUpperCase())
if unknownItem.length > 0
@ -202,34 +211,27 @@ class IssuesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
choicesFiltersFormat = (choices, type, byIdObject) =>
_.map choices, (t) ->
return {
id: t[0],
name: byIdObject[t[0]].name,
color: byIdObject[t[0]].color,
count: t[1],
type: type}
t.type = type
return t
tagsFilterFormat = (tags) =>
return _.map tags, (t) =>
return {
id: t[0],
name: t[0],
color: @scope.project.tags_colors[t[0]],
count: t[1],
type: "tags"
}
return _.map tags, (t) ->
t.id = t.name
t.type = 'tags'
return t
# Build filters data structure
@scope.filters.statuses = choicesFiltersFormat(data.statuses, "statuses", @scope.issueStatusById)
@scope.filters.status = choicesFiltersFormat(data.statuses, "status", @scope.issueStatusById)
@scope.filters.severities = choicesFiltersFormat(data.severities, "severities", @scope.severityById)
@scope.filters.priorities = choicesFiltersFormat(data.priorities, "priorities", @scope.priorityById)
@scope.filters.assignedTo = usersFiltersFormat(data.assigned_to, "assignedTo", "Unassigned")
@scope.filters.createdBy = usersFiltersFormat(data.created_by, "createdBy", "Unknown")
@scope.filters.createdBy = usersFiltersFormat(data.owners, "createdBy", "Unknown")
@scope.filters.types = choicesFiltersFormat(data.types, "types", @scope.issueTypeById)
@scope.filters.tags = tagsFilterFormat(data.tags)
@.removeNotExistingFiltersFromUrl()
@.markSelectedFilters(@scope.filters, urlfilters)
@rootscope.$broadcast("filters:loaded", @scope.filters)
# We need to guarantee that the last petition done here is the finally used
@ -257,7 +259,7 @@ class IssuesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
name = "assigned_to"
else if name == "createdBy"
name = "owner"
else if name == "statuses"
else if name == "status"
name = "status"
else if name == "types"
name = "type"
@ -272,14 +274,19 @@ class IssuesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
@scope.page = data.current
@scope.count = data.count
@scope.paginatedBy = data.paginatedBy
return data
return promise
loadInitialData: ->
promise = @.loadProject()
return promise.then (project) =>
@.fillUsersAndRoles(project.members, project.roles)
@.fillUsersAndRoles(project.users, project.roles)
@.initializeSubscription()
return @q.all([@.loadFilters(), @.loadIssues()])
@.loadFilters()
return @.loadIssues()
saveCurrentFiltersTo: (newFilter) ->
deferred = @q.defer()
@ -439,12 +446,13 @@ module.directive("tgIssues", ["$log", "$tgLocation", "$tgTemplate", "$compile",
## Issues Filters Directive
#############################################################################
IssuesFiltersDirective = ($log, $location, $rs, $confirm, $loading, $template, $translate, $compile, $auth) ->
IssuesFiltersDirective = ($q, $log, $location, $rs, $confirm, $loading, $template, $translate, $compile, $auth) ->
template = $template.get("issue/issues-filters.html", true)
templateSelected = $template.get("issue/issues-filters-selected.html", true)
link = ($scope, $el, $attrs) ->
$ctrl = $el.closest(".wrapper").controller()
selectedFilters = []
showFilters = (title, type) ->
@ -490,6 +498,16 @@ IssuesFiltersDirective = ($log, $location, $rs, $confirm, $loading, $template, $
html = $compile(html)($scope)
$el.find(".filter-list").html(html)
getFiltersType = () ->
return $el.find("h2 a.subfilter span.title").prop('data-type')
reloadIssues = () ->
currentFiltersType = getFiltersType()
$q.all([$ctrl.loadIssues(), $ctrl.loadFilters()]).then () ->
filters = $scope.filters[currentFiltersType]
renderFilters(_.reject(filters, "selected"))
toggleFilterSelection = (type, id) ->
if type == "myFilters"
$rs.issues.getMyFilters($scope.projectId).then (data) ->
@ -506,7 +524,6 @@ IssuesFiltersDirective = ($log, $location, $rs, $confirm, $loading, $template, $
filters = $scope.filters[type]
filterId = if type == 'tags' then taiga.toString(id) else id
filter = _.find(filters, {id: filterId})
filter.selected = (not filter.selected)
# Convert id to null as string for properly
@ -515,22 +532,23 @@ IssuesFiltersDirective = ($log, $location, $rs, $confirm, $loading, $template, $
if filter.selected
selectedFilters.push(filter)
$scope.$apply ->
$ctrl.selectFilter(type, id)
$ctrl.selectFilter("page", 1)
$ctrl.storeFilters()
$ctrl.loadIssues()
$ctrl.selectFilter(type, id)
$ctrl.selectFilter("page", 1)
$ctrl.storeFilters()
else
selectedFilters = _.reject(selectedFilters, filter)
$scope.$apply ->
$ctrl.unselectFilter(type, id)
$ctrl.selectFilter("page", 1)
$ctrl.storeFilters()
$ctrl.loadIssues()
selectedFilters = _.reject selectedFilters, (f) ->
return f.id == filter.id && f.type == filter.type
$ctrl.unselectFilter(type, id)
$ctrl.selectFilter("page", 1)
$ctrl.storeFilters()
reloadIssues()
renderSelectedFilters(selectedFilters)
currentFiltersType = $el.find("h2 a.subfilter span.title").prop('data-type')
currentFiltersType = getFiltersType()
if type == currentFiltersType
renderFilters(_.reject(filters, "selected"))
@ -539,7 +557,7 @@ IssuesFiltersDirective = ($log, $location, $rs, $confirm, $loading, $template, $
initializeSelectedFilters(filters)
$scope.$on "filters:issueupdate", (ctx, filters) ->
html = template({filters:filters.statuses})
html = template({filters:filters.status})
html = $compile(html)($scope)
$el.find(".filter-list").html(html)
@ -554,7 +572,8 @@ IssuesFiltersDirective = ($log, $location, $rs, $confirm, $loading, $template, $
else
$ctrl.replaceFilter("q", value)
$ctrl.storeFilters()
$ctrl.loadIssues()
reloadIssues()
$scope.$watch("filtersQ", selectQFilter)
@ -661,7 +680,7 @@ IssuesFiltersDirective = ($log, $location, $rs, $confirm, $loading, $template, $
return {link:link}
module.directive("tgIssuesFilters", ["$log", "$tgLocation", "$tgResources", "$tgConfirm", "$tgLoading",
module.directive("tgIssuesFilters", ["$q", "$log", "$tgLocation", "$tgResources", "$tgConfirm", "$tgLoading",
"$tgTemplate", "$translate", "$compile", "$tgAuth", IssuesFiltersDirective])
@ -708,7 +727,7 @@ IssueStatusInlineEditionDirective = ($repo, $template, $rootscope) ->
event.stopPropagation()
target = angular.element(event.currentTarget)
for filter in $scope.filters.statuses
for filter in $scope.filters.status
if filter.id == issue.status
filter.count--
@ -720,13 +739,13 @@ IssueStatusInlineEditionDirective = ($repo, $template, $rootscope) ->
$repo.save(issue).then ->
$ctrl.loadIssues()
for filter in $scope.filters.statuses
for filter in $scope.filters.status
if filter.id == issue.status
filter.count++
$rootscope.$broadcast("filters:issueupdate", $scope.filters)
for filter in $scope.filters.statuses
for filter in $scope.filters.status
if filter.id == issue.status
filter.count++
$rootscope.$broadcast("filters:issueupdate", $scope.filters)

View File

@ -82,6 +82,7 @@ urls = {
"bulk-update-us-backlog-order": "/userstories/bulk_update_backlog_order"
"bulk-update-us-sprint-order": "/userstories/bulk_update_sprint_order"
"bulk-update-us-kanban-order": "/userstories/bulk_update_kanban_order"
"userstories-filters": "/userstories/filters_data"
# Tasks
"tasks": "/tasks"
@ -91,6 +92,7 @@ urls = {
# Issues
"issues": "/issues"
"bulk-create-issues": "/issues/bulk_create"
"issues-filters": "/issues/filters_data"
# Wiki pages
"wiki": "/wiki"

View File

@ -58,8 +58,8 @@ resourceProvider = ($repo, $http, $urls, $storage, $q) ->
service.stats = (projectId) ->
return $repo.queryOneRaw("projects", "#{projectId}/issues_stats")
service.filtersData = (projectId) ->
return $repo.queryOneRaw("projects", "#{projectId}/issue_filters_data")
service.filtersData = (params) ->
return $repo.queryOneRaw("issues-filters", null, params)
service.listValues = (projectId, type) ->
params = {"project": projectId}

View File

@ -41,6 +41,9 @@ resourceProvider = ($repo, $http, $urls, $storage) ->
service.listInAllProjects = (filters) ->
return $repo.queryMany("userstories", filters)
service.filtersData = (params) ->
return $repo.queryOneRaw("userstories-filters", null, params)
service.listUnassigned = (projectId, filters) ->
params = {"project": projectId, "milestone": "null"}
params = _.extend({}, params, filters or {})

View File

@ -34,10 +34,10 @@ div.wrapper(tg-backlog, ng-controller="BacklogController as ctrl",
span.text(translate="BACKLOG.TAGS.SHOW")
include ../includes/components/addnewus
section.backlog-table(ng-class="{'hidden': !visibleUserstories.length}")
section.backlog-table(ng-class="{'hidden': !userstories.length}")
include ../includes/modules/backlog-table
div.empty.empty-backlog(ng-class="{'hidden': visibleUserstories.length}", tg-backlog-empty-sortable)
div.empty.empty-backlog(ng-class="{'hidden': userstories.length}", tg-backlog-empty-sortable)
span.icon.icon-backlog
span.title(translate="BACKLOG.EMPTY")
a(href="", title="{{'BACKLOG.CREATE_NEW_US' | translate}}",

View File

@ -3,11 +3,15 @@
a.single-filter.active(data-type!="<%- f.type %>", data-id!="<%- f.id %>")
span.name(style!="<%- f.style %>")
| <%- f.name %>
<% if (f.count){ %>
span.number <%- f.count %>
<% } %>
<% } else { %>
a.single-filter(data-type!="<%- f.type %>", data-id!="<%- f.id %>")
span.name(style!="<%- f.style %>")
| <%- f.name %>
<% if (f.count){ %>
span.number <%- f.count %>
<% } %>
<% } %>
<% }) %>

View File

@ -1,4 +1,4 @@
div.row.us-item-row(ng-repeat="us in visibleUserstories track by us.id", tg-bind-scope, ng-class="{blocked: us.is_blocked}", tg-class-permission="{'readonly': '!modify_us'}")
div.row.us-item-row(ng-repeat="us in userstories track by us.id", tg-bind-scope, ng-class="{blocked: us.is_blocked}", tg-class-permission="{'readonly': '!modify_us'}")
div.user-stories
div.tags-block(tg-colorize-tags="us.tags", tg-colorize-tags-type="backlog")
div.user-story-name

View File

@ -18,7 +18,7 @@ section.filters
div.filters-cats
ul
li
a(href="", title="{{'BACKLOG.FILTERS.FILTER_CATEGORY_STATUS' | translate}}", data-type="statuses")
a(href="", title="{{'BACKLOG.FILTERS.FILTER_CATEGORY_STATUS' | translate}}", data-type="status")
span.title(translate="BACKLOG.FILTERS.FILTER_CATEGORY_STATUS")
span.icon.icon-arrow-right
li

View File

@ -22,7 +22,7 @@ section.filters
span.title(translate="ISSUES.FILTERS.CATEGORIES.TYPE")
span.icon.icon-arrow-right
li
a(href="", title="{{ 'ISSUES.FILTERS.CATEGORIES.STATUS' | translate}}", data-type="statuses")
a(href="", title="{{ 'ISSUES.FILTERS.CATEGORIES.STATUS' | translate}}", data-type="status")
span.title(translate="ISSUES.FILTERS.CATEGORIES.STATUS")
span.icon.icon-arrow-right
li