taiga-front/app/modules/components/search-list/search-list.directive.coffee

114 lines
4.0 KiB
CoffeeScript

###
# Copyright (C) 2014-2018 Taiga Agile LLC
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# File: components/search-list/search-list.directive.coffee
###
module = angular.module("taigaComponents")
normalizeString = @.taiga.normalizeString
groupBy = @.taiga.groupBy
searchListDirective = ($translate) ->
link = (scope, el, attrs, model) ->
scope.templateUrl = "components/search-list/search-list-#{scope.itemType}-choice.html"
scope.currentSelected = null
filtering = false
avaliableItems = []
itemsById = {}
if scope.itemType == 'issue'
scope.milestonesById = groupBy(scope.project.milestones, (e) -> e.id)
if scope.filterClosed
scope.showClosed = false
if scope.itemType == 'sprint'
scope.textShowClosed = $translate.instant("BACKLOG.SPRINTS.ACTION_SHOW_CLOSED_SPRINTS")
scope.textHideClosed = $translate.instant("BACKLOG.SPRINTS.ACTION_HIDE_CLOSED_SPRINTS")
el.on "click", ".choice", (event) ->
choiceId = parseInt($(event.currentTarget).data("choice-id"))
value = if attrs.ngModel?.id != choiceId then itemsById[choiceId] else null
model.$setViewValue(value)
scope.currentSelected = value
scope.$apply()
isContainedIn = (needle, haystack) ->
return _.includes(parseString(haystack), parseString(needle))
parseString = (value) ->
if typeof value != 'string'
value = value.toString()
return normalizeString(value.toUpperCase())
resetSelected = () ->
scope.currentSelected = null
model.$setViewValue(null)
resetAll = () ->
resetSelected()
scope.searchText = ''
avaliableItems = angular.copy(scope.items)
itemsById = groupBy(avaliableItems, (x) -> x.id)
scope.isVisible = (item) ->
if !scope.filterClosed || scope.showClosed
return true
if (scope.itemType == 'sprint' && (item.closed || item.is_closed))
if (scope.currentSelected?.id == item.id)
resetSelected()
return false
return true
scope.toggleShowClosed = (item) ->
scope.showClosed = !scope.showClosed
scope.filterItems = (searchText) ->
scope.filtering = true
scope.items = _.filter(avaliableItems, (item) ->
itemAttrs = item.getAttrs()
if Array.isArray(scope.filterBy)
_.some(scope.filterBy, (attr) -> isContainedIn(searchText, itemAttrs[attr]))
else
isContainedIn(searchText, itemAttrs[scope.filterBy])
)
if !_.find(scope.items, scope.currentSelected)
resetSelected()
scope.$watch 'items', (items) ->
if !scope.filtering && items
resetAll()
return {
link: link,
templateUrl: "components/search-list/search-list.html",
require: "ngModel",
scope: {
label: '@',
placeholder: '@',
project: '=',
filterBy: '=',
items: '=',
itemType: '@',
filterClosed: '=',
itemDisabled: '='
}
}
module.directive('tgSearchList', ['$translate', searchListDirective])