201 lines
7.1 KiB
CoffeeScript
201 lines
7.1 KiB
CoffeeScript
###
|
|
# Copyright (C) 2014 Andrey Antukh <niwi@niwi.be>
|
|
# Copyright (C) 2014 Jesús Espino Garcia <jespinog@gmail.com>
|
|
# Copyright (C) 2014 David Barragán Merino <bameda@dbarragan.com>
|
|
#
|
|
# 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: modules/common/custom-field-values.coffee
|
|
###
|
|
|
|
taiga = @.taiga
|
|
bindMethods = @.taiga.bindMethods
|
|
bindOnce = @.taiga.bindOnce
|
|
debounce = @.taiga.debounce
|
|
generateHash = taiga.generateHash
|
|
|
|
module = angular.module("taigaCommon")
|
|
|
|
|
|
class CustomAttributesValuesController extends taiga.Controller
|
|
@.$inject = ["$scope", "$rootScope", "$tgRepo", "$tgResources", "$tgConfirm", "$q"]
|
|
|
|
constructor: (@scope, @rootscope, @repo, @rs, @confirm, @q) ->
|
|
bindMethods(@)
|
|
@.type = null
|
|
@.objectId = null
|
|
@.projectId = null
|
|
@.customAttributes = []
|
|
@.customAttributesValues = null
|
|
|
|
initialize: (type, objectId) ->
|
|
@.project = @scope.project
|
|
@.type = type
|
|
@.objectId = objectId
|
|
@.projectId = @scope.projectId
|
|
|
|
loadCustomAttributesValues: ->
|
|
return @.customAttributesValues if not @.objectId
|
|
return @rs.customAttributesValues[@.type].get(@.objectId).then (customAttributesValues) =>
|
|
@.customAttributes = @.project["#{@.type}_custom_attributes"]
|
|
@.customAttributesValues = customAttributesValues
|
|
return customAttributesValues
|
|
|
|
getAttributeValue: (attribute) ->
|
|
attributeValue = _.clone(attribute, false)
|
|
attributeValue.value = @.customAttributesValues.attributes_values[attribute.id]
|
|
return attributeValue
|
|
|
|
updateAttributeValue: (attributeValue) ->
|
|
onSuccess = =>
|
|
@rootscope.$broadcast("custom-attributes-values:edit")
|
|
|
|
onError = (response) =>
|
|
@confirm.notify("error")
|
|
return @q.reject()
|
|
|
|
# We need to update the full array so angular understand the model is modified
|
|
attributesValues = _.clone(@.customAttributesValues.attributes_values, true)
|
|
attributesValues[attributeValue.id] = attributeValue.value
|
|
@.customAttributesValues.attributes_values = attributesValues
|
|
@.customAttributesValues.id = @.objectId
|
|
return @repo.save(@.customAttributesValues).then(onSuccess, onError)
|
|
|
|
|
|
CustomAttributesValuesDirective = ($templates, $storage) ->
|
|
template = $templates.get("custom-attributes/custom-attributes-values.html", true)
|
|
collapsedHash = (type) ->
|
|
return generateHash(["custom-attributes-collapsed", type])
|
|
|
|
link = ($scope, $el, $attrs, $ctrls) ->
|
|
$ctrl = $ctrls[0]
|
|
$model = $ctrls[1]
|
|
|
|
bindOnce $scope, $attrs.ngModel, (value) ->
|
|
$ctrl.initialize($attrs.type, value.id)
|
|
$ctrl.loadCustomAttributesValues()
|
|
|
|
$el.on "click", ".custom-fields-header a", ->
|
|
hash = collapsedHash($attrs.type)
|
|
collapsed = not($storage.get(hash) or false)
|
|
$storage.set(hash, collapsed)
|
|
if collapsed
|
|
$el.find(".custom-fields-header a").removeClass("open")
|
|
$el.find(".custom-fields-body").removeClass("open")
|
|
else
|
|
$el.find(".custom-fields-header a").addClass("open")
|
|
$el.find(".custom-fields-body").addClass("open")
|
|
|
|
$scope.$on "$destroy", ->
|
|
$el.off()
|
|
|
|
templateFn = ($el, $attrs) ->
|
|
collapsed = $storage.get(collapsedHash($attrs.type)) or false
|
|
|
|
return template({
|
|
requiredEditionPerm: $attrs.requiredEditionPerm
|
|
collapsed: collapsed
|
|
})
|
|
|
|
return {
|
|
require: ["tgCustomAttributesValues", "ngModel"]
|
|
controller: CustomAttributesValuesController
|
|
controllerAs: "ctrl"
|
|
restrict: "AE"
|
|
scope: true
|
|
link: link
|
|
template: templateFn
|
|
}
|
|
|
|
module.directive("tgCustomAttributesValues", ["$tgTemplate", "$tgStorage", CustomAttributesValuesDirective])
|
|
|
|
|
|
CustomAttributeValueDirective = ($template, $selectedText, $compile) ->
|
|
template = $template.get("custom-attributes/custom-attribute-value.html", true)
|
|
templateEdit = $template.get("custom-attributes/custom-attribute-value-edit.html", true)
|
|
|
|
link = ($scope, $el, $attrs, $ctrl) ->
|
|
render = (attributeValue, edit=false) ->
|
|
value = attributeValue.value
|
|
editable = isEditable()
|
|
ctx = {
|
|
id: attributeValue.id
|
|
name: attributeValue.name
|
|
description: attributeValue.description
|
|
value: value
|
|
isEditable: editable
|
|
}
|
|
|
|
if editable and (edit or not value)
|
|
html = templateEdit(ctx)
|
|
html = $compile(html)($scope)
|
|
else
|
|
html = template(ctx)
|
|
html = $compile(html)($scope)
|
|
|
|
$el.html(html)
|
|
|
|
isEditable = ->
|
|
permissions = $scope.project.my_permissions
|
|
requiredEditionPerm = $attrs.requiredEditionPerm
|
|
return permissions.indexOf(requiredEditionPerm) > -1
|
|
|
|
saveAttributeValue = ->
|
|
attributeValue.value = $el.find("input").val()
|
|
|
|
$scope.$apply ->
|
|
$ctrl.updateAttributeValue(attributeValue).then ->
|
|
render(attributeValue, false)
|
|
|
|
$el.on "keyup", "input[name=description]", (event) ->
|
|
if event.keyCode == 13
|
|
submit(event)
|
|
else if event.keyCode == 27
|
|
render(attributeValue, false)
|
|
|
|
## Actions (on view mode)
|
|
$el.on "click", ".custom-field-value.read-mode", ->
|
|
return if not isEditable()
|
|
return if $selectedText.get().length
|
|
render(attributeValue, true)
|
|
$el.find("input[name='description']").focus().select()
|
|
|
|
$el.on "click", "a.icon-edit", (event) ->
|
|
event.preventDefault()
|
|
render(attributeValue, true)
|
|
$el.find("input[name='description']").focus().select()
|
|
|
|
## Actions (on edit mode)
|
|
submit = debounce 2000, (event) =>
|
|
event.preventDefault()
|
|
saveAttributeValue()
|
|
|
|
$el.on "submit", "form", submit
|
|
$el.on "click", "a.icon-floppy", submit
|
|
|
|
$scope.$on "$destroy", ->
|
|
$el.off()
|
|
|
|
# Bootstrap
|
|
attributeValue = $scope.$eval($attrs.tgCustomAttributeValue)
|
|
render(attributeValue)
|
|
|
|
return {
|
|
link: link
|
|
require: "^tgCustomAttributesValues"
|
|
restrict: "AE"
|
|
}
|
|
|
|
module.directive("tgCustomAttributeValue", ["$tgTemplate", "$selectedText", "$compile", CustomAttributeValueDirective])
|