Initial work on issues list filters.
parent
975a6cea55
commit
e0ffcada7a
|
@ -22,6 +22,9 @@
|
|||
taiga = @.taiga
|
||||
|
||||
groupBy = @.taiga.groupBy
|
||||
joinStr = @.taiga.joinStr
|
||||
trim = @.taiga.trim
|
||||
toString = @.taiga.toString
|
||||
|
||||
|
||||
class PageMixin
|
||||
|
@ -52,9 +55,8 @@ class FiltersMixin
|
|||
selectFilter: (name, value, load=false) ->
|
||||
params = @location.search()
|
||||
if params[name] != undefined and name != "page"
|
||||
existing = _.map(params[name].split(","), trim)
|
||||
existing.push(value)
|
||||
|
||||
existing = _.map(taiga.toString(params[name]).split(","), trim)
|
||||
existing.push(taiga.toString(value))
|
||||
value = joinStr(",", _.uniq(existing))
|
||||
|
||||
location = if load then @location else @location.noreload(@scope)
|
||||
|
@ -69,8 +71,8 @@ class FiltersMixin
|
|||
if value is undefined or value is null
|
||||
delete params[name]
|
||||
|
||||
parsedValues = _.map(params[name].split(","), trim)
|
||||
newValues = _.reject(parsedValues, (x) -> x == toString(value))
|
||||
parsedValues = _.map(taiga.toString(params[name]).split(","), trim)
|
||||
newValues = _.reject(parsedValues, (x) -> x == taiga.toString(value))
|
||||
|
||||
if _.isEmpty(newValues)
|
||||
value = null
|
||||
|
|
|
@ -55,9 +55,48 @@ class IssuesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
|
|||
console.log "FAIL" #TODO
|
||||
|
||||
loadFilters: ->
|
||||
defered = @q.defer()
|
||||
defered.resolve()
|
||||
return defered.promise
|
||||
return @rs.issues.filtersData(@scope.projectId).then (data) =>
|
||||
console.log data
|
||||
|
||||
# Build selected filters (from url) fast lookup data structure
|
||||
searchdata = {}
|
||||
for name, value of @.getFilters()
|
||||
if name == "page"
|
||||
continue
|
||||
|
||||
if not searchdata[name]?
|
||||
searchdata[name] = {}
|
||||
|
||||
for val in value.split(",")
|
||||
searchdata[name][val] = true
|
||||
|
||||
isSelected = (type, id) ->
|
||||
if searchdata[type]? and searchdata[type][id]
|
||||
return true
|
||||
return false
|
||||
|
||||
console.log "2222", searchdata
|
||||
|
||||
# Build filters data structure
|
||||
filters = {}
|
||||
filters.tags = _.map data.tags, (t) =>
|
||||
obj = {id:t[0], name:t[0], count: t[1], type:"tags"}
|
||||
obj.selected = true if isSelected("tags", obj.id)
|
||||
return obj
|
||||
|
||||
filters.priorities = _.map data.priorities, (t) =>
|
||||
obj = {id:t[0], name:@scope.priorityById[t[0]].name, count:t[1], type:"priorities"}
|
||||
obj.selected = true if isSelected("priorities", obj.id)
|
||||
return obj
|
||||
|
||||
filters.severities = _.map data.severities, (t) =>
|
||||
obj = {id:t[0], name:@scope.severityById[t[0]].name, count:t[1], type:"severities"}
|
||||
obj.selected = true if isSelected("severities", obj.id)
|
||||
return obj
|
||||
|
||||
@scope.filters = filters
|
||||
@rootscope.$broadcast("filters:loaded", filters)
|
||||
return data
|
||||
|
||||
loadProject: ->
|
||||
return @rs.projects.get(@scope.projectId).then (project) =>
|
||||
|
@ -69,12 +108,31 @@ class IssuesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.Fi
|
|||
return project
|
||||
|
||||
getFilters: ->
|
||||
filters = _.pick(@location.search(), "page", "tags", "status", "type")
|
||||
filters = _.pick(@location.search(), "page", "tags", "status", "type",
|
||||
"severities", "priorities")
|
||||
filters.page = 1 if not filters.page
|
||||
return filters
|
||||
|
||||
# Convert stored filters to http parameters
|
||||
# ready filters (the name difference exists
|
||||
# because of some automatic lookups and is
|
||||
# the simplest way todo it without adding
|
||||
# additional complexity to code.
|
||||
prepareFilters: ->
|
||||
filters = {}
|
||||
|
||||
for name, values of @.getFilters()
|
||||
if name == "severities"
|
||||
name = "severity"
|
||||
else if name == "priorities"
|
||||
name = "priority"
|
||||
|
||||
filters[name] = values
|
||||
return filters
|
||||
|
||||
loadIssues: ->
|
||||
filters = @.getFilters()
|
||||
filters = @.prepareFilters()
|
||||
console.log filters
|
||||
|
||||
promise = @rs.issues.list(@scope.projectId, filters).then (data) =>
|
||||
@scope.issues = data.models
|
||||
|
@ -221,7 +279,8 @@ IssuesDirective = ($log, $location) ->
|
|||
#########################
|
||||
|
||||
linkFilters = ($scope, $el, $attrs, $ctrl) ->
|
||||
$log.debug "IssuesDirective:linkFilters"
|
||||
$scope.filters = {}
|
||||
$scope.selectedFilters = []
|
||||
|
||||
#########################
|
||||
## Issues Link
|
||||
|
@ -235,4 +294,125 @@ IssuesDirective = ($log, $location) ->
|
|||
return {link:link}
|
||||
|
||||
|
||||
|
||||
IssuesFiltersDirective = ($log, $location) ->
|
||||
template = _.template("""
|
||||
<% _.each(filters, function(f) { %>
|
||||
<% if (f.selected) { %>
|
||||
<a class="single-filter active"
|
||||
data-type="<%= f.type %>"
|
||||
data-id="<%= f.id %>">
|
||||
<span class="name"><%- f.name %></span>
|
||||
<span class="number"><%- f.count %></span>
|
||||
</a>
|
||||
<% } else { %>
|
||||
<a class="single-filter"
|
||||
data-type="<%= f.type %>"
|
||||
data-id="<%= f.id %>">
|
||||
<span class="name"><%- f.name %></span>
|
||||
<span class="number"><%- f.count %></span>
|
||||
</a>
|
||||
<% } %>
|
||||
<% }) %>
|
||||
""")
|
||||
|
||||
templateSelected = _.template("""
|
||||
<% _.each(filters, function(f) { %>
|
||||
<a class="single-filter selected"
|
||||
data-type="<%= f.type %>"
|
||||
data-id="<%= f.id %>">
|
||||
<span class="name"><%- f.name %></span>
|
||||
<span class="icon icon-delete"></span>
|
||||
</a>
|
||||
<% }) %>
|
||||
""")
|
||||
|
||||
selectedFilters = []
|
||||
|
||||
showFilters = ($el) ->
|
||||
$el.find(".filters-cats").hide()
|
||||
$el.find(".filter-list").show()
|
||||
|
||||
showCategories = ($el) ->
|
||||
$el.find(".filters-cats").show()
|
||||
$el.find(".filter-list").hide()
|
||||
|
||||
initializeSelectedFilters = ($el, filters) ->
|
||||
for name, values of filters
|
||||
for val in values
|
||||
console.log "klkk", val.selected
|
||||
selectedFilters.push(val) if val.selected
|
||||
|
||||
renderSelectedFilters($el)
|
||||
|
||||
renderSelectedFilters = ($el) ->
|
||||
html = templateSelected({filters:selectedFilters})
|
||||
$el.find(".filters-applied").html(html)
|
||||
|
||||
renderFilters = ($el, filters) ->
|
||||
html = template({filters:filters})
|
||||
$el.find(".filter-list").html(html)
|
||||
|
||||
link = ($scope, $el, $attrs) ->
|
||||
$ctrl = $el.closest(".wrapper").controller()
|
||||
|
||||
$scope.$on "filters:loaded", (ctx, filters) ->
|
||||
initializeSelectedFilters($el, filters)
|
||||
|
||||
toggleFilterSelection = (type, id) ->
|
||||
filters = $scope.filters[type]
|
||||
filter = _.find(filters, {id:id})
|
||||
filter.selected = (not filter.selected)
|
||||
if filter.selected
|
||||
selectedFilters.push(filter)
|
||||
$scope.$apply ->
|
||||
$ctrl.selectFilter(type, id)
|
||||
$ctrl.selectFilter("page", 1)
|
||||
$ctrl.loadIssues()
|
||||
else
|
||||
selectedFilters = _.reject(selectedFilters, filter)
|
||||
$scope.$apply ->
|
||||
$ctrl.unselectFilter(type, id)
|
||||
$ctrl.selectFilter("page", 1)
|
||||
$ctrl.loadIssues()
|
||||
|
||||
renderSelectedFilters($el, selectedFilters)
|
||||
renderFilters($el, filters)
|
||||
|
||||
$el.on "click", ".filters-cats > ul > li > a", (event) ->
|
||||
event.preventDefault()
|
||||
target = angular.element(event.currentTarget)
|
||||
tags = $scope.filters[target.data("type")]
|
||||
|
||||
renderFilters($el, tags)
|
||||
showFilters($el)
|
||||
|
||||
$el.on "click", ".filters-inner > h1 > a.title", (event) ->
|
||||
event.preventDefault()
|
||||
showCategories($el)
|
||||
|
||||
$el.on "click", ".filters-applied a", (event) ->
|
||||
event.preventDefault()
|
||||
target = angular.element(event.currentTarget)
|
||||
|
||||
id = target.data("id")
|
||||
type = target.data("type")
|
||||
toggleFilterSelection(type, id)
|
||||
|
||||
$el.on "click", ".filter-list .single-filter", (event) ->
|
||||
event.preventDefault()
|
||||
target = angular.element(event.currentTarget)
|
||||
if target.hasClass("active")
|
||||
target.removeClass("active")
|
||||
# target.css("background-color")
|
||||
else
|
||||
target.addClass("active")
|
||||
|
||||
id = target.data("id")
|
||||
type = target.data("type")
|
||||
toggleFilterSelection(type, id)
|
||||
|
||||
return {link:link}
|
||||
|
||||
module.directive("tgIssuesFilters", ["$log", "$tgLocation", IssuesFiltersDirective])
|
||||
module.directive("tgIssues", ["$log", "$tgLocation", IssuesDirective])
|
||||
|
|
|
@ -37,7 +37,7 @@ resourceProvider = ($repo) ->
|
|||
return $repo.queryOneRaw("projects", "#{projectId}/issues_stats")
|
||||
|
||||
service.filtersData = (projectId) ->
|
||||
return $repo.queryOneRaw("projects", "#{projectId}/issues_filters_data")
|
||||
return $repo.queryOneRaw("projects", "#{projectId}/issue_filters_data")
|
||||
|
||||
return (instance) ->
|
||||
instance.issues = service
|
||||
|
|
|
@ -5,7 +5,7 @@ block head
|
|||
|
||||
block content
|
||||
div.wrapper.issues(tg-issues, ng-controller="IssuesController as ctrl", ng-init="section='issues'")
|
||||
sidebar.menu-secondary.extrabar.filters-bar
|
||||
sidebar.menu-secondary.extrabar.filters-bar(tg-issues-filters)
|
||||
include views/modules/filters
|
||||
|
||||
section.main.issues-page
|
||||
|
@ -20,5 +20,6 @@ block content
|
|||
|
||||
div.hidden.lightbox.lightbox_add-issue
|
||||
include views/modules/lightbox_add-issue
|
||||
div.lightbox.lightbox_add-bulk.hidden
|
||||
|
||||
div.hidden.lightbox.lightbox_add-bulk
|
||||
include views/modules/lightbox_add-bulk
|
||||
|
|
|
@ -7,37 +7,38 @@ section.filters
|
|||
span status
|
||||
form
|
||||
fieldset
|
||||
input(type="text", placeholder="Filter Filters", ng-model="filters.subject")
|
||||
input(type="text", placeholder="Search by subject...", ng-model="filters.subject")
|
||||
a.icon.icon-search(href="", title="search")
|
||||
|
||||
//- First step for selecting category
|
||||
div.filters-step-cat
|
||||
//- $(.filters-applied) only visible when filters are being applied
|
||||
div.filters-applied
|
||||
a.single-filter.selected
|
||||
span.name Filter23
|
||||
span.icon.icon-delete
|
||||
// a.single-filter.selected
|
||||
// span.name Filter23
|
||||
// span.icon.icon-delete
|
||||
div.filters-cats
|
||||
ul
|
||||
// li
|
||||
// a(href="", title="Status", data-type="status")
|
||||
// span.title Status
|
||||
// span.icon.icon-arrow-right
|
||||
// li
|
||||
// a(href="", title="Type", data-type="types")
|
||||
// span.title Type
|
||||
// span.icon.icon-arrow-right
|
||||
li
|
||||
a(href="", title="status")
|
||||
span Status
|
||||
a(href="", title="Severity", data-type="severities")
|
||||
span.title Severity
|
||||
span.icon.icon-arrow-right
|
||||
li
|
||||
a(href="", title="type")
|
||||
span Type
|
||||
a(href="", title="Priorities", data-type="priorities")
|
||||
span.title Priorities
|
||||
span.icon.icon-arrow-right
|
||||
li
|
||||
a(href="", title="Severity")
|
||||
span Severity
|
||||
span.icon.icon-arrow-right
|
||||
li
|
||||
a(href="", title="blablabla")
|
||||
span Blablabla
|
||||
a(href="", title="Tags", data-type="tags")
|
||||
span.title Tags
|
||||
span.icon.icon-arrow-right
|
||||
|
||||
//- Second step for selecting single filters to apply
|
||||
div.filter-list
|
||||
a.single-filter(ng-repeat="tag in filters.tags|filter:filtersSearch:strict" ng-class="{selected: tag.selected}")
|
||||
span.name(tg-bo-html="tag.name")
|
||||
span.number(tg-bo-html="tag.count")
|
||||
div.filter-list.hidden
|
||||
|
|
Loading…
Reference in New Issue