From 71f807af0ff4fabcfb53aaef8a4b89c38d735f8c Mon Sep 17 00:00:00 2001 From: Martin Edenhofer Date: Mon, 7 Mar 2016 07:46:11 +0100 Subject: [PATCH] Added only_shown_if_selectable support for form elements. --- .../_application_controller.coffee | 3 +- .../_application_controller_form.coffee | 14 +- .../controllers/agent_ticket_create.coffee | 14 +- db/migrate/20160307000001_only_one_group.rb | 219 ++++++++++++++++++ db/seeds.rb | 22 +- test/browser/aaa_getting_started_test.rb | 7 +- test/browser/abb_one_group_test.rb | 185 +++++++++++++++ test/browser/first_steps_test.rb | 27 +-- 8 files changed, 450 insertions(+), 41 deletions(-) create mode 100644 db/migrate/20160307000001_only_one_group.rb create mode 100644 test/browser/abb_one_group_test.rb diff --git a/app/assets/javascripts/app/controllers/_application_controller.coffee b/app/assets/javascripts/app/controllers/_application_controller.coffee index a5d83313b..1f32af140 100644 --- a/app/assets/javascripts/app/controllers/_application_controller.coffee +++ b/app/assets/javascripts/app/controllers/_application_controller.coffee @@ -527,7 +527,8 @@ class App.Controller extends Spine.Controller newElement = ui.formGenItem(item, classname, form) # replace new option list - form.find('[name="' + fieldNameToChange + '"]').closest('.form-group').replaceWith(newElement) + if newElement + form.find('[name="' + fieldNameToChange + '"]').closest('.form-group').replaceWith(newElement) stopPropagation: (e) -> e.stopPropagation() diff --git a/app/assets/javascripts/app/controllers/_application_controller_form.coffee b/app/assets/javascripts/app/controllers/_application_controller_form.coffee index f853945fc..1a4f950c2 100644 --- a/app/assets/javascripts/app/controllers/_application_controller_form.coffee +++ b/app/assets/javascripts/app/controllers/_application_controller_form.coffee @@ -245,6 +245,18 @@ class App.ControllerForm extends App.Controller else throw "Invalid UiElement.#{attribute.tag}" + if attribute.only_shown_if_selectable + count = Object.keys(attribute.options).length + if !attribute.null && (attribute.nulloption && count is 2) || (!attribute.nulloption && count is 1) + attribute.transparent = true + attributesNew = clone(attribute) + attributesNew.type = 'hidden' + attributesNew.value = '' + for item in attribute.options + if item.value && item.value isnt '' + attributesNew.value = item.value + item = $( App.view('generic/input')( attribute: attributesNew ) ) + if @handlers item.bind('change', (e) => params = App.ControllerForm.params( $(e.target) ) @@ -278,7 +290,7 @@ class App.ControllerForm extends App.Controller ui.show(action.change.name) ) - if !attribute.display + if !attribute.display || attribute.transparent # hide/show item #if attribute.hide diff --git a/app/assets/javascripts/app/controllers/agent_ticket_create.coffee b/app/assets/javascripts/app/controllers/agent_ticket_create.coffee index 2460e0475..f9d71e238 100644 --- a/app/assets/javascripts/app/controllers/agent_ticket_create.coffee +++ b/app/assets/javascripts/app/controllers/agent_ticket_create.coffee @@ -24,7 +24,7 @@ class App.TicketCreate extends App.Controller split = "/#{@ticket_id}/#{@article_id}" # update navbar highlighting - @navupdate '#ticket/create/id/' + @id + split + @navupdate "#ticket/create/id/#{@id}#{split}" # lisen if view need to be rerendered @bind 'ticket_create_rerender', (defaults) => @@ -174,7 +174,7 @@ class App.TicketCreate extends App.Controller t.body = App.Utils.text2html(a.body) # render page - @render( options: t ) + @render(options: t) ) render: (template = {}) -> @@ -427,10 +427,10 @@ class App.TicketCreate extends App.Controller # notify UI ui.notify - type: 'success', - msg: App.i18n.translateInline('Ticket %s created!', @number), + type: 'success' + msg: App.i18n.translateInline('Ticket %s created!', @number) link: "#ticket/zoom/#{@id}" - timeout: 4000, + timeout: 4000 # close ticket create task App.TaskManager.remove(ui.task_key) @@ -439,8 +439,8 @@ class App.TicketCreate extends App.Controller ui.scrollTo() # access to group - group_ids = App.Session.get('group_ids') - if group_ids && _.contains(group_ids, @group_id) + group_ids = _.filter(App.Session.get('group_ids'), (id) -> id.toString()) + if group_ids && _.contains(group_ids, @group_id.toString()) ui.navigate "#ticket/zoom/#{@id}" return diff --git a/db/migrate/20160307000001_only_one_group.rb b/db/migrate/20160307000001_only_one_group.rb new file mode 100644 index 000000000..569f4ebe3 --- /dev/null +++ b/db/migrate/20160307000001_only_one_group.rb @@ -0,0 +1,219 @@ + +class OnlyOneGroup < ActiveRecord::Migration + def up + ObjectManager::Attribute.add( + object: 'Ticket', + name: 'group_id', + display: 'Group', + data_type: 'select', + data_option: { + relation: 'Group', + relation_condition: { access: 'rw' }, + nulloption: true, + multiple: false, + null: false, + translate: false, + only_shown_if_selectable: true, + }, + editable: false, + active: true, + screens: { + create_middle: { + '-all-' => { + null: false, + item_class: 'column', + }, + }, + edit: { + Agent: { + null: false, + }, + }, + }, + pending_migration: false, + position: 25, + created_by_id: 1, + updated_by_id: 1, + ) + ObjectManager::Attribute.add( + object: 'User', + name: 'group_ids', + display: 'Groups', + data_type: 'checkbox', + data_option: { + multiple: true, + null: true, + relation: 'Group', + }, + editable: false, + active: true, + screens: { + signup: {}, + invite_agent: { + '-all-' => { + null: false, + only_shown_if_selectable: true, + }, + }, + invite_customer: {}, + edit: { + Admin: { + null: true, + }, + }, + view: { + '-all-' => { + shown: false, + }, + }, + }, + pending_migration: false, + position: 1700, + created_by_id: 1, + updated_by_id: 1, + ) + ObjectManager::Attribute.add( + object: 'User', + name: 'street', + display: 'Street', + data_type: 'input', + data_option: { + type: 'text', + maxlength: 100, + null: true, + }, + editable: true, + active: false, + screens: { + signup: {}, + invite_agent: {}, + invite_customer: {}, + edit: { + '-all-' => { + null: true, + }, + }, + view: { + '-all-' => { + shown: true, + }, + }, + }, + pending_migration: false, + position: 1100, + created_by_id: 1, + updated_by_id: 1, + ) + + ObjectManager::Attribute.add( + object: 'User', + name: 'zip', + display: 'Zip', + data_type: 'input', + data_option: { + type: 'text', + maxlength: 100, + null: true, + item_class: 'formGroup--halfSize', + }, + editable: true, + active: false, + screens: { + signup: {}, + invite_agent: {}, + invite_customer: {}, + edit: { + '-all-' => { + null: true, + }, + }, + view: { + '-all-' => { + shown: true, + }, + }, + }, + pending_migration: false, + position: 1200, + created_by_id: 1, + updated_by_id: 1, + ) + + ObjectManager::Attribute.add( + object: 'User', + name: 'city', + display: 'City', + data_type: 'input', + data_option: { + type: 'text', + maxlength: 100, + null: true, + item_class: 'formGroup--halfSize', + }, + editable: true, + active: false, + screens: { + signup: {}, + invite_agent: {}, + invite_customer: {}, + edit: { + '-all-' => { + null: true, + }, + }, + view: { + '-all-' => { + shown: true, + }, + }, + }, + pending_migration: false, + position: 1300, + created_by_id: 1, + updated_by_id: 1, + ) + + ObjectManager::Attribute.add( + object: 'User', + name: 'address', + display: 'Address', + data_type: 'textarea', + data_option: { + type: 'text', + maxlength: 500, + null: true, + item_class: 'formGroup--halfSize', + }, + editable: true, + active: true, + screens: { + signup: {}, + invite_agent: {}, + invite_customer: {}, + edit: { + '-all-' => { + null: true, + }, + }, + view: { + '-all-' => { + shown: true, + }, + }, + }, + pending_migration: false, + position: 1350, + created_by_id: 1, + updated_by_id: 1, + ) + + list = [] + User.all {|user| + next if !user.zip.empty? && !user.city.empty? && !user.street.empty? + #next if !user.address.empty? + list.push user + } + list + end + +end diff --git a/db/seeds.rb b/db/seeds.rb index 1b8dba617..418860f9c 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -1615,15 +1615,15 @@ Link::Object.create_if_not_exists(id: 3, name: 'Question/Answer') Link::Object.create_if_not_exists(id: 4, name: 'Idea') Link::Object.create_if_not_exists(id: 5, name: 'Bug') -Ticket::StateType.create_if_not_exists(id: 1, name: 'new' ) -Ticket::StateType.create_if_not_exists(id: 2, name: 'open' ) +Ticket::StateType.create_if_not_exists(id: 1, name: 'new') +Ticket::StateType.create_if_not_exists(id: 2, name: 'open') Ticket::StateType.create_if_not_exists(id: 3, name: 'pending reminder') Ticket::StateType.create_if_not_exists(id: 4, name: 'pending action') Ticket::StateType.create_if_not_exists(id: 5, name: 'closed') Ticket::StateType.create_if_not_exists(id: 6, name: 'merged') Ticket::StateType.create_if_not_exists(id: 7, name: 'removed') -Ticket::State.create_if_not_exists(id: 1, name: 'new', state_type_id: Ticket::StateType.find_by(name: 'new').id, ) +Ticket::State.create_if_not_exists(id: 1, name: 'new', state_type_id: Ticket::StateType.find_by(name: 'new').id) Ticket::State.create_if_not_exists(id: 2, name: 'open', state_type_id: Ticket::StateType.find_by(name: 'open').id) Ticket::State.create_if_not_exists(id: 3, name: 'pending reminder', state_type_id: Ticket::StateType.find_by(name: 'pending reminder').id, ignore_escalation: true) Ticket::State.create_if_not_exists(id: 4, name: 'closed', state_type_id: Ticket::StateType.find_by(name: 'closed').id, ignore_escalation: true) @@ -2183,6 +2183,7 @@ ObjectManager::Attribute.add( multiple: false, null: false, translate: false, + only_shown_if_selectable: true, }, editable: false, active: true, @@ -2876,8 +2877,8 @@ ObjectManager::Attribute.add( maxlength: 100, null: true, }, - editable: false, - active: true, + editable: true, + active: false, screens: { signup: {}, invite_agent: {}, @@ -2908,8 +2909,8 @@ ObjectManager::Attribute.add( null: true, item_class: 'formGroup--halfSize', }, - editable: false, - active: true, + editable: true, + active: false, screens: { signup: {}, invite_agent: {}, @@ -2940,8 +2941,8 @@ ObjectManager::Attribute.add( null: true, item_class: 'formGroup--halfSize', }, - editable: false, - active: true, + editable: true, + active: false, screens: { signup: {}, invite_agent: {}, @@ -2972,7 +2973,7 @@ ObjectManager::Attribute.add( null: true, item_class: 'formGroup--halfSize', }, - editable: false, + editable: true, active: true, screens: { signup: {}, @@ -3146,6 +3147,7 @@ ObjectManager::Attribute.add( invite_agent: { '-all-' => { null: false, + only_shown_if_selectable: true, }, }, invite_customer: {}, diff --git a/test/browser/aaa_getting_started_test.rb b/test/browser/aaa_getting_started_test.rb index 6f0a2b757..23258ecc3 100644 --- a/test/browser/aaa_getting_started_test.rb +++ b/test/browser/aaa_getting_started_test.rb @@ -142,9 +142,10 @@ class AaaGettingStartedTest < TestCase css: '.js-agent input[name="email"]', value: 'agent1@example.com', ) - click( - css: '.js-agent input[name="group_ids"][value="1"]', - ) + # not needed since we hide group selections if only one group exists + #click( + # css: '.js-agent input[name="group_ids"][value="1"]', + #) click( css: '.js-agent .btn--success', ) diff --git a/test/browser/abb_one_group_test.rb b/test/browser/abb_one_group_test.rb new file mode 100644 index 000000000..06632f1e1 --- /dev/null +++ b/test/browser/abb_one_group_test.rb @@ -0,0 +1,185 @@ +# encoding: utf-8 +require 'browser_test_helper' + +class AgentTicketActionLevel0Test < TestCase + + def test_aaa_agent_ticket_create_with_one_group + agent = "bob.smith_one_group#{rand(99_999_999)}" + + @browser = browser_instance + login( + username: 'master@example.com', + password: 'test', + url: browser_url, + ) + tasks_close_all() + + # create new ticket + ticket1 = ticket_create( + data: { + customer: 'nico', + Group: '-NONE-', + title: 'some subject 123äöü - one group 1', + body: 'some body 123äöü - one group 1', + }, + ) + sleep 1 + + # update ticket + ticket_update( + data: { + State: 'closed', + Group: '-NONE-', + body: 'some body 1234 äöüß - one group 1 - update', + }, + ) + + tasks_close_all() + + # invite agent (with one group) + click( + css: '#navigation a[href="#dashboard"]', + ) + click( + css: '.active.content .tab[data-area="first-steps-widgets"]', + ) + watch_for( + css: '.active.content', + value: 'Configuration', + ) + click( + css: '.active.content .js-inviteAgent', + ) + sleep 4 + set( + css: '.modal [name="firstname"]', + value: 'Bob', + ) + set( + css: '.modal [name="lastname"]', + value: 'Smith', + ) + set( + css: '.modal [name="email"]', + value: "#{agent}@example.com", + ) + exists_not( + css: '.modal select[name="group_ids"]', + ) + click( + css: '.modal button.btn.btn--primary', + fast: true, + ) + watch_for( + css: 'body div.modal', + value: 'Sending', + ) + watch_for_disappear( + css: 'body div.modal', + value: 'Sending', + ) + + end + + def test_bbb_customer_ticket_create_with_one_group + + @browser = browser_instance + login( + username: 'nicole.braun@zammad.org', + password: 'test', + url: browser_url, + ) + + # customer ticket create + click(css: 'a[href="#new"]') + click(css: 'a[href="#customer_ticket_new"]') + sleep 2 + + exists_not( + css: '.newTicket select[name="group_id"]', + ) + + set( + css: '.newTicket input[name="title"]', + value: 'one group', + ) + set( + css: '.newTicket [data-name="body"]', + value: 'one group body', + ) + click(css: '.newTicket button.js-submit') + sleep 5 + + # check if ticket is shown + location_check(url: '#ticket/zoom/') + + match( + css: '.active div.ticket-article', + value: 'one group body', + no_quote: true, + ) + + # update ticket + set( + css: '.active [data-name="body"]', + value: 'one group - some body 1234 äöüß', + no_click: true, + ) + + task_type( + type: 'stayOnTab', + ) + + click(css: '.active .js-submit') + + watch_for( + css: '.active div.ticket-article', + value: 'one group - some body 1234 äöüß', + ) + + end + + def test_ccc_agent_ticket_create_with_more_groups + + @browser = browser_instance + login( + username: 'master@example.com', + password: 'test', + url: browser_url, + ) + tasks_close_all() + + group_create( + data: { + name: "some group #{rand(999_999_999)}", + member: [ + 'master@example.com', + 'agent1@example.com', + ], + }, + ) + + # create new ticket + ticket1 = ticket_create( + data: { + customer: 'nico', + group: 'Users', + title: 'some subject 123äöü - one group 2', + body: 'some body 123äöü - one group 2', + }, + ) + sleep 1 + + # update ticket + ticket_update( + data: { + body: 'some body 1234 äöüß - one group 2 - update', + Group: 'Users', + }, + ) + + tasks_close_all() + + end + +end diff --git a/test/browser/first_steps_test.rb b/test/browser/first_steps_test.rb index 415e8d0ac..692162936 100644 --- a/test/browser/first_steps_test.rb +++ b/test/browser/first_steps_test.rb @@ -14,18 +14,15 @@ class FirstStepsTest < TestCase url: browser_url, ) tasks_close_all() - click( - css: '.active.content .tab[data-area="first-steps-widgets"]', - ) + + click(css: '.active.content .tab[data-area="first-steps-widgets"]') watch_for( css: '.active.content', value: 'Configuration', ) - # invite agent - click( - css: '.active.content .js-inviteAgent', - ) + # invite agent (with more then one group) + click(css: '.active.content .js-inviteAgent') sleep 4 set( css: '.modal [name="firstname"]', @@ -39,9 +36,7 @@ class FirstStepsTest < TestCase css: '.modal [name="email"]', value: "#{agent}@example.com", ) - check( - css: '.modal [name="group_ids"]', - ) + check(css: '.modal [name="group_ids"]') click( css: '.modal button.btn.btn--primary', fast: true, @@ -56,9 +51,7 @@ class FirstStepsTest < TestCase ) # invite customer - click( - css: '.active.content .js-inviteCustomer', - ) + click(css: '.active.content .js-inviteCustomer') sleep 4 set( css: '.modal [name="firstname"]', @@ -116,18 +109,14 @@ class FirstStepsTest < TestCase ) # check update - click( - css: '.active.content a[href="#channels/form"]', - ) + click(css: '.active.content a[href="#channels/form"]') sleep 2 switch( css: '#content .js-formSetting', type: 'on', ) sleep 2 - click( - css: '#navigation a[href="#dashboard"]', - ) + click(css: '#navigation a[href="#dashboard"]') hit = false (1..38).each { next if !@browser.find_elements(css: '.active.content a[href="#channels/form"].todo.is-done')[0]