From 9cf188ca6e16c634095651af1c5c4fa93f3a17f2 Mon Sep 17 00:00:00 2001 From: Martin Edenhofer Date: Mon, 21 Sep 2015 09:59:00 +0200 Subject: [PATCH] Improved wording. --- .../ticket_perform_action.js.coffee | 196 ++++++++++++++++++ .../views/generic/postmaster_match.jst.eco | 4 +- .../app/views/generic/postmaster_set.jst.eco | 4 +- .../generic/ticket_perform_action.jst.eco | 20 ++ .../app/views/generic/ticket_selector.jst.eco | 4 +- .../views/layout_ref/scheduler_modal.jst.eco | 24 +-- .../app/views/layout_ref/sla_modal.jst.eco | 4 +- 7 files changed, 236 insertions(+), 20 deletions(-) create mode 100644 app/assets/javascripts/app/controllers/_ui_element/ticket_perform_action.js.coffee create mode 100644 app/assets/javascripts/app/views/generic/ticket_perform_action.jst.eco diff --git a/app/assets/javascripts/app/controllers/_ui_element/ticket_perform_action.js.coffee b/app/assets/javascripts/app/controllers/_ui_element/ticket_perform_action.js.coffee new file mode 100644 index 000000000..0c73fbd31 --- /dev/null +++ b/app/assets/javascripts/app/controllers/_ui_element/ticket_perform_action.js.coffee @@ -0,0 +1,196 @@ +class App.UiElement.ticket_perform_action + @defaults: -> + defaults = ['ticket.state_id'] + + groups = + ticket: + name: 'Ticket' + model: 'Ticket' + + # megre config + elements = {} + for groupKey, groupMeta of groups + for row in App[groupMeta.model].configure_attributes + + # ignore passwords and relations + if row.type isnt 'password' && row.name.substr(row.name.length-4,4) isnt '_ids' + config = _.clone(row) + elements["#{groupKey}.#{config.name}"] = config + + [defaults, groups, elements] + + @render: (attribute, params = {}) -> + + [defaults, groups, elements] = @defaults() + + selector = @buildAttributeSelector(groups, elements) + + # return item + item = $( App.view('generic/ticket_perform_action')( attribute: attribute ) ) + item.find('.js-attributeSelector').prepend(selector) + + # add filter + item.find('.js-add').bind('click', (e) => + element = $(e.target).closest('.js-filterElement') + elementClone = element.clone(true) + element.after(elementClone) + elementClone.find('.js-attributeSelector select').trigger('change') + ) + + # remove filter + item.find('.js-remove').bind('click', (e) => + $(e.target).closest('.js-filterElement').remove() + @rebuildAttributeSelectors(item) + ) + + # change attribute selector + item.find('.js-attributeSelector select').bind('change', (e) => + groupAndAttribute = $(e.target).find('option:selected').attr('value') + elementRow = $(e.target).closest('.js-filterElement') + + @rebuildAttributeSelectors(item, elementRow, groupAndAttribute) + @buildValue(item, elementRow, groupAndAttribute, elements, undefined, attribute) + ) + + # build inital params + console.log('initial', params[attribute.name]) + if !_.isEmpty(params[attribute.name]) + + selectorExists = false + for groupAndAttribute, meta of params[attribute.name] + selectorExists = true + value = meta.value + + # get selector rows + elementFirst = item.find('.js-filterElement').first() + elementLast = item.find('.js-filterElement').last() + + # clone, rebuild and append + elementClone = elementFirst.clone(true) + @rebuildAttributeSelectors(item, elementClone, groupAndAttribute) + @buildValue(item, elementClone, groupAndAttribute, elements, value, attribute) + elementLast.after(elementClone) + + # remove first dummy row + if selectorExists + item.find('.js-filterElement').first().remove() + + else + for default_row in defaults + + # get selector rows + elementFirst = item.find('.js-filterElement').first() + elementLast = item.find('.js-filterElement').last() + + # clone, rebuild and append + elementClone = elementFirst.clone(true) + @rebuildAttributeSelectors(item, elementClone, default_row) + elementLast.after(elementClone) + item.find('.js-filterElement').first().remove() + + item + + @buildValue: (elementFull, elementRow, groupAndAttribute, elements, value, attribute) -> + + # do nothing if item already exists + name = "#{attribute.name}::#{groupAndAttribute}::value" + return if elementRow.find("[name=\"#{name}\"]").get(0) + return if elementRow.find("[data-name=\"#{name}\"]").get(0) + + # build new item + attributeConfig = elements[groupAndAttribute] + config = _.clone(attributeConfig) + + # force to use auto compition on user lookup + if config.relation is 'User' + config.tag = 'user_autocompletion' + + # render ui element + item = '' + if config && App.UiElement[config.tag] + config['name'] = name + config['value'] = value + if 'multiple' of config + config.multiple = false + config.nulloption = false + if config.tag is 'checkbox' + config.tag = 'select' + tagSearch = "#{config.tag}_search" + if App.UiElement[tagSearch] + item = App.UiElement[tagSearch].render(config, {}) + else + item = App.UiElement[config.tag].render(config, {}) + elementRow.find('.js-value').html(item) + + @buildAttributeSelector: (groups, elements) -> + selection = $('') + for groupKey, groupMeta of groups + displayName = App.i18n.translateInline(groupMeta.name) + selection.closest('select').append("") + optgroup = selection.find("optgroup.js-#{groupKey}") + for elementKey, elementGroup of elements + spacer = elementKey.split(/\./) + if spacer[0] is groupKey + attributeConfig = elements[elementKey] + displayName = App.i18n.translateInline(attributeConfig.display) + optgroup.append("") + selection + + @rebuildAttributeSelectors: (elementFull, elementRow, groupAndAttribute) -> + + # enable all + elementFull.find('.js-attributeSelector select option').removeAttr('disabled') + + # disable all used attributes + elementFull.find('.js-attributeSelector select').each(-> + keyLocal = $(@).val() + elementFull.find('.js-attributeSelector select option[value="' + keyLocal + '"]').attr('disabled', true) + ) + + # disable - if we only have one attribute + if elementFull.find('.js-attributeSelector select').length > 1 + elementFull.find('.js-remove').removeClass('is-disabled') + else + elementFull.find('.js-remove').addClass('is-disabled') + + # set attribute + if groupAndAttribute + elementRow.find('.js-attributeSelector select').val(groupAndAttribute) + + @humanText: (condition) -> + none = App.i18n.translateContent('No filter.') + return [none] if _.isEmpty(condition) + [defaults, groups, elements] = @defaults() + rules = [] + for attribute, value of condition + + objectAttribute = attribute.split(/\./) + + # get stored params + if meta && objectAttribute[1] + model = toCamelCase(objectAttribute[0]) + config = elements[attribute] + + valueHuman = [] + if _.isArray(value) + for data in value + r = @humanTextLookup(config, data) + valueHuman.push r + else + valueHuman.push @humanTextLookup(config, value) + + if valueHuman.join + valueHuman = valueHuman.join(', ') + rules.push "#{App.i18n.translateContent('Set')} #{App.i18n.translateContent(model)} -> #{App.i18n.translateContent(config.display)} #{App.i18n.translateContent('to')} #{valueHuman}." + + return [none] if _.isEmpty(rules) + rules + + @humanTextLookup: (config, value) -> + return value if !App[config.relation] + return value if !App[config.relation].exists(value) + data = App[config.relation].fullLocal(value) + return value if !data + if data.displayName + return App.i18n.translateContent( data.displayName() ) + valueHuman.push App.i18n.translateContent( data.name ) diff --git a/app/assets/javascripts/app/views/generic/postmaster_match.jst.eco b/app/assets/javascripts/app/views/generic/postmaster_match.jst.eco index edc7adf08..135590aab 100644 --- a/app/assets/javascripts/app/views/generic/postmaster_match.jst.eco +++ b/app/assets/javascripts/app/views/generic/postmaster_match.jst.eco @@ -15,10 +15,10 @@
-
+
<%- @Icon('minus') %>
-
+
<%- @Icon('plus') %>
diff --git a/app/assets/javascripts/app/views/generic/postmaster_set.jst.eco b/app/assets/javascripts/app/views/generic/postmaster_set.jst.eco index 8e1fe93d1..a1b34b1fe 100644 --- a/app/assets/javascripts/app/views/generic/postmaster_set.jst.eco +++ b/app/assets/javascripts/app/views/generic/postmaster_set.jst.eco @@ -9,10 +9,10 @@
-
+
<%- @Icon('minus') %>
-
+
<%- @Icon('plus') %>
diff --git a/app/assets/javascripts/app/views/generic/ticket_perform_action.jst.eco b/app/assets/javascripts/app/views/generic/ticket_perform_action.jst.eco new file mode 100644 index 000000000..a1b34b1fe --- /dev/null +++ b/app/assets/javascripts/app/views/generic/ticket_perform_action.jst.eco @@ -0,0 +1,20 @@ +
+
+
+
+
+ <%- @Icon('arrow-down', 'dropdown-arrow') %> +
+
+
+
+
+
+ <%- @Icon('minus') %> +
+
+ <%- @Icon('plus') %> +
+
+
+
\ No newline at end of file diff --git a/app/assets/javascripts/app/views/generic/ticket_selector.jst.eco b/app/assets/javascripts/app/views/generic/ticket_selector.jst.eco index 74f7825e8..41ef82f4e 100644 --- a/app/assets/javascripts/app/views/generic/ticket_selector.jst.eco +++ b/app/assets/javascripts/app/views/generic/ticket_selector.jst.eco @@ -15,10 +15,10 @@
-
+
<%- @Icon('minus') %>
-
+
<%- @Icon('plus') %>
diff --git a/app/assets/javascripts/app/views/layout_ref/scheduler_modal.jst.eco b/app/assets/javascripts/app/views/layout_ref/scheduler_modal.jst.eco index 249e2bf40..5c949756c 100644 --- a/app/assets/javascripts/app/views/layout_ref/scheduler_modal.jst.eco +++ b/app/assets/javascripts/app/views/layout_ref/scheduler_modal.jst.eco @@ -46,10 +46,10 @@
-
+
> <%- @Icon('minus') %>
-
+
> <%- @Icon('plus') %>
@@ -106,10 +106,10 @@
-
+
> <%- @Icon('minus') %>
-
+
> <%- @Icon('plus') %>
@@ -164,10 +164,10 @@
-
+
> <%- @Icon('minus') %>
-
+
> <%- @Icon('plus') %>
@@ -227,10 +227,10 @@
-
+
> <%- @Icon('minus') %>
-
+
> <%- @Icon('plus') %>
@@ -301,10 +301,10 @@
-
+
> <%- @Icon('minus') %>
-
+
> <%- @Icon('plus') %>
@@ -417,10 +417,10 @@
-
+
> <%- @Icon('minus') %>
-
+
> <%- @Icon('plus') %>
diff --git a/app/assets/javascripts/app/views/layout_ref/sla_modal.jst.eco b/app/assets/javascripts/app/views/layout_ref/sla_modal.jst.eco index 36491d473..4fdf58372 100644 --- a/app/assets/javascripts/app/views/layout_ref/sla_modal.jst.eco +++ b/app/assets/javascripts/app/views/layout_ref/sla_modal.jst.eco @@ -48,10 +48,10 @@
-
+
>
-
+
>