From c4c4ef35efea0f48159525c3a6b4fe3b5a419f39 Mon Sep 17 00:00:00 2001 From: Martin Edenhofer Date: Wed, 10 Sep 2014 01:42:20 +0200 Subject: [PATCH] Init version of object manager. --- .../_application_controller_form.js.coffee | 230 ++-- .../_application_controller_generic.js.coffee | 12 +- .../_application_controller_table.js.coffee | 7 +- .../controllers/agent_ticket_create.js.coffee | 135 +- .../customer_ticket_create.js.coffee | 76 +- .../app/controllers/signup.js.coffee | 2 +- .../app/controllers/ticket_zoom.js.coffee | 145 ++- .../app/controllers/widget/user.js.coffee | 15 +- .../app/lib/app_post/auth.js.coffee | 15 +- .../app/models/_application_model.js.coffee | 68 +- .../javascripts/app/models/user.js.coffee | 28 +- .../app/views/agent_ticket_create.jst.eco | 4 +- .../app/views/customer_ticket_create.jst.eco | 4 +- .../app/views/generic/attribute.jst.eco | 2 +- .../app/views/generic/date.jst.eco | 1 + app/controllers/sessions_controller.rb | 16 +- app/controllers/tickets_controller.rb | 42 +- app/models/object_manager.rb | 147 +++ app/models/ticket.rb | 2 + app/models/ticket/screen_options.rb | 75 +- .../20140831000001_create_object_manager.rb | 1137 +++++++++++++++++ lib/session_helper.rb | 10 + public/assets/tests/form.js | 51 + public/assets/tests/model.js | 200 +++ .../agent_ticket_actions_level3_test.rb | 49 +- .../agent_ticket_actions_level5_test.rb | 22 +- test/browser/agent_user_manage_test.rb | 6 +- test/browser/customer_ticket_create_test.rb | 2 +- test/browser/taskbar_task_test.rb | 12 +- test/browser_test_helper.rb | 20 +- 30 files changed, 2119 insertions(+), 416 deletions(-) create mode 100644 app/assets/javascripts/app/views/generic/date.jst.eco create mode 100644 app/models/object_manager.rb create mode 100644 db/migrate/20140831000001_create_object_manager.rb create mode 100644 public/assets/tests/model.js diff --git a/app/assets/javascripts/app/controllers/_application_controller_form.js.coffee b/app/assets/javascripts/app/controllers/_application_controller_form.js.coffee index 56450de6b..8b14bf64e 100644 --- a/app/assets/javascripts/app/controllers/_application_controller_form.js.coffee +++ b/app/assets/javascripts/app/controllers/_application_controller_form.js.coffee @@ -2,7 +2,11 @@ class App.ControllerForm extends App.Controller constructor: (params) -> for key, value of params @[key] = value - @attribute_count = 0 + + if !@handlers + @handlers = [] + @handlers.push @_showHideToggle + @handlers.push @_requiredMandantoryToggle if !@form @form = @formGen() @@ -23,37 +27,62 @@ class App.ControllerForm extends App.Controller fieldset = $('
') - for attribute_clean in @model.configure_attributes - attribute = _.clone( attribute_clean ) + # collect form attributes + @attributes = [] + if @model.attributesGet + attributesClean = @model.attributesGet(@screen) + else + attributesClean = App.Model.attributesGet(@screen, @model.configure_attributes ) - if !attribute.readonly && ( !@required || @required && attribute[@required] ) + for attributeName, attribute of attributesClean - @attribute_count = @attribute_count + 1 + # ignore read only attributes + if !attribute.readonly - # add item - item = @formGenItem( attribute, @model.className, fieldset ) - item.appendTo(fieldset) + # check generic filter + if @filter && !attribute.filter + if @filter[ attributeName ] + attribute.filter = @filter[ attributeName ] - # if password, add confirm password item - if attribute.type is 'password' + @attributes.push attribute - # set selected value passed on current params - if @params - if attribute.name of @params - attribute.value = @params[attribute.name] + attribute_count = 0 + className = @model.className + '_' + Math.floor( Math.random() * 999999 ).toString() - # rename display and name to _confirm - if !attribute.single - attribute.display = attribute.display + ' (confirm)' - attribute.name = attribute.name + '_confirm'; - item = @formGenItem( attribute, @model.className, fieldset ) - item.appendTo(fieldset) + for attribute in @attributes + attribute_count = attribute_count + 1 + + # add item + item = @formGenItem( attribute, className, fieldset, attribute_count ) + item.appendTo(fieldset) + + # if password, add confirm password item + if attribute.type is 'password' + + # set selected value passed on current params + if @params + if attribute.name of @params + attribute.value = @params[attribute.name] + + # rename display and name to _confirm + if !attribute.single + attribute.display = attribute.display + ' (confirm)' + attribute.name = attribute.name + '_confirm'; + item = @formGenItem( attribute, className, fieldset, attribute_count ) + item.appendTo(fieldset) if @fullForm if !@formClass @formClass = '' fieldset = $('
').prepend( fieldset ) + # bind form events + if @events + for eventSelector, callback of @events + do (eventSelector, callback) => + evs = eventSelector.split(' ') + fieldset.find( evs[1] ).bind(evs[0], (e) => callback(e) ) + # return form return fieldset @@ -131,14 +160,14 @@ class App.ControllerForm extends App.Controller ### - formGenItem: (attribute_config, classname, form ) -> - attribute = _.clone( attribute_config ) + formGenItem: (attribute_config, classname, form, attribute_count ) -> + attribute = clone( attribute_config ) # create item id attribute.id = classname + '_' + attribute.name # set autofocus - if @autofocus && @attribute_count is 1 + if @autofocus && attribute_count is 1 attribute.autofocus = 'autofocus' # set required option @@ -234,6 +263,22 @@ class App.ControllerForm extends App.Controller else if attribute.tag is 'select' item = $( App.view('generic/select')( attribute: attribute ) ) + # date + else if attribute.tag is 'date' + attribute.type = 'text' + item = $( App.view('generic/date')( attribute: attribute ) ) + #item.datetimepicker({ + # format: 'Y.m.d' + #}); + + # date + else if attribute.tag is 'datetime' + attribute.type = 'text' + item = $( App.view('generic/date')( attribute: attribute ) ) + #item.datetimepicker({ + # format: 'Y.m.d H:i' + #}); + # timezone else if attribute.tag is 'timezone' attribute.options = [] @@ -717,7 +762,7 @@ class App.ControllerForm extends App.Controller b = (event, item) => # set html form attribute - $(local_attribute).val(item.id) + $(local_attribute).val(item.id).trigger('change') $(local_attribute + '_autocompletion_value_shown').val(item.value) # call calback @@ -738,8 +783,11 @@ class App.ControllerForm extends App.Controller } ) ### + source = attribute.source + if typeof(source) is 'string' + source = source.replace('#{@apiPath}', App.Config.get('api_path') ); $(local_attribute_full).autocomplete( - source: attribute.source, + source: source, minLength: attribute.minLengt || 3, select: ( event, ui ) => b(event, ui.item) @@ -1221,63 +1269,12 @@ class App.ControllerForm extends App.Controller else item = $( App.view('generic/input')( attribute: attribute ) ) - if attribute.onchange - if typeof attribute.onchange is 'function' - attribute.onchange(attribute) - else - for i of attribute.onchange - a = i.split(/__/) - if a[1] - if a[0] is attribute.name - @attribute = attribute - @classname = classname - @attributes_clean = attributes_clean - @change = a - b = => -# console.log 'aaa', @attribute - attribute = @attribute - change = @change - classname = @classname - attributes_clean = @attributes_clean - ui = @ - $( '#' + @attribute.id ).bind('change', -> - ui.log 'change', @, attribute, change - ui.log change[0] + ' has changed - changing ' + change[1] - - item = $( ui.formGenItem(attribute, classname, attributes_clean) ) - ui.log item, classname - ) - App.Delay.set( b, 100, undefined, 'form_change' ) -# if attribute.onchange[] - - ui = @ - item.bind('change', -> - if ui.form_data - params = App.ControllerForm.params(@) - for i of ui.form_data - a = i.split(/__/) - if a[1] && a[0] is attribute.name - newListAttribute = i - changedAttribute = a[0] - toChangeAttribute = a[1] - - # get new option list - newListAttributes = ui['form_data'][newListAttribute][ params['group_id'] ] - - # find element to replace - for item in ui.model.configure_attributes - if item.name is toChangeAttribute - item.display = false - item['filter'][toChangeAttribute] = newListAttributes - if params[changedAttribute] - item.default = params[toChangeAttribute] - if !item.default - delete item['default'] - newElement = ui.formGenItem( item, classname, form ) - - # replace new option list - form.find('[name="' + toChangeAttribute + '"]').replaceWith( newElement ) - ) + if @handlers + item.bind('change', (e) => + params = App.ControllerForm.params( $(e.target) ) + for handler in @handlers + handler(params, attribute, @attributes, classname, form, @) + ) # bind dependency if @dependency @@ -1339,6 +1336,44 @@ class App.ControllerForm extends App.Controller el.find('[name="' + key + '"]').parents('.form-group').addClass('hide') el.find('[name="' + key + '"]').addClass('is-hidden') + _mandantory: (name, el = @el) -> + if !_.isArray(name) + name = [name] + for key in name + el.find('[name="' + key + '"]').attr('required', true) + el.find('[name="' + key + '"]').parents('.form-group').find('label span').html('*') + + _optional: (name, el = @el) -> + if !_.isArray(name) + name = [name] + for key in name + el.find('[name="' + key + '"]').attr('required', false) + el.find('[name="' + key + '"]').parents('.form-group').find('label span').html('') + + _showHideToggle: (params, changedAttribute, attributes, classname, form, ui) => + for attribute in attributes + if attribute.shown_if + hit = false + for refAttribute, refValue of attribute.shown_if + if params[refAttribute] && params[refAttribute].toString() is refValue.toString() + hit = true + if hit + ui._show(attribute.name) + else + ui._hide(attribute.name) + + _requiredMandantoryToggle: (params, changedAttribute, attributes, classname, form, ui) => + for attribute in attributes + if attribute.required_if + hit = false + for refAttribute, refValue of attribute.required_if + if params[refAttribute] && params[refAttribute].toString() is refValue.toString() + hit = true + if hit + ui._mandantory(attribute.name) + else + ui._optional(attribute.name) + # sort attribute.options _sortOptions: (attribute) -> @@ -1399,6 +1434,7 @@ class App.ControllerForm extends App.Controller list = [] if attribute.filter + App.Log.debug 'ControllerForm', '_getRelationOptionList:filter', attribute.filter # function based filter @@ -1426,6 +1462,22 @@ class App.ControllerForm extends App.Controller if record['id'] is key list.push record + # data based filter + else if attribute.filter && _.isArray attribute.filter + + App.Log.debug 'ControllerForm', '_getRelationOptionList:filter-array', attribute.filter + + # check all records + for record in App[ attribute.relation ].search( sortBy: attribute.sortBy ) + + # check all filter attributes + for key in attribute.filter + + # check all filter values as array + # if it's matching, use it for selection + if record['id'] is key + list.push record + # no data filter matched else App.Log.debug 'ControllerForm', '_getRelationOptionList:filter-data no filter matched' @@ -1512,8 +1564,9 @@ class App.ControllerForm extends App.Controller validate: (params) -> App.Model.validate( - model: @model, - params: params, + model: @model + params: params + screen: @screen ) # get all params of the form @@ -1637,13 +1690,8 @@ class App.ControllerForm extends App.Controller # show new errors for key, msg of data.errors - $(data.form).parents().find('[name*="' + key + '"]').parents('div .form-group').addClass('has-error') - $(data.form).parents().find('[name*="' + key + '"]').parent().find('.help-inline').html(msg) + $(data.form).parents().find('[name="' + key + '"]').parents('div .form-group').addClass('has-error') + $(data.form).parents().find('[name="' + key + '"]').parent().find('.help-inline').html(msg) # set autofocus $(data.form).parents().find('.has-error').find('input, textarea').first().focus() - -# # enable form again -# if $(data.form).parents().find('.has-error').html() -# @formEnable(data.form) - diff --git a/app/assets/javascripts/app/controllers/_application_controller_generic.js.coffee b/app/assets/javascripts/app/controllers/_application_controller_generic.js.coffee index 259554e34..53eb612ce 100644 --- a/app/assets/javascripts/app/controllers/_application_controller_generic.js.coffee +++ b/app/assets/javascripts/app/controllers/_application_controller_generic.js.coffee @@ -7,11 +7,11 @@ class App.ControllerGenericNew extends App.ControllerModal @html App.view('generic/admin/new')( head: @pageData.object ) new App.ControllerForm( - el: @el.find('#object_new'), - model: App[ @genericObject ], - params: @item, - required: @required, - autofocus: true, + el: @el.find('#object_new') + model: App[ @genericObject ] + params: @item + screen: @screen || 'edit' + autofocus: true ) @modalShow() @@ -59,7 +59,7 @@ class App.ControllerGenericEdit extends App.ControllerModal el: @el.find('#object_edit') model: App[ @genericObject ] params: @item - required: @required + screen: @screen || 'edit' autofocus: true ) @modalShow() diff --git a/app/assets/javascripts/app/controllers/_application_controller_table.js.coffee b/app/assets/javascripts/app/controllers/_application_controller_table.js.coffee index 263aeb88e..295ac7565 100644 --- a/app/assets/javascripts/app/controllers/_application_controller_table.js.coffee +++ b/app/assets/javascripts/app/controllers/_application_controller_table.js.coffee @@ -99,6 +99,7 @@ class App.ControllerTable extends App.Controller data.model = {} overview = data.overview || data.model.configure_overview || [] attributes = data.attributes || data.model.configure_attributes || {} + attributes = App.Model.attributesGet(false, attributes) destroy = data.model.configure_delete # check if table is empty @@ -146,13 +147,13 @@ class App.ControllerTable extends App.Controller header = [] for item in overview headerFound = false - for attribute in attributes - if attribute.name is item + for attributeName, attribute of attributes + if attributeName is item headerFound = true header.push attribute else rowWithoutId = item + '_id' - if attribute.name is rowWithoutId + if attributeName is rowWithoutId headerFound = true header.push attribute diff --git a/app/assets/javascripts/app/controllers/agent_ticket_create.js.coffee b/app/assets/javascripts/app/controllers/agent_ticket_create.js.coffee index 5bb518847..828699b36 100644 --- a/app/assets/javascripts/app/controllers/agent_ticket_create.js.coffee +++ b/app/assets/javascripts/app/controllers/agent_ticket_create.js.coffee @@ -14,7 +14,7 @@ class App.TicketCreate extends App.Controller # set title @form_id = App.ControllerForm.formId() - @edit_form = undefined + @form_meta = undefined # set article attributes default_type = 'call_inbound' @@ -25,14 +25,17 @@ class App.TicketCreate extends App.Controller sender: 'Customer' article: 'phone' title: 'Call Inbound' + screen: 'create_phone_in' call_outbound: sender: 'Agent' article: 'phone' title: 'Call Outbound' + screen: 'create_phone_out' email: sender: 'Agent' article: 'email' title: 'Email' + screen: 'create_email_out' @article_attributes = article_sender_type_map[@type] # remember split info if exists @@ -57,9 +60,9 @@ class App.TicketCreate extends App.Controller meta: => text = App.i18n.translateInline( @article_attributes['title'] ) - subject = @el.find('[name=subject]').val() - if subject - text = "#{text}: #{subject}" + title = @el.find('[name=title]').val() + if title + text = "#{text}: #{title}" meta = url: @url() head: text @@ -100,7 +103,7 @@ class App.TicketCreate extends App.Controller if cache && !params.ticket_id && !params.article_id # get edit form attributes - @edit_form = cache.edit_form + @form_meta = cache.form_meta # load assets App.Collection.loadAssets( cache.assets ) @@ -108,7 +111,7 @@ class App.TicketCreate extends App.Controller @render() else @ajax( - id: 'ticket_create' + id: 'ticket_create' + @task_key type: 'GET' url: @apiPath + '/ticket_create' data: @@ -121,7 +124,7 @@ class App.TicketCreate extends App.Controller App.Store.write( 'ticket_create_attributes', data ) # get edit form attributes - @edit_form = data.edit_form + @form_meta = data.form_meta # load assets App.Collection.loadAssets( data.assets ) @@ -143,22 +146,6 @@ class App.TicketCreate extends App.Controller render: (template = {}) -> - # set defaults - defaults = - state_id: App.TicketState.findByAttribute( 'name', 'open' ).id - priority_id: App.TicketPriority.findByAttribute( 'name', '2 normal' ).id - - # generate form - configure_attributes = [ - { name: 'customer_id', display: 'Customer', tag: 'autocompletion', type: 'text', limit: 200, null: false, relation: 'User', class: 'span7', autocapitalize: false, help: 'Select the customer of the Ticket or create one.', helpLink: '»', callback: @localUserInfo, source: @apiPath + '/users/search', minLengt: 2 }, - { name: 'group_id', display: 'Group', tag: 'select', multiple: false, null: false, filter: @edit_form, nulloption: true, relation: 'Group', default: defaults['group_id'], class: 'span7', }, - { name: 'owner_id', display: 'Owner', tag: 'select', multiple: false, null: true, filter: @edit_form, nulloption: true, relation: 'User', default: defaults['owner_id'], class: 'span7', }, - { name: 'tags', display: 'Tags', tag: 'tag', type: 'text', null: true, default: defaults['tags'], class: 'span7', }, - { name: 'subject', display: 'Subject', tag: 'input', type: 'text', limit: 200, null: false, default: defaults['subject'], class: 'span7', }, - { name: 'body', display: 'Text', tag: 'textarea', rows: 8, null: false, default: defaults['body'], class: 'span7', upload: true }, - { name: 'state_id', display: 'State', tag: 'select', multiple: false, null: false, filter: @edit_form, relation: 'TicketState', default: defaults['state_id'], translate: true, class: 'medium' }, - { name: 'priority_id', display: 'Priority', tag: 'select', multiple: false, null: false, filter: @edit_form, relation: 'TicketPriority', default: defaults['priority_id'], translate: true, class: 'medium' }, - ] @html App.view('agent_ticket_create')( head: 'New Ticket' title: @article_attributes['title'] @@ -172,14 +159,50 @@ class App.TicketCreate extends App.Controller else if App.TaskManager.get(@task_key) && !_.isEmpty( App.TaskManager.get(@task_key).state ) params = App.TaskManager.get(@task_key).state + formChanges = (params, attribute, attributes, classname, form, ui) => + if @form_meta.dependencies && @form_meta.dependencies[attribute.name] + dependency = @form_meta.dependencies[attribute.name][ parseInt(params[attribute.name]) ] + if dependency + + for fieldNameToChange of dependency + filter = [] + if dependency[fieldNameToChange] + filter = dependency[fieldNameToChange] + + # find element to replace + for item in attributes + if item.name is fieldNameToChange + item.display = false + item['filter'] = {} + item['filter'][ fieldNameToChange ] = filter + item.default = params[item.name] + #if !item.default + # delete item['default'] + newElement = ui.formGenItem( item, classname, form ) + + # replace new option list + form.find('[name="' + fieldNameToChange + '"]').replaceWith( newElement ) + new App.ControllerForm( - el: @el.find('.ticket_create') - form_id: @form_id - model: - configure_attributes: configure_attributes - className: 'create_' + @type + '_' + @id + el: @el.find('.ticket-form') + form_id: @form_id + model: App.Ticket + screen: @article_attributes['screen'] + events: + 'change [name=customer_id]': @localUserInfo + handlers: [ + formChanges + ] + filter: @form_meta.filter autofocus: true - form_data: @edit_form + params: params + ) + + new App.ControllerForm( + el: @el.find('.article-form') + form_id: @form_id + model: App.TicketArticle + screen: @article_attributes['screen'] params: params ) @@ -193,20 +216,23 @@ class App.TicketCreate extends App.Controller # show text module UI @textModule = new App.WidgetTextModule( - el: @el.find('.ticket-create').find('textarea') + el: @el.find('form').find('textarea') ) # start auto save @autosave() - localUserInfo: (params) => + localUserInfo: (e) => + + params = App.ControllerForm.params( $(e.target).closest('form') ) # update text module UI callback = (user) => - @textModule.reload( - ticket: - customer: user - ) + if @textModule + @textModule.reload( + ticket: + customer: user + ) @userInfo( user_id: params.customer_id @@ -234,7 +260,7 @@ class App.TicketCreate extends App.Controller params.title = params.subject # create ticket - object = new App.Ticket + ticket = new App.Ticket # find sender_id sender = App.TicketArticleSender.findByAttribute( 'name', @article_attributes['sender'] ) @@ -248,6 +274,7 @@ class App.TicketCreate extends App.Controller params['article'] = { to: (group && group.name) || '' from: params.customer_id_autocompletion + cc: params.cc subject: params.subject body: params.body type_id: type.id @@ -258,6 +285,7 @@ class App.TicketCreate extends App.Controller params['article'] = { from: (group && group.name) || '' to: params.customer_id_autocompletion + cc: params.cc subject: params.subject body: params.body type_id: type.id @@ -265,15 +293,30 @@ class App.TicketCreate extends App.Controller form_id: @form_id } - object.load(params) + ticket.load(params) # validate form - errors = object.validate() + ticketErrors = ticket.validate( + screen: @article_attributes['screen'] + ) + article = new App.TicketArticle + article.load(params['article']) + articleErrors = article.validate( + screen: @article_attributes['screen'] + ) + for key, value of articleErrors + if !ticketErrors + ticketErrors = {} + ticketErrors[key] = value # show errors in form - if errors - @log 'error', errors - @formValidate( form: e.target, errors: errors ) + if ticketErrors + @log 'error', ticketErrors + @formValidate( + form: e.target + errors: ticketErrors + screen: @article_attributes['screen'] + ) # save ticket, create article else @@ -281,7 +324,7 @@ class App.TicketCreate extends App.Controller # disable form @formDisable(e) ui = @ - object.save( + ticket.save( done: -> # notify UI @@ -322,10 +365,10 @@ class UserNew extends App.ControllerModal @html App.view('agent_user_create')( head: 'New User' ) new App.ControllerForm( - el: @el.find('#form-user'), - model: App.User, - required: 'quick', - autofocus: true, + el: @el.find('#form-user') + model: App.User + screen: 'edit' + autofocus: true ) @modalShow() diff --git a/app/assets/javascripts/app/controllers/customer_ticket_create.js.coffee b/app/assets/javascripts/app/controllers/customer_ticket_create.js.coffee index ce65556fb..96050555f 100644 --- a/app/assets/javascripts/app/controllers/customer_ticket_create.js.coffee +++ b/app/assets/javascripts/app/controllers/customer_ticket_create.js.coffee @@ -16,8 +16,6 @@ class Index extends App.ControllerContent @fetch(params) @navupdate '#customer_ticket_new' - @edit_form = undefined - # get data / in case also ticket data for split fetch: (params) -> @@ -26,9 +24,6 @@ class Index extends App.ControllerContent if cache - # get edit form attributes - @edit_form = cache.edit_form - # load assets App.Collection.loadAssets( cache.assets ) @@ -44,9 +39,6 @@ class Index extends App.ControllerContent # cache request App.Store.write( 'ticket_create_attributes', data ) - # get edit form attributes - @edit_form = data.edit_form - # load assets App.Collection.loadAssets( data.assets ) @@ -87,25 +79,25 @@ class Index extends App.ControllerContent return item if item && _.contains( group_ids, item.id.toString() ) ) - # generate form - configure_attributes = [ - { name: 'group_id', display: 'Group', tag: 'select', multiple: false, null: false, filter: groupFilter, nulloption: true, relation: 'Group', default: defaults['group_id'], class: 'span7', }, -# { name: 'owner_id', display: 'Owner', tag: 'select', multiple: false, null: true, filter: @edit_form, nulloption: true, relation: 'User', default: defaults['owner_id'], class: 'span7', }, - { name: 'subject', display: 'Subject', tag: 'input', type: 'text', limit: 100, null: false, default: defaults['subject'], class: 'span7', }, - { name: 'body', display: 'Text', tag: 'textarea', rows: 10, null: false, default: defaults['body'], class: 'span7', upload: true }, -# { name: 'state_id', display: 'State', tag: 'select', multiple: false, null: false, filter: @edit_form, relation: 'TicketState', default: defaults['state_id'], translate: true, class: 'medium' }, -# { name: 'priority_id', display: 'Priority', tag: 'select', multiple: false, null: false, filter: @edit_form, relation: 'TicketPriority', default: defaults['priority_id'], translate: true, class: 'medium' }, - ] @html App.view('customer_ticket_create')( head: 'New Ticket' ) new App.ControllerForm( - el: @el.find('#form_create') - form_id: @form_id - model: - configure_attributes: configure_attributes - className: 'create' + el: @el.find('.ticket-form') + form_id: @form_id + model: App.Ticket + screen: 'create_web' autofocus: true - form_data: @edit_form + filter: + group_id: groupFilter + params: defaults + ) + + new App.ControllerForm( + el: @el.find('.article-form') + form_id: @form_id + model: App.TicketArticle + screen: 'create_web' + params: defaults ) new App.ControllerDrox( @@ -128,19 +120,21 @@ class Index extends App.ControllerContent params.customer_id = @Session.get('id') # set prio - priority = App.TicketPriority.findByAttribute( 'name', '2 normal' ) - params.priority_id = priority.id + if !params.priority_id + priority = App.TicketPriority.findByAttribute( 'name', '2 normal' ) + params.priority_id = priority.id # set state - state = App.TicketState.findByAttribute( 'name', 'new' ) - params.state_id = state.id + if !params.state_id + state = App.TicketState.findByAttribute( 'name', 'new' ) + params.state_id = state.id # fillup params if !params.title params.title = params.subject # create ticket - object = new App.Ticket + ticket = new App.Ticket @log 'CustomerTicketCreate', 'notice', 'updateAttributes', params # find sender_id @@ -160,16 +154,27 @@ class Index extends App.ControllerContent form_id: @form_id } - object.load(params) + ticket.load(params) # validate form - errors = object.validate() + ticketErrors = ticket.validate( + screen: 'create_web' + ) + article = new App.TicketArticle + article.load(params['article']) + articleErrors = article.validate( + screen: 'create_web' + ) + for key, value of articleErrors + if !ticketErrors + ticketErrors = {} + ticketErrors[key] = value # show errors in form - if errors - @log 'CustomerTicketCreate', 'error', 'can not create', errors + if ticketErrors + @log 'CustomerTicketCreate', 'error', 'can not create', ticketErrors - @formValidate( form: e.target, errors: errors ) + @formValidate( form: e.target, errors: ticketErrors ) # save ticket, create article else @@ -177,7 +182,7 @@ class Index extends App.ControllerContent # disable form @formDisable(e) ui = @ - object.save( + ticket.save( done: -> # redirect to zoom @@ -189,7 +194,4 @@ class Index extends App.ControllerContent ) App.Config.set( 'customer_ticket_new', Index, 'Routes' ) - -#App.Config.set( 'CustomerTicketNew', { prio: 1600, parent: '', name: 'New Ticket', target: '#customer_ticket_new', role: ['Customer'] }, 'NavBar' ) App.Config.set( 'CustomerTicketNew', { prio: 8000, parent: '', name: 'New', target: '#customer_ticket_new', role: ['Customer'] }, 'NavBarRight' ) - diff --git a/app/assets/javascripts/app/controllers/signup.js.coffee b/app/assets/javascripts/app/controllers/signup.js.coffee index a3da92107..35abfb2cc 100644 --- a/app/assets/javascripts/app/controllers/signup.js.coffee +++ b/app/assets/javascripts/app/controllers/signup.js.coffee @@ -32,7 +32,7 @@ class Index extends App.ControllerContent new App.ControllerForm( el: @el.find('#form-signup') model: App.User - required: 'signup' + screen: 'signup' autofocus: true ) diff --git a/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee b/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee index 7006e03ef..dd8bbbcce 100644 --- a/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee +++ b/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee @@ -7,7 +7,7 @@ class App.TicketZoom extends App.Controller @navupdate '#' - @edit_form = undefined + @form_meta = undefined @ticket_id = params.ticket_id @article_id = params.article_id @signature = undefined @@ -111,7 +111,7 @@ class App.TicketZoom extends App.Controller @ticket_article_ids = data.ticket_article_ids # get edit form attributes - @edit_form = data.edit_form + @form_meta = data.form_meta # get signature @signature = data.signature @@ -181,7 +181,7 @@ class App.TicketZoom extends App.Controller new Edit( ticket: @ticket el: @el.find('.edit') - edit_form: @edit_form + form_meta: @form_meta task_key: @task_key ui: @ ) @@ -331,57 +331,55 @@ class Edit extends App.Controller formChanged: !_.isEmpty( App.TaskManager.get(@task_key).state ) ) - @configure_attributes_ticket = [ - { name: 'state_id', display: 'State', tag: 'select', multiple: false, null: true, relation: 'TicketState', filter: @edit_form, translate: true, class: 'span2', item_class: 'pull-left' }, - { name: 'priority_id', display: 'Priority', tag: 'select', multiple: false, null: true, relation: 'TicketPriority', filter: @edit_form, translate: true, class: 'span2', item_class: 'pull-left' }, - { name: 'group_id', display: 'Group', tag: 'select', multiple: false, null: true, relation: 'Group', filter: @edit_form, class: 'span2', item_class: 'pull-left' }, - { name: 'owner_id', display: 'Owner', tag: 'select', multiple: false, null: true, relation: 'User', filter: @edit_form, nulloption: true, class: 'span2', item_class: 'pull-left' }, - ] - if @isRole('Customer') - @configure_attributes_ticket = [ - { name: 'state_id', display: 'State', tag: 'select', multiple: false, null: true, relation: 'TicketState', filter: @edit_form, translate: true, class: 'span2', item_class: 'pull-left' }, - { name: 'priority_id', display: 'Priority', tag: 'select', multiple: false, null: true, relation: 'TicketPriority', filter: @edit_form, translate: true, class: 'span2', item_class: 'pull-left' }, - ] - - @configure_attributes_article = [ - { name: 'type_id', display: 'Type', tag: 'select', multiple: false, null: true, relation: 'TicketArticleType', filter: @edit_form, default: '9', translate: true, class: 'medium' }, - { name: 'internal', display: 'Visibility', tag: 'select', null: true, options: { true: 'internal', false: 'public' }, class: 'medium', item_class: '', default: false }, - { name: 'to', display: 'To', tag: 'input', type: 'text', limit: 100, null: true, class: 'span7', hide: true }, - { name: 'cc', display: 'Cc', tag: 'input', type: 'text', limit: 100, null: true, class: 'span7', hide: true }, -# { name: 'subject', display: 'Subject', tag: 'input', type: 'text', limit: 100, null: true, class: 'span7', hide: true }, - { name: 'in_reply_to', display: 'In Reply to', tag: 'input', type: 'text', limit: 100, null: true, class: 'span7', item_class: 'hide' }, - { name: 'body', display: 'Text', tag: 'textarea', rows: 6, limit: 100, null: true, class: 'span7', item_class: '', upload: true }, - ] - if @isRole('Customer') - @configure_attributes_article = [ - { name: 'to', display: 'To', tag: 'input', type: 'text', limit: 100, null: true, class: 'span7', hide: true }, - { name: 'cc', display: 'Cc', tag: 'input', type: 'text', limit: 100, null: true, class: 'span7', hide: true }, -# { name: 'subject', display: 'Subject', tag: 'input', type: 'text', limit: 100, null: true, class: 'span7', hide: true }, - { name: 'in_reply_to', display: 'In Reply to', tag: 'input', type: 'text', limit: 100, null: true, class: 'span7', item_class: 'hide' }, - { name: 'body', display: 'Text', tag: 'textarea', rows: 6, limit: 100, null: true, class: 'span7', item_class: '', upload: true }, - ] - @form_id = App.ControllerForm.formId() - defaults = ticket + defaults = ticket.attributes() + if @isRole('Customer') + delete defaults['state_id'] + delete defaults['state'] if !_.isEmpty( App.TaskManager.get(@task_key).state ) defaults = App.TaskManager.get(@task_key).state - new App.ControllerForm( - el: @el.find('.form-ticket-update') - form_id: @form_id - model: - configure_attributes: @configure_attributes_ticket - className: 'update_ticket_' + ticket.id - params: defaults - form_data: @edit_form - ) + formChanges = (params, attribute, attributes, classname, form, ui) => + if @form_meta.dependencies && @form_meta.dependencies[attribute.name] + dependency = @form_meta.dependencies[attribute.name][ parseInt(params[attribute.name]) ] + if dependency + for fieldNameToChange of dependency + filter = [] + if dependency[fieldNameToChange] + filter = dependency[fieldNameToChange] + + # find element to replace + for item in attributes + if item.name is fieldNameToChange + item.display = false + item['filter'] = {} + item['filter'][ fieldNameToChange ] = filter + item.default = params[item.name] + #if !item.default + # delete item['default'] + newElement = ui.formGenItem( item, classname, form ) + + # replace new option list + form.find('[name="' + fieldNameToChange + '"]').replaceWith( newElement ) + + new App.ControllerForm( + el: @el.find('.form-ticket-update') + form_id: @form_id + model: App.Ticket + screen: 'edit' + handlers: [ + formChanges + ] + filter: @form_meta.filter + params: defaults + ) new App.ControllerForm( el: @el.find('.form-article-update') form_id: @form_id - model: - configure_attributes: @configure_attributes_article - className: 'update_ticket_' + ticket.id - form_data: @edit_form + model: App.TicketArticle + screen: 'edit' + filter: + type_id: [1,9,5] params: defaults dependency: [ { @@ -399,13 +397,24 @@ class Edit extends App.Controller bind: { name: 'type_id' relation: 'TicketArticleType' - value: ['note', 'twitter status', 'twitter direct-message'] + value: ['note', 'phone', 'twitter status'] }, change: { action: 'hide' name: ['to', 'cc'], }, }, + { + bind: { + name: 'type_id' + relation: 'TicketArticleType' + value: ['twitter direct-message'] + }, + change: { + action: 'show' + name: ['to'], + }, + }, ] ) @@ -453,10 +462,16 @@ class Edit extends App.Controller @autosaveStop() params = @formParam(e.target) + # get ticket ticket = App.Ticket.fullLocal( @ticket.id ) @log 'notice', 'update', params, ticket + # update local ticket + + # create local article + + # find sender_id if @isRole('Customer') sender = App.TicketArticleSender.findByAttribute( 'name', 'Customer' ) @@ -469,17 +484,16 @@ class Edit extends App.Controller params.sender_id = sender.id # update ticket - ticket_update = {} - for item in @configure_attributes_ticket - ticket_update[item.name] = params[item.name] + for key, value of params + ticket[key] = value # check owner assignment if !@isRole('Customer') - if !ticket_update['owner_id'] - ticket_update['owner_id'] = 1 + if !ticket['owner_id'] + ticket['owner_id'] = 1 # check if title exists - if !ticket_update['title'] && !ticket.title + if !ticket['title'] alert( App.i18n.translateContent('Title needed') ) return @@ -505,22 +519,32 @@ class Edit extends App.Controller @autosaveStart() return - ticket.load( ticket_update ) - @log 'notice', 'update ticket', ticket_update, ticket + # submit ticket & article + @log 'notice', 'update ticket', ticket # disable form @formDisable(e) # validate ticket - errors = ticket.validate() + errors = ticket.validate( + screen: 'edit' + ) if errors @log 'error', 'update', errors + + @log 'error', errors + @formValidate( + form: e.target + errors: errors + screen: 'edit' + ) @formEnable(e) @autosaveStart() return # validate article - if params['body'] + articleAttributes = App.TicketArticle.attributesGet( 'edit' ) + if params['body'] || ( articleAttributes['body'] && articleAttributes['body']['null'] is false ) article = new App.TicketArticle params.from = @Session.get( 'firstname' ) + ' ' + @Session.get( 'lastname' ) params.ticket_id = ticket.id @@ -534,6 +558,11 @@ class Edit extends App.Controller errors = article.validate() if errors @log 'error', 'update article', errors + @formValidate( + form: e.target + errors: errors + screen: 'edit' + ) @formEnable(e) @autosaveStart() return diff --git a/app/assets/javascripts/app/controllers/widget/user.js.coffee b/app/assets/javascripts/app/controllers/widget/user.js.coffee index ac8b48d0d..a6cdf4f7f 100644 --- a/app/assets/javascripts/app/controllers/widget/user.js.coffee +++ b/app/assets/javascripts/app/controllers/widget/user.js.coffee @@ -109,13 +109,12 @@ class App.WidgetUser extends App.ControllerDrox edit: (e) => e.preventDefault() new App.ControllerGenericEdit( - id: @user_id, - genericObject: 'User', - required: 'quick', - pageData: { - title: 'Users', - object: 'User', - objects: 'Users', - }, + id: @user_id + genericObject: 'User' + screen: 'edit' + pageData: + title: 'Users' + object: 'User' + objects: 'Users' callback: @render ) diff --git a/app/assets/javascripts/app/lib/app_post/auth.js.coffee b/app/assets/javascripts/app/lib/app_post/auth.js.coffee index 20e1bf495..a9bb71617 100644 --- a/app/assets/javascripts/app/lib/app_post/auth.js.coffee +++ b/app/assets/javascripts/app/lib/app_post/auth.js.coffee @@ -69,12 +69,26 @@ class App.Auth App.Event.trigger( 'auth:logout' ) App.Event.trigger( 'ui:rerender' ) + # update model definition + if data.models + for model, attributes of data.models + for attribute in attributes + App[model].attributes.push attribute.name + App[model].configure_attributes.push attribute + return false; # clear local store if type isnt 'check' App.Event.trigger( 'clearStore' ) + # update model definition + if data.models + for model, attributes of data.models + for attribute in attributes + App[model].attributes.push attribute.name + App[model].configure_attributes.push attribute + # update config for key, value of data.config App.Config.set( key, value ) @@ -129,4 +143,3 @@ class App.Auth App.Event.trigger( 'auth:logout' ) App.Event.trigger( 'ui:rerender' ) App.Event.trigger( 'clearStore' ) - diff --git a/app/assets/javascripts/app/models/_application_model.js.coffee b/app/assets/javascripts/app/models/_application_model.js.coffee index 2d4cfca2c..4eda4c77f 100644 --- a/app/assets/javascripts/app/models/_application_model.js.coffee +++ b/app/assets/javascripts/app/models/_application_model.js.coffee @@ -64,19 +64,17 @@ class App.Model extends Spine.Model return '???' @validate: ( data = {} ) -> - attributes = _.clone( data['model'].configure_attributes ) - return if !attributes - # check params of screen if screen is requested - if data['screen'] - for attribute in attributes - if attribute.screen - if attribute && attribute.screen && attribute.screen[ data['screen'] ] && !_.isEmpty(attribute.screen[ data['screen'] ]) - for item, value of attribute.screen[ data['screen'] ] - attribute[item] = value + # based on model attrbutes + if App[ data['model'] ] && App[ data['model'] ].attributesGet + attributes = App[ data['model'] ].attributesGet( data['screen'] ) + + # based on custom attributes + else if data['model'].configure_attributes + attributes = App.Model.attributesGet( data['screen'], data['model'].configure_attributes ) # check required_if attributes - for attribute in attributes + for attributeName, attribute of attributes if attribute['required_if'] for key, values of attribute['required_if'] @@ -98,7 +96,7 @@ class App.Model extends Spine.Model # check attributes/each attribute of object errors = {} - for attribute in attributes + for attributeName, attribute of attributes # only if attribute is not read only if !attribute.readonly @@ -111,25 +109,25 @@ class App.Model extends Spine.Model if parts[0] && !parts[1] # key exists not in hash || value is '' || value is undefined - if !( attribute.name of data['params'] ) || data['params'][attribute.name] is '' || data['params'][attribute.name] is undefined - errors[attribute.name] = 'is required' + if !( attributeName of data['params'] ) || data['params'][attributeName] is '' || data['params'][attributeName] is undefined + errors[attributeName] = 'is required' else if parts[0] && parts[1] && !parts[2] # key exists not in hash || value is '' || value is undefined if !data.params[parts[0]] || !( parts[1] of data.params[parts[0]] ) || data.params[parts[0]][parts[1]] is '' || data.params[parts[0]][parts[1]] is undefined - errors[attribute.name] = 'is required' + errors[attributeName] = 'is required' else throw "can't parse '#{attribute.name}'" # check confirm password - if attribute.type is 'password' && data['params'][attribute.name] && "#{attribute.name}_confirm" of data['params'] + if attribute.type is 'password' && data['params'][attributeName] && "#{attributeName}_confirm" of data['params'] # get confirm password - if data['params'][attribute.name] isnt data['params']["#{attribute.name}_confirm"] - errors[attribute.name] = 'didn\'t match' - errors["#{attribute.name}_confirm"] = '' + if data['params'][attributeName] isnt data['params']["#{attributeName}_confirm"] + errors[attributeName] = 'didn\'t match' + errors["#{attributeName}_confirm"] = '' # return error object if !_.isEmpty(errors) @@ -139,9 +137,41 @@ class App.Model extends Spine.Model # return no errors return + ### + + attributes = App.Model.attributesGet(optionalScreen, optionalAttributesList) + + ### + + @attributesGet: (screen = undefined, attributes = false) -> + if !attributes + attributes = clone( App[ @.className ].configure_attributes ) + else + attributes = clone( attributes ) + + # in case if no configure_attributes exist + return if !attributes + attributesNew = {} + + # check params of screen if screen is requested + if screen + for attribute in attributes + if attribute.screen + if attribute && attribute.screen && attribute.screen[ screen ] && !_.isEmpty( attribute.screen[ screen ] ) + for item, value of attribute.screen[ screen ] + attribute[item] = value + attributesNew[ attribute.name ] = attribute + + if !screen || _.isEmpty( attributesNew ) + console.log(attributesNew) + for attribute in attributes + attributesNew[ attribute.name ] = attribute + + attributesNew + validate: (params = {}) -> App.Model.validate( - model: @constructor + model: @constructor.className params: @ screen: params.screen ) diff --git a/app/assets/javascripts/app/models/user.js.coffee b/app/assets/javascripts/app/models/user.js.coffee index 1f93d32c9..6460efc0d 100644 --- a/app/assets/javascripts/app/models/user.js.coffee +++ b/app/assets/javascripts/app/models/user.js.coffee @@ -6,20 +6,20 @@ class App.User extends App.Model # @hasMany 'roles', 'App.Role' @configure_attributes = [ { name: 'login', display: 'Login', tag: 'input', type: 'text', limit: 100, null: false, class: 'span4', autocapitalize: false, signup: false, quick: false }, - { name: 'firstname', display: 'Firstname', tag: 'input', type: 'text', limit: 100, null: false, class: 'span4', signup: true, quick: true, info: true, invite_agent: true }, - { name: 'lastname', display: 'Lastname', tag: 'input', type: 'text', limit: 100, null: false, class: 'span4', signup: true, quick: true, info: true, invite_agent: true }, - { name: 'email', display: 'Email', tag: 'input', type: 'email', limit: 100, null: false, class: 'span4', signup: true, quick: true, info: true, invite_agent: true }, - { name: 'web', display: 'Web', tag: 'input', type: 'url', limit: 100, null: true, class: 'span4', signup: false, quick: true, info: true }, - { name: 'phone', display: 'Phone', tag: 'input', type: 'phone', limit: 100, null: true, class: 'span4', signup: false, quick: true, info: true }, - { name: 'mobile', display: 'Mobile', tag: 'input', type: 'phone', limit: 100, null: true, class: 'span4', signup: false, quick: true, info: true }, - { name: 'fax', display: 'Fax', tag: 'input', type: 'phone', limit: 100, null: true, class: 'span4', signup: false, quick: true, info: true }, - { name: 'organization_id', display: 'Organization', tag: 'select', multiple: false, nulloption: true, null: true, relation: 'Organization', class: 'span4', signup: false, quick: true, info: true }, - { name: 'department', display: 'Department', tag: 'input', type: 'text', limit: 200, null: true, class: 'span4', signup: false, quick: true, info: true }, - { name: 'street', display: 'Street', tag: 'input', type: 'text', limit: 100, null: true, class: 'span4', signup: false, quick: true, info: true }, - { name: 'zip', display: 'Zip', tag: 'input', type: 'text', limit: 100, null: true, class: 'span4', signup: false, quick: true, info: true }, - { name: 'city', display: 'City', tag: 'input', type: 'text', limit: 100, null: true, class: 'span4', signup: false, quick: true, info: true }, - { name: 'password', display: 'Password', tag: 'input', type: 'password', limit: 50, null: true, autocomplete: 'off', class: 'span4', signup: true, quick: false, }, - { name: 'note', display: 'Note', tag: 'textarea', note: 'Notes are visible to agents only, never to customers.', limit: 250, null: true, class: 'span4', quick: true, info: true }, + { name: 'firstname', display: 'Firstname', tag: 'input', type: 'text', limit: 100, null: false, class: 'span4', signup: true, info: true, invite_agent: true }, + { name: 'lastname', display: 'Lastname', tag: 'input', type: 'text', limit: 100, null: false, class: 'span4', signup: true, info: true, invite_agent: true }, + { name: 'email', display: 'Email', tag: 'input', type: 'email', limit: 100, null: false, class: 'span4', signup: true, info: true, invite_agent: true }, + { name: 'web', display: 'Web', tag: 'input', type: 'url', limit: 100, null: true, class: 'span4', signup: false, info: true }, + { name: 'phone', display: 'Phone', tag: 'input', type: 'phone', limit: 100, null: true, class: 'span4', signup: false, info: true }, + { name: 'mobile', display: 'Mobile', tag: 'input', type: 'phone', limit: 100, null: true, class: 'span4', signup: false, info: true }, + { name: 'fax', display: 'Fax', tag: 'input', type: 'phone', limit: 100, null: true, class: 'span4', signup: false, info: true }, + { name: 'organization_id', display: 'Organization', tag: 'select', multiple: false, nulloption: true, null: true, relation: 'Organization', class: 'span4', signup: false, info: true }, + { name: 'department', display: 'Department', tag: 'input', type: 'text', limit: 200, null: true, class: 'span4', signup: false, info: true }, + { name: 'street', display: 'Street', tag: 'input', type: 'text', limit: 100, null: true, class: 'span4', signup: false, info: true }, + { name: 'zip', display: 'Zip', tag: 'input', type: 'text', limit: 100, null: true, class: 'span4', signup: false, info: true }, + { name: 'city', display: 'City', tag: 'input', type: 'text', limit: 100, null: true, class: 'span4', signup: false, info: true }, + { name: 'password', display: 'Password', tag: 'input', type: 'password', limit: 50, null: true, autocomplete: 'off', class: 'span4', signup: true, }, + { name: 'note', display: 'Note', tag: 'textarea', note: 'Notes are visible to agents only, never to customers.', limit: 250, null: true, class: 'span4', info: true }, { name: 'role_ids', display: 'Roles', tag: 'checkbox', multiple: true, null: false, relation: 'Role', class: 'span4' }, { name: 'group_ids', display: 'Groups', tag: 'checkbox', multiple: true, null: true, relation: 'Group', class: 'span4', invite_agent: true }, { name: 'active', display: 'Active', tag: 'boolean', default: true, null: true, class: 'span4' }, diff --git a/app/assets/javascripts/app/views/agent_ticket_create.jst.eco b/app/assets/javascripts/app/views/agent_ticket_create.jst.eco index 2462ec549..c81bbfd77 100644 --- a/app/assets/javascripts/app/views/agent_ticket_create.jst.eco +++ b/app/assets/javascripts/app/views/agent_ticket_create.jst.eco @@ -14,8 +14,8 @@
- -
+
+
 
diff --git a/app/assets/javascripts/app/views/customer_ticket_create.jst.eco b/app/assets/javascripts/app/views/customer_ticket_create.jst.eco index a84e55d2c..cbf63c463 100644 --- a/app/assets/javascripts/app/views/customer_ticket_create.jst.eco +++ b/app/assets/javascripts/app/views/customer_ticket_create.jst.eco @@ -11,8 +11,8 @@
- -
+
+
diff --git a/app/assets/javascripts/app/views/generic/attribute.jst.eco b/app/assets/javascripts/app/views/generic/attribute.jst.eco index 2194406ef..41af11fc8 100644 --- a/app/assets/javascripts/app/views/generic/attribute.jst.eco +++ b/app/assets/javascripts/app/views/generic/attribute.jst.eco @@ -1,5 +1,5 @@
- +
<%- @item %><% if @attribute.note: %><% end %> <% if @attribute.remove: %><% end %> diff --git a/app/assets/javascripts/app/views/generic/date.jst.eco b/app/assets/javascripts/app/views/generic/date.jst.eco new file mode 100644 index 000000000..724d3f226 --- /dev/null +++ b/app/assets/javascripts/app/views/generic/date.jst.eco @@ -0,0 +1 @@ +> \ No newline at end of file diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index dd1c6561c..c8184be83 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -33,8 +33,12 @@ class SessionsController < ApplicationController # auto population of default collections collections, assets = SessionHelper::default_collections(user) + # add session user assets assets = user.assets(assets) + # get models + models = SessionHelper::models(user) + # check logon session logon_session_key = nil if params['logon_session'] @@ -50,6 +54,7 @@ class SessionsController < ApplicationController # return new session data render :json => { :session => user, + :models => models, :collections => collections, :assets => assets, :logon_session => logon_session_key, @@ -75,9 +80,13 @@ class SessionsController < ApplicationController end if !user_id + # get models + models = SessionHelper::models() + render :json => { :error => 'no valid session', :config => config_frontend, + :models => models, } return end @@ -89,13 +98,18 @@ class SessionsController < ApplicationController # auto population of default collections collections, assets = SessionHelper::default_collections(user) + # add session user assets assets = user.assets(assets) + # get models + models = SessionHelper::models(user) + # return current session render :json => { :session => user, + :models => models, :collections => collections, - :assets => assets, + :assets => assets, :config => config_frontend, } end diff --git a/app/controllers/tickets_controller.rb b/app/controllers/tickets_controller.rb index 7b380ebab..cd0887e8f 100644 --- a/app/controllers/tickets_controller.rb +++ b/app/controllers/tickets_controller.rb @@ -255,24 +255,12 @@ class TicketsController < ApplicationController ) end - # get related users - assets = {} - assets = ticket.assets(assets) - # get attributes to update attributes_to_change = Ticket::ScreenOptions.attributes_to_change( :user => current_user, :ticket => ticket ) - attributes_to_change[:owner_id].each { |user_id| - user = User.find(user_id) - assets = user.assets(assets) - } - - attributes_to_change[:group_id__owner_id].each {|group_id, user_ids| - user_ids.each {|user_id| - user = User.find(user_id) - assets = user.assets(assets) - } - } + # get related users + assets = attributes_to_change[:assets] + assets = ticket.assets(assets) # get related articles articles = Ticket::Article.where( :ticket_id => params[:id] ) @@ -297,6 +285,7 @@ class TicketsController < ApplicationController :ticket_article_ids => article_ids, :signature => signature, :assets => assets, + :form_meta => attributes_to_change, :edit_form => attributes_to_change, } end @@ -311,20 +300,7 @@ class TicketsController < ApplicationController # :article_id => params[:article_id] ) - assets = {} - assets[ User.to_app_model ] = {} - attributes_to_change[:owner_id].each { |user_id| - user = User.find(user_id) - assets = user.assets(assets) - } - - attributes_to_change[:group_id__owner_id].each {|group_id, user_ids| - user_ids.each {|user_id| - user = User.find(user_id) - assets = user.assets(assets) - } - } - + assets = attributes_to_change[:assets] # split data split = {} if params[:ticket_id] && params[:article_id] @@ -332,12 +308,6 @@ class TicketsController < ApplicationController split[:ticket_id] = ticket.id assets = ticket.assets(assets) - owner_ids = [] - ticket.agent_of_group.each { |user| - owner_ids.push user.id - assets = user.assets(assets) - } - # get related articles article = Ticket::Article.find( params[:article_id] ) split[:article_id] = article.id @@ -348,7 +318,7 @@ class TicketsController < ApplicationController render :json => { :split => split, :assets => assets, - :edit_form => attributes_to_change, + :form_meta => attributes_to_change, } end diff --git a/app/models/object_manager.rb b/app/models/object_manager.rb new file mode 100644 index 000000000..27f918f84 --- /dev/null +++ b/app/models/object_manager.rb @@ -0,0 +1,147 @@ +# Copyright (C) 2012-2014 Zammad Foundation, http://zammad-foundation.org/ + +class ObjectManager + +=begin + +add a new activity entry for an object + + ObjectManager.listObjects() + +=end + + def self.listObjects + ['Ticket', 'TicketArticle', 'Group', 'Organization', 'User'] + end + +end + +class ObjectManager::Attribute < ApplicationModel + self.table_name = 'object_manager_attributes' + belongs_to :object_lookup, :class_name => 'ObjectLookup' + validates :name, :presence => true + store :screens + store :data_option + + +=begin + +add a new activity entry for an object + + ObjectManager::Attribute.add( + :object => 'Ticket', + :name => 'group_id', + :frontend => 'Group', + :data_type => 'select', + :data_option => { + :relation => 'Group', + :relation_condition => { :access => 'rw' }, + :multiple => false, + :null => true, + }, + :editable => false, + :active => true, + :screens => { + :create => { + '-all-' => { + :required => true, + }, + }, + :edit => { + :Agent => { + :required => true, + }, + }, + }, + :pending_migration => false, + :position => 20, + :created_by_id => 1, + :updated_by_id => 1, + :created_at => '2014-06-04 10:00:00', + :updated_at => '2014-06-04 10:00:00', + ) + + +=end + + def self.add(data) + + # lookups + if data[:object] + data[:object_lookup_id] = ObjectLookup.by_name( data[:object] ) + end + data.delete(:object) + + # check newest entry - is needed + result = ObjectManager::Attribute.where( + :object_lookup_id => data[:object_lookup_id], + :name => data[:name], + ).first + if result +# raise "ERROR: attribute #{data[:name]} for #{data[:object]} already exists" + return result.update_attributes(data) + end + + # create history + ObjectManager::Attribute.create(data) + end + + +=begin + +get list of object attributes + + attribute_list = ObjectManager::Attribute.by_object('Ticket', user) + +returns: + + [ + { :name => 'api_key', :display => 'API KEY', :tag => 'input', :null => true, :edit => true, :maxlength => 32 }, + { :name => 'api_ip_regexp', :display => 'API IP RegExp', :tag => 'input', :null => true, :edit => true }, + { :name => 'api_ip_max', :display => 'API IP Max', :tag => 'input', :null => true, :edit => true }, + ] + +=end + + def self.by_object(object, user) + + # lookups + if object + object_lookup_id = ObjectLookup.by_name( object ) + end + + # get attributes in right order + result = ObjectManager::Attribute.where( + :object_lookup_id => object_lookup_id, + :active => true, + ).order('position ASC') + attributes = [] + result.each {|item| + data = { + :name => item.name, + :display => item.display, + :tag => item.data_type, + #:null => item.null, + } + if item.screens + data[:screen] = {} + item.screens.each {|screen, roles_options | + data[:screen][screen] = {} + roles_options.each {|role, options| + if role == '-all-' + data[:screen][screen] = options + elsif user && user.is_role(role) + data[:screen][screen] = options + end + } + } + end + if item.data_option + data = data.merge( item.data_option ) + end + attributes.push data + } + attributes + end + +end \ No newline at end of file diff --git a/app/models/ticket.rb b/app/models/ticket.rb index cc78eb2a4..58178f0df 100644 --- a/app/models/ticket.rb +++ b/app/models/ticket.rb @@ -56,6 +56,8 @@ class Ticket < ApplicationModel belongs_to :create_article_type, :class_name => 'Ticket::Article::Type' belongs_to :create_article_sender, :class_name => 'Ticket::Article::Sender' + self.inheritance_column = nil + attr_accessor :callback_loop =begin diff --git a/app/models/ticket/screen_options.rb b/app/models/ticket/screen_options.rb index fb0246d2c..9e7037882 100644 --- a/app/models/ticket/screen_options.rb +++ b/app/models/ticket/screen_options.rb @@ -50,6 +50,9 @@ returns params[:article] = self.find( params[:article_id] ) end + filter = {} + assets = {} + # get ticket states state_ids = [] if params[:ticket] @@ -63,44 +66,21 @@ returns state_type = Ticket::StateType.where( :name => type ).first if state_type state_type.states.each {|state| + assets = state.assets(assets) state_ids.push state.id } end } - - # get owner - owner_ids = [] - if params[:ticket] - params[:ticket].agent_of_group.each { |user| - owner_ids.push user.id - } - end - - # get group - group_ids = [] - Group.where( :active => true ).each { |group| - group_ids.push group.id - } - - # get group / user relations - agents = {} - Ticket::ScreenOptions.agents.each { |user| - agents[ user.id ] = 1 - } - groups_users = {} - group_ids.each {|group_id| - groups_users[ group_id ] = [] - Group.find( group_id ).users.each {|user| - next if !agents[ user.id ] - groups_users[ group_id ].push user.id - } - } + filter[:state_id] = state_ids # get priorities priority_ids = [] Ticket::Priority.where( :active => true ).each { |priority| + assets = priority.assets(assets) priority_ids.push priority.id } + filter[:priority_id] = priority_ids + type_ids = [] if params[:ticket] @@ -115,14 +95,29 @@ returns end } end + filter[:type_id] = type_ids + + # get group / user relations + agents = {} + Ticket::ScreenOptions.agents.each { |user| + agents[ user.id ] = 1 + } + + dependencies = { :group_id => { '' => [] } } + Group.where( :active => true ).each { |group| + assets = group.assets(assets) + dependencies[:group_id][group.id] = { :owner_id => [] } + group.users.each {|user| + next if !agents[ user.id ] + assets = user.assets(assets) + dependencies[:group_id][ group.id ][ :owner_id ].push user.id + } + } return { - :type_id => type_ids, - :state_id => state_ids, - :priority_id => priority_ids, - :owner_id => owner_ids, - :group_id => group_ids, - :group_id__owner_id => groups_users, + :assets => assets, + :filter => filter, + :dependencies => dependencies, } end @@ -131,8 +126,8 @@ returns list tickets by customer groupd in state categroie open and closed result = Ticket::ScreenOptions.list_by_customer( - :customer_id => 123, - :limit => 15, # optional, default 15 + :customer_id => 123, + :limit => 15, # optional, default 15 ) returns @@ -152,13 +147,13 @@ returns # get tickets tickets_open = Ticket.where( - :customer_id => data[:customer_id], - :state_id => state_list_open + :customer_id => data[:customer_id], + :state_id => state_list_open ).limit( data[:limit] || 15 ).order('created_at DESC') tickets_closed = Ticket.where( - :customer_id => data[:customer_id], - :state_id => state_list_closed + :customer_id => data[:customer_id], + :state_id => state_list_closed ).limit( data[:limit] || 15 ).order('created_at DESC') return { diff --git a/db/migrate/20140831000001_create_object_manager.rb b/db/migrate/20140831000001_create_object_manager.rb new file mode 100644 index 000000000..b60c7de2e --- /dev/null +++ b/db/migrate/20140831000001_create_object_manager.rb @@ -0,0 +1,1137 @@ +class CreateObjectManager < ActiveRecord::Migration + def up + add_column :tickets, :pending_time, :timestamp, :null => true + add_index :tickets, [:pending_time] + + add_column :tickets, :type, :string, :limit => 100, :null => true + add_index :tickets, [:type] + + create_table :object_manager_attributes do |t| + t.references :object_lookup, :null => false + t.column :name, :string, :limit => 200, :null => false + t.column :display, :string, :limit => 200, :null => false + t.column :data_type, :string, :limit => 100, :null => false + t.column :data_option, :string, :limit => 8000, :null => true + t.column :editable, :boolean, :null => false, :default => true + t.column :active, :boolean, :null => false, :default => true + t.column :screens, :string, :limit => 2000, :null => true + t.column :pending_migration, :boolean, :null => false, :default => true + t.column :position, :integer, :null => false + t.column :created_by_id, :integer, :null => false + t.column :updated_by_id, :integer, :null => false + t.timestamps + end + add_index :object_manager_attributes, [:name], :unique => true + add_index :object_manager_attributes, [:object_lookup_id] + + ObjectManager::Attribute.add( + :object => 'Ticket', + :name => 'customer_id', + :display => 'Customer', + :data_type => 'autocompletion', + :data_option => { + :relation => 'User', + :autocapitalize => false, + :multiple => false, + :null => false, + :limit => 200, + :help => 'Select the customer of the Ticket or create one.', + :helpLink => '»', + :minLengt => 2, + :translate => false, + :source => '#{@apiPath}/users/search', + }, + :editable => false, + :active => true, + :screens => { + :create_phone_in => { + '-all-' => { + :null => false, + }, + }, + :create_phone_out => { + '-all-' => { + :null => false, + }, + }, + :create_email_out => { + '-all-' => { + :null => false, + }, + }, + :create_web => {}, + :edit => {}, + }, + :pending_migration => false, + :position => 10, + :created_by_id => 1, + :updated_by_id => 1, + ) + + + ObjectManager::Attribute.add( + :object => 'Ticket', + :name => 'type', + :display => 'Type', + :data_type => 'select', + :data_option => { + :options => { + 'Incident' => 'Incident', + 'Problem' => 'Problem', + 'Request for Change' => 'Request for Change', + }, + :nulloption => true, + :multiple => false, + :null => true, + :translate => true, + }, + :editable => false, + :active => false, + :screens => { + :create_phone_in => { + '-all-' => { + :null => true, + }, + }, + :create_phone_out => { + '-all-' => { + :null => true, + }, + }, + :create_email_out => { + '-all-' => { + :null => true, + }, + }, + :create_web => {}, + :edit => { + :Agent => { + :null => false, + }, + }, + }, + :pending_migration => false, + :position => 20, + :created_by_id => 1, + :updated_by_id => 1, + ) + 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, + }, + :editable => false, + :active => true, + :screens => { + :create_phone_in => { + '-all-' => { + :null => false, + }, + }, + :create_phone_out => { + '-all-' => { + :null => false, + }, + }, + :create_email_out => { + '-all-' => { + :null => false, + }, + }, + :create_web => { + '-all-' => { + :null => false, + }, + }, + :edit => { + :Agent => { + :null => false, + }, + }, + }, + :pending_migration => false, + :position => 20, + :created_by_id => 1, + :updated_by_id => 1, + ) + ObjectManager::Attribute.add( + :object => 'Ticket', + :name => 'owner_id', + :display => 'Owner', + :data_type => 'select', + :data_option => { + :relation => 'User', + :relation_condition => { :roles => 'Agent' }, + :nulloption => true, + :multiple => false, + :null => true, + :translate => false, + }, + :editable => false, + :active => true, + :screens => { + :create_phone_in => { + '-all-' => { + :null => true, + }, + }, + :create_phone_out => { + '-all-' => { + :null => true, + }, + }, + :create_email_out => { + '-all-' => { + :null => true, + }, + }, + :create_web => {}, + :edit => { + :Agent => { + :null => true, + }, + }, + }, + :pending_migration => false, + :position => 30, + :created_by_id => 1, + :updated_by_id => 1, + ) + ObjectManager::Attribute.add( + :object => 'Ticket', + :name => 'state_id', + :display => 'State', + :data_type => 'select', + :data_option => { + :relation => 'TicketState', + :nulloption => true, + :multiple => false, + :null => false, + :default => 2, + :translate => true, + :filter => [1,2,3,4], + }, + :editable => false, + :active => true, + :screens => { + :create_phone_in => { + '-all-' => { + :null => false, + :filter => [2,3,4], + }, + }, + :create_phone_out => { + '-all-' => { + :null => false, + :filter => [2,3,4], + }, + }, + :create_email_out => { + '-all-' => { + :null => false, + :filter => [2,3,4], + }, + }, + :create_web => {}, + :edit => { + :Agent => { + :nulloption => false, + :null => false, + :filter => [2,3,4], + }, + :Customer => { + :nulloption => false, + :null => true, + :filter => [2,4], + :default => 2, + }, + }, + }, + :pending_migration => false, + :position => 40, + :created_by_id => 1, + :updated_by_id => 1, + ) + ObjectManager::Attribute.add( + :object => 'Ticket', + :name => 'pending_time', + :display => 'Pending till', + :data_type => 'datetime', + :data_option => { + :future => true, + :past => false, + :diff => 24, + :null => true, + :translate => true, + :required_if => { + :state_id => [3] + }, + :shown_if => { + :state_id => [3] + }, + }, + :editable => false, + :active => true, + :screens => { + :create_phone_in => { + '-all-' => { + :null => false, + }, + }, + :create_phone_out => { + '-all-' => { + :null => false, + }, + }, + :create_email_out => { + '-all-' => { + :null => false, + }, + }, + :create_web => {}, + :edit => { + :Agent => { + :null => false, + }, + }, + }, + :pending_migration => false, + :position => 41, + :created_by_id => 1, + :updated_by_id => 1, + ) + ObjectManager::Attribute.add( + :object => 'Ticket', + :name => 'priority_id', + :display => 'Priority', + :data_type => 'select', + :data_option => { + :relation => 'TicketPriority', + :nulloption => true, + :multiple => false, + :null => false, + :default => 2, + :translate => true, + }, + :editable => false, + :active => true, + :screens => { + :create_phone_in => { + '-all-' => { + :null => false, + }, + }, + :create_phone_out => { + '-all-' => { + :null => false, + }, + }, + :create_email_out => { + '-all-' => { + :null => false, + }, + }, + :create_web => {}, + :edit => { + :Agent => { + :null => false, + :nulloption => false, + }, + }, + }, + :pending_migration => false, + :position => 80, + :created_by_id => 1, + :updated_by_id => 1, + ) + + ObjectManager::Attribute.add( + :object => 'Ticket', + :name => 'tags', + :display => 'Tags', + :data_type => 'tag', + :data_option => { + :type => 'text', + :null => true, + :translate => false, + }, + :editable => false, + :active => true, + :screens => { + :create_phone_in => { + '-all-' => { + :null => true, + }, + }, + :create_phone_out => { + '-all-' => { + :null => true, + }, + }, + :create_email_out => { + '-all-' => { + :null => true, + }, + }, + :create_web => {}, + :edit => {}, + }, + :pending_migration => false, + :position => 900, + :created_by_id => 1, + :updated_by_id => 1, + ) + + ObjectManager::Attribute.add( + :object => 'Ticket', + :name => 'title', + :display => 'Title', + :data_type => 'input', + :data_option => { + :type => 'text', + :maxlength => 200, + :null => false, + :translate => false, + }, + :editable => false, + :active => true, + :screens => { + :create_phone_in => { + '-all-' => { + :null => false, + }, + }, + :create_phone_out => { + '-all-' => { + :null => false, + }, + }, + :create_email_out => { + '-all-' => { + :null => false, + }, + }, + :create_web => { + '-all-' => { + :null => false, + }, + }, + :edit => {}, + }, + :pending_migration => false, + :position => 15, + :created_by_id => 1, + :updated_by_id => 1, + ) + + ObjectManager::Attribute.add( + :object => 'TicketArticle', + :name => 'type_id', + :display => 'Type', + :data_type => 'select', + :data_option => { + :relation => 'TicketArticleType', + :nulloption => false, + :multiple => false, + :null => false, + :default => 9, + :translate => true, + }, + :editable => false, + :active => true, + :screens => { + :create_phone_in => {}, + :create_phone_out => {}, + :create_email_out => {}, + :create_web => {}, + :edit => { + :Agent => { + :null => false, + }, + }, + }, + :pending_migration => false, + :position => 100, + :created_by_id => 1, + :updated_by_id => 1, + ) + + ObjectManager::Attribute.add( + :object => 'TicketArticle', + :name => 'internal', + :display => 'Visibility', + :data_type => 'select', + :data_option => { + :options => { :true => 'internal', :false => 'public' }, + :nulloption => false, + :multiple => false, + :null => true, + :default => false, + :translate => true, + }, + :editable => false, + :active => true, + :screens => { + :create_phone_in => {}, + :create_phone_out => {}, + :create_email_out => {}, + :create_web => {}, + :edit => { + :Agent => { + :null => false, + }, + }, + }, + :pending_migration => false, + :position => 200, + :created_by_id => 1, + :updated_by_id => 1, + ) + + ObjectManager::Attribute.add( + :object => 'TicketArticle', + :name => 'to', + :display => 'To', + :data_type => 'input', + :data_option => { + :type => 'text', + :maxlength => 1000, + :null => true, + }, + :editable => false, + :active => true, + :screens => { + :create_phone_in => {}, + :create_phone_out => {}, + :create_email_out => {}, + :create_web => {}, + :edit => { + :Agent => { + :null => true, + }, + }, }, + :pending_migration => false, + :position => 300, + :created_by_id => 1, + :updated_by_id => 1, + ) + ObjectManager::Attribute.add( + :object => 'TicketArticle', + :name => 'cc', + :display => 'Cc', + :data_type => 'input', + :data_option => { + :type => 'text', + :maxlength => 1000, + :null => true, + }, + :editable => false, + :active => true, + :screens => { + :create_phone_in => {}, + :create_phone_out => {}, + :create_email_out => { + '-all-' => { + :null => true, + } + }, + :create_web => {}, + :edit => { + :Agent => { + :null => true, + }, + }, }, + :pending_migration => false, + :position => 400, + :created_by_id => 1, + :updated_by_id => 1, + ) + + ObjectManager::Attribute.add( + :object => 'TicketArticle', + :name => 'body', + :display => 'Text', + :data_type => 'textarea', + :data_option => { + :type => 'text', + :maxlength => 20000, + :upload => true, + :rows => 8, + :null => true, + }, + :editable => false, + :active => true, + :screens => { + :create_phone_in => { + '-all-' => { + :null => false, + }, + }, + :create_phone_out => { + '-all-' => { + :null => false, + }, + }, + :create_email_out => { + '-all-' => { + :null => false, + }, + }, + :create_web => { + '-all-' => { + :null => false, + }, + }, + :edit => { + :Agent => { + :null => true, + }, + :Customer => { + :null => false, + }, + }, + }, + :pending_migration => false, + :position => 600, + :created_by_id => 1, + :updated_by_id => 1, + ) + + ObjectManager::Attribute.add( + :object => 'User', + :name => 'login', + :display => 'Login', + :data_type => 'input', + :data_option => { + :type => 'text', + :maxlength => 100, + :null => false, + :autocapitalize => false, + }, + :editable => false, + :active => true, + :screens => { + :signup => {}, + :invite_agent => {}, + :edit => { + :Agent => {}, + :Admin => { + :null => false, + }, + }, + }, + :pending_migration => false, + :position => 100, + :created_by_id => 1, + :updated_by_id => 1, + ) + + ObjectManager::Attribute.add( + :object => 'User', + :name => 'firstname', + :display => 'Firstname', + :data_type => 'input', + :data_option => { + :type => 'text', + :maxlength => 150, + :null => false, + }, + :editable => false, + :active => true, + :screens => { + :signup => { + '-all-' => { + :null => false, + }, + }, + :invite_agent => { + '-all-' => { + :null => false, + }, + }, + :edit => { + '-all-' => { + :null => false, + }, + }, + }, + :pending_migration => false, + :position => 200, + :created_by_id => 1, + :updated_by_id => 1, + ) + + ObjectManager::Attribute.add( + :object => 'User', + :name => 'lastname', + :display => 'Lastname', + :data_type => 'input', + :data_option => { + :type => 'text', + :maxlength => 150, + :null => false, + }, + :editable => false, + :active => true, + :screens => { + :signup => { + '-all-' => { + :null => false, + }, + }, + :invite_agent => { + '-all-' => { + :null => false, + }, + }, + :edit => { + '-all-' => { + :null => false, + }, + }, + }, + :pending_migration => false, + :position => 300, + :created_by_id => 1, + :updated_by_id => 1, + ) + + ObjectManager::Attribute.add( + :object => 'User', + :name => 'email', + :display => 'Email', + :data_type => 'input', + :data_option => { + :type => 'email', + :maxlength => 150, + :null => false, + }, + :editable => false, + :active => true, + :screens => { + :signup => { + '-all-' => { + :null => false, + }, + }, + :invite_agent => { + '-all-' => { + :null => false, + }, + }, + :edit => { + '-all-' => { + :null => false, + }, + }, + }, + :pending_migration => false, + :position => 400, + :created_by_id => 1, + :updated_by_id => 1, + ) + + ObjectManager::Attribute.add( + :object => 'User', + :name => 'web', + :display => 'Web', + :data_type => 'input', + :data_option => { + :type => 'url', + :maxlength => 250, + :null => true, + }, + :editable => false, + :active => true, + :screens => { + :signup => {}, + :invite_agent => {}, + :edit => { + '-all-' => { + :null => true, + }, + }, + }, + :pending_migration => false, + :position => 500, + :created_by_id => 1, + :updated_by_id => 1, + ) + + ObjectManager::Attribute.add( + :object => 'User', + :name => 'phone', + :display => 'Phone', + :data_type => 'input', + :data_option => { + :type => 'phone', + :maxlength => 100, + :null => true, + }, + :editable => false, + :active => true, + :screens => { + :signup => {}, + :invite_agent => {}, + :edit => { + '-all-' => { + :null => true, + }, + }, + }, + :pending_migration => false, + :position => 600, + :created_by_id => 1, + :updated_by_id => 1, + ) + + ObjectManager::Attribute.add( + :object => 'User', + :name => 'mobile', + :display => 'Mobile', + :data_type => 'input', + :data_option => { + :type => 'phone', + :maxlength => 100, + :null => true, + }, + :editable => false, + :active => true, + :screens => { + :signup => {}, + :invite_agent => {}, + :edit => { + '-all-' => { + :null => true, + }, + }, + }, + :pending_migration => false, + :position => 700, + :created_by_id => 1, + :updated_by_id => 1, + ) + + ObjectManager::Attribute.add( + :object => 'User', + :name => 'fax', + :display => 'Fax', + :data_type => 'input', + :data_option => { + :type => 'phone', + :maxlength => 100, + :null => true, + }, + :editable => false, + :active => true, + :screens => { + :signup => {}, + :invite_agent => {}, + :edit => { + '-all-' => { + :null => true, + }, + }, + }, + :pending_migration => false, + :position => 800, + :created_by_id => 1, + :updated_by_id => 1, + ) + + ObjectManager::Attribute.add( + :object => 'User', + :name => 'organization_id', + :display => 'Organization', + :data_type => 'select', + :data_option => { + :multiple => false, + :nulloption => true, + :null => true, + :relation => 'Organization', + }, + :editable => false, + :active => true, + :screens => { + :signup => {}, + :invite_agent => {}, + :edit => { + '-all-' => { + :null => true, + }, + }, + }, + :pending_migration => false, + :position => 900, + :created_by_id => 1, + :updated_by_id => 1, + ) + + ObjectManager::Attribute.add( + :object => 'User', + :name => 'department', + :display => 'Department', + :data_type => 'input', + :data_option => { + :type => 'text', + :maxlength => 200, + :null => true, + }, + :editable => false, + :active => true, + :screens => { + :signup => {}, + :invite_agent => {}, + :edit => { + '-all-' => { + :null => true, + }, + }, + }, + :pending_migration => false, + :position => 1000, + :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 => false, + :active => true, + :screens => { + :signup => {}, + :invite_agent => {}, + :edit => { + '-all-' => { + :null => 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, + }, + :editable => false, + :active => true, + :screens => { + :signup => {}, + :invite_agent => {}, + :edit => { + '-all-' => { + :null => 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, + }, + :editable => false, + :active => true, + :screens => { + :signup => {}, + :invite_agent => {}, + :edit => { + '-all-' => { + :null => true, + }, + }, + }, + :pending_migration => false, + :position => 1300, + :created_by_id => 1, + :updated_by_id => 1, + ) + + ObjectManager::Attribute.add( + :object => 'User', + :name => 'password', + :display => 'Password', + :data_type => 'input', + :data_option => { + :type => 'password', + :maxlength => 100, + :null => true, + :autocomplete => 'off', + }, + :editable => false, + :active => true, + :screens => { + :signup => { + '-all-' => { + :null => true, + }, + }, + :invite_agent => {}, + :edit => { + :Admin => { + :null => true, + }, + }, + }, + :pending_migration => false, + :position => 1400, + :created_by_id => 1, + :updated_by_id => 1, + ) + + + ObjectManager::Attribute.add( + :object => 'User', + :name => 'note', + :display => 'Note', + :data_type => 'textarea', + :data_option => { + :type => 'text', + :maxlength => 250, + :null => true, + :note => 'Notes are visible to agents only, never to customers.', + }, + :editable => false, + :active => true, + :screens => { + :signup => {}, + :invite_agent => {}, + :edit => { + '-all-' => { + :null => true, + }, + }, + }, + :pending_migration => false, + :position => 1500, + :created_by_id => 1, + :updated_by_id => 1, + ) + + ObjectManager::Attribute.add( + :object => 'User', + :name => 'role_ids', + :display => 'Roles', + :data_type => 'checkbox', + :data_option => { + :multiple => true, + :null => false, + :relation => 'Role', + }, + :editable => false, + :active => true, + :screens => { + :signup => {}, + :invite_agent => {}, + :edit => { + :Admin => { + :null => false, + }, + }, + }, + :pending_migration => false, + :position => 1600, + :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, + }, + }, + :edit => { + :Admin => { + :null => true, + }, + }, + }, + :pending_migration => false, + :position => 1700, + :created_by_id => 1, + :updated_by_id => 1, + ) + + ObjectManager::Attribute.add( + :object => 'User', + :name => 'active', + :display => 'Active', + :data_type => 'boolean', + :data_option => { + :maxlength => 250, + :null => true, + :default => true, + }, + :editable => false, + :active => true, + :screens => { + :signup => {}, + :invite_agent => {}, + :edit => { + :Admin => { + :null => false, + }, + }, + }, + :pending_migration => false, + :position => 1800, + :created_by_id => 1, + :updated_by_id => 1, + ) + + end + + def down + drop_table :object_manager_attributes + end +end diff --git a/lib/session_helper.rb b/lib/session_helper.rb index d9c16c298..ec60d26c1 100644 --- a/lib/session_helper.rb +++ b/lib/session_helper.rb @@ -16,6 +16,16 @@ module SessionHelper return default_collection, assets end + def self.models(user = nil) + models = {} + objects = ObjectManager.listObjects + objects.each {|object| + attributes = ObjectManager::Attribute.by_object(object, user) + models[object] = attributes + } + models + end + def self.cleanup_expired # web sessions diff --git a/public/assets/tests/form.js b/public/assets/tests/form.js index b3af4bf94..ba70564c2 100644 --- a/public/assets/tests/form.js +++ b/public/assets/tests/form.js @@ -495,3 +495,54 @@ test( "form selector", function() { deepEqual( params, test_params, 'form param check via $("#form").parent()' ); }); + +test( "form required_if + shown_if", function() { + $('#forms').append('

form required_if + shown_if

') + var el = $('#form7') + var defaults = { + input2: 'some name66', + } + new App.ControllerForm({ + el: el, + model: { + configure_attributes: [ + { name: 'input1', display: 'Input1', tag: 'input', type: 'text', limit: 100, null: true, default: 'some not used default33' }, + { name: 'input2', display: 'Input2', tag: 'input', type: 'text', limit: 100, null: true, default: 'some used default', required_if: { active: true }, shown_if: { active: true } }, + { name: 'active', display: 'Active', tag: 'boolean', type: 'boolean', 'default': true, null: false }, + ], + }, + params: defaults, + }); + test_params = { + input1: "some not used default33", + input2: "some name66", + active: true + }; + params = App.ControllerForm.params( el ) + deepEqual( params, test_params, 'form param check via $("#form")' ); + equal( el.find('[name="input2"]').attr('required'), 'required', 'check required attribute of input2 ') + equal( el.find('[name="input2"]').is(":visible"), true, 'check visible attribute of input2 ') + + el.find('[name="active"]').val('{boolean}::false').trigger('change') + test_params = { + input1: "some not used default33", + active: false + }; + params = App.ControllerForm.params( el ) + deepEqual( params, test_params, 'form param check via $("#form")' ); + equal( el.find('[name="input2"]').attr('required'), undefined, 'check required attribute of input2 ') + equal( el.find('[name="input2"]').is(":visible"), false, 'check visible attribute of input2 ') + + + el.find('[name="active"]').val('{boolean}::true').trigger('change') + test_params = { + input1: "some not used default33", + input2: "some name66", + active: true + }; + params = App.ControllerForm.params( el ) + deepEqual( params, test_params, 'form param check via $("#form")' ); + equal( el.find('[name="input2"]').attr('required'), 'required', 'check required attribute of input2 ') + equal( el.find('[name="input2"]').is(":visible"), true, 'check visible attribute of input2 ') + +}); \ No newline at end of file diff --git a/public/assets/tests/model.js b/public/assets/tests/model.js new file mode 100644 index 000000000..ae7869f9c --- /dev/null +++ b/public/assets/tests/model.js @@ -0,0 +1,200 @@ +// model +test( "model basic tests", function() { + + // define model + var configure_attributes_org = _.clone( App.Ticket.configure_attributes ) + var attribute1 = { + name: 'test1', display: 'Test 1', tag: 'input', type: 'text', limit: 200, 'null': false + }; + App.Ticket.configure_attributes.push( attribute1 ) + var attribute2 = { + name: 'test2', display: 'Test 2', tag: 'input', type: 'text', limit: 200, 'null': true + }; + App.Ticket.configure_attributes.push( attribute2 ) + var attribute3 = { + name: 'pending_time1', display: 'Pending till1', tag: 'input', type: 'text', limit: 200, 'null': false, required_if: { state_id: [3] }, + }; + App.Ticket.configure_attributes.push( attribute3 ) + var attribute4 = { + name: 'pending_time2', display: 'Pending till2', tag: 'input', type: 'text', limit: 200, 'null': true, required_if: { state_id: [3] }, + }; + App.Ticket.configure_attributes.push( attribute4 ) + + // check validation + + console.log('TEST 1') + var ticket = new App.Ticket() + ticket.load({title: 'some title'}) + + var error = ticket.validate() + ok( error['group_id'], 'group_id is required') + ok( !error['title'], 'title is required') + ok( error['state_id'], 'state_id is required') + ok( error['test1'], 'test1 is required') + ok( !error['test2'], 'test2 is not required') + ok( !error['pending_time1'], 'pending_time1 is not required') + ok( !error['pending_time2'], 'pending_time2 is not required') + + + console.log('TEST 2') + ticket.title = 'some new title' + ticket.state_id = [2,3] + ticket.test2 = 123 + error = ticket.validate() + ok( error['group_id'], 'group_id is required') + ok( !error['title'], 'title exists') + ok( !error['state_id'], 'state_id is') + ok( error['test1'], 'test1 is required') + ok( !error['test2'], 'test2 is not required') + ok( error['pending_time1'], 'pending_time1 is required') + ok( error['pending_time2'], 'pending_time2 is required') + + console.log('TEST 3') + ticket.title = 'some new title' + ticket.state_id = [2,1] + ticket.test2 = 123 + error = ticket.validate() + ok( error['group_id'], 'group_id is required') + ok( !error['title'], 'title exists') + ok( !error['state_id'], 'state_id is') + ok( error['test1'], 'test1 is required') + ok( !error['test2'], 'test2 is not required') + ok( !error['pending_time1'], 'pending_time1 is required') + ok( !error['pending_time2'], 'pending_time2 is required') + + console.log('TEST 4') + ticket.title = 'some new title' + ticket.state_id = [2,3] + ticket.test2 = 123 + error = ticket.validate() + ok( error['group_id'], 'group_id is required') + ok( !error['title'], 'title exists') + ok( !error['state_id'], 'state_id is') + ok( error['test1'], 'test1 is required') + ok( !error['test2'], 'test2 is not required') + ok( error['pending_time1'], 'pending_time1 is required') + ok( error['pending_time2'], 'pending_time2 is required') + + console.log('TEST 5') + ticket.title = 'some new title' + ticket.state_id = [2,3] + ticket.test2 = 123 + ticket.pending_time1 = '2014-10-10 09:00' + error = ticket.validate() + ok( error['group_id'], 'group_id is required') + ok( !error['title'], 'title exists') + ok( !error['state_id'], 'state_id is') + ok( error['test1'], 'test1 is required') + ok( !error['test2'], 'test2 is not required') + ok( !error['pending_time1'], 'pending_time1 is required') + ok( error['pending_time2'], 'pending_time2 is required') + + + // define model with screen + App.Ticket.configure_attributes = configure_attributes_org + var attribute1 = { + name: 'test1', display: 'Test 1', tag: 'input', type: 'text', limit: 200, 'null': false, screen: { some_screen: { required_if: { state_id: [3] } } }, + }; + App.Ticket.configure_attributes.push( attribute1 ) + var attribute2 = { + name: 'test2', display: 'Test 2', tag: 'input', type: 'text', limit: 200, 'null': true, screen: { some_screen: { required_if: { state_id: [3] } } }, + }; + App.Ticket.configure_attributes.push( attribute2 ) + var attribute3 = { + name: 'group_id', display: 'Group', tag: 'select', multiple: false, null: false, relation: 'Group', screen: { some_screen: { null: false } }, + }; + App.Ticket.configure_attributes.push( attribute3 ) + var attribute4 = { + name: 'owner_id', display: 'Owner', tag: 'select', multiple: false, null: false, relation: 'User', screen: { some_screen: { null: false } }, + }; + App.Ticket.configure_attributes.push( attribute4 ) + var attribute5 = { + name: 'state_id', display: 'State', tag: 'select', multiple: false, null: false, relation: 'TicketState', screen: { some_screen: { null: false } }, + }; + App.Ticket.configure_attributes.push( attribute5 ) + + // check validation with screen + console.log('TEST 6') + ticket = new App.Ticket() + ticket.load({title: 'some title'}) + + error = ticket.validate() + ok( error['group_id'], 'group_id is required') + ok( !error['title'], 'title is required') + ok( error['state_id'], 'state_id is required') + ok( error['test1'], 'test1 is required') + ok( !error['test2'], 'test2 is not required') + + console.log('TEST 7') + ticket.state_id = 3 + error = ticket.validate() + ok( error['group_id'], 'group_id is required') + ok( !error['title'], 'title is required') + ok( !error['state_id'], 'state_id is required') + ok( error['test1'], 'test1 is required') + ok( !error['test2'], 'test2 is not required') + + console.log('TEST 8') + ticket.state_id = 2 + error = ticket.validate() + ok( error['group_id'], 'group_id is required') + ok( !error['title'], 'title is required') + ok( !error['state_id'], 'state_id is required') + ok( error['test1'], 'test1 is required') + ok( !error['test2'], 'test2 is not required') + + console.log('TEST 9') + ticket.state_id = undefined + error = ticket.validate({screen: 'some_screen'}) + ok( error['group_id'], 'group_id is required') + ok( !error['title'], 'title is required') + ok( error['state_id'], 'state_id is required') + ok( !error['test1'], 'test1 is required') + ok( !error['test2'], 'test2 is required') + + console.log('TEST 10') + ticket.state_id = 2 + error = ticket.validate({screen: 'some_screen'}) + ok( error['group_id'], 'group_id is required') + ok( !error['title'], 'title is required') + ok( !error['state_id'], 'state_id is required') + ok( !error['test1'], 'test1 is required') + ok( !error['test2'], 'test2 is not required') + + console.log('TEST 11') + ticket.state_id = 3 + error = ticket.validate({screen: 'some_screen'}) + ok( error['group_id'], 'group_id is required') + ok( !error['title'], 'title is required') + ok( !error['state_id'], 'state_id is required') + ok( error['test1'], 'test1 is required') + ok( error['test2'], 'test2 is required') + + console.log('TEST 12') + ticket.state_id = 2 + error = ticket.validate() + ok( error['group_id'], 'group_id is required') + ok( !error['title'], 'title is required') + ok( !error['state_id'], 'state_id is required') + ok( error['test1'], 'test1 is required') + ok( !error['test2'], 'test2 is not required') + + console.log('TEST 13') + ticket.state_id = 3 + error = ticket.validate() + ok( error['group_id'], 'group_id is required') + ok( !error['title'], 'title is required') + ok( !error['state_id'], 'state_id is required') + ok( error['test1'], 'test1 is required') + ok( !error['test2'], 'test2 is required') + + console.log('TEST 14') + ticket.state_id = 2 + error = ticket.validate() + ok( error['group_id'], 'group_id is required') + ok( !error['title'], 'title is required') + ok( !error['state_id'], 'state_id is required') + ok( error['test1'], 'test1 is required') + ok( !error['test2'], 'test2 is not required') + +}); diff --git a/test/browser/agent_ticket_actions_level3_test.rb b/test/browser/agent_ticket_actions_level3_test.rb index b7d3a5329..80e535f07 100644 --- a/test/browser/agent_ticket_actions_level3_test.rb +++ b/test/browser/agent_ticket_actions_level3_test.rb @@ -111,8 +111,9 @@ class AgentTicketActionsLevel3Test < TestCase { :where => :instance2, :execute => 'match', - :css => '.content_permanent.active', - :value => 'Discard your unsaved changes.', + :css => '.content_permanent.active .reset-message', + :value => '(Discard your unsaved changes.|Verwerfen der)', + :no_quote => true, :match_result => true, }, { @@ -127,8 +128,9 @@ class AgentTicketActionsLevel3Test < TestCase { :where => :instance2, :execute => 'match', - :css => '.content_permanent.active', - :value => 'Discard your unsaved changes.', + :css => '.content_permanent.active .reset-message', + :value => '(Discard your unsaved changes.|Verwerfen der)', + :no_quote => true, :match_result => false, }, @@ -150,8 +152,9 @@ class AgentTicketActionsLevel3Test < TestCase { :where => :instance1, :execute => 'match', - :css => '.content_permanent.active', - :value => 'Discard your unsaved changes.', + :css => '.content_permanent.active .reset-message', + :value => '(Discard your unsaved changes.|Verwerfen der)', + :no_quote => true, :match_result => true, }, @@ -204,8 +207,9 @@ class AgentTicketActionsLevel3Test < TestCase { :where => :instance1, :execute => 'match', - :css => '.content_permanent.active', - :value => 'Discard your unsaved changes.', + :css => '.content_permanent.active .reset-message', + :value => '(Discard your unsaved changes.|Verwerfen der)', + :no_quote => true, :match_result => false, }, { @@ -219,8 +223,9 @@ class AgentTicketActionsLevel3Test < TestCase { :where => :instance2, :execute => 'match', - :css => '.content_permanent.active', - :value => 'Discard your unsaved changes.', + :css => '.content_permanent.active .reset-message', + :value => '(Discard your unsaved changes.|Verwerfen der)', + :no_quote => true, :match_result => false, }, @@ -246,8 +251,9 @@ class AgentTicketActionsLevel3Test < TestCase { :where => :instance1, :execute => 'match', - :css => '.content_permanent.active', - :value => 'Discard your unsaved changes.', + :css => '.content_permanent.active .reset-message', + :value => '(Discard your unsaved changes.|Verwerfen der)', + :no_quote => true, :match_result => false, }, { @@ -261,8 +267,9 @@ class AgentTicketActionsLevel3Test < TestCase { :where => :instance2, :execute => 'match', - :css => '.content_permanent.active', - :value => 'Discard your unsaved changes.', + :css => '.content_permanent.active .reset-message', + :value => '(Discard your unsaved changes.|Verwerfen der)', + :no_quote => true, :match_result => false, }, @@ -280,8 +287,9 @@ class AgentTicketActionsLevel3Test < TestCase { :where => :instance2, :execute => 'match', - :css => '.content_permanent.active', - :value => 'Discard your unsaved changes.', + :css => '.content_permanent.active .reset-message', + :value => '(Discard your unsaved changes.|Verwerfen der)', + :no_quote => true, :match_result => true, }, { @@ -298,8 +306,9 @@ class AgentTicketActionsLevel3Test < TestCase { :where => :instance2, :execute => 'match', - :css => '.content_permanent.active', - :value => 'Discard your unsaved changes.', + :css => '.content_permanent.active .reset-message', + :value => '(Discard your unsaved changes.|Verwerfen der)', + :no_quote => true, :match_result => true, }, { @@ -315,7 +324,9 @@ class AgentTicketActionsLevel3Test < TestCase :where => :instance2, :execute => 'match', :css => '.content_permanent.active', - :value => 'Discard your unsaved changes.', + :css => '.content_permanent.active .reset-message', + :value => '(Discard your unsaved changes.|Verwerfen der)', + :no_quote => true, :match_result => false, }, { diff --git a/test/browser/agent_ticket_actions_level5_test.rb b/test/browser/agent_ticket_actions_level5_test.rb index a0a7e9a27..bedf4be63 100644 --- a/test/browser/agent_ticket_actions_level5_test.rb +++ b/test/browser/agent_ticket_actions_level5_test.rb @@ -3,8 +3,8 @@ require 'browser_test_helper' class AgentTicketActionLevel5Test < TestCase def test_I - random = 'text_module_test_' + rand(999999).to_s - random2 = 'text_module_test_' + rand(999999).to_s + random = 'text_module_test_' + rand(99999999).to_s + random2 = 'text_module_test_' + rand(99999999).to_s # user tests = [ @@ -153,9 +153,9 @@ class AgentTicketActionLevel5Test < TestCase browser_signle_test_with_login(tests, { :username => 'master@example.com' }) end def test_II - random = 'text_II_module_test_' + rand(999999).to_s + random = 'text_II_module_test_' + rand(99999999).to_s - user_rand = rand(999999).to_s + user_rand = rand(99999999).to_s login = 'agent-text-module-' + user_rand firstname = 'Text' + user_rand lastname = 'Module' + user_rand @@ -191,7 +191,7 @@ class AgentTicketActionLevel5Test < TestCase { :where => :instance2, :execute => 'set', - :css => '.active input[name=subject]', + :css => '.active input[name=title]', :value => 'A', }, { @@ -207,7 +207,7 @@ class AgentTicketActionLevel5Test < TestCase { :where => :instance2, :execute => 'set', - :css => '.active input[name=subject]', + :css => '.active input[name=title]', :value => 'B', }, @@ -330,7 +330,7 @@ class AgentTicketActionLevel5Test < TestCase { :where => :instance2, :execute => 'set', - :css => '.active .ticket_create input[name="customer_id_autocompletion"]', + :css => '.active .ticket-create input[name="customer_id_autocompletion"]', :value => 'nicole', }, { @@ -340,13 +340,13 @@ class AgentTicketActionLevel5Test < TestCase { :where => :instance2, :execute => 'sendkey', - :css => '.active .ticket_create input[name="customer_id_autocompletion"]', + :css => '.active .ticket-create input[name="customer_id_autocompletion"]', :value => :arrow_down, }, { :where => :instance2, :execute => 'sendkey', - :css => '.active .ticket_create input[name="customer_id_autocompletion"]', + :css => '.active .ticket-create input[name="customer_id_autocompletion"]', :value => :tab, }, { @@ -425,7 +425,7 @@ class AgentTicketActionLevel5Test < TestCase }, { :execute => 'wait', - :value => 4, + :value => 2, }, { :where => :instance2, @@ -536,7 +536,7 @@ class AgentTicketActionLevel5Test < TestCase }, { :execute => 'wait', - :value => 0.2, + :value => 0.5, }, # { # :where => :instance2, diff --git a/test/browser/agent_user_manage_test.rb b/test/browser/agent_user_manage_test.rb index 045eac769..9c8e05082 100644 --- a/test/browser/agent_user_manage_test.rb +++ b/test/browser/agent_user_manage_test.rb @@ -142,7 +142,7 @@ class AgentUserManageTest < TestCase }, { :execute => 'set', - :css => '.active .ticket_create input[name="customer_id_autocompletion"]', + :css => '.active .ticket-create input[name="customer_id_autocompletion"]', :value => customer_user_email, }, { @@ -151,12 +151,12 @@ class AgentUserManageTest < TestCase }, { :execute => 'sendkey', - :css => '.active .ticket_create input[name="customer_id_autocompletion"]', + :css => '.active .ticket-create input[name="customer_id_autocompletion"]', :value => :arrow_down, }, { :execute => 'sendkey', - :css => '.active .ticket_create input[name="customer_id_autocompletion"]', + :css => '.active .ticket-create input[name="customer_id_autocompletion"]', :value => :tab, }, { diff --git a/test/browser/customer_ticket_create_test.rb b/test/browser/customer_ticket_create_test.rb index 22c14aa46..1a556846f 100644 --- a/test/browser/customer_ticket_create_test.rb +++ b/test/browser/customer_ticket_create_test.rb @@ -27,7 +27,7 @@ class CustomerTicketCreateTest < TestCase }, { :execute => 'set', - :css => '.ticket-create input[name="subject"]', + :css => '.ticket-create input[name="title"]', :value => 'some subject 123äöü', }, { diff --git a/test/browser/taskbar_task_test.rb b/test/browser/taskbar_task_test.rb index 62039c180..4d0970edb 100644 --- a/test/browser/taskbar_task_test.rb +++ b/test/browser/taskbar_task_test.rb @@ -32,12 +32,12 @@ class TaskbarTaskTest < TestCase }, { :execute => 'check', - :css => '.active .ticket_create', + :css => '.active .ticket-create', :result => true, }, { :execute => 'set', - :css => '.active .ticket_create input[name="subject"]', + :css => '.active .ticket-create input[name="title"]', :value => 'some test AAA', }, { @@ -113,7 +113,7 @@ class TaskbarTaskTest < TestCase }, { :execute => 'set', - :css => '.active .ticket_create input[name="subject"]', + :css => '.active .ticket-create input[name="title"]', :value => 'INBOUND TEST#1', }, { @@ -122,7 +122,7 @@ class TaskbarTaskTest < TestCase }, { :execute => 'set', - :css => '.active .ticket_create textarea[name="body"]', + :css => '.active .ticket-create textarea[name="body"]', :value => 'INBOUND BODY TEST#1', }, { @@ -139,7 +139,7 @@ class TaskbarTaskTest < TestCase }, { :execute => 'set', - :css => '.active .ticket_create input[name="subject"]', + :css => '.active .ticket-create input[name="title"]', :value => 'OUTBOUND TEST#1', }, { @@ -148,7 +148,7 @@ class TaskbarTaskTest < TestCase }, { :execute => 'set', - :css => '.active .ticket_create textarea[name="body"]', + :css => '.active .ticket-create textarea[name="body"]', :value => 'OUTBOUND BODY TEST#1', }, { diff --git a/test/browser_test_helper.rb b/test/browser_test_helper.rb index b946a036e..ca6de3afa 100644 --- a/test/browser_test_helper.rb +++ b/test/browser_test_helper.rb @@ -297,40 +297,40 @@ class TestCase < Test::Unit::TestCase elsif action[:execute] == 'create_ticket' instance.find_element( { :css => 'a[href="#new"]' } ).click instance.find_element( { :css => 'a[href="#ticket/create/call_inbound"]' } ).click - element = instance.find_element( { :css => '.active .ticket_create' } ) + element = instance.find_element( { :css => '.active .ticket-create' } ) if !element assert( false, "(#{test[:name]}) no ticket create screen found!" ) return end sleep 2 - element = instance.find_element( { :css => '.active .ticket_create input[name="customer_id_autocompletion"]' } ) + element = instance.find_element( { :css => '.active .ticket-create input[name="customer_id_autocompletion"]' } ) element.clear element.send_keys( 'nico*' ) sleep 4 - element = instance.find_element( { :css => '.active .ticket_create input[name="customer_id_autocompletion"]' } ) + element = instance.find_element( { :css => '.active .ticket-create input[name="customer_id_autocompletion"]' } ) element.send_keys( :arrow_down ) sleep 0.2 - element = instance.find_element( { :css => '.active .ticket_create input[name="customer_id_autocompletion"]' } ) + element = instance.find_element( { :css => '.active .ticket-create input[name="customer_id_autocompletion"]' } ) element.send_keys( :tab ) sleep 0.1 - element = instance.find_element( { :css => '.active .ticket_create select[name="group_id"]' } ) + element = instance.find_element( { :css => '.active .ticket-create select[name="group_id"]' } ) dropdown = Selenium::WebDriver::Support::Select.new(element) dropdown.select_by( :text, action[:group]) sleep 0.1 - element = instance.find_element( { :css => '.active .ticket_create input[name="subject"]' } ) + element = instance.find_element( { :css => '.active .ticket-create input[name="title"]' } ) element.clear element.send_keys( action[:subject] ) sleep 0.1 - element = instance.find_element( { :css => '.active .ticket_create textarea[name="body"]' } ) + element = instance.find_element( { :css => '.active .ticket-create textarea[name="body"]' } ) element.clear element.send_keys( action[:body] ) if action[:do_not_submit] assert( true, "(#{test[:name]}) ticket created without submit" ) return end - sleep 0.5 + sleep 0.8 instance.find_element( { :css => '.active .form-actions button[type="submit"]' } ).click - sleep 2 + sleep 1 (1..14).each {|loop| if instance.current_url =~ /#{Regexp.quote('#ticket/zoom/')}/ assert( true, "(#{test[:name]}) ticket created" ) @@ -338,7 +338,7 @@ class TestCase < Test::Unit::TestCase end sleep 0.5 } - assert( true, "(#{test[:name]}) ticket creation failed, can't get zoom url" ) + assert( false, "(#{test[:name]}) ticket creation failed, can't get zoom url" ) return elsif action[:execute] == 'close_all_tasks' for i in 1..100