Merge branch 'develop' into interface
Conflicts: app/assets/javascripts/app/controllers/customer_ticket_create.js.coffee app/assets/javascripts/app/controllers/ticket_zoom.js.coffee app/assets/javascripts/app/models/user.js.coffee app/assets/javascripts/app/views/agent_ticket_create.jst.eco app/assets/javascripts/app/views/customer_ticket_create.jst.eco app/assets/javascripts/app/views/navigation/personal.jst.eco config/routes/test.rb test/browser/aab_unit_test.rb
This commit is contained in:
commit
5a11480447
60 changed files with 12252 additions and 11438 deletions
2
Gemfile
2
Gemfile
|
@ -1,6 +1,6 @@
|
|||
source 'http://rubygems.org'
|
||||
|
||||
gem 'rails', '4.1.4'
|
||||
gem 'rails', '4.1.5'
|
||||
gem 'rails-observers'
|
||||
gem 'activerecord-session_store'
|
||||
|
||||
|
|
|
@ -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,33 +27,51 @@ class App.ControllerForm extends App.Controller
|
|||
|
||||
fieldset = $('<fieldset></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
|
||||
|
||||
if @no_fieldset
|
||||
# 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 @noFieldset
|
||||
fieldset = fieldset.children()
|
||||
|
||||
if @fullForm
|
||||
|
@ -57,6 +79,13 @@ class App.ControllerForm extends App.Controller
|
|||
@formClass = ''
|
||||
fieldset = $('<form class="' + @formClass + '"><button class="btn">' + App.i18n.translateContent('Submit') + '</button></form>').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
|
||||
|
||||
|
@ -85,7 +114,7 @@ class App.ControllerForm extends App.Controller
|
|||
null: false
|
||||
relation: 'User'
|
||||
autocapitalize: false
|
||||
help: 'Select the customer of the Ticket or create one.'
|
||||
help: 'Select the customer of the ticket or create one.'
|
||||
helpLink: '<a href="" class="customer_new">»</a>'
|
||||
callback: @userInfo
|
||||
class: 'span7'
|
||||
|
@ -134,14 +163,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
|
||||
|
@ -237,6 +266,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 = []
|
||||
|
@ -720,7 +765,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
|
||||
|
@ -741,8 +786,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)
|
||||
|
@ -1224,63 +1272,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
|
||||
|
@ -1342,6 +1339,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) ->
|
||||
|
||||
|
@ -1402,6 +1437,7 @@ class App.ControllerForm extends App.Controller
|
|||
|
||||
list = []
|
||||
if attribute.filter
|
||||
|
||||
App.Log.debug 'ControllerForm', '_getRelationOptionList:filter', attribute.filter
|
||||
|
||||
# function based filter
|
||||
|
@ -1429,6 +1465,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'
|
||||
|
@ -1515,9 +1567,10 @@ 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
|
||||
@params: (form) ->
|
||||
|
@ -1640,13 +1693,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('form').find('[name="' + key + '"]').parents('div .form-group').addClass('has-error')
|
||||
$(data.form).parents('form').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)
|
||||
|
||||
$(data.form).parents('form').find('.has-error').find('input, textarea').first().focus()
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
class App.TicketCreate extends App.Controller
|
||||
events:
|
||||
'click .customer_new': 'userNew'
|
||||
'submit form': 'submit'
|
||||
'click .submit': 'submit'
|
||||
'click .cancel': 'cancel'
|
||||
'click .type-tabs .tab': 'changeFormType'
|
||||
'click .customer_new': 'userNew'
|
||||
'submit form': 'submit'
|
||||
'click .submit': 'submit'
|
||||
'click .cancel': 'cancel'
|
||||
|
||||
constructor: (params) ->
|
||||
super
|
||||
|
@ -13,40 +14,18 @@ class App.TicketCreate extends App.Controller
|
|||
|
||||
# set title
|
||||
@form_id = App.ControllerForm.formId()
|
||||
@form_meta = undefined
|
||||
|
||||
@edit_form = undefined
|
||||
|
||||
# set article attributes
|
||||
default_type = 'call_inbound'
|
||||
if !@type
|
||||
@type = default_type
|
||||
article_sender_type_map =
|
||||
call_inbound:
|
||||
sender: 'Customer'
|
||||
article: 'phone'
|
||||
title: 'Call Inbound'
|
||||
call_outbound:
|
||||
sender: 'Agent'
|
||||
article: 'phone'
|
||||
title: 'Call Outbound'
|
||||
email:
|
||||
sender: 'Agent'
|
||||
article: 'email'
|
||||
title: 'Email'
|
||||
@article_attributes = article_sender_type_map[@type]
|
||||
# define default type
|
||||
@default_type = 'phone-in'
|
||||
|
||||
# remember split info if exists
|
||||
split = ''
|
||||
if @ticket_id && @article_id
|
||||
split = "/#{@ticket_id}/#{@article_id}"
|
||||
|
||||
# if no map entry exists, route to default
|
||||
if !@article_attributes
|
||||
@navigate '#ticket/create/' + default_type + split
|
||||
return
|
||||
|
||||
# update navbar highlighting
|
||||
@navupdate '#ticket/create/' + @type + '/id/' + @id + split
|
||||
@navupdate '#ticket/create/id/' + @id + split
|
||||
|
||||
@fetch(params)
|
||||
|
||||
|
@ -55,20 +34,72 @@ class App.TicketCreate extends App.Controller
|
|||
@log 'notice', 'error', defaults
|
||||
@render(defaults)
|
||||
|
||||
changeFormType: (e) =>
|
||||
type = $(e.target).data('type')
|
||||
if !type
|
||||
type = $(e.target).parent().data('type')
|
||||
@setFormTypeInUi(type)
|
||||
|
||||
setFormTypeInUi: (type) =>
|
||||
|
||||
# detect current form type
|
||||
if !type
|
||||
type = @el.find('.type-tabs .tab.active').data('type')
|
||||
if !type
|
||||
type = @default_type
|
||||
|
||||
# reset all tabs
|
||||
tabs = @el.find('.type-tabs .tab')
|
||||
tabs.removeClass('active')
|
||||
tabIcons = @el.find('.type-tabs .tab .icon')
|
||||
tabIcons.addClass('gray')
|
||||
tabIcons.removeClass('white')
|
||||
|
||||
# set active tab
|
||||
selectedTab = @el.find(".type-tabs .tab[data-type='#{type}']")
|
||||
selectedTab.addClass('active')
|
||||
selectedTabIcon = @el.find(".type-tabs .tab[data-type='#{type}'] .icon")
|
||||
selectedTabIcon.removeClass('gray')
|
||||
selectedTabIcon.addClass('white')
|
||||
|
||||
# set form type attributes
|
||||
articleSenderTypeMap =
|
||||
'phone-in':
|
||||
sender: 'Customer'
|
||||
article: 'phone'
|
||||
title: 'Call Inbound'
|
||||
screen: 'create_phone_in'
|
||||
'phone-out':
|
||||
sender: 'Agent'
|
||||
article: 'phone'
|
||||
title: 'Call Outbound'
|
||||
screen: 'create_phone_out'
|
||||
'email-out':
|
||||
sender: 'Agent'
|
||||
article: 'email'
|
||||
title: 'Email'
|
||||
screen: 'create_email_out'
|
||||
@articleAttributes = articleSenderTypeMap[type]
|
||||
|
||||
# update form
|
||||
@el.find('[name="formSenderType"]').val(type)
|
||||
|
||||
meta: =>
|
||||
text = App.i18n.translateInline( @article_attributes['title'] )
|
||||
subject = @el.find('[name=subject]').val()
|
||||
if subject
|
||||
text = "#{text}: #{subject}"
|
||||
text = ''
|
||||
if @articleAttributes
|
||||
text = App.i18n.translateInline( @articleAttributes['title'] )
|
||||
title = @el.find('[name=title]').val()
|
||||
if title
|
||||
text = "#{text}: #{title}"
|
||||
meta =
|
||||
url: @url()
|
||||
head: text
|
||||
title: text
|
||||
id: @type
|
||||
id: @id
|
||||
iconClass: 'pen'
|
||||
|
||||
url: =>
|
||||
'#ticket/create/' + @type + '/id/' + @id
|
||||
'#ticket/create/id/' + @id
|
||||
|
||||
activate: =>
|
||||
@navupdate '#'
|
||||
|
@ -101,7 +132,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 )
|
||||
|
@ -109,7 +140,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:
|
||||
|
@ -122,7 +153,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 )
|
||||
|
@ -144,43 +175,90 @@ 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: '<a href="" class="customer_new">»</a>', 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']
|
||||
agent: @isRole('Agent')
|
||||
admin: @isRole('Admin')
|
||||
)
|
||||
|
||||
params = undefined
|
||||
# get params
|
||||
params = {}
|
||||
if template && !_.isEmpty( template.options )
|
||||
params = template.options
|
||||
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-top')
|
||||
form_id: @form_id
|
||||
model: App.Ticket
|
||||
screen: 'create_top'
|
||||
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-top')
|
||||
form_id: @form_id
|
||||
model: App.TicketArticle
|
||||
screen: 'create_top'
|
||||
params: params
|
||||
)
|
||||
new App.ControllerForm(
|
||||
el: @el.find('.ticket-form-middle')
|
||||
form_id: @form_id
|
||||
model: App.Ticket
|
||||
screen: 'create_middle'
|
||||
events:
|
||||
'change [name=customer_id]': @localUserInfo
|
||||
handlers: [
|
||||
formChanges
|
||||
]
|
||||
filter: @form_meta.filter
|
||||
params: params
|
||||
noFieldset: true
|
||||
)
|
||||
new App.ControllerForm(
|
||||
el: @el.find('.ticket-form-bottom')
|
||||
form_id: @form_id
|
||||
model: App.Ticket
|
||||
screen: 'create_bottom'
|
||||
events:
|
||||
'change [name=customer_id]': @localUserInfo
|
||||
handlers: [
|
||||
formChanges
|
||||
]
|
||||
filter: @form_meta.filter
|
||||
params: params
|
||||
)
|
||||
|
||||
|
@ -190,11 +268,15 @@ class App.TicketCreate extends App.Controller
|
|||
# template_id: template['id']
|
||||
# )
|
||||
|
||||
# set type selector
|
||||
@setFormTypeInUi( params['formSenderType'] )
|
||||
|
||||
# remember form params of init load
|
||||
@formDefault = @formParam( @el.find('.ticket-create') )
|
||||
|
||||
# show text module UI
|
||||
@textModule = new App.WidgetTextModule(
|
||||
el: @el.find('.ticket-create').find('textarea')
|
||||
el: @el.find('form').find('textarea')
|
||||
)
|
||||
|
||||
$('#tags').tokenfield()
|
||||
|
@ -202,14 +284,17 @@ class App.TicketCreate extends App.Controller
|
|||
# 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
|
||||
|
@ -223,7 +308,8 @@ class App.TicketCreate extends App.Controller
|
|||
create_screen: @
|
||||
)
|
||||
|
||||
cancel: ->
|
||||
cancel: (e) ->
|
||||
e.preventDefault()
|
||||
@navigate '#'
|
||||
|
||||
submit: (e) ->
|
||||
|
@ -237,11 +323,11 @@ 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'] )
|
||||
type = App.TicketArticleType.findByAttribute( 'name', @article_attributes['article'] )
|
||||
sender = App.TicketArticleSender.findByAttribute( 'name', @articleAttributes['sender'] )
|
||||
type = App.TicketArticleType.findByAttribute( 'name', @articleAttributes['article'] )
|
||||
|
||||
if params.group_id
|
||||
group = App.Group.find( params.group_id )
|
||||
|
@ -251,6 +337,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
|
||||
|
@ -261,6 +348,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
|
||||
|
@ -268,15 +356,38 @@ class App.TicketCreate extends App.Controller
|
|||
form_id: @form_id
|
||||
}
|
||||
|
||||
object.load(params)
|
||||
ticket.load(params)
|
||||
|
||||
# validate form
|
||||
errors = object.validate()
|
||||
ticketErrorsTop = ticket.validate(
|
||||
screen: 'create_top'
|
||||
)
|
||||
ticketErrorsMiddle = ticket.validate(
|
||||
screen: 'create_middle'
|
||||
)
|
||||
ticketErrorsBottom = ticket.validate(
|
||||
screen: 'create_bottom'
|
||||
)
|
||||
|
||||
article = new App.TicketArticle
|
||||
article.load( params['article'] )
|
||||
articleErrors = article.validate(
|
||||
screen: 'create_top'
|
||||
)
|
||||
|
||||
# collect whole validation result
|
||||
errors = {}
|
||||
errors = _.extend( errors, ticketErrorsTop )
|
||||
errors = _.extend( errors, ticketErrorsMiddle )
|
||||
errors = _.extend( errors, ticketErrorsBottom )
|
||||
errors = _.extend( errors, articleErrors )
|
||||
|
||||
# show errors in form
|
||||
if errors
|
||||
if !_.isEmpty( errors )
|
||||
@log 'error', errors
|
||||
@formValidate( form: e.target, errors: errors )
|
||||
@formValidate(
|
||||
form: e.target
|
||||
errors: errors
|
||||
)
|
||||
|
||||
# save ticket, create article
|
||||
else
|
||||
|
@ -284,7 +395,7 @@ class App.TicketCreate extends App.Controller
|
|||
# disable form
|
||||
@formDisable(e)
|
||||
ui = @
|
||||
object.save(
|
||||
ticket.save(
|
||||
done: ->
|
||||
|
||||
# notify UI
|
||||
|
@ -325,10 +436,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()
|
||||
|
@ -390,7 +501,7 @@ class Router extends App.ControllerPermanent
|
|||
split = "/#{params['ticket_id']}/#{params['article_id']}"
|
||||
|
||||
id = Math.floor( Math.random() * 99999 )
|
||||
@navigate "#ticket/create/#{params['type']}/id/#{id}#{split}"
|
||||
@navigate "#ticket/create/id/#{id}#{split}"
|
||||
return
|
||||
|
||||
# cleanup params
|
||||
|
@ -400,20 +511,16 @@ class Router extends App.ControllerPermanent
|
|||
type: params.type
|
||||
id: params.id
|
||||
|
||||
App.TaskManager.add( 'TicketCreateScreen-' + params['type'] + '-' + params['id'], 'TicketCreate', clean_params )
|
||||
App.TaskManager.add( 'TicketCreateScreen-' + params['id'], 'TicketCreate', clean_params )
|
||||
|
||||
# create new ticket routes/controller
|
||||
App.Config.set( 'ticket/create', Router, 'Routes' )
|
||||
App.Config.set( 'ticket/create/:type', Router, 'Routes' )
|
||||
App.Config.set( 'ticket/create/:type/id/:id', Router, 'Routes' )
|
||||
|
||||
App.Config.set( 'ticket/create/', Router, 'Routes' )
|
||||
App.Config.set( 'ticket/create/id/:id', Router, 'Routes' )
|
||||
|
||||
# split ticket
|
||||
App.Config.set( 'ticket/create/:type/:ticket_id/:article_id', Router, 'Routes' )
|
||||
App.Config.set( 'ticket/create/:type/id/:id/:ticket_id/:article_id', Router, 'Routes' )
|
||||
|
||||
# set new task actions
|
||||
App.Config.set( 'TicketNewCallOutbound', { prio: 8001, parent: '#new', name: 'Call Outbound', target: '#ticket/create/call_outbound', role: ['Agent'], divider: true }, 'NavBarRight' )
|
||||
App.Config.set( 'TicketNewCallInbound', { prio: 8002, parent: '#new', name: 'Call Inbound', target: '#ticket/create/call_inbound', role: ['Agent'], divider: true }, 'NavBarRight' )
|
||||
App.Config.set( 'TicketNewEmail', { prio: 8003, parent: '#new', name: 'Email', target: '#ticket/create/email', role: ['Agent'], divider: true }, 'NavBarRight' )
|
||||
App.Config.set( 'ticket/create/:ticket_id/:article_id', Router, 'Routes' )
|
||||
App.Config.set( 'ticket/create/id/:id/:ticket_id/:article_id', Router, 'Routes' )
|
||||
|
||||
# set new actions
|
||||
App.Config.set( 'TicketCreate', { prio: 8003, parent: '#new', name: 'New Ticket', target: '#ticket/create', role: ['Agent'], divider: true }, 'NavBarRight' )
|
||||
|
|
|
@ -13,11 +13,11 @@ class Index extends App.ControllerContent
|
|||
# set title
|
||||
@title 'New Ticket'
|
||||
@form_id = App.ControllerForm.formId()
|
||||
@form_meta = undefined
|
||||
|
||||
@fetch(params)
|
||||
@navupdate '#customer_ticket_new'
|
||||
|
||||
@edit_form = undefined
|
||||
|
||||
# get data / in case also ticket data for split
|
||||
fetch: (params) ->
|
||||
|
||||
|
@ -27,7 +27,7 @@ class Index extends App.ControllerContent
|
|||
if cache
|
||||
|
||||
# get edit form attributes
|
||||
@edit_form = cache.edit_form
|
||||
@form_meta = cache.form_meta
|
||||
|
||||
# load assets
|
||||
App.Collection.loadAssets( cache.assets )
|
||||
|
@ -45,7 +45,7 @@ class Index extends App.ControllerContent
|
|||
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 )
|
||||
|
@ -87,27 +87,77 @@ 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' },
|
||||
]
|
||||
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 )
|
||||
|
||||
@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-top')
|
||||
form_id: @form_id
|
||||
model: App.Ticket
|
||||
screen: 'create_top'#@article_attributes['screen']
|
||||
handlers: [
|
||||
formChanges
|
||||
]
|
||||
filter: @form_meta.filter
|
||||
autofocus: true
|
||||
form_data: @edit_form
|
||||
params: defaults
|
||||
)
|
||||
|
||||
new App.ControllerForm(
|
||||
el: @el.find('.article-form-top')
|
||||
form_id: @form_id
|
||||
model: App.TicketArticle
|
||||
screen: 'create_top'#@article_attributes['screen']
|
||||
params: defaults
|
||||
)
|
||||
new App.ControllerForm(
|
||||
el: @el.find('.ticket-form-middle')
|
||||
form_id: @form_id
|
||||
model: App.Ticket
|
||||
screen: 'create_middle'#@article_attributes['screen']
|
||||
handlers: [
|
||||
formChanges
|
||||
]
|
||||
filter: @form_meta.filter
|
||||
params: defaults
|
||||
noFieldset: true
|
||||
)
|
||||
#new App.ControllerForm(
|
||||
# el: @el.find('.ticket-form-bottom')
|
||||
# form_id: @form_id
|
||||
# model: App.Ticket
|
||||
# screen: 'create_bottom'#@article_attributes['screen']
|
||||
# handlers: [
|
||||
# formChanges
|
||||
# ]
|
||||
# filter: @form_meta.filter
|
||||
# params: defaults
|
||||
#)
|
||||
|
||||
new App.ControllerDrox(
|
||||
el: @el.find('.sidebar')
|
||||
data:
|
||||
|
@ -128,19 +178,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 +212,35 @@ class Index extends App.ControllerContent
|
|||
form_id: @form_id
|
||||
}
|
||||
|
||||
object.load(params)
|
||||
ticket.load(params)
|
||||
|
||||
# validate form
|
||||
errors = object.validate()
|
||||
ticketErrorsTop = ticket.validate(
|
||||
screen: 'create_top'
|
||||
)
|
||||
ticketErrorsMiddle = ticket.validate(
|
||||
screen: 'create_middle'
|
||||
)
|
||||
article = new App.TicketArticle
|
||||
article.load(params['article'])
|
||||
articleErrors = article.validate(
|
||||
screen: 'create_top'
|
||||
)
|
||||
|
||||
# collect whole validation
|
||||
errors = {}
|
||||
errors = _.extend( errors, ticketErrorsTop )
|
||||
errors = _.extend( errors, ticketErrorsMiddle )
|
||||
errors = _.extend( errors, articleErrors )
|
||||
|
||||
# show errors in form
|
||||
if errors
|
||||
if !_.isEmpty(errors)
|
||||
@log 'CustomerTicketCreate', 'error', 'can not create', errors
|
||||
|
||||
@formValidate( form: e.target, errors: errors )
|
||||
@formValidate(
|
||||
form: e.target
|
||||
errors: errors
|
||||
)
|
||||
|
||||
# save ticket, create article
|
||||
else
|
||||
|
@ -177,7 +248,7 @@ class Index extends App.ControllerContent
|
|||
# disable form
|
||||
@formDisable(e)
|
||||
ui = @
|
||||
object.save(
|
||||
ticket.save(
|
||||
done: ->
|
||||
|
||||
# redirect to zoom
|
||||
|
|
|
@ -32,7 +32,7 @@ class Index extends App.ControllerContent
|
|||
new App.ControllerForm(
|
||||
el: @el.find('form')
|
||||
model: App.User
|
||||
required: 'signup'
|
||||
screen: 'signup'
|
||||
autofocus: true
|
||||
)
|
||||
|
||||
|
|
|
@ -322,7 +322,7 @@ class Table extends App.ControllerContent
|
|||
configure_attributes: @configure_attributes_ticket
|
||||
className: 'create'
|
||||
form_data: @bulk
|
||||
no_fieldset: true
|
||||
noFieldset: true
|
||||
)
|
||||
#html.delegate('.bulk-action-form', 'submit', (e) =>
|
||||
html.bind('submit', (e) =>
|
||||
|
|
|
@ -5,7 +5,9 @@ class App.TicketZoom extends App.Controller
|
|||
# check authentication
|
||||
return if !@authenticate()
|
||||
|
||||
@edit_form = undefined
|
||||
@navupdate '#'
|
||||
|
||||
@form_meta = undefined
|
||||
@ticket_id = params.ticket_id
|
||||
@article_id = params.article_id
|
||||
@signature = undefined
|
||||
|
@ -112,7 +114,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
|
||||
|
@ -145,7 +147,7 @@ class App.TicketZoom extends App.Controller
|
|||
new App.ControllerForm(
|
||||
el: @el.find('.edit')
|
||||
model: App.Ticket
|
||||
required: required
|
||||
screen: 'edit'
|
||||
params: App.Ticket.find(@ticket.id)
|
||||
)
|
||||
# start link info controller
|
||||
|
@ -163,13 +165,14 @@ class App.TicketZoom extends App.Controller
|
|||
new App.ControllerForm(
|
||||
el: @el.find('.customer-edit')
|
||||
model: App.User
|
||||
required: 'quick'
|
||||
screen: 'edit'
|
||||
params: App.User.find(@ticket.customer_id)
|
||||
)
|
||||
new App.ControllerForm(
|
||||
el: @el.find('.organization-edit')
|
||||
model: App.Organization
|
||||
params: App.Organization.find(@ticket.organitaion_id)
|
||||
screen: 'edit'
|
||||
)
|
||||
|
||||
@TicketAction()
|
||||
|
@ -214,7 +217,8 @@ class App.TicketZoom extends App.Controller
|
|||
new Edit(
|
||||
ticket: @ticket
|
||||
el: @el.find('.ticket-edit')
|
||||
edit_form: @edit_form
|
||||
#el: @el.find('.edit')
|
||||
form_meta: @form_meta
|
||||
task_key: @task_key
|
||||
ui: @
|
||||
)
|
||||
|
@ -244,9 +248,13 @@ class TicketTitle extends App.Controller
|
|||
|
||||
render: (ticket) =>
|
||||
@html App.view('ticket_zoom/title')(
|
||||
ticket: ticket
|
||||
ticket: ticket
|
||||
isCustomer: @isRole('Customer')
|
||||
)
|
||||
|
||||
# show frontend times
|
||||
@frontendTimeUpdate()
|
||||
|
||||
update: (e) =>
|
||||
$this = $(e.target)
|
||||
title = $this.html()
|
||||
|
@ -372,57 +380,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: [
|
||||
{
|
||||
|
@ -440,13 +446,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'],
|
||||
},
|
||||
},
|
||||
]
|
||||
)
|
||||
|
||||
|
@ -680,10 +697,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' )
|
||||
|
@ -696,17 +719,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
|
||||
|
||||
|
@ -732,22 +754,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
|
||||
|
@ -761,6 +793,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
|
||||
|
|
|
@ -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
|
||||
)
|
||||
|
|
|
@ -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' )
|
||||
|
||||
|
|
File diff suppressed because one or more lines are too long
9301
app/assets/javascripts/app/lib/core/jquery-1.8.1.js
vendored
9301
app/assets/javascripts/app/lib/core/jquery-1.8.1.js
vendored
File diff suppressed because it is too large
Load diff
File diff suppressed because one or more lines are too long
9190
app/assets/javascripts/app/lib/core/jquery-2.1.1.js
vendored
Normal file
9190
app/assets/javascripts/app/lib/core/jquery-2.1.1.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
4
app/assets/javascripts/app/lib/core/jquery-2.1.1.min.js
vendored
Normal file
4
app/assets/javascripts/app/lib/core/jquery-2.1.1.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
0
app/assets/javascripts/app/lib/spine/ajax.coffee
Executable file → Normal file
0
app/assets/javascripts/app/lib/spine/ajax.coffee
Executable file → Normal file
0
app/assets/javascripts/app/lib/spine/bindings.coffee
Executable file → Normal file
0
app/assets/javascripts/app/lib/spine/bindings.coffee
Executable file → Normal file
0
app/assets/javascripts/app/lib/spine/list.coffee
Executable file → Normal file
0
app/assets/javascripts/app/lib/spine/list.coffee
Executable file → Normal file
0
app/assets/javascripts/app/lib/spine/local.coffee
Executable file → Normal file
0
app/assets/javascripts/app/lib/spine/local.coffee
Executable file → Normal file
0
app/assets/javascripts/app/lib/spine/manager.coffee
Executable file → Normal file
0
app/assets/javascripts/app/lib/spine/manager.coffee
Executable file → Normal file
9
app/assets/javascripts/app/lib/spine/relation.coffee
Executable file → Normal file
9
app/assets/javascripts/app/lib/spine/relation.coffee
Executable file → Normal file
|
@ -1,6 +1,5 @@
|
|||
Spine = @Spine or require('spine')
|
||||
isArray = Spine.isArray
|
||||
require = @require or ((value) -> eval(value))
|
||||
|
||||
class Collection extends Spine.Module
|
||||
constructor: (options = {}) ->
|
||||
|
@ -111,8 +110,14 @@ underscore = (str) ->
|
|||
.replace(/-/g, '_')
|
||||
.toLowerCase()
|
||||
|
||||
requireModel = (model) ->
|
||||
if typeof model is 'string'
|
||||
require?(model) or eval(model)
|
||||
else
|
||||
model
|
||||
|
||||
association = (name, model, record, fkey, Ctor) ->
|
||||
model = require(model) if typeof model is 'string'
|
||||
model = requireModel(model) if typeof model is 'string'
|
||||
new Ctor(name: name, model: model, record: record, fkey: fkey)
|
||||
|
||||
Spine.Model.extend
|
||||
|
|
30
app/assets/javascripts/app/lib/spine/route.coffee
Executable file → Normal file
30
app/assets/javascripts/app/lib/spine/route.coffee
Executable file → Normal file
|
@ -71,6 +71,9 @@ class Route extends Spine.Module
|
|||
@change()
|
||||
|
||||
@unbind: ->
|
||||
unbindResult = Spine.Events.unbind.apply this, arguments
|
||||
return unbindResult if arguments.length > 0
|
||||
|
||||
return if @options.shim
|
||||
|
||||
if @history
|
||||
|
@ -80,33 +83,30 @@ class Route extends Spine.Module
|
|||
|
||||
@navigate: (args...) ->
|
||||
options = {}
|
||||
|
||||
lastArg = args[args.length - 1]
|
||||
if typeof lastArg is 'object'
|
||||
options = args.pop()
|
||||
else if typeof lastArg is 'boolean'
|
||||
options.trigger = args.pop()
|
||||
|
||||
options = $.extend({}, @options, options)
|
||||
|
||||
path = args.join('/')
|
||||
return if @path is path
|
||||
@path = path
|
||||
|
||||
@trigger('navigate', @path)
|
||||
if options.trigger
|
||||
@trigger('navigate', @path)
|
||||
routes = @matchRoutes(@path, options)
|
||||
unless routes.length
|
||||
if typeof options.redirect is 'function'
|
||||
return options.redirect.apply this, [@path, options]
|
||||
else
|
||||
if options.redirect is true
|
||||
@redirect(@path)
|
||||
|
||||
routes = @matchRoutes(@path, options) if options.trigger
|
||||
|
||||
return if options.shim
|
||||
|
||||
unless routes.length
|
||||
if typeof options.redirect is 'function'
|
||||
return options.redirect.apply this, [@path, options]
|
||||
else
|
||||
if options.redirect is true
|
||||
@redirect(@path)
|
||||
|
||||
if @history and options.replace
|
||||
if options.shim
|
||||
true
|
||||
else if @history and options.replace
|
||||
history.replaceState({}, document.title, @path)
|
||||
else if @history
|
||||
history.pushState({}, document.title, @path)
|
||||
|
|
17
app/assets/javascripts/app/lib/spine/spine.coffee
Executable file → Normal file
17
app/assets/javascripts/app/lib/spine/spine.coffee
Executable file → Normal file
|
@ -149,13 +149,14 @@ class Model extends Module
|
|||
@toString: -> "#{@className}(#{@attributes.join(", ")})"
|
||||
|
||||
@find: (id, notFound = @notFound) ->
|
||||
record = @irecords[id]?.clone()
|
||||
return record or notFound?(id)
|
||||
@irecords[id]?.clone() or notFound?(id)
|
||||
|
||||
@notFound: (id) -> return null
|
||||
@findAll: (ids, notFound) ->
|
||||
(@find(id) for id in ids when @find(id, notFound))
|
||||
|
||||
@exists: (id) ->
|
||||
return if @irecords[id] then true else false
|
||||
@notFound: (id) -> null
|
||||
|
||||
@exists: (id) -> Boolean @irecords[id]
|
||||
|
||||
@addRecord: (record, options = {}) ->
|
||||
if record.id and @irecords[record.id]
|
||||
|
@ -321,8 +322,8 @@ class Model extends Module
|
|||
result
|
||||
|
||||
eql: (rec) ->
|
||||
!!(rec and rec.constructor is @constructor and
|
||||
((rec.cid is @cid) or (rec.id and rec.id is @id)))
|
||||
rec and rec.constructor is @constructor and
|
||||
((rec.cid is @cid) or (rec.id and rec.id is @id))
|
||||
|
||||
save: (options = {}) ->
|
||||
unless options.validate is false
|
||||
|
@ -634,7 +635,7 @@ makeArray = (args) ->
|
|||
Spine = @Spine = {}
|
||||
module?.exports = Spine
|
||||
|
||||
Spine.version = '1.3.1'
|
||||
Spine.version = '1.3.2'
|
||||
Spine.isArray = isArray
|
||||
Spine.isBlank = isBlank
|
||||
Spine.$ = $
|
||||
|
|
|
@ -73,55 +73,116 @@ class App.Model extends Spine.Model
|
|||
''
|
||||
|
||||
@validate: ( data = {} ) ->
|
||||
return if !data['model'].configure_attributes
|
||||
|
||||
# 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 attributeName, attribute of attributes
|
||||
if attribute['required_if']
|
||||
|
||||
for key, values of attribute['required_if']
|
||||
|
||||
localValues = data['params'][key]
|
||||
if !_.isArray( localValues )
|
||||
localValues = [ localValues ]
|
||||
|
||||
match = false
|
||||
for value in values
|
||||
if localValues
|
||||
for localValue in localValues
|
||||
if value && localValue && value.toString() is localValue.toString()
|
||||
match = true
|
||||
if match is true
|
||||
attribute['null'] = false
|
||||
else
|
||||
attribute['null'] = true
|
||||
|
||||
# check attributes/each attribute of object
|
||||
errors = {}
|
||||
for attribute in data['model'].configure_attributes
|
||||
for attributeName, attribute of attributes
|
||||
|
||||
# only if attribute is not read only
|
||||
if !attribute.readonly
|
||||
|
||||
# check required // if null is defined && null is false
|
||||
if 'null' of attribute && !attribute[null]
|
||||
if 'null' of attribute && !attribute['null']
|
||||
|
||||
# check :: fields
|
||||
parts = attribute.name.split '::'
|
||||
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)
|
||||
console.log 'error', 'validation vailed', errors
|
||||
console.log 'error', 'validation failed', errors
|
||||
return errors
|
||||
|
||||
# return no errors
|
||||
return
|
||||
|
||||
validate: ->
|
||||
###
|
||||
|
||||
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 )
|
||||
for attribute in attributes
|
||||
attributesNew[ attribute.name ] = attribute
|
||||
|
||||
console.log(attributesNew)
|
||||
attributesNew
|
||||
|
||||
validate: (params = {}) ->
|
||||
App.Model.validate(
|
||||
model: @constructor,
|
||||
params: @,
|
||||
model: @constructor.className
|
||||
params: @
|
||||
screen: params.screen
|
||||
)
|
||||
|
||||
isOnline: ->
|
||||
|
|
|
@ -5,7 +5,7 @@ class App.Group extends App.Model
|
|||
|
||||
@configure_attributes = [
|
||||
{ name: 'name', display: 'Name', tag: 'input', type: 'text', limit: 100, 'null': false, 'class': 'span4' },
|
||||
{ name: 'assignment_timeout', display: 'Assignment Timout', tag: 'input', note: 'Assignment timout in minutes if assigned agent is not working on it. Ticket will be shown as unassigend.', type: 'text', limit: 100, 'null': true, 'class': 'span4' },
|
||||
{ name: 'assignment_timeout', display: 'Assignment Timeout', tag: 'input', note: 'Assignment timeout in minutes if assigned agent is not working on it. Ticket will be shown as unassigend.', type: 'text', limit: 100, 'null': true, 'class': 'span4' },
|
||||
{ name: 'follow_up_possible', display: 'Follow up possible',tag: 'select', default: 'yes', options: { yes: 'yes', reject: 'reject follow up/do not reopen Ticket', 'new_ticket': 'do not reopen Ticket but create new Ticket' }, 'null': false, note: 'Follow up for closed ticket possible or not.', 'class': 'span4' },
|
||||
{ name: 'follow_up_assignment', display: 'Assign Follow Ups', tag: 'select', default: 'yes', options: { true: 'yes', false: 'no' }, 'null': false, note: 'Assign follow up to latest agent again.', 'class': 'span4' },
|
||||
{ name: 'email_address_id', display: 'Email', tag: 'select', multiple: false, null: true, relation: 'EmailAddress', nulloption: true, class: 'span4' },
|
||||
|
|
|
@ -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' },
|
||||
|
|
|
@ -2,87 +2,41 @@
|
|||
<div class="create-new main flex">
|
||||
<div class="box">
|
||||
<div class="page-header">
|
||||
<h1><%- @T( 'Create New Ticket' ) %></h1>
|
||||
<h1><%- @T( @head ) %></h1>
|
||||
</div>
|
||||
|
||||
<ul class="horizontal tabs type-tabs">
|
||||
|
||||
<li class="tab u-textTruncate active">
|
||||
<div class="white email channel icon"></div>
|
||||
<%- @T( 'E-Mail' ) %>
|
||||
|
||||
<li class="tab u-textTruncate">
|
||||
<li class="tab u-textTruncate" data-type="phone-in">
|
||||
<div class="gray received-calls channel icon"></div>
|
||||
<%- @T( 'Received Call' ) %>
|
||||
</li>
|
||||
|
||||
<li class="tab u-textTruncate">
|
||||
<li class="tab u-textTruncate" data-type="phone-out">
|
||||
<div class="gray outbound-calls channel icon"></div>
|
||||
<%- @T( 'Outbound Call' ) %>
|
||||
</li>
|
||||
|
||||
<li class="tab u-textTruncate" data-type="email-out">
|
||||
<div class="gray email channel icon"></div>
|
||||
<%- @T( 'Send E-Mail' ) %>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<form role="form">
|
||||
|
||||
<div class="form-group">
|
||||
<label for="customer"><%- @T('Customer') %></label>
|
||||
<input class="form-control" id="customer" placeholder="<%- @T('Enter Person or Organisation/Company') %>">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="subject"><%- @T('Subject') %></label>
|
||||
<input class="form-control" id="subject">
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="text"><%- @T('Text') %></label>
|
||||
<textarea class="form-control" id="text" rows="4"></textarea>
|
||||
</div>
|
||||
<form role="form" class="form-large ticket-create">
|
||||
<input type="hidden" name="formSenderType"/>
|
||||
<div class="ticket-form-top"></div>
|
||||
<div class="article-form-top"></div>
|
||||
|
||||
<div class="formset-inset">
|
||||
<div class="horizontal two-columns">
|
||||
<div class="form-group column">
|
||||
<label for="owner"><%- @T('Owner') %></label>
|
||||
<select class="form-control" id="owner">
|
||||
<option>Support -> Oliver Ruhm</option>
|
||||
<option>Engineering -> Web-Dev</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group column">
|
||||
<label for="type"><%- @T('Type') %></label>
|
||||
<select class="form-control" id="type">
|
||||
<option>Inquiry</option>
|
||||
<option>Support</option>
|
||||
<option selected>Question</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group column">
|
||||
<label for="status"><%- @T('Status') %></label>
|
||||
<select class="form-control" id="status">
|
||||
<option selected>open</option>
|
||||
<option>closed</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group column">
|
||||
<label for="proprity"><%- @T('Priority') %></label>
|
||||
<select class="form-control" id="proprity">
|
||||
<option>low</option>
|
||||
<option selected>normal</option>
|
||||
<option>high</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="tags"><%- @T('Tags') %></label>
|
||||
<input class="form-control" id="tags" placeholder="<%- @T('Tag hinzufügen') %>" value="New Website, Feedback">
|
||||
</div>
|
||||
|
||||
<div class="ticket-form-middle horizontal two-columns"></div>
|
||||
<div class="ticket-form-bottom"></div>
|
||||
</div>
|
||||
|
||||
<input type="hidden" value="" name="article_type"/>
|
||||
|
||||
<div class="form-actions horizontal">
|
||||
<a class="subtle-link standalone cancel" href="#/"><%- @T( 'Cancel & Go Back' ) %></a>
|
||||
<button type="submit" class="btn btn-create submit align-right"><%- @T( 'Create Ticket' ) %></button>
|
||||
<button type="submit" class="btn btn-create submit align-right"><%- @T( 'Create' ) %></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
@ -1,18 +1,27 @@
|
|||
<div class="main flex">
|
||||
<div class="create-new horizontal flex">
|
||||
<div class="create-new main flex">
|
||||
<div class="box">
|
||||
<div class="page-header">
|
||||
<h1><%- @T( 'New Ticket' ) %></h1>
|
||||
</div>
|
||||
|
||||
<div class="ticket-create vertical">
|
||||
<div class="page-header">
|
||||
<h1 class="pull-left"><%- @T( 'New Ticket' ) %></h1>
|
||||
</div>
|
||||
<div class="page-content">
|
||||
<form class="form-horizontal form-large">
|
||||
<input type="hidden" value="" name="article_type"/>
|
||||
<div id="form_create"></div>
|
||||
<div class="form-actions">
|
||||
<button type="reset" class="btn btn-default cancel"><%- @T( 'Cancel' ) %></button>
|
||||
<button type="submit" class="btn btn-primary submit"><%- @T( 'Create' ) %></button>
|
||||
<form role="form" class="form-large ticket-create">
|
||||
|
||||
<div class="ticket-form-top"></div>
|
||||
<div class="article-form-top"></div>
|
||||
|
||||
<div class="formset-inset">
|
||||
<div class="ticket-form-middle horizontal two-columns"></div>
|
||||
<div class="ticket-form-bottom"></div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-actions horizontal">
|
||||
<a class="subtle-link standalone cancel" href="#/"><%- @T( 'Cancel & Go Back' ) %></a>
|
||||
<button type="submit" class="btn btn-create submit align-right"><%- @T( 'Create' ) %></button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<div class="form-group <%= @attribute.item_class %>">
|
||||
<label for="<%= @attribute.id %>"><%- @T( @attribute.display ) %><% if !@attribute.null: %> *<% end %></label>
|
||||
<label for="<%= @attribute.id %>"><%- @T( @attribute.display ) %> <span><% if !@attribute.null: %>*<% end %></span></label>
|
||||
<div class="controls">
|
||||
<%- @item %><% if @attribute.note: %><span class="glyphicon glyphicon-question-sign help-message" title="<%- @Ti( @attribute.note ) + ' ' %>"></span><% end %>
|
||||
<% if @attribute.remove: %><span><a href="#" class="glyphicon glyphicon-minus"></a></span><% end %>
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
<input id="<%= @attribute.id %>" type="hidden" name="<%= @attribute.name %>" value="<%= @attribute.value %>" <%= @attribute.required %> />
|
||||
<input id="<%= @attribute.id %>_autocompletion" type="text" name="<%= @attribute.name %>_autocompletion" value="<%= @attribute.valueShown %>" class="form-control <%= @attribute.class %>" <%= @attribute.required %> <%= @attribute.autofocus %> <%- @attribute.autocapitalize %>/>
|
||||
<input id="<%= @attribute.id %>_autocompletion" type="text" name="<%= @attribute.name %>_autocompletion" value="<%= @attribute.valueShown %>" class="form-control <%= @attribute.class %>" <%= @attribute.required %> <%= @attribute.autofocus %> <%- @attribute.autocapitalize %> <% if @attribute.placeholder: %>placeholder="<%- @T(@attribute.placeholder) %>"<% end %>/>
|
||||
<input id="<%= @attribute.id %>_autocompletion_value_shown" type="hidden" name="<%= @attribute.name %>_autocompletion_value_shown" value="<%= @attribute.valueShown %>"/>
|
||||
|
|
1
app/assets/javascripts/app/views/generic/date.jst.eco
Normal file
1
app/assets/javascripts/app/views/generic/date.jst.eco
Normal file
|
@ -0,0 +1 @@
|
|||
<input id="<%= @attribute.id %>" type="<%= @attribute.type %>" class="form-control <%= @attribute.class %>" placeholder="<%= @attribute.placeholder %>" name="<%= @attribute.name %>" value="<%= @attribute.value %>" <%= @attribute.required %>>
|
|
@ -1 +1 @@
|
|||
<input id="<%= @attribute.id %>" type="<%= @attribute.type %>" name="<%= @attribute.name %>" value="<%= @attribute.value %>" class="form-control <%= @attribute.class %>" <%= @attribute.required %> <%= @attribute.autofocus %> <%- @attribute.autocapitalize %> <%- @attribute.autocomplete %>/>
|
||||
<input id="<%= @attribute.id %>" type="<%= @attribute.type %>" name="<%= @attribute.name %>" value="<%= @attribute.value %>" class="form-control <%= @attribute.class %>" <% if @attribute.placeholder: %>placeholder="<%- @T(@attribute.placeholder) %>"<% end %> <%= @attribute.required %> <%= @attribute.autofocus %> <%- @attribute.autocapitalize %> <%- @attribute.autocomplete %>/>
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<select id="<%= @attribute.id %>" class="form-control <%= @attribute.class %>" name="<%= @attribute.name %>" <%= @attribute.multiple %> <%= @attribute.required %> <%= @attribute.autofocus %>>
|
||||
<% if @attribute.options: %>
|
||||
<% for row in @attribute.options: %>
|
||||
<option value="<%= row.value %>" <%= row.selected %> <%= row.disabled %>><%= row.name %></option>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</select>
|
||||
|
|
|
@ -1,8 +1,14 @@
|
|||
<% for item in @items: %>
|
||||
<% if item.child: %>
|
||||
<li class="dropdown <%= item.class %> <% if @open_tab[item.target] : %>open<% end %>">
|
||||
<a href="<%= item.target %>" class="dropdown-toggle" data-toggle="dropdown">
|
||||
<%- @T( item.name ) %> <b class="caret"></b>
|
||||
<a href="<%= item.target %>" class="dropdown-toggle horizontal center" data-toggle="dropdown">
|
||||
<span class="nav-item-icon">
|
||||
<span class="<%= item.class %> icon"></span>
|
||||
</span>
|
||||
<span class="nav-item-name flex">
|
||||
<%- @T( item.name ) %>
|
||||
</span>
|
||||
<b class="caret"></b>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<% for item in item.child: %>
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
// the compiled file.
|
||||
//
|
||||
|
||||
//= require ./app/lib/core/jquery-1.11.0.js
|
||||
//= require ./app/lib/core/jquery-2.1.1.js
|
||||
//= require ./app/lib/core/jquery-ui-1.8.23.custom.min.js
|
||||
//= require ./app/lib/core/underscore-1.6.0.js
|
||||
//= require ./app/lib/core/underscore-1.7.0.js
|
||||
|
||||
//= require ./app/lib/animations/velocity.min.js
|
||||
//= require ./app/lib/animations/velocity.ui.js
|
||||
|
@ -69,6 +69,13 @@ function difference(object1, object2) {
|
|||
return changes;
|
||||
}
|
||||
|
||||
function clone(object) {
|
||||
if (!object) {
|
||||
return object
|
||||
}
|
||||
return JSON.parse(JSON.stringify(object));
|
||||
}
|
||||
|
||||
jQuery.event.special.remove = {
|
||||
remove: function(e) {
|
||||
if (e.handler) e.handler();
|
||||
|
|
|
@ -658,13 +658,13 @@ label {
|
|||
.form-control:focus,
|
||||
.tokenfield.focus {
|
||||
box-shadow: none;
|
||||
border-color: #419ed7;
|
||||
border-color: #419ed7 !important;
|
||||
}
|
||||
|
||||
.has-error .form-control,
|
||||
.has-error .form-control:focus {
|
||||
box-shadow: none;
|
||||
border-color: red;
|
||||
border-color: red !important;
|
||||
}
|
||||
|
||||
.help-inline {
|
||||
|
@ -752,6 +752,9 @@ label {
|
|||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.help-block {
|
||||
color: #bcbcbc;
|
||||
}
|
||||
.form-horizontal .help-inline, .form-horizontal .help-block {
|
||||
font-size: 12px;
|
||||
margin-top: 4px;
|
||||
|
@ -3240,7 +3243,7 @@ footer {
|
|||
|
||||
.tokenfield .token {
|
||||
padding: 0 0 0 10px;
|
||||
margin: -1px 5px 0 0;
|
||||
margin: -1px 5px 8px 0;
|
||||
height: 26px;
|
||||
line-height: 27px;
|
||||
color: white;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
@ -307,24 +296,11 @@ class TicketsController < ApplicationController
|
|||
# get attributes to update
|
||||
attributes_to_change = Ticket::ScreenOptions.attributes_to_change(
|
||||
:user => current_user,
|
||||
# :ticket_id => params[:ticket_id],
|
||||
# :article_id => params[:article_id]
|
||||
:ticket_id => params[:ticket_id],
|
||||
: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,13 +318,19 @@ class TicketsController < ApplicationController
|
|||
render :json => {
|
||||
:split => split,
|
||||
:assets => assets,
|
||||
:edit_form => attributes_to_change,
|
||||
:form_meta => {
|
||||
:filter => attributes_to_change[:filter],
|
||||
:dependencies => attributes_to_change[:dependencies],
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
# GET /api/v1/tickets/search
|
||||
def search
|
||||
|
||||
# permit nested conditions
|
||||
params.require(:condition).permit!
|
||||
|
||||
# build result list
|
||||
tickets = Ticket.search(
|
||||
:limit => params[:limit],
|
||||
|
|
147
app/models/object_manager.rb
Normal file
147
app/models/object_manager.rb
Normal file
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
16
app/views/tests/model.html.erb
Normal file
16
app/views/tests/model.html.erb
Normal file
|
@ -0,0 +1,16 @@
|
|||
|
||||
<link rel="stylesheet" href="/assets/tests/qunit-1.10.0.css">
|
||||
<script src="/assets/tests/qunit-1.10.0.js"></script>
|
||||
<script src="/assets/tests/model.js"></script>
|
||||
|
||||
<style type="text/css">
|
||||
body {
|
||||
padding-top: 0px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script type="text/javascript">
|
||||
</script>
|
||||
|
||||
<div id="qunit"></div>
|
||||
|
|
@ -2,6 +2,7 @@ Zammad::Application.routes.draw do
|
|||
|
||||
match '/tests-core', :to => 'tests#core', :via => :get
|
||||
match '/tests-ui', :to => 'tests#ui', :via => :get
|
||||
match '/tests-model', :to => 'tests#model', :via => :get
|
||||
match '/tests-form', :to => 'tests#form', :via => :get
|
||||
match '/tests-table', :to => 'tests#table', :via => :get
|
||||
match '/tests/wait/:sec', :to => 'tests#wait', :via => :get
|
||||
|
|
1017
db/migrate/20140831000001_create_object_manager.rb
Normal file
1017
db/migrate/20140831000001_create_object_manager.rb
Normal file
File diff suppressed because it is too large
Load diff
34
db/seeds.rb
34
db/seeds.rb
|
@ -1311,20 +1311,20 @@ Link::Object.create_if_not_exists( :name => 'Question/Answer' )
|
|||
Link::Object.create_if_not_exists( :name => 'Idea' )
|
||||
Link::Object.create_if_not_exists( :name => 'Bug' )
|
||||
|
||||
Ticket::StateType.create_if_not_exists( :name => 'new', :updated_by_id => 1 )
|
||||
Ticket::StateType.create_if_not_exists( :name => 'open', :updated_by_id => 1 )
|
||||
Ticket::StateType.create_if_not_exists( :name => 'pending reminder', :updated_by_id => 1 )
|
||||
Ticket::StateType.create_if_not_exists( :name => 'pending action', :updated_by_id => 1 )
|
||||
Ticket::StateType.create_if_not_exists( :name => 'closed', :updated_by_id => 1 )
|
||||
Ticket::StateType.create_if_not_exists( :name => 'merged', :updated_by_id => 1 )
|
||||
Ticket::StateType.create_if_not_exists( :name => 'removed', :updated_by_id => 1 )
|
||||
Ticket::StateType.create_if_not_exists( :id => 1, :name => 'new', :updated_by_id => 1 )
|
||||
Ticket::StateType.create_if_not_exists( :id => 2, :name => 'open', :updated_by_id => 1 )
|
||||
Ticket::StateType.create_if_not_exists( :id => 3, :name => 'pending reminder', :updated_by_id => 1 )
|
||||
Ticket::StateType.create_if_not_exists( :id => 4, :name => 'pending action', :updated_by_id => 1 )
|
||||
Ticket::StateType.create_if_not_exists( :id => 5, :name => 'closed', :updated_by_id => 1 )
|
||||
Ticket::StateType.create_if_not_exists( :id => 6, :name => 'merged', :updated_by_id => 1 )
|
||||
Ticket::StateType.create_if_not_exists( :id => 7, :name => 'removed', :updated_by_id => 1 )
|
||||
|
||||
Ticket::State.create_if_not_exists( :name => 'new', :state_type_id => Ticket::StateType.where(:name => 'new').first.id )
|
||||
Ticket::State.create_if_not_exists( :name => 'open', :state_type_id => Ticket::StateType.where(:name => 'open').first.id )
|
||||
Ticket::State.create_if_not_exists( :name => 'pending', :state_type_id => Ticket::StateType.where(:name => 'pending reminder').first.id )
|
||||
Ticket::State.create_if_not_exists( :name => 'closed', :state_type_id => Ticket::StateType.where(:name => 'closed').first.id )
|
||||
Ticket::State.create_if_not_exists( :name => 'merged', :state_type_id => Ticket::StateType.where(:name => 'merged').first.id )
|
||||
Ticket::State.create_if_not_exists( :name => 'removed', :state_type_id => Ticket::StateType.where(:name => 'removed').first.id )
|
||||
Ticket::State.create_if_not_exists( :id => 1, :name => 'new', :state_type_id => Ticket::StateType.where(:name => 'new').first.id )
|
||||
Ticket::State.create_if_not_exists( :id => 2, :name => 'open', :state_type_id => Ticket::StateType.where(:name => 'open').first.id )
|
||||
Ticket::State.create_if_not_exists( :id => 3, :name => 'pending', :state_type_id => Ticket::StateType.where(:name => 'pending reminder').first.id )
|
||||
Ticket::State.create_if_not_exists( :id => 4, :name => 'closed', :state_type_id => Ticket::StateType.where(:name => 'closed').first.id )
|
||||
Ticket::State.create_if_not_exists( :id => 5, :name => 'merged', :state_type_id => Ticket::StateType.where(:name => 'merged').first.id )
|
||||
Ticket::State.create_if_not_exists( :id => 6, :name => 'removed', :state_type_id => Ticket::StateType.where(:name => 'removed').first.id )
|
||||
|
||||
Ticket::Priority.create_if_not_exists( :name => '1 low' )
|
||||
Ticket::Priority.create_if_not_exists( :name => '2 normal' )
|
||||
|
@ -1683,7 +1683,7 @@ Translation.create_if_not_exists( :locale => 'de', :source => "Direction", :targ
|
|||
Translation.create_if_not_exists( :locale => 'de', :source => "Owner", :target => "Besitzer" )
|
||||
Translation.create_if_not_exists( :locale => 'de', :source => "Subject", :target => "Betreff" )
|
||||
Translation.create_if_not_exists( :locale => 'de', :source => "Priority", :target => "Priorität" )
|
||||
Translation.create_if_not_exists( :locale => 'de', :source => "Select the customer of the Ticket or create one.", :target => "Wähle den Kundn f<>r das Ticket oder erstell einen neuen." )
|
||||
Translation.create_if_not_exists( :locale => 'de', :source => "Select the customer of the ticket or create one.", :target => "Wähle den Kunden f<>r das Ticket oder erstelle einen Neuen." )
|
||||
Translation.create_if_not_exists( :locale => 'de', :source => "New Ticket", :target => "Neues Ticket" )
|
||||
Translation.create_if_not_exists( :locale => 'de', :source => "Firstname", :target => "Vorname" )
|
||||
Translation.create_if_not_exists( :locale => 'de', :source => "Lastname", :target => "Nachname" )
|
||||
|
@ -1756,7 +1756,7 @@ Translation.create_if_not_exists( :locale => 'de', :source => "Forgot your passw
|
|||
Translation.create_if_not_exists( :locale => 'de', :source => "Templates", :target => "Vorlagen" )
|
||||
Translation.create_if_not_exists( :locale => 'de', :source => "Delete", :target => "Löschen" )
|
||||
Translation.create_if_not_exists( :locale => 'de', :source => "Apply", :target => "Übernehmen" )
|
||||
Translation.create_if_not_exists( :locale => 'de', :source => "Save as Template", :target => "Als Template speichern" )
|
||||
Translation.create_if_not_exists( :locale => 'de', :source => "Save as Template", :target => "Als Vorlage speichern" )
|
||||
Translation.create_if_not_exists( :locale => 'de', :source => "Save", :target => "Speichern" )
|
||||
Translation.create_if_not_exists( :locale => 'de', :source => "Open Tickets", :target => "Offene Ticket" )
|
||||
Translation.create_if_not_exists( :locale => 'de', :source => "Closed Tickets", :target => "Geschlossene Ticket" )
|
||||
|
@ -1771,7 +1771,7 @@ Translation.create_if_not_exists( :locale => 'de', :source => "3 high", :target
|
|||
Translation.create_if_not_exists( :locale => 'de', :source => "public", :target => "öffentlich" )
|
||||
Translation.create_if_not_exists( :locale => 'de', :source => "internal", :target => "intern" )
|
||||
Translation.create_if_not_exists( :locale => 'de', :source => "Attach files", :target => "Dateien anhängen" )
|
||||
Translation.create_if_not_exists( :locale => 'de', :source => "Visability", :target => "Sichtbarkeit" )
|
||||
Translation.create_if_not_exists( :locale => 'de', :source => "Visibility", :target => "Sichtbarkeit" )
|
||||
Translation.create_if_not_exists( :locale => 'de', :source => "Actions", :target => "Aktionen" )
|
||||
Translation.create_if_not_exists( :locale => 'de', :source => "Email", :target => "E-Mail" )
|
||||
Translation.create_if_not_exists( :locale => 'de', :source => "email", :target => "E-Mail" )
|
||||
|
@ -1791,7 +1791,7 @@ Translation.create_if_not_exists( :locale => 'de', :source => "Change Customer",
|
|||
Translation.create_if_not_exists( :locale => 'de', :source => "My Tickets", :target => "Meine Tickets" )
|
||||
Translation.create_if_not_exists( :locale => 'de', :source => "My Organization Tickets", :target => "Meine Organisations Tickets" )
|
||||
Translation.create_if_not_exists( :locale => 'de', :source => "My Organization", :target => "Meine Organisation" )
|
||||
Translation.create_if_not_exists( :locale => 'de', :source => "Assignment Timout", :target => "Zeitliche Zuweisungsüberschritung" )
|
||||
Translation.create_if_not_exists( :locale => 'de', :source => "Assignment Timeout", :target => "Zeitliche Zuweisungsüberschritung" )
|
||||
Translation.create_if_not_exists( :locale => 'de', :source => "We've sent password reset instructions to your email address.", :target => "Wir haben Ihnen die Anleitung zum zurücksetzen Ihres Passworts an Ihre E-Mail-Adresse gesendet." )
|
||||
Translation.create_if_not_exists( :locale => 'de', :source => "Enter your username or email address", :target => "Bitte geben Sie Ihren Benutzernamen oder E-Mail-Adresse ein" )
|
||||
Translation.create_if_not_exists( :locale => 'de', :source => "Choose your new password.", :target => "Wählen Sie Ihr neues Passwort." )
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -8,9 +8,9 @@ class Sessions::Backend::TicketCreate
|
|||
|
||||
def load
|
||||
|
||||
# get whole collection
|
||||
# get attributes to update
|
||||
ticket_create_attributes = Ticket::ScreenOptions.attributes_to_change(
|
||||
:current_user_id => @user.id,
|
||||
:user => @user.id,
|
||||
)
|
||||
|
||||
# no data exists
|
||||
|
@ -38,32 +38,31 @@ class Sessions::Backend::TicketCreate
|
|||
# set new timeout
|
||||
Sessions::CacheIn.set( self.client_key, true, { :expires_in => 25.seconds } )
|
||||
|
||||
create_attributes = self.load
|
||||
ticket_create_attributes = self.load
|
||||
|
||||
return if !ticket_create_attributes
|
||||
|
||||
return if !create_attributes
|
||||
|
||||
users = {}
|
||||
create_attributes[:owner_id].each {|user_id|
|
||||
if !users[user_id]
|
||||
users[user_id] = User.find(user_id).attributes
|
||||
end
|
||||
}
|
||||
data = {
|
||||
:users => users,
|
||||
:edit_form => create_attributes,
|
||||
:assets => ticket_create_attributes[:assets],
|
||||
:form_meta => {
|
||||
:filter => ticket_create_attributes[:filter],
|
||||
:dependencies => ticket_create_attributes[:dependencies],
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if !@client
|
||||
return {
|
||||
:collection => 'ticket_create_attributes',
|
||||
:data => create_attributes,
|
||||
:data => data,
|
||||
}
|
||||
end
|
||||
|
||||
@client.log 'notify', "push ticket_create for user #{ @user.id }"
|
||||
@client.send({
|
||||
:collection => 'ticket_create_attributes',
|
||||
:data => create_attributes,
|
||||
:data => data,
|
||||
})
|
||||
end
|
||||
|
||||
|
|
|
@ -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('<hr><h1>form required_if + shown_if</h1><div><form id="form7"></form></div>')
|
||||
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 ')
|
||||
|
||||
});
|
200
public/assets/tests/model.js
Normal file
200
public/assets/tests/model.js
Normal file
|
@ -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')
|
||||
|
||||
});
|
|
@ -46,6 +46,28 @@ class AAbUnitTest < TestCase
|
|||
]
|
||||
browser_single_test(tests)
|
||||
end
|
||||
def test_model
|
||||
tests = [
|
||||
{
|
||||
:name => 'start',
|
||||
:instance => browser_instance,
|
||||
:url => browser_url + '/tests-model',
|
||||
:action => [
|
||||
{
|
||||
:execute => 'wait',
|
||||
:value => 8,
|
||||
},
|
||||
{
|
||||
:execute => 'match',
|
||||
:css => '.result .failed',
|
||||
:value => '0',
|
||||
:match_result => true,
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
browser_single_test(tests)
|
||||
end
|
||||
def test_form
|
||||
tests = [
|
||||
{
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
{
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
{
|
||||
|
|
|
@ -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äöü',
|
||||
},
|
||||
{
|
||||
|
|
|
@ -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',
|
||||
},
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -74,26 +74,57 @@ class TagTest < ActiveSupport::TestCase
|
|||
},
|
||||
},
|
||||
|
||||
# test 5
|
||||
{
|
||||
:tag_remove => {
|
||||
:item => 'tag1',
|
||||
:object => 'Object1',
|
||||
:o_id => 123,
|
||||
:created_by_id => 1
|
||||
},
|
||||
:verify => {
|
||||
:object => 'Object1',
|
||||
:items => {
|
||||
'tag1' => false,
|
||||
'tag2' => true,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
]
|
||||
tests.each { |test|
|
||||
success = Tag.tag_add( test[:tag_add] )
|
||||
assert( success, "Tag.tag_add successful")
|
||||
list = Tag.tag_list( test[:tag_add] )
|
||||
tags = nil
|
||||
if test[:tag_add]
|
||||
tags = test[:tag_add]
|
||||
success = Tag.tag_add( tags )
|
||||
assert( success, "Tag.tag_add successful")
|
||||
else
|
||||
tags = test[:tag_remove]
|
||||
success = Tag.tag_remove( tags )
|
||||
assert( success, "Tag.tag_remove successful")
|
||||
end
|
||||
list = Tag.tag_list( tags )
|
||||
test[:verify][:items].each {|key, value|
|
||||
if value == true
|
||||
assert( list.include?( key ), "Tag verify #{ test[:tag_add][:item] }")
|
||||
assert( list.include?( key ), "Tag verify - should exists but exists #{ key }")
|
||||
else
|
||||
assert( !list.include?( key ), "Tag verify #{ test[:tag_add][:item] }")
|
||||
assert( !list.include?( key ), "Tag verify - exists but should not #{ key }")
|
||||
end
|
||||
}
|
||||
}
|
||||
|
||||
# delete tags
|
||||
tests.each { |test|
|
||||
success = Tag.tag_remove( test[:tag_add] )
|
||||
tags = nil
|
||||
if test[:tag_add]
|
||||
tags = test[:tag_add]
|
||||
else
|
||||
tags = test[:tag_remove]
|
||||
end
|
||||
success = Tag.tag_remove( tags )
|
||||
assert( success, "Tag.tag_remove successful")
|
||||
list = Tag.tag_list( test[:tag_add] )
|
||||
assert( !list.include?( test[:tag_add][:item] ), "Tag entry destroyed")
|
||||
list = Tag.tag_list( tags )
|
||||
assert( !list.include?( tags[:item] ), "Tag entry destroyed")
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue