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'
|
source 'http://rubygems.org'
|
||||||
|
|
||||||
gem 'rails', '4.1.4'
|
gem 'rails', '4.1.5'
|
||||||
gem 'rails-observers'
|
gem 'rails-observers'
|
||||||
gem 'activerecord-session_store'
|
gem 'activerecord-session_store'
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,11 @@ class App.ControllerForm extends App.Controller
|
||||||
constructor: (params) ->
|
constructor: (params) ->
|
||||||
for key, value of params
|
for key, value of params
|
||||||
@[key] = value
|
@[key] = value
|
||||||
@attribute_count = 0
|
|
||||||
|
if !@handlers
|
||||||
|
@handlers = []
|
||||||
|
@handlers.push @_showHideToggle
|
||||||
|
@handlers.push @_requiredMandantoryToggle
|
||||||
|
|
||||||
if !@form
|
if !@form
|
||||||
@form = @formGen()
|
@form = @formGen()
|
||||||
|
@ -23,33 +27,51 @@ class App.ControllerForm extends App.Controller
|
||||||
|
|
||||||
fieldset = $('<fieldset></fieldset>')
|
fieldset = $('<fieldset></fieldset>')
|
||||||
|
|
||||||
for attribute_clean in @model.configure_attributes
|
# collect form attributes
|
||||||
attribute = _.clone( attribute_clean )
|
@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
|
# check generic filter
|
||||||
item = @formGenItem( attribute, @model.className, fieldset )
|
if @filter && !attribute.filter
|
||||||
item.appendTo(fieldset)
|
if @filter[ attributeName ]
|
||||||
|
attribute.filter = @filter[ attributeName ]
|
||||||
|
|
||||||
# if password, add confirm password item
|
@attributes.push attribute
|
||||||
if attribute.type is 'password'
|
|
||||||
|
|
||||||
# set selected value passed on current params
|
attribute_count = 0
|
||||||
if @params
|
className = @model.className + '_' + Math.floor( Math.random() * 999999 ).toString()
|
||||||
if attribute.name of @params
|
|
||||||
attribute.value = @params[attribute.name]
|
|
||||||
|
|
||||||
# rename display and name to _confirm
|
for attribute in @attributes
|
||||||
if !attribute.single
|
attribute_count = attribute_count + 1
|
||||||
attribute.display = attribute.display + ' (confirm)'
|
|
||||||
attribute.name = attribute.name + '_confirm';
|
|
||||||
item = @formGenItem( attribute, @model.className, fieldset )
|
|
||||||
item.appendTo(fieldset)
|
|
||||||
|
|
||||||
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()
|
fieldset = fieldset.children()
|
||||||
|
|
||||||
if @fullForm
|
if @fullForm
|
||||||
|
@ -57,6 +79,13 @@ class App.ControllerForm extends App.Controller
|
||||||
@formClass = ''
|
@formClass = ''
|
||||||
fieldset = $('<form class="' + @formClass + '"><button class="btn">' + App.i18n.translateContent('Submit') + '</button></form>').prepend( fieldset )
|
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 form
|
||||||
return fieldset
|
return fieldset
|
||||||
|
|
||||||
|
@ -85,7 +114,7 @@ class App.ControllerForm extends App.Controller
|
||||||
null: false
|
null: false
|
||||||
relation: 'User'
|
relation: 'User'
|
||||||
autocapitalize: false
|
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>'
|
helpLink: '<a href="" class="customer_new">»</a>'
|
||||||
callback: @userInfo
|
callback: @userInfo
|
||||||
class: 'span7'
|
class: 'span7'
|
||||||
|
@ -134,14 +163,14 @@ class App.ControllerForm extends App.Controller
|
||||||
|
|
||||||
###
|
###
|
||||||
|
|
||||||
formGenItem: (attribute_config, classname, form ) ->
|
formGenItem: (attribute_config, classname, form, attribute_count ) ->
|
||||||
attribute = _.clone( attribute_config )
|
attribute = clone( attribute_config )
|
||||||
|
|
||||||
# create item id
|
# create item id
|
||||||
attribute.id = classname + '_' + attribute.name
|
attribute.id = classname + '_' + attribute.name
|
||||||
|
|
||||||
# set autofocus
|
# set autofocus
|
||||||
if @autofocus && @attribute_count is 1
|
if @autofocus && attribute_count is 1
|
||||||
attribute.autofocus = 'autofocus'
|
attribute.autofocus = 'autofocus'
|
||||||
|
|
||||||
# set required option
|
# set required option
|
||||||
|
@ -237,6 +266,22 @@ class App.ControllerForm extends App.Controller
|
||||||
else if attribute.tag is 'select'
|
else if attribute.tag is 'select'
|
||||||
item = $( App.view('generic/select')( attribute: attribute ) )
|
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
|
# timezone
|
||||||
else if attribute.tag is 'timezone'
|
else if attribute.tag is 'timezone'
|
||||||
attribute.options = []
|
attribute.options = []
|
||||||
|
@ -720,7 +765,7 @@ class App.ControllerForm extends App.Controller
|
||||||
|
|
||||||
b = (event, item) =>
|
b = (event, item) =>
|
||||||
# set html form attribute
|
# set html form attribute
|
||||||
$(local_attribute).val(item.id)
|
$(local_attribute).val(item.id).trigger('change')
|
||||||
$(local_attribute + '_autocompletion_value_shown').val(item.value)
|
$(local_attribute + '_autocompletion_value_shown').val(item.value)
|
||||||
|
|
||||||
# call calback
|
# 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(
|
$(local_attribute_full).autocomplete(
|
||||||
source: attribute.source,
|
source: source,
|
||||||
minLength: attribute.minLengt || 3,
|
minLength: attribute.minLengt || 3,
|
||||||
select: ( event, ui ) =>
|
select: ( event, ui ) =>
|
||||||
b(event, ui.item)
|
b(event, ui.item)
|
||||||
|
@ -1224,63 +1272,12 @@ class App.ControllerForm extends App.Controller
|
||||||
else
|
else
|
||||||
item = $( App.view('generic/input')( attribute: attribute ) )
|
item = $( App.view('generic/input')( attribute: attribute ) )
|
||||||
|
|
||||||
if attribute.onchange
|
if @handlers
|
||||||
if typeof attribute.onchange is 'function'
|
item.bind('change', (e) =>
|
||||||
attribute.onchange(attribute)
|
params = App.ControllerForm.params( $(e.target) )
|
||||||
else
|
for handler in @handlers
|
||||||
for i of attribute.onchange
|
handler(params, attribute, @attributes, classname, form, @)
|
||||||
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 )
|
|
||||||
)
|
|
||||||
|
|
||||||
# bind dependency
|
# bind dependency
|
||||||
if @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 + '"]').parents('.form-group').addClass('hide')
|
||||||
el.find('[name="' + key + '"]').addClass('is-hidden')
|
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
|
# sort attribute.options
|
||||||
_sortOptions: (attribute) ->
|
_sortOptions: (attribute) ->
|
||||||
|
|
||||||
|
@ -1402,6 +1437,7 @@ class App.ControllerForm extends App.Controller
|
||||||
|
|
||||||
list = []
|
list = []
|
||||||
if attribute.filter
|
if attribute.filter
|
||||||
|
|
||||||
App.Log.debug 'ControllerForm', '_getRelationOptionList:filter', attribute.filter
|
App.Log.debug 'ControllerForm', '_getRelationOptionList:filter', attribute.filter
|
||||||
|
|
||||||
# function based filter
|
# function based filter
|
||||||
|
@ -1429,6 +1465,22 @@ class App.ControllerForm extends App.Controller
|
||||||
if record['id'] is key
|
if record['id'] is key
|
||||||
list.push record
|
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
|
# no data filter matched
|
||||||
else
|
else
|
||||||
App.Log.debug 'ControllerForm', '_getRelationOptionList:filter-data no filter matched'
|
App.Log.debug 'ControllerForm', '_getRelationOptionList:filter-data no filter matched'
|
||||||
|
@ -1515,9 +1567,10 @@ class App.ControllerForm extends App.Controller
|
||||||
|
|
||||||
validate: (params) ->
|
validate: (params) ->
|
||||||
App.Model.validate(
|
App.Model.validate(
|
||||||
model: @model,
|
model: @model
|
||||||
params: params,
|
params: params
|
||||||
)
|
screen: @screen
|
||||||
|
)
|
||||||
|
|
||||||
# get all params of the form
|
# get all params of the form
|
||||||
@params: (form) ->
|
@params: (form) ->
|
||||||
|
@ -1640,13 +1693,8 @@ class App.ControllerForm extends App.Controller
|
||||||
|
|
||||||
# show new errors
|
# show new errors
|
||||||
for key, msg of data.errors
|
for key, msg of data.errors
|
||||||
$(data.form).parents().find('[name*="' + key + '"]').parents('div .form-group').addClass('has-error')
|
$(data.form).parents('form').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 + '"]').parent().find('.help-inline').html(msg)
|
||||||
|
|
||||||
# set autofocus
|
# set autofocus
|
||||||
$(data.form).parents().find('.has-error').find('input, textarea').first().focus()
|
$(data.form).parents('form').find('.has-error').find('input, textarea').first().focus()
|
||||||
|
|
||||||
# # enable form again
|
|
||||||
# if $(data.form).parents().find('.has-error').html()
|
|
||||||
# @formEnable(data.form)
|
|
||||||
|
|
||||||
|
|
|
@ -7,11 +7,11 @@ class App.ControllerGenericNew extends App.ControllerModal
|
||||||
|
|
||||||
@html App.view('generic/admin/new')( head: @pageData.object )
|
@html App.view('generic/admin/new')( head: @pageData.object )
|
||||||
new App.ControllerForm(
|
new App.ControllerForm(
|
||||||
el: @el.find('#object_new'),
|
el: @el.find('#object_new')
|
||||||
model: App[ @genericObject ],
|
model: App[ @genericObject ]
|
||||||
params: @item,
|
params: @item
|
||||||
required: @required,
|
screen: @screen || 'edit'
|
||||||
autofocus: true,
|
autofocus: true
|
||||||
)
|
)
|
||||||
@modalShow()
|
@modalShow()
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ class App.ControllerGenericEdit extends App.ControllerModal
|
||||||
el: @el.find('#object_edit')
|
el: @el.find('#object_edit')
|
||||||
model: App[ @genericObject ]
|
model: App[ @genericObject ]
|
||||||
params: @item
|
params: @item
|
||||||
required: @required
|
screen: @screen || 'edit'
|
||||||
autofocus: true
|
autofocus: true
|
||||||
)
|
)
|
||||||
@modalShow()
|
@modalShow()
|
||||||
|
|
|
@ -99,6 +99,7 @@ class App.ControllerTable extends App.Controller
|
||||||
data.model = {}
|
data.model = {}
|
||||||
overview = data.overview || data.model.configure_overview || []
|
overview = data.overview || data.model.configure_overview || []
|
||||||
attributes = data.attributes || data.model.configure_attributes || {}
|
attributes = data.attributes || data.model.configure_attributes || {}
|
||||||
|
attributes = App.Model.attributesGet(false, attributes)
|
||||||
destroy = data.model.configure_delete
|
destroy = data.model.configure_delete
|
||||||
|
|
||||||
# check if table is empty
|
# check if table is empty
|
||||||
|
@ -146,13 +147,13 @@ class App.ControllerTable extends App.Controller
|
||||||
header = []
|
header = []
|
||||||
for item in overview
|
for item in overview
|
||||||
headerFound = false
|
headerFound = false
|
||||||
for attribute in attributes
|
for attributeName, attribute of attributes
|
||||||
if attribute.name is item
|
if attributeName is item
|
||||||
headerFound = true
|
headerFound = true
|
||||||
header.push attribute
|
header.push attribute
|
||||||
else
|
else
|
||||||
rowWithoutId = item + '_id'
|
rowWithoutId = item + '_id'
|
||||||
if attribute.name is rowWithoutId
|
if attributeName is rowWithoutId
|
||||||
headerFound = true
|
headerFound = true
|
||||||
header.push attribute
|
header.push attribute
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
class App.TicketCreate extends App.Controller
|
class App.TicketCreate extends App.Controller
|
||||||
events:
|
events:
|
||||||
'click .customer_new': 'userNew'
|
'click .type-tabs .tab': 'changeFormType'
|
||||||
'submit form': 'submit'
|
'click .customer_new': 'userNew'
|
||||||
'click .submit': 'submit'
|
'submit form': 'submit'
|
||||||
'click .cancel': 'cancel'
|
'click .submit': 'submit'
|
||||||
|
'click .cancel': 'cancel'
|
||||||
|
|
||||||
constructor: (params) ->
|
constructor: (params) ->
|
||||||
super
|
super
|
||||||
|
@ -13,40 +14,18 @@ class App.TicketCreate extends App.Controller
|
||||||
|
|
||||||
# set title
|
# set title
|
||||||
@form_id = App.ControllerForm.formId()
|
@form_id = App.ControllerForm.formId()
|
||||||
|
@form_meta = undefined
|
||||||
|
|
||||||
@edit_form = undefined
|
# define default type
|
||||||
|
@default_type = 'phone-in'
|
||||||
# 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]
|
|
||||||
|
|
||||||
# remember split info if exists
|
# remember split info if exists
|
||||||
split = ''
|
split = ''
|
||||||
if @ticket_id && @article_id
|
if @ticket_id && @article_id
|
||||||
split = "/#{@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
|
# update navbar highlighting
|
||||||
@navupdate '#ticket/create/' + @type + '/id/' + @id + split
|
@navupdate '#ticket/create/id/' + @id + split
|
||||||
|
|
||||||
@fetch(params)
|
@fetch(params)
|
||||||
|
|
||||||
|
@ -55,20 +34,72 @@ class App.TicketCreate extends App.Controller
|
||||||
@log 'notice', 'error', defaults
|
@log 'notice', 'error', defaults
|
||||||
@render(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: =>
|
meta: =>
|
||||||
text = App.i18n.translateInline( @article_attributes['title'] )
|
text = ''
|
||||||
subject = @el.find('[name=subject]').val()
|
if @articleAttributes
|
||||||
if subject
|
text = App.i18n.translateInline( @articleAttributes['title'] )
|
||||||
text = "#{text}: #{subject}"
|
title = @el.find('[name=title]').val()
|
||||||
|
if title
|
||||||
|
text = "#{text}: #{title}"
|
||||||
meta =
|
meta =
|
||||||
url: @url()
|
url: @url()
|
||||||
head: text
|
head: text
|
||||||
title: text
|
title: text
|
||||||
id: @type
|
id: @id
|
||||||
iconClass: 'pen'
|
iconClass: 'pen'
|
||||||
|
|
||||||
url: =>
|
url: =>
|
||||||
'#ticket/create/' + @type + '/id/' + @id
|
'#ticket/create/id/' + @id
|
||||||
|
|
||||||
activate: =>
|
activate: =>
|
||||||
@navupdate '#'
|
@navupdate '#'
|
||||||
|
@ -101,7 +132,7 @@ class App.TicketCreate extends App.Controller
|
||||||
if cache && !params.ticket_id && !params.article_id
|
if cache && !params.ticket_id && !params.article_id
|
||||||
|
|
||||||
# get edit form attributes
|
# get edit form attributes
|
||||||
@edit_form = cache.edit_form
|
@form_meta = cache.form_meta
|
||||||
|
|
||||||
# load assets
|
# load assets
|
||||||
App.Collection.loadAssets( cache.assets )
|
App.Collection.loadAssets( cache.assets )
|
||||||
|
@ -109,7 +140,7 @@ class App.TicketCreate extends App.Controller
|
||||||
@render()
|
@render()
|
||||||
else
|
else
|
||||||
@ajax(
|
@ajax(
|
||||||
id: 'ticket_create'
|
id: 'ticket_create' + @task_key
|
||||||
type: 'GET'
|
type: 'GET'
|
||||||
url: @apiPath + '/ticket_create'
|
url: @apiPath + '/ticket_create'
|
||||||
data:
|
data:
|
||||||
|
@ -122,7 +153,7 @@ class App.TicketCreate extends App.Controller
|
||||||
App.Store.write( 'ticket_create_attributes', data )
|
App.Store.write( 'ticket_create_attributes', data )
|
||||||
|
|
||||||
# get edit form attributes
|
# get edit form attributes
|
||||||
@edit_form = data.edit_form
|
@form_meta = data.form_meta
|
||||||
|
|
||||||
# load assets
|
# load assets
|
||||||
App.Collection.loadAssets( data.assets )
|
App.Collection.loadAssets( data.assets )
|
||||||
|
@ -144,43 +175,90 @@ class App.TicketCreate extends App.Controller
|
||||||
|
|
||||||
render: (template = {}) ->
|
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')(
|
@html App.view('agent_ticket_create')(
|
||||||
head: 'New Ticket'
|
head: 'New Ticket'
|
||||||
title: @article_attributes['title']
|
|
||||||
agent: @isRole('Agent')
|
agent: @isRole('Agent')
|
||||||
admin: @isRole('Admin')
|
admin: @isRole('Admin')
|
||||||
)
|
)
|
||||||
|
|
||||||
params = undefined
|
# get params
|
||||||
|
params = {}
|
||||||
if template && !_.isEmpty( template.options )
|
if template && !_.isEmpty( template.options )
|
||||||
params = template.options
|
params = template.options
|
||||||
else if App.TaskManager.get(@task_key) && !_.isEmpty( App.TaskManager.get(@task_key).state )
|
else if App.TaskManager.get(@task_key) && !_.isEmpty( App.TaskManager.get(@task_key).state )
|
||||||
params = 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(
|
new App.ControllerForm(
|
||||||
el: @el.find('.ticket_create')
|
el: @el.find('.ticket-form-top')
|
||||||
form_id: @form_id
|
form_id: @form_id
|
||||||
model:
|
model: App.Ticket
|
||||||
configure_attributes: configure_attributes
|
screen: 'create_top'
|
||||||
className: 'create_' + @type + '_' + @id
|
events:
|
||||||
|
'change [name=customer_id]': @localUserInfo
|
||||||
|
handlers: [
|
||||||
|
formChanges
|
||||||
|
]
|
||||||
|
filter: @form_meta.filter
|
||||||
autofocus: true
|
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
|
params: params
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -190,11 +268,15 @@ class App.TicketCreate extends App.Controller
|
||||||
# template_id: template['id']
|
# template_id: template['id']
|
||||||
# )
|
# )
|
||||||
|
|
||||||
|
# set type selector
|
||||||
|
@setFormTypeInUi( params['formSenderType'] )
|
||||||
|
|
||||||
|
# remember form params of init load
|
||||||
@formDefault = @formParam( @el.find('.ticket-create') )
|
@formDefault = @formParam( @el.find('.ticket-create') )
|
||||||
|
|
||||||
# show text module UI
|
# show text module UI
|
||||||
@textModule = new App.WidgetTextModule(
|
@textModule = new App.WidgetTextModule(
|
||||||
el: @el.find('.ticket-create').find('textarea')
|
el: @el.find('form').find('textarea')
|
||||||
)
|
)
|
||||||
|
|
||||||
$('#tags').tokenfield()
|
$('#tags').tokenfield()
|
||||||
|
@ -202,14 +284,17 @@ class App.TicketCreate extends App.Controller
|
||||||
# start auto save
|
# start auto save
|
||||||
@autosave()
|
@autosave()
|
||||||
|
|
||||||
localUserInfo: (params) =>
|
localUserInfo: (e) =>
|
||||||
|
|
||||||
|
params = App.ControllerForm.params( $(e.target).closest('form') )
|
||||||
|
|
||||||
# update text module UI
|
# update text module UI
|
||||||
callback = (user) =>
|
callback = (user) =>
|
||||||
@textModule.reload(
|
if @textModule
|
||||||
ticket:
|
@textModule.reload(
|
||||||
customer: user
|
ticket:
|
||||||
)
|
customer: user
|
||||||
|
)
|
||||||
|
|
||||||
@userInfo(
|
@userInfo(
|
||||||
user_id: params.customer_id
|
user_id: params.customer_id
|
||||||
|
@ -223,7 +308,8 @@ class App.TicketCreate extends App.Controller
|
||||||
create_screen: @
|
create_screen: @
|
||||||
)
|
)
|
||||||
|
|
||||||
cancel: ->
|
cancel: (e) ->
|
||||||
|
e.preventDefault()
|
||||||
@navigate '#'
|
@navigate '#'
|
||||||
|
|
||||||
submit: (e) ->
|
submit: (e) ->
|
||||||
|
@ -237,11 +323,11 @@ class App.TicketCreate extends App.Controller
|
||||||
params.title = params.subject
|
params.title = params.subject
|
||||||
|
|
||||||
# create ticket
|
# create ticket
|
||||||
object = new App.Ticket
|
ticket = new App.Ticket
|
||||||
|
|
||||||
# find sender_id
|
# find sender_id
|
||||||
sender = App.TicketArticleSender.findByAttribute( 'name', @article_attributes['sender'] )
|
sender = App.TicketArticleSender.findByAttribute( 'name', @articleAttributes['sender'] )
|
||||||
type = App.TicketArticleType.findByAttribute( 'name', @article_attributes['article'] )
|
type = App.TicketArticleType.findByAttribute( 'name', @articleAttributes['article'] )
|
||||||
|
|
||||||
if params.group_id
|
if params.group_id
|
||||||
group = App.Group.find( params.group_id )
|
group = App.Group.find( params.group_id )
|
||||||
|
@ -251,6 +337,7 @@ class App.TicketCreate extends App.Controller
|
||||||
params['article'] = {
|
params['article'] = {
|
||||||
to: (group && group.name) || ''
|
to: (group && group.name) || ''
|
||||||
from: params.customer_id_autocompletion
|
from: params.customer_id_autocompletion
|
||||||
|
cc: params.cc
|
||||||
subject: params.subject
|
subject: params.subject
|
||||||
body: params.body
|
body: params.body
|
||||||
type_id: type.id
|
type_id: type.id
|
||||||
|
@ -261,6 +348,7 @@ class App.TicketCreate extends App.Controller
|
||||||
params['article'] = {
|
params['article'] = {
|
||||||
from: (group && group.name) || ''
|
from: (group && group.name) || ''
|
||||||
to: params.customer_id_autocompletion
|
to: params.customer_id_autocompletion
|
||||||
|
cc: params.cc
|
||||||
subject: params.subject
|
subject: params.subject
|
||||||
body: params.body
|
body: params.body
|
||||||
type_id: type.id
|
type_id: type.id
|
||||||
|
@ -268,15 +356,38 @@ class App.TicketCreate extends App.Controller
|
||||||
form_id: @form_id
|
form_id: @form_id
|
||||||
}
|
}
|
||||||
|
|
||||||
object.load(params)
|
ticket.load(params)
|
||||||
|
|
||||||
# validate form
|
ticketErrorsTop = ticket.validate(
|
||||||
errors = object.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
|
# show errors in form
|
||||||
if errors
|
if !_.isEmpty( errors )
|
||||||
@log 'error', errors
|
@log 'error', errors
|
||||||
@formValidate( form: e.target, errors: errors )
|
@formValidate(
|
||||||
|
form: e.target
|
||||||
|
errors: errors
|
||||||
|
)
|
||||||
|
|
||||||
# save ticket, create article
|
# save ticket, create article
|
||||||
else
|
else
|
||||||
|
@ -284,7 +395,7 @@ class App.TicketCreate extends App.Controller
|
||||||
# disable form
|
# disable form
|
||||||
@formDisable(e)
|
@formDisable(e)
|
||||||
ui = @
|
ui = @
|
||||||
object.save(
|
ticket.save(
|
||||||
done: ->
|
done: ->
|
||||||
|
|
||||||
# notify UI
|
# notify UI
|
||||||
|
@ -325,10 +436,10 @@ class UserNew extends App.ControllerModal
|
||||||
@html App.view('agent_user_create')( head: 'New User' )
|
@html App.view('agent_user_create')( head: 'New User' )
|
||||||
|
|
||||||
new App.ControllerForm(
|
new App.ControllerForm(
|
||||||
el: @el.find('#form-user'),
|
el: @el.find('#form-user')
|
||||||
model: App.User,
|
model: App.User
|
||||||
required: 'quick',
|
screen: 'edit'
|
||||||
autofocus: true,
|
autofocus: true
|
||||||
)
|
)
|
||||||
|
|
||||||
@modalShow()
|
@modalShow()
|
||||||
|
@ -390,7 +501,7 @@ class Router extends App.ControllerPermanent
|
||||||
split = "/#{params['ticket_id']}/#{params['article_id']}"
|
split = "/#{params['ticket_id']}/#{params['article_id']}"
|
||||||
|
|
||||||
id = Math.floor( Math.random() * 99999 )
|
id = Math.floor( Math.random() * 99999 )
|
||||||
@navigate "#ticket/create/#{params['type']}/id/#{id}#{split}"
|
@navigate "#ticket/create/id/#{id}#{split}"
|
||||||
return
|
return
|
||||||
|
|
||||||
# cleanup params
|
# cleanup params
|
||||||
|
@ -400,20 +511,16 @@ class Router extends App.ControllerPermanent
|
||||||
type: params.type
|
type: params.type
|
||||||
id: params.id
|
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
|
# create new ticket routes/controller
|
||||||
App.Config.set( 'ticket/create', Router, 'Routes' )
|
App.Config.set( 'ticket/create', Router, 'Routes' )
|
||||||
App.Config.set( 'ticket/create/:type', Router, 'Routes' )
|
App.Config.set( 'ticket/create/', Router, 'Routes' )
|
||||||
App.Config.set( 'ticket/create/:type/id/:id', Router, 'Routes' )
|
App.Config.set( 'ticket/create/id/:id', Router, 'Routes' )
|
||||||
|
|
||||||
|
|
||||||
# split ticket
|
# split ticket
|
||||||
App.Config.set( 'ticket/create/:type/:ticket_id/:article_id', Router, 'Routes' )
|
App.Config.set( 'ticket/create/:ticket_id/:article_id', Router, 'Routes' )
|
||||||
App.Config.set( 'ticket/create/:type/id/:id/:ticket_id/:article_id', Router, 'Routes' )
|
App.Config.set( 'ticket/create/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' )
|
|
||||||
|
|
||||||
|
# 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
|
# set title
|
||||||
@title 'New Ticket'
|
@title 'New Ticket'
|
||||||
@form_id = App.ControllerForm.formId()
|
@form_id = App.ControllerForm.formId()
|
||||||
|
@form_meta = undefined
|
||||||
|
|
||||||
@fetch(params)
|
@fetch(params)
|
||||||
@navupdate '#customer_ticket_new'
|
@navupdate '#customer_ticket_new'
|
||||||
|
|
||||||
@edit_form = undefined
|
|
||||||
|
|
||||||
# get data / in case also ticket data for split
|
# get data / in case also ticket data for split
|
||||||
fetch: (params) ->
|
fetch: (params) ->
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ class Index extends App.ControllerContent
|
||||||
if cache
|
if cache
|
||||||
|
|
||||||
# get edit form attributes
|
# get edit form attributes
|
||||||
@edit_form = cache.edit_form
|
@form_meta = cache.form_meta
|
||||||
|
|
||||||
# load assets
|
# load assets
|
||||||
App.Collection.loadAssets( cache.assets )
|
App.Collection.loadAssets( cache.assets )
|
||||||
|
@ -45,7 +45,7 @@ class Index extends App.ControllerContent
|
||||||
App.Store.write( 'ticket_create_attributes', data )
|
App.Store.write( 'ticket_create_attributes', data )
|
||||||
|
|
||||||
# get edit form attributes
|
# get edit form attributes
|
||||||
@edit_form = data.edit_form
|
@form_meta = data.form_meta
|
||||||
|
|
||||||
# load assets
|
# load assets
|
||||||
App.Collection.loadAssets( data.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() )
|
return item if item && _.contains( group_ids, item.id.toString() )
|
||||||
)
|
)
|
||||||
|
|
||||||
# generate form
|
formChanges = (params, attribute, attributes, classname, form, ui) =>
|
||||||
configure_attributes = [
|
if @form_meta.dependencies && @form_meta.dependencies[attribute.name]
|
||||||
{ name: 'group_id', display: 'Group', tag: 'select', multiple: false, null: false, filter: groupFilter, nulloption: true, relation: 'Group', default: defaults['group_id'], class: 'span7', },
|
dependency = @form_meta.dependencies[attribute.name][ parseInt(params[attribute.name]) ]
|
||||||
# { name: 'owner_id', display: 'Owner', tag: 'select', multiple: false, null: true, filter: @edit_form, nulloption: true, relation: 'User', default: defaults['owner_id'], class: 'span7', },
|
if dependency
|
||||||
{ 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 },
|
for fieldNameToChange of dependency
|
||||||
# { name: 'state_id', display: 'State', tag: 'select', multiple: false, null: false, filter: @edit_form, relation: 'TicketState', default: defaults['state_id'], translate: true, class: 'medium' },
|
filter = []
|
||||||
# { name: 'priority_id', display: 'Priority', tag: 'select', multiple: false, null: false, filter: @edit_form, relation: 'TicketPriority', default: defaults['priority_id'], translate: true, class: 'medium' },
|
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' )
|
@html App.view('customer_ticket_create')( head: 'New Ticket' )
|
||||||
|
|
||||||
|
|
||||||
new App.ControllerForm(
|
new App.ControllerForm(
|
||||||
el: @el.find('#form_create')
|
el: @el.find('.ticket-form-top')
|
||||||
form_id: @form_id
|
form_id: @form_id
|
||||||
model:
|
model: App.Ticket
|
||||||
configure_attributes: configure_attributes
|
screen: 'create_top'#@article_attributes['screen']
|
||||||
className: 'create'
|
handlers: [
|
||||||
|
formChanges
|
||||||
|
]
|
||||||
|
filter: @form_meta.filter
|
||||||
autofocus: true
|
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(
|
new App.ControllerDrox(
|
||||||
el: @el.find('.sidebar')
|
el: @el.find('.sidebar')
|
||||||
data:
|
data:
|
||||||
|
@ -128,19 +178,21 @@ class Index extends App.ControllerContent
|
||||||
params.customer_id = @Session.get('id')
|
params.customer_id = @Session.get('id')
|
||||||
|
|
||||||
# set prio
|
# set prio
|
||||||
priority = App.TicketPriority.findByAttribute( 'name', '2 normal' )
|
if !params.priority_id
|
||||||
params.priority_id = priority.id
|
priority = App.TicketPriority.findByAttribute( 'name', '2 normal' )
|
||||||
|
params.priority_id = priority.id
|
||||||
|
|
||||||
# set state
|
# set state
|
||||||
state = App.TicketState.findByAttribute( 'name', 'new' )
|
if !params.state_id
|
||||||
params.state_id = state.id
|
state = App.TicketState.findByAttribute( 'name', 'new' )
|
||||||
|
params.state_id = state.id
|
||||||
|
|
||||||
# fillup params
|
# fillup params
|
||||||
if !params.title
|
if !params.title
|
||||||
params.title = params.subject
|
params.title = params.subject
|
||||||
|
|
||||||
# create ticket
|
# create ticket
|
||||||
object = new App.Ticket
|
ticket = new App.Ticket
|
||||||
@log 'CustomerTicketCreate', 'notice', 'updateAttributes', params
|
@log 'CustomerTicketCreate', 'notice', 'updateAttributes', params
|
||||||
|
|
||||||
# find sender_id
|
# find sender_id
|
||||||
|
@ -160,16 +212,35 @@ class Index extends App.ControllerContent
|
||||||
form_id: @form_id
|
form_id: @form_id
|
||||||
}
|
}
|
||||||
|
|
||||||
object.load(params)
|
ticket.load(params)
|
||||||
|
|
||||||
# validate form
|
# 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
|
# show errors in form
|
||||||
if errors
|
if !_.isEmpty(errors)
|
||||||
@log 'CustomerTicketCreate', 'error', 'can not create', errors
|
@log 'CustomerTicketCreate', 'error', 'can not create', errors
|
||||||
|
|
||||||
@formValidate( form: e.target, errors: errors )
|
@formValidate(
|
||||||
|
form: e.target
|
||||||
|
errors: errors
|
||||||
|
)
|
||||||
|
|
||||||
# save ticket, create article
|
# save ticket, create article
|
||||||
else
|
else
|
||||||
|
@ -177,7 +248,7 @@ class Index extends App.ControllerContent
|
||||||
# disable form
|
# disable form
|
||||||
@formDisable(e)
|
@formDisable(e)
|
||||||
ui = @
|
ui = @
|
||||||
object.save(
|
ticket.save(
|
||||||
done: ->
|
done: ->
|
||||||
|
|
||||||
# redirect to zoom
|
# redirect to zoom
|
||||||
|
@ -189,4 +260,4 @@ class Index extends App.ControllerContent
|
||||||
)
|
)
|
||||||
|
|
||||||
App.Config.set( 'customer_ticket_new', Index, 'Routes' )
|
App.Config.set( 'customer_ticket_new', Index, 'Routes' )
|
||||||
App.Config.set( 'CustomerTicketNew', { prio: 8003, parent: '#new', name: 'New Ticket', target: '#customer_ticket_new', role: ['Customer'], divider: true }, 'NavBarRight' )
|
App.Config.set( 'CustomerTicketNew', { prio: 8003, parent: '#new', name: 'New Ticket', target: '#customer_ticket_new', role: ['Customer'], divider: true }, 'NavBarRight' )
|
||||||
|
|
|
@ -32,7 +32,7 @@ class Index extends App.ControllerContent
|
||||||
new App.ControllerForm(
|
new App.ControllerForm(
|
||||||
el: @el.find('form')
|
el: @el.find('form')
|
||||||
model: App.User
|
model: App.User
|
||||||
required: 'signup'
|
screen: 'signup'
|
||||||
autofocus: true
|
autofocus: true
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -322,7 +322,7 @@ class Table extends App.ControllerContent
|
||||||
configure_attributes: @configure_attributes_ticket
|
configure_attributes: @configure_attributes_ticket
|
||||||
className: 'create'
|
className: 'create'
|
||||||
form_data: @bulk
|
form_data: @bulk
|
||||||
no_fieldset: true
|
noFieldset: true
|
||||||
)
|
)
|
||||||
#html.delegate('.bulk-action-form', 'submit', (e) =>
|
#html.delegate('.bulk-action-form', 'submit', (e) =>
|
||||||
html.bind('submit', (e) =>
|
html.bind('submit', (e) =>
|
||||||
|
|
|
@ -5,7 +5,9 @@ class App.TicketZoom extends App.Controller
|
||||||
# check authentication
|
# check authentication
|
||||||
return if !@authenticate()
|
return if !@authenticate()
|
||||||
|
|
||||||
@edit_form = undefined
|
@navupdate '#'
|
||||||
|
|
||||||
|
@form_meta = undefined
|
||||||
@ticket_id = params.ticket_id
|
@ticket_id = params.ticket_id
|
||||||
@article_id = params.article_id
|
@article_id = params.article_id
|
||||||
@signature = undefined
|
@signature = undefined
|
||||||
|
@ -112,7 +114,7 @@ class App.TicketZoom extends App.Controller
|
||||||
@ticket_article_ids = data.ticket_article_ids
|
@ticket_article_ids = data.ticket_article_ids
|
||||||
|
|
||||||
# get edit form attributes
|
# get edit form attributes
|
||||||
@edit_form = data.edit_form
|
@form_meta = data.form_meta
|
||||||
|
|
||||||
# get signature
|
# get signature
|
||||||
@signature = data.signature
|
@signature = data.signature
|
||||||
|
@ -145,7 +147,7 @@ class App.TicketZoom extends App.Controller
|
||||||
new App.ControllerForm(
|
new App.ControllerForm(
|
||||||
el: @el.find('.edit')
|
el: @el.find('.edit')
|
||||||
model: App.Ticket
|
model: App.Ticket
|
||||||
required: required
|
screen: 'edit'
|
||||||
params: App.Ticket.find(@ticket.id)
|
params: App.Ticket.find(@ticket.id)
|
||||||
)
|
)
|
||||||
# start link info controller
|
# start link info controller
|
||||||
|
@ -163,13 +165,14 @@ class App.TicketZoom extends App.Controller
|
||||||
new App.ControllerForm(
|
new App.ControllerForm(
|
||||||
el: @el.find('.customer-edit')
|
el: @el.find('.customer-edit')
|
||||||
model: App.User
|
model: App.User
|
||||||
required: 'quick'
|
screen: 'edit'
|
||||||
params: App.User.find(@ticket.customer_id)
|
params: App.User.find(@ticket.customer_id)
|
||||||
)
|
)
|
||||||
new App.ControllerForm(
|
new App.ControllerForm(
|
||||||
el: @el.find('.organization-edit')
|
el: @el.find('.organization-edit')
|
||||||
model: App.Organization
|
model: App.Organization
|
||||||
params: App.Organization.find(@ticket.organitaion_id)
|
params: App.Organization.find(@ticket.organitaion_id)
|
||||||
|
screen: 'edit'
|
||||||
)
|
)
|
||||||
|
|
||||||
@TicketAction()
|
@TicketAction()
|
||||||
|
@ -214,7 +217,8 @@ class App.TicketZoom extends App.Controller
|
||||||
new Edit(
|
new Edit(
|
||||||
ticket: @ticket
|
ticket: @ticket
|
||||||
el: @el.find('.ticket-edit')
|
el: @el.find('.ticket-edit')
|
||||||
edit_form: @edit_form
|
#el: @el.find('.edit')
|
||||||
|
form_meta: @form_meta
|
||||||
task_key: @task_key
|
task_key: @task_key
|
||||||
ui: @
|
ui: @
|
||||||
)
|
)
|
||||||
|
@ -244,9 +248,13 @@ class TicketTitle extends App.Controller
|
||||||
|
|
||||||
render: (ticket) =>
|
render: (ticket) =>
|
||||||
@html App.view('ticket_zoom/title')(
|
@html App.view('ticket_zoom/title')(
|
||||||
ticket: ticket
|
ticket: ticket
|
||||||
|
isCustomer: @isRole('Customer')
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# show frontend times
|
||||||
|
@frontendTimeUpdate()
|
||||||
|
|
||||||
update: (e) =>
|
update: (e) =>
|
||||||
$this = $(e.target)
|
$this = $(e.target)
|
||||||
title = $this.html()
|
title = $this.html()
|
||||||
|
@ -298,7 +306,7 @@ class Sidebar extends App.Controller
|
||||||
if name
|
if name
|
||||||
if name is @currentTab
|
if name is @currentTab
|
||||||
@toggleSidebar()
|
@toggleSidebar()
|
||||||
else
|
else
|
||||||
@el.find('.ticket-zoom .sidebar-tab').removeClass('active')
|
@el.find('.ticket-zoom .sidebar-tab').removeClass('active')
|
||||||
$(e.target).closest('.sidebar-tab').addClass('active')
|
$(e.target).closest('.sidebar-tab').addClass('active')
|
||||||
|
|
||||||
|
@ -372,57 +380,55 @@ class Edit extends App.Controller
|
||||||
formChanged: !_.isEmpty( App.TaskManager.get(@task_key).state )
|
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()
|
@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 )
|
if !_.isEmpty( App.TaskManager.get(@task_key).state )
|
||||||
defaults = App.TaskManager.get(@task_key).state
|
defaults = App.TaskManager.get(@task_key).state
|
||||||
new App.ControllerForm(
|
formChanges = (params, attribute, attributes, classname, form, ui) =>
|
||||||
el: @el.find('.form-ticket-update')
|
if @form_meta.dependencies && @form_meta.dependencies[attribute.name]
|
||||||
form_id: @form_id
|
dependency = @form_meta.dependencies[attribute.name][ parseInt(params[attribute.name]) ]
|
||||||
model:
|
if dependency
|
||||||
configure_attributes: @configure_attributes_ticket
|
|
||||||
className: 'update_ticket_' + ticket.id
|
|
||||||
params: defaults
|
|
||||||
form_data: @edit_form
|
|
||||||
)
|
|
||||||
|
|
||||||
|
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(
|
new App.ControllerForm(
|
||||||
el: @el.find('.form-article-update')
|
el: @el.find('.form-article-update')
|
||||||
form_id: @form_id
|
form_id: @form_id
|
||||||
model:
|
model: App.TicketArticle
|
||||||
configure_attributes: @configure_attributes_article
|
screen: 'edit'
|
||||||
className: 'update_ticket_' + ticket.id
|
filter:
|
||||||
form_data: @edit_form
|
type_id: [1,9,5]
|
||||||
params: defaults
|
params: defaults
|
||||||
dependency: [
|
dependency: [
|
||||||
{
|
{
|
||||||
|
@ -440,13 +446,24 @@ class Edit extends App.Controller
|
||||||
bind: {
|
bind: {
|
||||||
name: 'type_id'
|
name: 'type_id'
|
||||||
relation: 'TicketArticleType'
|
relation: 'TicketArticleType'
|
||||||
value: ['note', 'twitter status', 'twitter direct-message']
|
value: ['note', 'phone', 'twitter status']
|
||||||
},
|
},
|
||||||
change: {
|
change: {
|
||||||
action: 'hide'
|
action: 'hide'
|
||||||
name: ['to', 'cc'],
|
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()
|
@autosaveStop()
|
||||||
params = @formParam(e.target)
|
params = @formParam(e.target)
|
||||||
|
|
||||||
|
# get ticket
|
||||||
ticket = App.Ticket.fullLocal( @ticket.id )
|
ticket = App.Ticket.fullLocal( @ticket.id )
|
||||||
|
|
||||||
@log 'notice', 'update', params, ticket
|
@log 'notice', 'update', params, ticket
|
||||||
|
|
||||||
|
# update local ticket
|
||||||
|
|
||||||
|
# create local article
|
||||||
|
|
||||||
|
|
||||||
# find sender_id
|
# find sender_id
|
||||||
if @isRole('Customer')
|
if @isRole('Customer')
|
||||||
sender = App.TicketArticleSender.findByAttribute( 'name', 'Customer' )
|
sender = App.TicketArticleSender.findByAttribute( 'name', 'Customer' )
|
||||||
|
@ -696,17 +719,16 @@ class Edit extends App.Controller
|
||||||
params.sender_id = sender.id
|
params.sender_id = sender.id
|
||||||
|
|
||||||
# update ticket
|
# update ticket
|
||||||
ticket_update = {}
|
for key, value of params
|
||||||
for item in @configure_attributes_ticket
|
ticket[key] = value
|
||||||
ticket_update[item.name] = params[item.name]
|
|
||||||
|
|
||||||
# check owner assignment
|
# check owner assignment
|
||||||
if !@isRole('Customer')
|
if !@isRole('Customer')
|
||||||
if !ticket_update['owner_id']
|
if !ticket['owner_id']
|
||||||
ticket_update['owner_id'] = 1
|
ticket['owner_id'] = 1
|
||||||
|
|
||||||
# check if title exists
|
# check if title exists
|
||||||
if !ticket_update['title'] && !ticket.title
|
if !ticket['title']
|
||||||
alert( App.i18n.translateContent('Title needed') )
|
alert( App.i18n.translateContent('Title needed') )
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -732,22 +754,32 @@ class Edit extends App.Controller
|
||||||
@autosaveStart()
|
@autosaveStart()
|
||||||
return
|
return
|
||||||
|
|
||||||
ticket.load( ticket_update )
|
# submit ticket & article
|
||||||
@log 'notice', 'update ticket', ticket_update, ticket
|
@log 'notice', 'update ticket', ticket
|
||||||
|
|
||||||
# disable form
|
# disable form
|
||||||
@formDisable(e)
|
@formDisable(e)
|
||||||
|
|
||||||
# validate ticket
|
# validate ticket
|
||||||
errors = ticket.validate()
|
errors = ticket.validate(
|
||||||
|
screen: 'edit'
|
||||||
|
)
|
||||||
if errors
|
if errors
|
||||||
@log 'error', 'update', errors
|
@log 'error', 'update', errors
|
||||||
|
|
||||||
|
@log 'error', errors
|
||||||
|
@formValidate(
|
||||||
|
form: e.target
|
||||||
|
errors: errors
|
||||||
|
screen: 'edit'
|
||||||
|
)
|
||||||
@formEnable(e)
|
@formEnable(e)
|
||||||
@autosaveStart()
|
@autosaveStart()
|
||||||
return
|
return
|
||||||
|
|
||||||
# validate article
|
# validate article
|
||||||
if params['body']
|
articleAttributes = App.TicketArticle.attributesGet( 'edit' )
|
||||||
|
if params['body'] || ( articleAttributes['body'] && articleAttributes['body']['null'] is false )
|
||||||
article = new App.TicketArticle
|
article = new App.TicketArticle
|
||||||
params.from = @Session.get( 'firstname' ) + ' ' + @Session.get( 'lastname' )
|
params.from = @Session.get( 'firstname' ) + ' ' + @Session.get( 'lastname' )
|
||||||
params.ticket_id = ticket.id
|
params.ticket_id = ticket.id
|
||||||
|
@ -761,6 +793,11 @@ class Edit extends App.Controller
|
||||||
errors = article.validate()
|
errors = article.validate()
|
||||||
if errors
|
if errors
|
||||||
@log 'error', 'update article', errors
|
@log 'error', 'update article', errors
|
||||||
|
@formValidate(
|
||||||
|
form: e.target
|
||||||
|
errors: errors
|
||||||
|
screen: 'edit'
|
||||||
|
)
|
||||||
@formEnable(e)
|
@formEnable(e)
|
||||||
@autosaveStart()
|
@autosaveStart()
|
||||||
return
|
return
|
||||||
|
|
|
@ -109,13 +109,12 @@ class App.WidgetUser extends App.ControllerDrox
|
||||||
edit: (e) =>
|
edit: (e) =>
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
new App.ControllerGenericEdit(
|
new App.ControllerGenericEdit(
|
||||||
id: @user_id,
|
id: @user_id
|
||||||
genericObject: 'User',
|
genericObject: 'User'
|
||||||
required: 'quick',
|
screen: 'edit'
|
||||||
pageData: {
|
pageData:
|
||||||
title: 'Users',
|
title: 'Users'
|
||||||
object: 'User',
|
object: 'User'
|
||||||
objects: 'Users',
|
objects: 'Users'
|
||||||
},
|
|
||||||
callback: @render
|
callback: @render
|
||||||
)
|
)
|
||||||
|
|
|
@ -69,12 +69,26 @@ class App.Auth
|
||||||
App.Event.trigger( 'auth:logout' )
|
App.Event.trigger( 'auth:logout' )
|
||||||
App.Event.trigger( 'ui:rerender' )
|
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;
|
return false;
|
||||||
|
|
||||||
# clear local store
|
# clear local store
|
||||||
if type isnt 'check'
|
if type isnt 'check'
|
||||||
App.Event.trigger( 'clearStore' )
|
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
|
# update config
|
||||||
for key, value of data.config
|
for key, value of data.config
|
||||||
App.Config.set( key, value )
|
App.Config.set( key, value )
|
||||||
|
@ -129,4 +143,3 @@ class App.Auth
|
||||||
App.Event.trigger( 'auth:logout' )
|
App.Event.trigger( 'auth:logout' )
|
||||||
App.Event.trigger( 'ui:rerender' )
|
App.Event.trigger( 'ui:rerender' )
|
||||||
App.Event.trigger( 'clearStore' )
|
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')
|
Spine = @Spine or require('spine')
|
||||||
isArray = Spine.isArray
|
isArray = Spine.isArray
|
||||||
require = @require or ((value) -> eval(value))
|
|
||||||
|
|
||||||
class Collection extends Spine.Module
|
class Collection extends Spine.Module
|
||||||
constructor: (options = {}) ->
|
constructor: (options = {}) ->
|
||||||
|
@ -111,8 +110,14 @@ underscore = (str) ->
|
||||||
.replace(/-/g, '_')
|
.replace(/-/g, '_')
|
||||||
.toLowerCase()
|
.toLowerCase()
|
||||||
|
|
||||||
|
requireModel = (model) ->
|
||||||
|
if typeof model is 'string'
|
||||||
|
require?(model) or eval(model)
|
||||||
|
else
|
||||||
|
model
|
||||||
|
|
||||||
association = (name, model, record, fkey, Ctor) ->
|
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)
|
new Ctor(name: name, model: model, record: record, fkey: fkey)
|
||||||
|
|
||||||
Spine.Model.extend
|
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()
|
@change()
|
||||||
|
|
||||||
@unbind: ->
|
@unbind: ->
|
||||||
|
unbindResult = Spine.Events.unbind.apply this, arguments
|
||||||
|
return unbindResult if arguments.length > 0
|
||||||
|
|
||||||
return if @options.shim
|
return if @options.shim
|
||||||
|
|
||||||
if @history
|
if @history
|
||||||
|
@ -80,33 +83,30 @@ class Route extends Spine.Module
|
||||||
|
|
||||||
@navigate: (args...) ->
|
@navigate: (args...) ->
|
||||||
options = {}
|
options = {}
|
||||||
|
|
||||||
lastArg = args[args.length - 1]
|
lastArg = args[args.length - 1]
|
||||||
if typeof lastArg is 'object'
|
if typeof lastArg is 'object'
|
||||||
options = args.pop()
|
options = args.pop()
|
||||||
else if typeof lastArg is 'boolean'
|
else if typeof lastArg is 'boolean'
|
||||||
options.trigger = args.pop()
|
options.trigger = args.pop()
|
||||||
|
|
||||||
options = $.extend({}, @options, options)
|
options = $.extend({}, @options, options)
|
||||||
|
|
||||||
path = args.join('/')
|
path = args.join('/')
|
||||||
return if @path is path
|
return if @path is path
|
||||||
@path = 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
|
if options.shim
|
||||||
|
true
|
||||||
return if options.shim
|
else if @history and options.replace
|
||||||
|
|
||||||
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
|
|
||||||
history.replaceState({}, document.title, @path)
|
history.replaceState({}, document.title, @path)
|
||||||
else if @history
|
else if @history
|
||||||
history.pushState({}, document.title, @path)
|
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(", ")})"
|
@toString: -> "#{@className}(#{@attributes.join(", ")})"
|
||||||
|
|
||||||
@find: (id, notFound = @notFound) ->
|
@find: (id, notFound = @notFound) ->
|
||||||
record = @irecords[id]?.clone()
|
@irecords[id]?.clone() or notFound?(id)
|
||||||
return record or notFound?(id)
|
|
||||||
|
|
||||||
@notFound: (id) -> return null
|
@findAll: (ids, notFound) ->
|
||||||
|
(@find(id) for id in ids when @find(id, notFound))
|
||||||
|
|
||||||
@exists: (id) ->
|
@notFound: (id) -> null
|
||||||
return if @irecords[id] then true else false
|
|
||||||
|
@exists: (id) -> Boolean @irecords[id]
|
||||||
|
|
||||||
@addRecord: (record, options = {}) ->
|
@addRecord: (record, options = {}) ->
|
||||||
if record.id and @irecords[record.id]
|
if record.id and @irecords[record.id]
|
||||||
|
@ -321,8 +322,8 @@ class Model extends Module
|
||||||
result
|
result
|
||||||
|
|
||||||
eql: (rec) ->
|
eql: (rec) ->
|
||||||
!!(rec and rec.constructor is @constructor and
|
rec and rec.constructor is @constructor and
|
||||||
((rec.cid is @cid) or (rec.id and rec.id is @id)))
|
((rec.cid is @cid) or (rec.id and rec.id is @id))
|
||||||
|
|
||||||
save: (options = {}) ->
|
save: (options = {}) ->
|
||||||
unless options.validate is false
|
unless options.validate is false
|
||||||
|
@ -634,7 +635,7 @@ makeArray = (args) ->
|
||||||
Spine = @Spine = {}
|
Spine = @Spine = {}
|
||||||
module?.exports = Spine
|
module?.exports = Spine
|
||||||
|
|
||||||
Spine.version = '1.3.1'
|
Spine.version = '1.3.2'
|
||||||
Spine.isArray = isArray
|
Spine.isArray = isArray
|
||||||
Spine.isBlank = isBlank
|
Spine.isBlank = isBlank
|
||||||
Spine.$ = $
|
Spine.$ = $
|
||||||
|
|
|
@ -73,55 +73,116 @@ class App.Model extends Spine.Model
|
||||||
''
|
''
|
||||||
|
|
||||||
@validate: ( data = {} ) ->
|
@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
|
# check attributes/each attribute of object
|
||||||
errors = {}
|
errors = {}
|
||||||
for attribute in data['model'].configure_attributes
|
for attributeName, attribute of attributes
|
||||||
|
|
||||||
# only if attribute is not read only
|
# only if attribute is not read only
|
||||||
if !attribute.readonly
|
if !attribute.readonly
|
||||||
|
|
||||||
# check required // if null is defined && null is false
|
# check required // if null is defined && null is false
|
||||||
if 'null' of attribute && !attribute[null]
|
if 'null' of attribute && !attribute['null']
|
||||||
|
|
||||||
# check :: fields
|
# check :: fields
|
||||||
parts = attribute.name.split '::'
|
parts = attribute.name.split '::'
|
||||||
if parts[0] && !parts[1]
|
if parts[0] && !parts[1]
|
||||||
|
|
||||||
# key exists not in hash || value is '' || value is undefined
|
# 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
|
if !( attributeName of data['params'] ) || data['params'][attributeName] is '' || data['params'][attributeName] is undefined
|
||||||
errors[attribute.name] = 'is required'
|
errors[attributeName] = 'is required'
|
||||||
|
|
||||||
else if parts[0] && parts[1] && !parts[2]
|
else if parts[0] && parts[1] && !parts[2]
|
||||||
|
|
||||||
# key exists not in hash || value is '' || value is undefined
|
# 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
|
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
|
else
|
||||||
throw "can't parse '#{attribute.name}'"
|
throw "can't parse '#{attribute.name}'"
|
||||||
|
|
||||||
# check confirm password
|
# 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
|
# get confirm password
|
||||||
if data['params'][attribute.name] isnt data['params']["#{attribute.name}_confirm"]
|
if data['params'][attributeName] isnt data['params']["#{attributeName}_confirm"]
|
||||||
errors[attribute.name] = 'didn\'t match'
|
errors[attributeName] = 'didn\'t match'
|
||||||
errors["#{attribute.name}_confirm"] = ''
|
errors["#{attributeName}_confirm"] = ''
|
||||||
|
|
||||||
# return error object
|
# return error object
|
||||||
if !_.isEmpty(errors)
|
if !_.isEmpty(errors)
|
||||||
console.log 'error', 'validation vailed', errors
|
console.log 'error', 'validation failed', errors
|
||||||
return errors
|
return errors
|
||||||
|
|
||||||
# return no errors
|
# return no errors
|
||||||
return
|
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(
|
App.Model.validate(
|
||||||
model: @constructor,
|
model: @constructor.className
|
||||||
params: @,
|
params: @
|
||||||
|
screen: params.screen
|
||||||
)
|
)
|
||||||
|
|
||||||
isOnline: ->
|
isOnline: ->
|
||||||
|
|
|
@ -5,7 +5,7 @@ class App.Group extends App.Model
|
||||||
|
|
||||||
@configure_attributes = [
|
@configure_attributes = [
|
||||||
{ name: 'name', display: 'Name', tag: 'input', type: 'text', limit: 100, 'null': false, 'class': 'span4' },
|
{ 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_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: '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' },
|
{ name: 'email_address_id', display: 'Email', tag: 'select', multiple: false, null: true, relation: 'EmailAddress', nulloption: true, class: 'span4' },
|
||||||
|
@ -19,4 +19,4 @@ class App.Group extends App.Model
|
||||||
]
|
]
|
||||||
|
|
||||||
uiUrl: ->
|
uiUrl: ->
|
||||||
'#group/zoom/' + @id
|
'#group/zoom/' + @id
|
||||||
|
|
|
@ -6,20 +6,20 @@ class App.User extends App.Model
|
||||||
# @hasMany 'roles', 'App.Role'
|
# @hasMany 'roles', 'App.Role'
|
||||||
@configure_attributes = [
|
@configure_attributes = [
|
||||||
{ name: 'login', display: 'Login', tag: 'input', type: 'text', limit: 100, null: false, class: 'span4', autocapitalize: false, signup: false, quick: false },
|
{ 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: '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, quick: 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, quick: 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, quick: true, info: 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, quick: true, 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, quick: true, 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, quick: true, 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, quick: true, 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, quick: true, 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, quick: true, 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, quick: true, 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, quick: true, 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, quick: false },
|
{ 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', quick: true, info: 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: '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: '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' },
|
{ name: 'active', display: 'Active', tag: 'boolean', default: true, null: true, class: 'span4' },
|
||||||
|
|
|
@ -2,87 +2,41 @@
|
||||||
<div class="create-new main flex">
|
<div class="create-new main flex">
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<div class="page-header">
|
<div class="page-header">
|
||||||
<h1><%- @T( 'Create New Ticket' ) %></h1>
|
<h1><%- @T( @head ) %></h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ul class="horizontal tabs type-tabs">
|
<ul class="horizontal tabs type-tabs">
|
||||||
|
|
||||||
<li class="tab u-textTruncate active">
|
<li class="tab u-textTruncate" data-type="phone-in">
|
||||||
<div class="white email channel icon"></div>
|
|
||||||
<%- @T( 'E-Mail' ) %>
|
|
||||||
|
|
||||||
<li class="tab u-textTruncate">
|
|
||||||
<div class="gray received-calls channel icon"></div>
|
<div class="gray received-calls channel icon"></div>
|
||||||
<%- @T( 'Received Call' ) %>
|
<%- @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>
|
<div class="gray outbound-calls channel icon"></div>
|
||||||
<%- @T( 'Outbound Call' ) %>
|
<%- @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>
|
</ul>
|
||||||
|
|
||||||
<form role="form">
|
<form role="form" class="form-large ticket-create">
|
||||||
|
<input type="hidden" name="formSenderType"/>
|
||||||
<div class="form-group">
|
<div class="ticket-form-top"></div>
|
||||||
<label for="customer"><%- @T('Customer') %></label>
|
<div class="article-form-top"></div>
|
||||||
<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>
|
|
||||||
|
|
||||||
<div class="formset-inset">
|
<div class="formset-inset">
|
||||||
<div class="horizontal two-columns">
|
<div class="ticket-form-middle horizontal two-columns"></div>
|
||||||
<div class="form-group column">
|
<div class="ticket-form-bottom"></div>
|
||||||
<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>
|
</div>
|
||||||
|
|
||||||
<input type="hidden" value="" name="article_type"/>
|
|
||||||
<div class="form-actions horizontal">
|
<div class="form-actions horizontal">
|
||||||
<a class="subtle-link standalone cancel" href="#/"><%- @T( 'Cancel & Go Back' ) %></a>
|
<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>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
@ -208,4 +162,4 @@
|
||||||
<div class="text_module"></div>
|
<div class="text_module"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</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">
|
<form role="form" class="form-large ticket-create">
|
||||||
<div class="page-header">
|
|
||||||
<h1 class="pull-left"><%- @T( 'New Ticket' ) %></h1>
|
<div class="ticket-form-top"></div>
|
||||||
</div>
|
<div class="article-form-top"></div>
|
||||||
<div class="page-content">
|
|
||||||
<form class="form-horizontal form-large">
|
<div class="formset-inset">
|
||||||
<input type="hidden" value="" name="article_type"/>
|
<div class="ticket-form-middle horizontal two-columns"></div>
|
||||||
<div id="form_create"></div>
|
<div class="ticket-form-bottom"></div>
|
||||||
<div class="form-actions">
|
</div>
|
||||||
<button type="reset" class="btn btn-default cancel"><%- @T( 'Cancel' ) %></button>
|
|
||||||
<button type="submit" class="btn btn-primary submit"><%- @T( 'Create' ) %></button>
|
|
||||||
|
<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>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<div class="form-group <%= @attribute.item_class %>">
|
<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">
|
<div class="controls">
|
||||||
<%- @item %><% if @attribute.note: %><span class="glyphicon glyphicon-question-sign help-message" title="<%- @Ti( @attribute.note ) + ' ' %>"></span><% end %>
|
<%- @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 %>
|
<% 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 %>" 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 %>"/>
|
<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 %>>
|
<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: %>
|
<% for row in @attribute.options: %>
|
||||||
<option value="<%= row.value %>" <%= row.selected %> <%= row.disabled %>><%= row.name %></option>
|
<option value="<%= row.value %>" <%= row.selected %> <%= row.disabled %>><%= row.name %></option>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
<% end %>
|
||||||
</select>
|
</select>
|
||||||
|
|
|
@ -1,8 +1,14 @@
|
||||||
<% for item in @items: %>
|
<% for item in @items: %>
|
||||||
<% if item.child: %>
|
<% if item.child: %>
|
||||||
<li class="dropdown <%= item.class %> <% if @open_tab[item.target] : %>open<% end %>">
|
<li class="dropdown <%= item.class %> <% if @open_tab[item.target] : %>open<% end %>">
|
||||||
<a href="<%= item.target %>" class="dropdown-toggle" data-toggle="dropdown">
|
<a href="<%= item.target %>" class="dropdown-toggle horizontal center" data-toggle="dropdown">
|
||||||
<%- @T( item.name ) %> <b class="caret"></b>
|
<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>
|
</a>
|
||||||
<ul class="dropdown-menu">
|
<ul class="dropdown-menu">
|
||||||
<% for item in item.child: %>
|
<% for item in item.child: %>
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
// the compiled file.
|
// 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/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.min.js
|
||||||
//= require ./app/lib/animations/velocity.ui.js
|
//= require ./app/lib/animations/velocity.ui.js
|
||||||
|
@ -69,6 +69,13 @@ function difference(object1, object2) {
|
||||||
return changes;
|
return changes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function clone(object) {
|
||||||
|
if (!object) {
|
||||||
|
return object
|
||||||
|
}
|
||||||
|
return JSON.parse(JSON.stringify(object));
|
||||||
|
}
|
||||||
|
|
||||||
jQuery.event.special.remove = {
|
jQuery.event.special.remove = {
|
||||||
remove: function(e) {
|
remove: function(e) {
|
||||||
if (e.handler) e.handler();
|
if (e.handler) e.handler();
|
||||||
|
|
|
@ -658,13 +658,13 @@ label {
|
||||||
.form-control:focus,
|
.form-control:focus,
|
||||||
.tokenfield.focus {
|
.tokenfield.focus {
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
border-color: #419ed7;
|
border-color: #419ed7 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.has-error .form-control,
|
.has-error .form-control,
|
||||||
.has-error .form-control:focus {
|
.has-error .form-control:focus {
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
border-color: red;
|
border-color: red !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.help-inline {
|
.help-inline {
|
||||||
|
@ -752,6 +752,9 @@ label {
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.help-block {
|
||||||
|
color: #bcbcbc;
|
||||||
|
}
|
||||||
.form-horizontal .help-inline, .form-horizontal .help-block {
|
.form-horizontal .help-inline, .form-horizontal .help-block {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
margin-top: 4px;
|
margin-top: 4px;
|
||||||
|
@ -3240,7 +3243,7 @@ footer {
|
||||||
|
|
||||||
.tokenfield .token {
|
.tokenfield .token {
|
||||||
padding: 0 0 0 10px;
|
padding: 0 0 0 10px;
|
||||||
margin: -1px 5px 0 0;
|
margin: -1px 5px 8px 0;
|
||||||
height: 26px;
|
height: 26px;
|
||||||
line-height: 27px;
|
line-height: 27px;
|
||||||
color: white;
|
color: white;
|
||||||
|
@ -3255,7 +3258,7 @@ footer {
|
||||||
}
|
}
|
||||||
|
|
||||||
.tokenfield .token .token-label {
|
.tokenfield .token .token-label {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tokenfield.form-control {
|
.tokenfield.form-control {
|
||||||
|
|
|
@ -33,8 +33,12 @@ class SessionsController < ApplicationController
|
||||||
# auto population of default collections
|
# auto population of default collections
|
||||||
collections, assets = SessionHelper::default_collections(user)
|
collections, assets = SessionHelper::default_collections(user)
|
||||||
|
|
||||||
|
# add session user assets
|
||||||
assets = user.assets(assets)
|
assets = user.assets(assets)
|
||||||
|
|
||||||
|
# get models
|
||||||
|
models = SessionHelper::models(user)
|
||||||
|
|
||||||
# check logon session
|
# check logon session
|
||||||
logon_session_key = nil
|
logon_session_key = nil
|
||||||
if params['logon_session']
|
if params['logon_session']
|
||||||
|
@ -50,6 +54,7 @@ class SessionsController < ApplicationController
|
||||||
# return new session data
|
# return new session data
|
||||||
render :json => {
|
render :json => {
|
||||||
:session => user,
|
:session => user,
|
||||||
|
:models => models,
|
||||||
:collections => collections,
|
:collections => collections,
|
||||||
:assets => assets,
|
:assets => assets,
|
||||||
:logon_session => logon_session_key,
|
:logon_session => logon_session_key,
|
||||||
|
@ -75,9 +80,13 @@ class SessionsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
if !user_id
|
if !user_id
|
||||||
|
# get models
|
||||||
|
models = SessionHelper::models()
|
||||||
|
|
||||||
render :json => {
|
render :json => {
|
||||||
:error => 'no valid session',
|
:error => 'no valid session',
|
||||||
:config => config_frontend,
|
:config => config_frontend,
|
||||||
|
:models => models,
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
@ -89,13 +98,18 @@ class SessionsController < ApplicationController
|
||||||
# auto population of default collections
|
# auto population of default collections
|
||||||
collections, assets = SessionHelper::default_collections(user)
|
collections, assets = SessionHelper::default_collections(user)
|
||||||
|
|
||||||
|
# add session user assets
|
||||||
assets = user.assets(assets)
|
assets = user.assets(assets)
|
||||||
|
|
||||||
|
# get models
|
||||||
|
models = SessionHelper::models(user)
|
||||||
|
|
||||||
# return current session
|
# return current session
|
||||||
render :json => {
|
render :json => {
|
||||||
:session => user,
|
:session => user,
|
||||||
|
:models => models,
|
||||||
:collections => collections,
|
:collections => collections,
|
||||||
:assets => assets,
|
:assets => assets,
|
||||||
:config => config_frontend,
|
:config => config_frontend,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
|
@ -255,24 +255,12 @@ class TicketsController < ApplicationController
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
# get related users
|
|
||||||
assets = {}
|
|
||||||
assets = ticket.assets(assets)
|
|
||||||
|
|
||||||
# get attributes to update
|
# get attributes to update
|
||||||
attributes_to_change = Ticket::ScreenOptions.attributes_to_change( :user => current_user, :ticket => ticket )
|
attributes_to_change = Ticket::ScreenOptions.attributes_to_change( :user => current_user, :ticket => ticket )
|
||||||
|
|
||||||
attributes_to_change[:owner_id].each { |user_id|
|
# get related users
|
||||||
user = User.find(user_id)
|
assets = attributes_to_change[:assets]
|
||||||
assets = user.assets(assets)
|
assets = ticket.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 articles
|
# get related articles
|
||||||
articles = Ticket::Article.where( :ticket_id => params[:id] )
|
articles = Ticket::Article.where( :ticket_id => params[:id] )
|
||||||
|
@ -297,6 +285,7 @@ class TicketsController < ApplicationController
|
||||||
:ticket_article_ids => article_ids,
|
:ticket_article_ids => article_ids,
|
||||||
:signature => signature,
|
:signature => signature,
|
||||||
:assets => assets,
|
:assets => assets,
|
||||||
|
:form_meta => attributes_to_change,
|
||||||
:edit_form => attributes_to_change,
|
:edit_form => attributes_to_change,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
@ -307,24 +296,11 @@ class TicketsController < ApplicationController
|
||||||
# get attributes to update
|
# get attributes to update
|
||||||
attributes_to_change = Ticket::ScreenOptions.attributes_to_change(
|
attributes_to_change = Ticket::ScreenOptions.attributes_to_change(
|
||||||
:user => current_user,
|
:user => current_user,
|
||||||
# :ticket_id => params[:ticket_id],
|
:ticket_id => params[:ticket_id],
|
||||||
# :article_id => params[:article_id]
|
:article_id => params[:article_id]
|
||||||
)
|
)
|
||||||
|
|
||||||
assets = {}
|
assets = attributes_to_change[: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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# split data
|
# split data
|
||||||
split = {}
|
split = {}
|
||||||
if params[:ticket_id] && params[:article_id]
|
if params[:ticket_id] && params[:article_id]
|
||||||
|
@ -332,12 +308,6 @@ class TicketsController < ApplicationController
|
||||||
split[:ticket_id] = ticket.id
|
split[:ticket_id] = ticket.id
|
||||||
assets = ticket.assets(assets)
|
assets = ticket.assets(assets)
|
||||||
|
|
||||||
owner_ids = []
|
|
||||||
ticket.agent_of_group.each { |user|
|
|
||||||
owner_ids.push user.id
|
|
||||||
assets = user.assets(assets)
|
|
||||||
}
|
|
||||||
|
|
||||||
# get related articles
|
# get related articles
|
||||||
article = Ticket::Article.find( params[:article_id] )
|
article = Ticket::Article.find( params[:article_id] )
|
||||||
split[:article_id] = article.id
|
split[:article_id] = article.id
|
||||||
|
@ -348,13 +318,19 @@ class TicketsController < ApplicationController
|
||||||
render :json => {
|
render :json => {
|
||||||
:split => split,
|
:split => split,
|
||||||
:assets => assets,
|
:assets => assets,
|
||||||
:edit_form => attributes_to_change,
|
:form_meta => {
|
||||||
|
:filter => attributes_to_change[:filter],
|
||||||
|
:dependencies => attributes_to_change[:dependencies],
|
||||||
|
}
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
# GET /api/v1/tickets/search
|
# GET /api/v1/tickets/search
|
||||||
def search
|
def search
|
||||||
|
|
||||||
|
# permit nested conditions
|
||||||
|
params.require(:condition).permit!
|
||||||
|
|
||||||
# build result list
|
# build result list
|
||||||
tickets = Ticket.search(
|
tickets = Ticket.search(
|
||||||
:limit => params[:limit],
|
: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_type, :class_name => 'Ticket::Article::Type'
|
||||||
belongs_to :create_article_sender, :class_name => 'Ticket::Article::Sender'
|
belongs_to :create_article_sender, :class_name => 'Ticket::Article::Sender'
|
||||||
|
|
||||||
|
self.inheritance_column = nil
|
||||||
|
|
||||||
attr_accessor :callback_loop
|
attr_accessor :callback_loop
|
||||||
|
|
||||||
=begin
|
=begin
|
||||||
|
|
|
@ -50,6 +50,9 @@ returns
|
||||||
params[:article] = self.find( params[:article_id] )
|
params[:article] = self.find( params[:article_id] )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
filter = {}
|
||||||
|
assets = {}
|
||||||
|
|
||||||
# get ticket states
|
# get ticket states
|
||||||
state_ids = []
|
state_ids = []
|
||||||
if params[:ticket]
|
if params[:ticket]
|
||||||
|
@ -63,44 +66,21 @@ returns
|
||||||
state_type = Ticket::StateType.where( :name => type ).first
|
state_type = Ticket::StateType.where( :name => type ).first
|
||||||
if state_type
|
if state_type
|
||||||
state_type.states.each {|state|
|
state_type.states.each {|state|
|
||||||
|
assets = state.assets(assets)
|
||||||
state_ids.push state.id
|
state_ids.push state.id
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
filter[:state_id] = state_ids
|
||||||
# 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# get priorities
|
# get priorities
|
||||||
priority_ids = []
|
priority_ids = []
|
||||||
Ticket::Priority.where( :active => true ).each { |priority|
|
Ticket::Priority.where( :active => true ).each { |priority|
|
||||||
|
assets = priority.assets(assets)
|
||||||
priority_ids.push priority.id
|
priority_ids.push priority.id
|
||||||
}
|
}
|
||||||
|
filter[:priority_id] = priority_ids
|
||||||
|
|
||||||
|
|
||||||
type_ids = []
|
type_ids = []
|
||||||
if params[:ticket]
|
if params[:ticket]
|
||||||
|
@ -115,14 +95,29 @@ returns
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
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 {
|
return {
|
||||||
:type_id => type_ids,
|
:assets => assets,
|
||||||
:state_id => state_ids,
|
:filter => filter,
|
||||||
:priority_id => priority_ids,
|
:dependencies => dependencies,
|
||||||
:owner_id => owner_ids,
|
|
||||||
:group_id => group_ids,
|
|
||||||
:group_id__owner_id => groups_users,
|
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -131,8 +126,8 @@ returns
|
||||||
list tickets by customer groupd in state categroie open and closed
|
list tickets by customer groupd in state categroie open and closed
|
||||||
|
|
||||||
result = Ticket::ScreenOptions.list_by_customer(
|
result = Ticket::ScreenOptions.list_by_customer(
|
||||||
:customer_id => 123,
|
:customer_id => 123,
|
||||||
:limit => 15, # optional, default 15
|
:limit => 15, # optional, default 15
|
||||||
)
|
)
|
||||||
|
|
||||||
returns
|
returns
|
||||||
|
@ -152,13 +147,13 @@ returns
|
||||||
|
|
||||||
# get tickets
|
# get tickets
|
||||||
tickets_open = Ticket.where(
|
tickets_open = Ticket.where(
|
||||||
:customer_id => data[:customer_id],
|
:customer_id => data[:customer_id],
|
||||||
:state_id => state_list_open
|
:state_id => state_list_open
|
||||||
).limit( data[:limit] || 15 ).order('created_at DESC')
|
).limit( data[:limit] || 15 ).order('created_at DESC')
|
||||||
|
|
||||||
tickets_closed = Ticket.where(
|
tickets_closed = Ticket.where(
|
||||||
:customer_id => data[:customer_id],
|
:customer_id => data[:customer_id],
|
||||||
:state_id => state_list_closed
|
:state_id => state_list_closed
|
||||||
).limit( data[:limit] || 15 ).order('created_at DESC')
|
).limit( data[:limit] || 15 ).order('created_at DESC')
|
||||||
|
|
||||||
return {
|
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-core', :to => 'tests#core', :via => :get
|
||||||
match '/tests-ui', :to => 'tests#ui', :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-form', :to => 'tests#form', :via => :get
|
||||||
match '/tests-table', :to => 'tests#table', :via => :get
|
match '/tests-table', :to => 'tests#table', :via => :get
|
||||||
match '/tests/wait/:sec', :to => 'tests#wait', :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 => 'Idea' )
|
||||||
Link::Object.create_if_not_exists( :name => 'Bug' )
|
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( :id => 1, :name => 'new', :updated_by_id => 1 )
|
||||||
Ticket::StateType.create_if_not_exists( :name => 'open', :updated_by_id => 1 )
|
Ticket::StateType.create_if_not_exists( :id => 2, :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( :id => 3, :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( :id => 4, :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( :id => 5, :name => 'closed', :updated_by_id => 1 )
|
||||||
Ticket::StateType.create_if_not_exists( :name => 'merged', :updated_by_id => 1 )
|
Ticket::StateType.create_if_not_exists( :id => 6, :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 => 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( :id => 1, :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( :id => 2, :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( :id => 3, :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( :id => 4, :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( :id => 5, :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 => 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 => '1 low' )
|
||||||
Ticket::Priority.create_if_not_exists( :name => '2 normal' )
|
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 => "Owner", :target => "Besitzer" )
|
||||||
Translation.create_if_not_exists( :locale => 'de', :source => "Subject", :target => "Betreff" )
|
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 => "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 => "New Ticket", :target => "Neues Ticket" )
|
||||||
Translation.create_if_not_exists( :locale => 'de', :source => "Firstname", :target => "Vorname" )
|
Translation.create_if_not_exists( :locale => 'de', :source => "Firstname", :target => "Vorname" )
|
||||||
Translation.create_if_not_exists( :locale => 'de', :source => "Lastname", :target => "Nachname" )
|
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 => "Templates", :target => "Vorlagen" )
|
||||||
Translation.create_if_not_exists( :locale => 'de', :source => "Delete", :target => "Löschen" )
|
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 => "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 => "Save", :target => "Speichern" )
|
||||||
Translation.create_if_not_exists( :locale => 'de', :source => "Open Tickets", :target => "Offene Ticket" )
|
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" )
|
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 => "public", :target => "öffentlich" )
|
||||||
Translation.create_if_not_exists( :locale => 'de', :source => "internal", :target => "intern" )
|
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 => "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 => "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" )
|
||||||
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 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 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 => "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 => "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 => "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." )
|
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
|
return default_collection, assets
|
||||||
end
|
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
|
def self.cleanup_expired
|
||||||
|
|
||||||
# web sessions
|
# web sessions
|
||||||
|
|
|
@ -8,9 +8,9 @@ class Sessions::Backend::TicketCreate
|
||||||
|
|
||||||
def load
|
def load
|
||||||
|
|
||||||
# get whole collection
|
# get attributes to update
|
||||||
ticket_create_attributes = Ticket::ScreenOptions.attributes_to_change(
|
ticket_create_attributes = Ticket::ScreenOptions.attributes_to_change(
|
||||||
:current_user_id => @user.id,
|
:user => @user.id,
|
||||||
)
|
)
|
||||||
|
|
||||||
# no data exists
|
# no data exists
|
||||||
|
@ -38,32 +38,31 @@ class Sessions::Backend::TicketCreate
|
||||||
# set new timeout
|
# set new timeout
|
||||||
Sessions::CacheIn.set( self.client_key, true, { :expires_in => 25.seconds } )
|
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 = {
|
data = {
|
||||||
:users => users,
|
:assets => ticket_create_attributes[:assets],
|
||||||
:edit_form => create_attributes,
|
:form_meta => {
|
||||||
|
:filter => ticket_create_attributes[:filter],
|
||||||
|
:dependencies => ticket_create_attributes[:dependencies],
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if !@client
|
if !@client
|
||||||
return {
|
return {
|
||||||
:collection => 'ticket_create_attributes',
|
:collection => 'ticket_create_attributes',
|
||||||
:data => create_attributes,
|
:data => data,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
@client.log 'notify', "push ticket_create for user #{ @user.id }"
|
@client.log 'notify', "push ticket_create for user #{ @user.id }"
|
||||||
@client.send({
|
@client.send({
|
||||||
:collection => 'ticket_create_attributes',
|
:collection => 'ticket_create_attributes',
|
||||||
:data => create_attributes,
|
:data => data,
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -495,3 +495,54 @@ test( "form selector", function() {
|
||||||
deepEqual( params, test_params, 'form param check via $("#form").parent()' );
|
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)
|
browser_single_test(tests)
|
||||||
end
|
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
|
def test_form
|
||||||
tests = [
|
tests = [
|
||||||
{
|
{
|
||||||
|
|
|
@ -111,8 +111,9 @@ class AgentTicketActionsLevel3Test < TestCase
|
||||||
{
|
{
|
||||||
:where => :instance2,
|
:where => :instance2,
|
||||||
:execute => 'match',
|
:execute => 'match',
|
||||||
:css => '.content_permanent.active',
|
:css => '.content_permanent.active .reset-message',
|
||||||
:value => 'Discard your unsaved changes.',
|
:value => '(Discard your unsaved changes.|Verwerfen der)',
|
||||||
|
:no_quote => true,
|
||||||
:match_result => true,
|
:match_result => true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -127,8 +128,9 @@ class AgentTicketActionsLevel3Test < TestCase
|
||||||
{
|
{
|
||||||
:where => :instance2,
|
:where => :instance2,
|
||||||
:execute => 'match',
|
:execute => 'match',
|
||||||
:css => '.content_permanent.active',
|
:css => '.content_permanent.active .reset-message',
|
||||||
:value => 'Discard your unsaved changes.',
|
:value => '(Discard your unsaved changes.|Verwerfen der)',
|
||||||
|
:no_quote => true,
|
||||||
:match_result => false,
|
:match_result => false,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -150,8 +152,9 @@ class AgentTicketActionsLevel3Test < TestCase
|
||||||
{
|
{
|
||||||
:where => :instance1,
|
:where => :instance1,
|
||||||
:execute => 'match',
|
:execute => 'match',
|
||||||
:css => '.content_permanent.active',
|
:css => '.content_permanent.active .reset-message',
|
||||||
:value => 'Discard your unsaved changes.',
|
:value => '(Discard your unsaved changes.|Verwerfen der)',
|
||||||
|
:no_quote => true,
|
||||||
:match_result => true,
|
:match_result => true,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -204,8 +207,9 @@ class AgentTicketActionsLevel3Test < TestCase
|
||||||
{
|
{
|
||||||
:where => :instance1,
|
:where => :instance1,
|
||||||
:execute => 'match',
|
:execute => 'match',
|
||||||
:css => '.content_permanent.active',
|
:css => '.content_permanent.active .reset-message',
|
||||||
:value => 'Discard your unsaved changes.',
|
:value => '(Discard your unsaved changes.|Verwerfen der)',
|
||||||
|
:no_quote => true,
|
||||||
:match_result => false,
|
:match_result => false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -219,8 +223,9 @@ class AgentTicketActionsLevel3Test < TestCase
|
||||||
{
|
{
|
||||||
:where => :instance2,
|
:where => :instance2,
|
||||||
:execute => 'match',
|
:execute => 'match',
|
||||||
:css => '.content_permanent.active',
|
:css => '.content_permanent.active .reset-message',
|
||||||
:value => 'Discard your unsaved changes.',
|
:value => '(Discard your unsaved changes.|Verwerfen der)',
|
||||||
|
:no_quote => true,
|
||||||
:match_result => false,
|
:match_result => false,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -246,8 +251,9 @@ class AgentTicketActionsLevel3Test < TestCase
|
||||||
{
|
{
|
||||||
:where => :instance1,
|
:where => :instance1,
|
||||||
:execute => 'match',
|
:execute => 'match',
|
||||||
:css => '.content_permanent.active',
|
:css => '.content_permanent.active .reset-message',
|
||||||
:value => 'Discard your unsaved changes.',
|
:value => '(Discard your unsaved changes.|Verwerfen der)',
|
||||||
|
:no_quote => true,
|
||||||
:match_result => false,
|
:match_result => false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -261,8 +267,9 @@ class AgentTicketActionsLevel3Test < TestCase
|
||||||
{
|
{
|
||||||
:where => :instance2,
|
:where => :instance2,
|
||||||
:execute => 'match',
|
:execute => 'match',
|
||||||
:css => '.content_permanent.active',
|
:css => '.content_permanent.active .reset-message',
|
||||||
:value => 'Discard your unsaved changes.',
|
:value => '(Discard your unsaved changes.|Verwerfen der)',
|
||||||
|
:no_quote => true,
|
||||||
:match_result => false,
|
:match_result => false,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -280,8 +287,9 @@ class AgentTicketActionsLevel3Test < TestCase
|
||||||
{
|
{
|
||||||
:where => :instance2,
|
:where => :instance2,
|
||||||
:execute => 'match',
|
:execute => 'match',
|
||||||
:css => '.content_permanent.active',
|
:css => '.content_permanent.active .reset-message',
|
||||||
:value => 'Discard your unsaved changes.',
|
:value => '(Discard your unsaved changes.|Verwerfen der)',
|
||||||
|
:no_quote => true,
|
||||||
:match_result => true,
|
:match_result => true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -298,8 +306,9 @@ class AgentTicketActionsLevel3Test < TestCase
|
||||||
{
|
{
|
||||||
:where => :instance2,
|
:where => :instance2,
|
||||||
:execute => 'match',
|
:execute => 'match',
|
||||||
:css => '.content_permanent.active',
|
:css => '.content_permanent.active .reset-message',
|
||||||
:value => 'Discard your unsaved changes.',
|
:value => '(Discard your unsaved changes.|Verwerfen der)',
|
||||||
|
:no_quote => true,
|
||||||
:match_result => true,
|
:match_result => true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -315,7 +324,9 @@ class AgentTicketActionsLevel3Test < TestCase
|
||||||
:where => :instance2,
|
:where => :instance2,
|
||||||
:execute => 'match',
|
:execute => 'match',
|
||||||
:css => '.content_permanent.active',
|
: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,
|
:match_result => false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,8 +3,8 @@ require 'browser_test_helper'
|
||||||
|
|
||||||
class AgentTicketActionLevel5Test < TestCase
|
class AgentTicketActionLevel5Test < TestCase
|
||||||
def test_I
|
def test_I
|
||||||
random = 'text_module_test_' + rand(999999).to_s
|
random = 'text_module_test_' + rand(99999999).to_s
|
||||||
random2 = 'text_module_test_' + rand(999999).to_s
|
random2 = 'text_module_test_' + rand(99999999).to_s
|
||||||
|
|
||||||
# user
|
# user
|
||||||
tests = [
|
tests = [
|
||||||
|
@ -153,9 +153,9 @@ class AgentTicketActionLevel5Test < TestCase
|
||||||
browser_signle_test_with_login(tests, { :username => 'master@example.com' })
|
browser_signle_test_with_login(tests, { :username => 'master@example.com' })
|
||||||
end
|
end
|
||||||
def test_II
|
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
|
login = 'agent-text-module-' + user_rand
|
||||||
firstname = 'Text' + user_rand
|
firstname = 'Text' + user_rand
|
||||||
lastname = 'Module' + user_rand
|
lastname = 'Module' + user_rand
|
||||||
|
@ -191,7 +191,7 @@ class AgentTicketActionLevel5Test < TestCase
|
||||||
{
|
{
|
||||||
:where => :instance2,
|
:where => :instance2,
|
||||||
:execute => 'set',
|
:execute => 'set',
|
||||||
:css => '.active input[name=subject]',
|
:css => '.active input[name=title]',
|
||||||
:value => 'A',
|
:value => 'A',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -207,7 +207,7 @@ class AgentTicketActionLevel5Test < TestCase
|
||||||
{
|
{
|
||||||
:where => :instance2,
|
:where => :instance2,
|
||||||
:execute => 'set',
|
:execute => 'set',
|
||||||
:css => '.active input[name=subject]',
|
:css => '.active input[name=title]',
|
||||||
:value => 'B',
|
:value => 'B',
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -330,7 +330,7 @@ class AgentTicketActionLevel5Test < TestCase
|
||||||
{
|
{
|
||||||
:where => :instance2,
|
:where => :instance2,
|
||||||
:execute => 'set',
|
:execute => 'set',
|
||||||
:css => '.active .ticket_create input[name="customer_id_autocompletion"]',
|
:css => '.active .ticket-create input[name="customer_id_autocompletion"]',
|
||||||
:value => 'nicole',
|
:value => 'nicole',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -340,13 +340,13 @@ class AgentTicketActionLevel5Test < TestCase
|
||||||
{
|
{
|
||||||
:where => :instance2,
|
:where => :instance2,
|
||||||
:execute => 'sendkey',
|
:execute => 'sendkey',
|
||||||
:css => '.active .ticket_create input[name="customer_id_autocompletion"]',
|
:css => '.active .ticket-create input[name="customer_id_autocompletion"]',
|
||||||
:value => :arrow_down,
|
:value => :arrow_down,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
:where => :instance2,
|
:where => :instance2,
|
||||||
:execute => 'sendkey',
|
:execute => 'sendkey',
|
||||||
:css => '.active .ticket_create input[name="customer_id_autocompletion"]',
|
:css => '.active .ticket-create input[name="customer_id_autocompletion"]',
|
||||||
:value => :tab,
|
:value => :tab,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -425,7 +425,7 @@ class AgentTicketActionLevel5Test < TestCase
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
:execute => 'wait',
|
:execute => 'wait',
|
||||||
:value => 4,
|
:value => 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
:where => :instance2,
|
:where => :instance2,
|
||||||
|
@ -536,7 +536,7 @@ class AgentTicketActionLevel5Test < TestCase
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
:execute => 'wait',
|
:execute => 'wait',
|
||||||
:value => 0.2,
|
:value => 0.5,
|
||||||
},
|
},
|
||||||
# {
|
# {
|
||||||
# :where => :instance2,
|
# :where => :instance2,
|
||||||
|
|
|
@ -142,7 +142,7 @@ class AgentUserManageTest < TestCase
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
:execute => 'set',
|
:execute => 'set',
|
||||||
:css => '.active .ticket_create input[name="customer_id_autocompletion"]',
|
:css => '.active .ticket-create input[name="customer_id_autocompletion"]',
|
||||||
:value => customer_user_email,
|
:value => customer_user_email,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -151,12 +151,12 @@ class AgentUserManageTest < TestCase
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
:execute => 'sendkey',
|
:execute => 'sendkey',
|
||||||
:css => '.active .ticket_create input[name="customer_id_autocompletion"]',
|
:css => '.active .ticket-create input[name="customer_id_autocompletion"]',
|
||||||
:value => :arrow_down,
|
:value => :arrow_down,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
:execute => 'sendkey',
|
:execute => 'sendkey',
|
||||||
:css => '.active .ticket_create input[name="customer_id_autocompletion"]',
|
:css => '.active .ticket-create input[name="customer_id_autocompletion"]',
|
||||||
:value => :tab,
|
:value => :tab,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -27,7 +27,7 @@ class CustomerTicketCreateTest < TestCase
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
:execute => 'set',
|
:execute => 'set',
|
||||||
:css => '.ticket-create input[name="subject"]',
|
:css => '.ticket-create input[name="title"]',
|
||||||
:value => 'some subject 123äöü',
|
:value => 'some subject 123äöü',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -32,12 +32,12 @@ class TaskbarTaskTest < TestCase
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
:execute => 'check',
|
:execute => 'check',
|
||||||
:css => '.active .ticket_create',
|
:css => '.active .ticket-create',
|
||||||
:result => true,
|
:result => true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
:execute => 'set',
|
:execute => 'set',
|
||||||
:css => '.active .ticket_create input[name="subject"]',
|
:css => '.active .ticket-create input[name="title"]',
|
||||||
:value => 'some test AAA',
|
:value => 'some test AAA',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -113,7 +113,7 @@ class TaskbarTaskTest < TestCase
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
:execute => 'set',
|
:execute => 'set',
|
||||||
:css => '.active .ticket_create input[name="subject"]',
|
:css => '.active .ticket-create input[name="title"]',
|
||||||
:value => 'INBOUND TEST#1',
|
:value => 'INBOUND TEST#1',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -122,7 +122,7 @@ class TaskbarTaskTest < TestCase
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
:execute => 'set',
|
:execute => 'set',
|
||||||
:css => '.active .ticket_create textarea[name="body"]',
|
:css => '.active .ticket-create textarea[name="body"]',
|
||||||
:value => 'INBOUND BODY TEST#1',
|
:value => 'INBOUND BODY TEST#1',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -139,7 +139,7 @@ class TaskbarTaskTest < TestCase
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
:execute => 'set',
|
:execute => 'set',
|
||||||
:css => '.active .ticket_create input[name="subject"]',
|
:css => '.active .ticket-create input[name="title"]',
|
||||||
:value => 'OUTBOUND TEST#1',
|
:value => 'OUTBOUND TEST#1',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -148,7 +148,7 @@ class TaskbarTaskTest < TestCase
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
:execute => 'set',
|
:execute => 'set',
|
||||||
:css => '.active .ticket_create textarea[name="body"]',
|
:css => '.active .ticket-create textarea[name="body"]',
|
||||||
:value => 'OUTBOUND BODY TEST#1',
|
:value => 'OUTBOUND BODY TEST#1',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -297,40 +297,40 @@ class TestCase < Test::Unit::TestCase
|
||||||
elsif action[:execute] == 'create_ticket'
|
elsif action[:execute] == 'create_ticket'
|
||||||
instance.find_element( { :css => 'a[href="#new"]' } ).click
|
instance.find_element( { :css => 'a[href="#new"]' } ).click
|
||||||
instance.find_element( { :css => 'a[href="#ticket/create/call_inbound"]' } ).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
|
if !element
|
||||||
assert( false, "(#{test[:name]}) no ticket create screen found!" )
|
assert( false, "(#{test[:name]}) no ticket create screen found!" )
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
sleep 2
|
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.clear
|
||||||
element.send_keys( 'nico*' )
|
element.send_keys( 'nico*' )
|
||||||
sleep 4
|
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 )
|
element.send_keys( :arrow_down )
|
||||||
sleep 0.2
|
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 )
|
element.send_keys( :tab )
|
||||||
sleep 0.1
|
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 = Selenium::WebDriver::Support::Select.new(element)
|
||||||
dropdown.select_by( :text, action[:group])
|
dropdown.select_by( :text, action[:group])
|
||||||
sleep 0.1
|
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.clear
|
||||||
element.send_keys( action[:subject] )
|
element.send_keys( action[:subject] )
|
||||||
sleep 0.1
|
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.clear
|
||||||
element.send_keys( action[:body] )
|
element.send_keys( action[:body] )
|
||||||
if action[:do_not_submit]
|
if action[:do_not_submit]
|
||||||
assert( true, "(#{test[:name]}) ticket created without submit" )
|
assert( true, "(#{test[:name]}) ticket created without submit" )
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
sleep 0.5
|
sleep 0.8
|
||||||
instance.find_element( { :css => '.active .form-actions button[type="submit"]' } ).click
|
instance.find_element( { :css => '.active .form-actions button[type="submit"]' } ).click
|
||||||
sleep 2
|
sleep 1
|
||||||
(1..14).each {|loop|
|
(1..14).each {|loop|
|
||||||
if instance.current_url =~ /#{Regexp.quote('#ticket/zoom/')}/
|
if instance.current_url =~ /#{Regexp.quote('#ticket/zoom/')}/
|
||||||
assert( true, "(#{test[:name]}) ticket created" )
|
assert( true, "(#{test[:name]}) ticket created" )
|
||||||
|
@ -338,7 +338,7 @@ class TestCase < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
sleep 0.5
|
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
|
return
|
||||||
elsif action[:execute] == 'close_all_tasks'
|
elsif action[:execute] == 'close_all_tasks'
|
||||||
for i in 1..100
|
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|
|
tests.each { |test|
|
||||||
success = Tag.tag_add( test[:tag_add] )
|
tags = nil
|
||||||
assert( success, "Tag.tag_add successful")
|
if test[:tag_add]
|
||||||
list = Tag.tag_list( 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|
|
test[:verify][:items].each {|key, value|
|
||||||
if value == true
|
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
|
else
|
||||||
assert( !list.include?( key ), "Tag verify #{ test[:tag_add][:item] }")
|
assert( !list.include?( key ), "Tag verify - exists but should not #{ key }")
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# delete tags
|
# delete tags
|
||||||
tests.each { |test|
|
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")
|
assert( success, "Tag.tag_remove successful")
|
||||||
list = Tag.tag_list( test[:tag_add] )
|
list = Tag.tag_list( tags )
|
||||||
assert( !list.include?( test[:tag_add][:item] ), "Tag entry destroyed")
|
assert( !list.include?( tags[:item] ), "Tag entry destroyed")
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue