Fix custom attributes

stable
David Barragán Merino 2015-10-14 22:05:55 +02:00
parent d905b05977
commit 2c729b2edf
4 changed files with 153 additions and 69 deletions

View File

@ -374,6 +374,27 @@ module.directive("tgColorSelection", ColorSelectionDirective)
## Custom Attributes Controller
#############################################################################
# Custom attributes types (see taiga-back/taiga/projects/custom_attributes/choices.py)
TEXT_TYPE = "text"
MULTILINE_TYPE = "multiline"
DATE_TYPE = "date"
TYPE_CHOICES = [
{
key: TEXT_TYPE,
name: "ADMIN.CUSTOM_FIELDS.FIELD_TYPE_TEXT"
},
{
key: MULTILINE_TYPE,
name: "ADMIN.CUSTOM_FIELDS.FIELD_TYPE_MULTI"
},
{
key: DATE_TYPE,
name: "ADMIN.CUSTOM_FIELDS.FIELD_TYPE_DATE"
}
]
class ProjectCustomAttributesController extends mixOf(taiga.Controller, taiga.PageMixin)
@.$inject = [
"$scope",
@ -390,6 +411,8 @@ class ProjectCustomAttributesController extends mixOf(taiga.Controller, taiga.Pa
constructor: (@scope, @rootscope, @repo, @rs, @params, @q, @location, @navUrls, @appMetaService,
@translate) ->
@scope.TYPE_CHOICES = TYPE_CHOICES
@scope.project = {}
@rootscope.$on "project:loaded", =>

View File

@ -27,6 +27,28 @@ generateHash = taiga.generateHash
module = angular.module("taigaCommon")
# Custom attributes types (see taiga-back/taiga/projects/custom_attributes/choices.py)
TEXT_TYPE = "text"
MULTILINE_TYPE = "multiline"
DATE_TYPE = "date"
TYPE_CHOICES = [
{
key: TEXT_TYPE,
name: "ADMIN.CUSTOM_FIELDS.FIELD_TYPE_TEXT"
},
{
key: MULTILINE_TYPE,
name: "ADMIN.CUSTOM_FIELDS.FIELD_TYPE_MULTI"
},
{
key: DATE_TYPE,
name: "ADMIN.CUSTOM_FIELDS.FIELD_TYPE_DATE"
}
]
class CustomAttributesValuesController extends taiga.Controller
@.$inject = ["$scope", "$rootScope", "$tgRepo", "$tgResources", "$tgConfirm", "$q"]
@ -118,7 +140,8 @@ CustomAttributesValuesDirective = ($templates, $storage) ->
template: templateFn
}
module.directive("tgCustomAttributesValues", ["$tgTemplate", "$tgStorage", "$translate", CustomAttributesValuesDirective])
module.directive("tgCustomAttributesValues", ["$tgTemplate", "$tgStorage", "$translate",
CustomAttributesValuesDirective])
CustomAttributeValueDirective = ($template, $selectedText, $compile, $translate, datePickerConfigService) ->
@ -130,7 +153,6 @@ CustomAttributeValueDirective = ($template, $selectedText, $compile, $translate,
render = (attributeValue, edit=false) ->
value = attributeValue.value
innerText = attributeValue.value
editable = isEditable()
ctx = {
id: attributeValue.id
@ -138,7 +160,7 @@ CustomAttributeValueDirective = ($template, $selectedText, $compile, $translate,
description: attributeValue.description
value: value
isEditable: editable
field_type: attributeValue.field_type
type: attributeValue.type
}
if editable and (edit or not value)
@ -150,18 +172,17 @@ CustomAttributeValueDirective = ($template, $selectedText, $compile, $translate,
$el.html(html)
if attributeValue.field_type == "DATE"
if attributeValue.type == DATE_TYPE
datePickerConfig = datePickerConfigService.get()
_.merge(datePickerConfig, {
field: $el.find('input')[0]
field: $el.find("input[name=value]")[0]
onSelect: (date) =>
selectedDate = date
onOpen: =>
$el.picker.setDate(selectedDate) if selectedDate?
})
selectedDate = null
$el.picker = new Pikaday(datePickerConfig)
isEditable = ->
@ -170,28 +191,32 @@ CustomAttributeValueDirective = ($template, $selectedText, $compile, $translate,
return permissions.indexOf(requiredEditionPerm) > -1
saveAttributeValue = ->
attributeValue.value = $el.find("input, textarea").val()
if attributeValue.field_type == "DATE"
if attributeValue.value
return if moment(attributeValue.value).isValid() != true
attributeValue.value = $el.find("input[name=value], textarea[name='value']").val()
if attributeValue.type is DATE_TYPE
if moment(attributeValue.value, prettyDate).isValid()
attributeValue.value = moment(attributeValue.value, prettyDate).format("YYYY-MM-DD")
else
attributeValue.reset()
return
$scope.$apply ->
$ctrl.updateAttributeValue(attributeValue).then ->
if attributeValue.field_type == "DATE" and attributeValue.value
if attributeValue.type is "DATE_TYPE" and attributeValue.value
attributeValue.value = moment(attributeValue.value, "YYYY-MM-DD").format(prettyDate)
render(attributeValue, false)
$el.on "keyup", "input[name=description], textarea[name='description']", (event) ->
if event.keyCode == 13 and event.currentTarget.type != "textarea"
submit(event)
else if event.keyCode == 27
return if attributeValue.field_type == "DATE" and moment(attributeValue.value).isValid() != true
submit = debounce 2000, (event) =>
event.preventDefault()
saveAttributeValue()
render(attributeValue, false)
# Bootstrap
attributeValue = $scope.$eval($attrs.tgCustomAttributeValue)
if attributeValue.type is DATE_TYPE and attributeValue.value
attributeValue.value = moment(attributeValue.value, "YYYY-MM-DD").format(prettyDate)
render(attributeValue)
## Actions (on view mode)
$el.on "click", ".custom-field-value.read-mode", ->
@ -206,28 +231,24 @@ CustomAttributeValueDirective = ($template, $selectedText, $compile, $translate,
$el.find("input[name='description'], textarea[name='description']").focus().select()
## Actions (on edit mode)
submit = debounce 2000, (event) =>
event.preventDefault()
saveAttributeValue()
$el.on "keyup", "input[name=value], textarea[name='value']", (event) ->
if event.keyCode is 13 and event.currentTarget.type isnt "textarea"
submit(event)
else if event.keyCode == 27
render(attributeValue, false)
$el.on "submit", "form", submit
$el.on "click", "a.icon-floppy", submit
$scope.$on "$destroy", ->
$el.off()
# Bootstrap
attributeValue = $scope.$eval($attrs.tgCustomAttributeValue)
if attributeValue.field_type == "DATE" and attributeValue.value
attributeValue.value = moment(attributeValue.value, "YYYY-MM-DD").format(prettyDate)
render(attributeValue)
return {
link: link
require: "^tgCustomAttributesValues"
restrict: "AE"
}
module.directive("tgCustomAttributeValue", ["$tgTemplate", "$selectedText", "$compile", "$translate", "tgDatePickerConfigService", CustomAttributeValueDirective])
module.directive("tgCustomAttributeValue", ["$tgTemplate", "$selectedText", "$compile", "$translate",
"tgDatePickerConfigService", CustomAttributeValueDirective])

View File

@ -1,6 +1,6 @@
form.custom-field-single.editable
div.custom-field-data
label.custom-field-name(for="custom-field-description")
label.custom-field-name(for="custom-field-value")
<%- name %>
<% if (description){ %>
span.custom-field-description
@ -8,22 +8,15 @@ form.custom-field-single.editable
<% } %>
div.custom-field-value
<% if (field_type=="MULTI") { %>
textarea#custom-field-description(name="description")
<%- value %>
<% } %>
<% if (field_type=="TEXT") { %>
input#custom-field-description(name="description", type="text", value!="<%- value %>")
<% } %>
<% if (field_type=="DATE" && value!="") { %>
input#custom-field-description(name="description", type="text", value!="<%- moment(value).format('DD MMM YYYY') %>")
<% } %>
<% if (field_type=="DATE" && value=="") { %>
input#custom-field-description(name="description", type="text", value!="")
//- See TYPE_CHOICES in app/coffee/modules/common/custom-field-values.coffee
<% if (type=="text") { %>
input#custom-field-value(name="value", type="text", value!="<%- value %>")
<% } else if (type=="multiline") { %>
textarea#custom-field-value(name="value") <%- value %>
<% } else if (type=="date") { %>
input#custom-field-value(name="value", type="text", value!="<%- value %>")
<% } else { %>
input#custom-field-value(name="value", type="text", value!="<%- value %>")
<% } %>
div.custom-field-options

View File

@ -1,7 +1,10 @@
section.custom-fields-table.basic-table
div.project-values-title
h2 {{ customFieldSectionTitle | translate }}
a.button.button-gray.show-add-new.js-add-custom-field-button(href="", title="{{ customFieldButtonTitle | translate }}")
a.button.button-gray.show-add-new.js-add-custom-field-button(
href=""
title="{{ customFieldButtonTitle | translate }}"
)
span(translate="ADMIN.CUSTOM_ATTRIBUTES.ADD")
div.table-header
@ -24,40 +27,84 @@ section.custom-fields-table.basic-table
span {{ attr.name }}
div.custom-description
span {{ attr.description }}
div.custom-field-type
span(translate="ADMIN.CUSTOM_FIELDS.FIELD_TYPE_{{ attr.field_type }}")
div.custom-field-type(ng-switch on="attr.type")
//- See TYPE_CHOICES in app/coffee/modules/admin/project-values.coffee
span(ng-switch-default, translate="ADMIN.CUSTOM_FIELDS.FIELD_TYPE_TEXT")
span(ng-switch-when="multiline", translate="ADMIN.CUSTOM_FIELDS.FIELD_TYPE_MULTI")
span(ng-switch-when="date", translate="ADMIN.CUSTOM_FIELDS.FIELD_TYPE_DATE")
div.custom-options
div.custom-options-wrapper
a.js-edit-custom-field-button.icon.icon-edit(href="", title="{{'ADMIN.CUSTOM_ATTRIBUTES.EDIT' | translate}}")
a.js-delete-custom-field-button.icon.icon-delete(href="", title="{{'ADMIN.CUSTOM_ATTRIBUTES.DELETE' | translate}}")
a.js-edit-custom-field-button.icon.icon-edit(
href=""
title="{{'ADMIN.CUSTOM_ATTRIBUTES.EDIT' | translate}}"
)
a.js-delete-custom-field-button.icon.icon-delete(
href=""
title="{{'ADMIN.CUSTOM_ATTRIBUTES.DELETE' | translate}}"
)
div.row.single-custom-field.js-edit-custom-field.hidden
fieldset.custom-name
input(type="text", name="name", placeholder="{{'ADMIN.CUSTOM_ATTRIBUTES.SET_FIELD_NAME' | translate}}",
ng-model="attr.name", data-required="true" data-maxlength="64")
input(
type="text"
name="name"
placeholder="{{'ADMIN.CUSTOM_ATTRIBUTES.SET_FIELD_NAME' | translate}}"
ng-model="attr.name"
data-required="true"
data-maxlength="64"
)
fieldset.custom-description
input(type="text", name="description", placeholder="{{'ADMIN.CUSTOM_ATTRIBUTES.SET_FIELD_DESCRIPTION' | translate}}",
ng-model="attr.description")
input(
type="text"
name="description"
placeholder="{{'ADMIN.CUSTOM_ATTRIBUTES.SET_FIELD_DESCRIPTION' | translate}}"
ng-model="attr.description"
)
fieldset.custom-field-type
select(ng-model="attr.field_type",
ng-options="e.id as e.name | translate for e in [{'id':'TEXT', 'name': 'ADMIN.CUSTOM_FIELDS.FIELD_TYPE_TEXT'},{'id':'MULTI', 'name': 'ADMIN.CUSTOM_FIELDS.FIELD_TYPE_MULTI'},{'id':'DATE', 'name': 'ADMIN.CUSTOM_FIELDS.FIELD_TYPE_DATE'}]")
select(
ng-model="attr.type"
ng-options="type.key as type.name | translate for type in TYPE_CHOICES"
)
fieldset.custom-options
div.custom-options-wrapper
a.js-update-custom-field-button.icon.icon-floppy(href="", title="{{'ADMIN.CUSTOM_ATTRIBUTES.ACTION_UPDATE' | translate}}")
a.js-cancel-edit-custom-field-button.icon.icon-delete(href="", title="{{'ADMIN.CUSTOM_ATTRIBUTES.ACTION_CANCEL_EDITION' | translate}}")
a.js-update-custom-field-button.icon.icon-floppy(
href=""
title="{{'ADMIN.CUSTOM_ATTRIBUTES.ACTION_UPDATE' | translate}}"
)
a.js-cancel-edit-custom-field-button.icon.icon-delete(
href=""
title="{{'ADMIN.CUSTOM_ATTRIBUTES.ACTION_CANCEL_EDITION' | translate}}"
)
form.row.single-custom-field.js-new-custom-field.hidden
fieldset.custom-name
input(type="text", name="name", placeholder="{{'ADMIN.CUSTOM_ATTRIBUTES.SET_FIELD_NAME' | translate}}",
ng-model="newAttr.name", data-required="true", data-maxlength="64")
input(
type="text"
name="name"
placeholder="{{'ADMIN.CUSTOM_ATTRIBUTES.SET_FIELD_NAME' | translate}}"
ng-model="newAttr.name"
data-required="true"
data-maxlength="64"
)
fieldset.custom-description
input(type="text", name="description", placeholder="{{'ADMIN.CUSTOM_ATTRIBUTES.SET_FIELD_DESCRIPTION' | translate}}",
ng-model="newAttr.description")
input(
type="text"
name="description"
placeholder="{{'ADMIN.CUSTOM_ATTRIBUTES.SET_FIELD_DESCRIPTION' | translate}}"
ng-model="newAttr.description"
)
fieldset.custom-field-type
select(ng-model="newAttr.field_type",
ng-options="e.id as e.name | translate for e in [{'id':'TEXT', 'name': 'ADMIN.CUSTOM_FIELDS.FIELD_TYPE_TEXT'},{'id':'MULTI', 'name': 'ADMIN.CUSTOM_FIELDS.FIELD_TYPE_MULTI'},{'id':'DATE', 'name': 'ADMIN.CUSTOM_FIELDS.FIELD_TYPE_DATE'}]")
select(
ng-model="newAttr.type"
ng-options="type.key as type.name for type in TYPE_CHOICES"
)
fieldset.custom-options
div.custom-options-wrapper
a.js-create-custom-field-button.icon.icon-floppy(href="", title="{{'ADMIN.CUSTOM_ATTRIBUTES.SAVE_TITLE' | translate}}")
a.js-cancel-new-custom-field-button.icon.icon-delete(href="", title="{{'ADMIN.CUSTOM_ATTRIBUTES.CANCEL_TITLE' | translate}}")
a.js-create-custom-field-button.icon.icon-floppy(
href=""
title="{{'ADMIN.CUSTOM_ATTRIBUTES.SAVE_TITLE' | translate}}"
)
a.js-cancel-new-custom-field-button.icon.icon-delete(
href=""
title="{{'ADMIN.CUSTOM_ATTRIBUTES.CANCEL_TITLE' | translate}}"
)