Init version of object manager.

This commit is contained in:
Martin Edenhofer 2014-09-10 01:42:20 +02:00
parent 0f1eb5dd55
commit c4c4ef35ef
30 changed files with 2119 additions and 416 deletions

View file

@ -2,7 +2,11 @@ class App.ControllerForm extends App.Controller
constructor: (params) ->
for key, value of params
@[key] = value
@attribute_count = 0
if !@handlers
@handlers = []
@handlers.push @_showHideToggle
@handlers.push @_requiredMandantoryToggle
if !@form
@form = @formGen()
@ -23,37 +27,62 @@ class App.ControllerForm extends App.Controller
fieldset = $('<fieldset></fieldset>')
for attribute_clean in @model.configure_attributes
attribute = _.clone( attribute_clean )
# collect form attributes
@attributes = []
if @model.attributesGet
attributesClean = @model.attributesGet(@screen)
else
attributesClean = App.Model.attributesGet(@screen, @model.configure_attributes )
if !attribute.readonly && ( !@required || @required && attribute[@required] )
for attributeName, attribute of attributesClean
@attribute_count = @attribute_count + 1
# ignore read only attributes
if !attribute.readonly
# add item
item = @formGenItem( attribute, @model.className, fieldset )
item.appendTo(fieldset)
# check generic filter
if @filter && !attribute.filter
if @filter[ attributeName ]
attribute.filter = @filter[ attributeName ]
# if password, add confirm password item
if attribute.type is 'password'
@attributes.push attribute
# set selected value passed on current params
if @params
if attribute.name of @params
attribute.value = @params[attribute.name]
attribute_count = 0
className = @model.className + '_' + Math.floor( Math.random() * 999999 ).toString()
# rename display and name to _confirm
if !attribute.single
attribute.display = attribute.display + ' (confirm)'
attribute.name = attribute.name + '_confirm';
item = @formGenItem( attribute, @model.className, fieldset )
item.appendTo(fieldset)
for attribute in @attributes
attribute_count = attribute_count + 1
# add item
item = @formGenItem( attribute, className, fieldset, attribute_count )
item.appendTo(fieldset)
# if password, add confirm password item
if attribute.type is 'password'
# set selected value passed on current params
if @params
if attribute.name of @params
attribute.value = @params[attribute.name]
# rename display and name to _confirm
if !attribute.single
attribute.display = attribute.display + ' (confirm)'
attribute.name = attribute.name + '_confirm';
item = @formGenItem( attribute, className, fieldset, attribute_count )
item.appendTo(fieldset)
if @fullForm
if !@formClass
@formClass = ''
fieldset = $('<form class="' + @formClass + '"><button class="btn">' + App.i18n.translateContent('Submit') + '</button></form>').prepend( fieldset )
# bind form events
if @events
for eventSelector, callback of @events
do (eventSelector, callback) =>
evs = eventSelector.split(' ')
fieldset.find( evs[1] ).bind(evs[0], (e) => callback(e) )
# return form
return fieldset
@ -131,14 +160,14 @@ class App.ControllerForm extends App.Controller
###
formGenItem: (attribute_config, classname, form ) ->
attribute = _.clone( attribute_config )
formGenItem: (attribute_config, classname, form, attribute_count ) ->
attribute = clone( attribute_config )
# create item id
attribute.id = classname + '_' + attribute.name
# set autofocus
if @autofocus && @attribute_count is 1
if @autofocus && attribute_count is 1
attribute.autofocus = 'autofocus'
# set required option
@ -234,6 +263,22 @@ class App.ControllerForm extends App.Controller
else if attribute.tag is 'select'
item = $( App.view('generic/select')( attribute: attribute ) )
# date
else if attribute.tag is 'date'
attribute.type = 'text'
item = $( App.view('generic/date')( attribute: attribute ) )
#item.datetimepicker({
# format: 'Y.m.d'
#});
# date
else if attribute.tag is 'datetime'
attribute.type = 'text'
item = $( App.view('generic/date')( attribute: attribute ) )
#item.datetimepicker({
# format: 'Y.m.d H:i'
#});
# timezone
else if attribute.tag is 'timezone'
attribute.options = []
@ -717,7 +762,7 @@ class App.ControllerForm extends App.Controller
b = (event, item) =>
# set html form attribute
$(local_attribute).val(item.id)
$(local_attribute).val(item.id).trigger('change')
$(local_attribute + '_autocompletion_value_shown').val(item.value)
# call calback
@ -738,8 +783,11 @@ class App.ControllerForm extends App.Controller
}
)
###
source = attribute.source
if typeof(source) is 'string'
source = source.replace('#{@apiPath}', App.Config.get('api_path') );
$(local_attribute_full).autocomplete(
source: attribute.source,
source: source,
minLength: attribute.minLengt || 3,
select: ( event, ui ) =>
b(event, ui.item)
@ -1221,63 +1269,12 @@ class App.ControllerForm extends App.Controller
else
item = $( App.view('generic/input')( attribute: attribute ) )
if attribute.onchange
if typeof attribute.onchange is 'function'
attribute.onchange(attribute)
else
for i of attribute.onchange
a = i.split(/__/)
if a[1]
if a[0] is attribute.name
@attribute = attribute
@classname = classname
@attributes_clean = attributes_clean
@change = a
b = =>
# console.log 'aaa', @attribute
attribute = @attribute
change = @change
classname = @classname
attributes_clean = @attributes_clean
ui = @
$( '#' + @attribute.id ).bind('change', ->
ui.log 'change', @, attribute, change
ui.log change[0] + ' has changed - changing ' + change[1]
item = $( ui.formGenItem(attribute, classname, attributes_clean) )
ui.log item, classname
)
App.Delay.set( b, 100, undefined, 'form_change' )
# if attribute.onchange[]
ui = @
item.bind('change', ->
if ui.form_data
params = App.ControllerForm.params(@)
for i of ui.form_data
a = i.split(/__/)
if a[1] && a[0] is attribute.name
newListAttribute = i
changedAttribute = a[0]
toChangeAttribute = a[1]
# get new option list
newListAttributes = ui['form_data'][newListAttribute][ params['group_id'] ]
# find element to replace
for item in ui.model.configure_attributes
if item.name is toChangeAttribute
item.display = false
item['filter'][toChangeAttribute] = newListAttributes
if params[changedAttribute]
item.default = params[toChangeAttribute]
if !item.default
delete item['default']
newElement = ui.formGenItem( item, classname, form )
# replace new option list
form.find('[name="' + toChangeAttribute + '"]').replaceWith( newElement )
)
if @handlers
item.bind('change', (e) =>
params = App.ControllerForm.params( $(e.target) )
for handler in @handlers
handler(params, attribute, @attributes, classname, form, @)
)
# bind dependency
if @dependency
@ -1339,6 +1336,44 @@ class App.ControllerForm extends App.Controller
el.find('[name="' + key + '"]').parents('.form-group').addClass('hide')
el.find('[name="' + key + '"]').addClass('is-hidden')
_mandantory: (name, el = @el) ->
if !_.isArray(name)
name = [name]
for key in name
el.find('[name="' + key + '"]').attr('required', true)
el.find('[name="' + key + '"]').parents('.form-group').find('label span').html('*')
_optional: (name, el = @el) ->
if !_.isArray(name)
name = [name]
for key in name
el.find('[name="' + key + '"]').attr('required', false)
el.find('[name="' + key + '"]').parents('.form-group').find('label span').html('')
_showHideToggle: (params, changedAttribute, attributes, classname, form, ui) =>
for attribute in attributes
if attribute.shown_if
hit = false
for refAttribute, refValue of attribute.shown_if
if params[refAttribute] && params[refAttribute].toString() is refValue.toString()
hit = true
if hit
ui._show(attribute.name)
else
ui._hide(attribute.name)
_requiredMandantoryToggle: (params, changedAttribute, attributes, classname, form, ui) =>
for attribute in attributes
if attribute.required_if
hit = false
for refAttribute, refValue of attribute.required_if
if params[refAttribute] && params[refAttribute].toString() is refValue.toString()
hit = true
if hit
ui._mandantory(attribute.name)
else
ui._optional(attribute.name)
# sort attribute.options
_sortOptions: (attribute) ->
@ -1399,6 +1434,7 @@ class App.ControllerForm extends App.Controller
list = []
if attribute.filter
App.Log.debug 'ControllerForm', '_getRelationOptionList:filter', attribute.filter
# function based filter
@ -1426,6 +1462,22 @@ class App.ControllerForm extends App.Controller
if record['id'] is key
list.push record
# data based filter
else if attribute.filter && _.isArray attribute.filter
App.Log.debug 'ControllerForm', '_getRelationOptionList:filter-array', attribute.filter
# check all records
for record in App[ attribute.relation ].search( sortBy: attribute.sortBy )
# check all filter attributes
for key in attribute.filter
# check all filter values as array
# if it's matching, use it for selection
if record['id'] is key
list.push record
# no data filter matched
else
App.Log.debug 'ControllerForm', '_getRelationOptionList:filter-data no filter matched'
@ -1512,8 +1564,9 @@ class App.ControllerForm extends App.Controller
validate: (params) ->
App.Model.validate(
model: @model,
params: params,
model: @model
params: params
screen: @screen
)
# get all params of the form
@ -1637,13 +1690,8 @@ class App.ControllerForm extends App.Controller
# show new errors
for key, msg of data.errors
$(data.form).parents().find('[name*="' + key + '"]').parents('div .form-group').addClass('has-error')
$(data.form).parents().find('[name*="' + key + '"]').parent().find('.help-inline').html(msg)
$(data.form).parents().find('[name="' + key + '"]').parents('div .form-group').addClass('has-error')
$(data.form).parents().find('[name="' + key + '"]').parent().find('.help-inline').html(msg)
# set autofocus
$(data.form).parents().find('.has-error').find('input, textarea').first().focus()
# # enable form again
# if $(data.form).parents().find('.has-error').html()
# @formEnable(data.form)

View file

@ -7,11 +7,11 @@ class App.ControllerGenericNew extends App.ControllerModal
@html App.view('generic/admin/new')( head: @pageData.object )
new App.ControllerForm(
el: @el.find('#object_new'),
model: App[ @genericObject ],
params: @item,
required: @required,
autofocus: true,
el: @el.find('#object_new')
model: App[ @genericObject ]
params: @item
screen: @screen || 'edit'
autofocus: true
)
@modalShow()
@ -59,7 +59,7 @@ class App.ControllerGenericEdit extends App.ControllerModal
el: @el.find('#object_edit')
model: App[ @genericObject ]
params: @item
required: @required
screen: @screen || 'edit'
autofocus: true
)
@modalShow()

View file

@ -99,6 +99,7 @@ class App.ControllerTable extends App.Controller
data.model = {}
overview = data.overview || data.model.configure_overview || []
attributes = data.attributes || data.model.configure_attributes || {}
attributes = App.Model.attributesGet(false, attributes)
destroy = data.model.configure_delete
# check if table is empty
@ -146,13 +147,13 @@ class App.ControllerTable extends App.Controller
header = []
for item in overview
headerFound = false
for attribute in attributes
if attribute.name is item
for attributeName, attribute of attributes
if attributeName is item
headerFound = true
header.push attribute
else
rowWithoutId = item + '_id'
if attribute.name is rowWithoutId
if attributeName is rowWithoutId
headerFound = true
header.push attribute

View file

@ -14,7 +14,7 @@ class App.TicketCreate extends App.Controller
# set title
@form_id = App.ControllerForm.formId()
@edit_form = undefined
@form_meta = undefined
# set article attributes
default_type = 'call_inbound'
@ -25,14 +25,17 @@ class App.TicketCreate extends App.Controller
sender: 'Customer'
article: 'phone'
title: 'Call Inbound'
screen: 'create_phone_in'
call_outbound:
sender: 'Agent'
article: 'phone'
title: 'Call Outbound'
screen: 'create_phone_out'
email:
sender: 'Agent'
article: 'email'
title: 'Email'
screen: 'create_email_out'
@article_attributes = article_sender_type_map[@type]
# remember split info if exists
@ -57,9 +60,9 @@ class App.TicketCreate extends App.Controller
meta: =>
text = App.i18n.translateInline( @article_attributes['title'] )
subject = @el.find('[name=subject]').val()
if subject
text = "#{text}: #{subject}"
title = @el.find('[name=title]').val()
if title
text = "#{text}: #{title}"
meta =
url: @url()
head: text
@ -100,7 +103,7 @@ class App.TicketCreate extends App.Controller
if cache && !params.ticket_id && !params.article_id
# get edit form attributes
@edit_form = cache.edit_form
@form_meta = cache.form_meta
# load assets
App.Collection.loadAssets( cache.assets )
@ -108,7 +111,7 @@ class App.TicketCreate extends App.Controller
@render()
else
@ajax(
id: 'ticket_create'
id: 'ticket_create' + @task_key
type: 'GET'
url: @apiPath + '/ticket_create'
data:
@ -121,7 +124,7 @@ class App.TicketCreate extends App.Controller
App.Store.write( 'ticket_create_attributes', data )
# get edit form attributes
@edit_form = data.edit_form
@form_meta = data.form_meta
# load assets
App.Collection.loadAssets( data.assets )
@ -143,22 +146,6 @@ class App.TicketCreate extends App.Controller
render: (template = {}) ->
# set defaults
defaults =
state_id: App.TicketState.findByAttribute( 'name', 'open' ).id
priority_id: App.TicketPriority.findByAttribute( 'name', '2 normal' ).id
# generate form
configure_attributes = [
{ name: 'customer_id', display: 'Customer', tag: 'autocompletion', type: 'text', limit: 200, null: false, relation: 'User', class: 'span7', autocapitalize: false, help: 'Select the customer of the Ticket or create one.', helpLink: '<a href="" class="customer_new">&raquo;</a>', callback: @localUserInfo, source: @apiPath + '/users/search', minLengt: 2 },
{ name: 'group_id', display: 'Group', tag: 'select', multiple: false, null: false, filter: @edit_form, nulloption: true, relation: 'Group', default: defaults['group_id'], class: 'span7', },
{ name: 'owner_id', display: 'Owner', tag: 'select', multiple: false, null: true, filter: @edit_form, nulloption: true, relation: 'User', default: defaults['owner_id'], class: 'span7', },
{ name: 'tags', display: 'Tags', tag: 'tag', type: 'text', null: true, default: defaults['tags'], class: 'span7', },
{ name: 'subject', display: 'Subject', tag: 'input', type: 'text', limit: 200, null: false, default: defaults['subject'], class: 'span7', },
{ name: 'body', display: 'Text', tag: 'textarea', rows: 8, null: false, default: defaults['body'], class: 'span7', upload: true },
{ name: 'state_id', display: 'State', tag: 'select', multiple: false, null: false, filter: @edit_form, relation: 'TicketState', default: defaults['state_id'], translate: true, class: 'medium' },
{ name: 'priority_id', display: 'Priority', tag: 'select', multiple: false, null: false, filter: @edit_form, relation: 'TicketPriority', default: defaults['priority_id'], translate: true, class: 'medium' },
]
@html App.view('agent_ticket_create')(
head: 'New Ticket'
title: @article_attributes['title']
@ -172,14 +159,50 @@ class App.TicketCreate extends App.Controller
else if App.TaskManager.get(@task_key) && !_.isEmpty( App.TaskManager.get(@task_key).state )
params = App.TaskManager.get(@task_key).state
formChanges = (params, attribute, attributes, classname, form, ui) =>
if @form_meta.dependencies && @form_meta.dependencies[attribute.name]
dependency = @form_meta.dependencies[attribute.name][ parseInt(params[attribute.name]) ]
if dependency
for fieldNameToChange of dependency
filter = []
if dependency[fieldNameToChange]
filter = dependency[fieldNameToChange]
# find element to replace
for item in attributes
if item.name is fieldNameToChange
item.display = false
item['filter'] = {}
item['filter'][ fieldNameToChange ] = filter
item.default = params[item.name]
#if !item.default
# delete item['default']
newElement = ui.formGenItem( item, classname, form )
# replace new option list
form.find('[name="' + fieldNameToChange + '"]').replaceWith( newElement )
new App.ControllerForm(
el: @el.find('.ticket_create')
form_id: @form_id
model:
configure_attributes: configure_attributes
className: 'create_' + @type + '_' + @id
el: @el.find('.ticket-form')
form_id: @form_id
model: App.Ticket
screen: @article_attributes['screen']
events:
'change [name=customer_id]': @localUserInfo
handlers: [
formChanges
]
filter: @form_meta.filter
autofocus: true
form_data: @edit_form
params: params
)
new App.ControllerForm(
el: @el.find('.article-form')
form_id: @form_id
model: App.TicketArticle
screen: @article_attributes['screen']
params: params
)
@ -193,20 +216,23 @@ class App.TicketCreate extends App.Controller
# show text module UI
@textModule = new App.WidgetTextModule(
el: @el.find('.ticket-create').find('textarea')
el: @el.find('form').find('textarea')
)
# start auto save
@autosave()
localUserInfo: (params) =>
localUserInfo: (e) =>
params = App.ControllerForm.params( $(e.target).closest('form') )
# update text module UI
callback = (user) =>
@textModule.reload(
ticket:
customer: user
)
if @textModule
@textModule.reload(
ticket:
customer: user
)
@userInfo(
user_id: params.customer_id
@ -234,7 +260,7 @@ class App.TicketCreate extends App.Controller
params.title = params.subject
# create ticket
object = new App.Ticket
ticket = new App.Ticket
# find sender_id
sender = App.TicketArticleSender.findByAttribute( 'name', @article_attributes['sender'] )
@ -248,6 +274,7 @@ class App.TicketCreate extends App.Controller
params['article'] = {
to: (group && group.name) || ''
from: params.customer_id_autocompletion
cc: params.cc
subject: params.subject
body: params.body
type_id: type.id
@ -258,6 +285,7 @@ class App.TicketCreate extends App.Controller
params['article'] = {
from: (group && group.name) || ''
to: params.customer_id_autocompletion
cc: params.cc
subject: params.subject
body: params.body
type_id: type.id
@ -265,15 +293,30 @@ class App.TicketCreate extends App.Controller
form_id: @form_id
}
object.load(params)
ticket.load(params)
# validate form
errors = object.validate()
ticketErrors = ticket.validate(
screen: @article_attributes['screen']
)
article = new App.TicketArticle
article.load(params['article'])
articleErrors = article.validate(
screen: @article_attributes['screen']
)
for key, value of articleErrors
if !ticketErrors
ticketErrors = {}
ticketErrors[key] = value
# show errors in form
if errors
@log 'error', errors
@formValidate( form: e.target, errors: errors )
if ticketErrors
@log 'error', ticketErrors
@formValidate(
form: e.target
errors: ticketErrors
screen: @article_attributes['screen']
)
# save ticket, create article
else
@ -281,7 +324,7 @@ class App.TicketCreate extends App.Controller
# disable form
@formDisable(e)
ui = @
object.save(
ticket.save(
done: ->
# notify UI
@ -322,10 +365,10 @@ class UserNew extends App.ControllerModal
@html App.view('agent_user_create')( head: 'New User' )
new App.ControllerForm(
el: @el.find('#form-user'),
model: App.User,
required: 'quick',
autofocus: true,
el: @el.find('#form-user')
model: App.User
screen: 'edit'
autofocus: true
)
@modalShow()

View file

@ -16,8 +16,6 @@ class Index extends App.ControllerContent
@fetch(params)
@navupdate '#customer_ticket_new'
@edit_form = undefined
# get data / in case also ticket data for split
fetch: (params) ->
@ -26,9 +24,6 @@ class Index extends App.ControllerContent
if cache
# get edit form attributes
@edit_form = cache.edit_form
# load assets
App.Collection.loadAssets( cache.assets )
@ -44,9 +39,6 @@ class Index extends App.ControllerContent
# cache request
App.Store.write( 'ticket_create_attributes', data )
# get edit form attributes
@edit_form = data.edit_form
# load assets
App.Collection.loadAssets( data.assets )
@ -87,25 +79,25 @@ class Index extends App.ControllerContent
return item if item && _.contains( group_ids, item.id.toString() )
)
# generate form
configure_attributes = [
{ name: 'group_id', display: 'Group', tag: 'select', multiple: false, null: false, filter: groupFilter, nulloption: true, relation: 'Group', default: defaults['group_id'], class: 'span7', },
# { name: 'owner_id', display: 'Owner', tag: 'select', multiple: false, null: true, filter: @edit_form, nulloption: true, relation: 'User', default: defaults['owner_id'], class: 'span7', },
{ name: 'subject', display: 'Subject', tag: 'input', type: 'text', limit: 100, null: false, default: defaults['subject'], class: 'span7', },
{ name: 'body', display: 'Text', tag: 'textarea', rows: 10, null: false, default: defaults['body'], class: 'span7', upload: true },
# { name: 'state_id', display: 'State', tag: 'select', multiple: false, null: false, filter: @edit_form, relation: 'TicketState', default: defaults['state_id'], translate: true, class: 'medium' },
# { name: 'priority_id', display: 'Priority', tag: 'select', multiple: false, null: false, filter: @edit_form, relation: 'TicketPriority', default: defaults['priority_id'], translate: true, class: 'medium' },
]
@html App.view('customer_ticket_create')( head: 'New Ticket' )
new App.ControllerForm(
el: @el.find('#form_create')
form_id: @form_id
model:
configure_attributes: configure_attributes
className: 'create'
el: @el.find('.ticket-form')
form_id: @form_id
model: App.Ticket
screen: 'create_web'
autofocus: true
form_data: @edit_form
filter:
group_id: groupFilter
params: defaults
)
new App.ControllerForm(
el: @el.find('.article-form')
form_id: @form_id
model: App.TicketArticle
screen: 'create_web'
params: defaults
)
new App.ControllerDrox(
@ -128,19 +120,21 @@ class Index extends App.ControllerContent
params.customer_id = @Session.get('id')
# set prio
priority = App.TicketPriority.findByAttribute( 'name', '2 normal' )
params.priority_id = priority.id
if !params.priority_id
priority = App.TicketPriority.findByAttribute( 'name', '2 normal' )
params.priority_id = priority.id
# set state
state = App.TicketState.findByAttribute( 'name', 'new' )
params.state_id = state.id
if !params.state_id
state = App.TicketState.findByAttribute( 'name', 'new' )
params.state_id = state.id
# fillup params
if !params.title
params.title = params.subject
# create ticket
object = new App.Ticket
ticket = new App.Ticket
@log 'CustomerTicketCreate', 'notice', 'updateAttributes', params
# find sender_id
@ -160,16 +154,27 @@ class Index extends App.ControllerContent
form_id: @form_id
}
object.load(params)
ticket.load(params)
# validate form
errors = object.validate()
ticketErrors = ticket.validate(
screen: 'create_web'
)
article = new App.TicketArticle
article.load(params['article'])
articleErrors = article.validate(
screen: 'create_web'
)
for key, value of articleErrors
if !ticketErrors
ticketErrors = {}
ticketErrors[key] = value
# show errors in form
if errors
@log 'CustomerTicketCreate', 'error', 'can not create', errors
if ticketErrors
@log 'CustomerTicketCreate', 'error', 'can not create', ticketErrors
@formValidate( form: e.target, errors: errors )
@formValidate( form: e.target, errors: ticketErrors )
# save ticket, create article
else
@ -177,7 +182,7 @@ class Index extends App.ControllerContent
# disable form
@formDisable(e)
ui = @
object.save(
ticket.save(
done: ->
# redirect to zoom
@ -189,7 +194,4 @@ class Index extends App.ControllerContent
)
App.Config.set( 'customer_ticket_new', Index, 'Routes' )
#App.Config.set( 'CustomerTicketNew', { prio: 1600, parent: '', name: 'New Ticket', target: '#customer_ticket_new', role: ['Customer'] }, 'NavBar' )
App.Config.set( 'CustomerTicketNew', { prio: 8000, parent: '', name: 'New', target: '#customer_ticket_new', role: ['Customer'] }, 'NavBarRight' )

View file

@ -32,7 +32,7 @@ class Index extends App.ControllerContent
new App.ControllerForm(
el: @el.find('#form-signup')
model: App.User
required: 'signup'
screen: 'signup'
autofocus: true
)

View file

@ -7,7 +7,7 @@ class App.TicketZoom extends App.Controller
@navupdate '#'
@edit_form = undefined
@form_meta = undefined
@ticket_id = params.ticket_id
@article_id = params.article_id
@signature = undefined
@ -111,7 +111,7 @@ class App.TicketZoom extends App.Controller
@ticket_article_ids = data.ticket_article_ids
# get edit form attributes
@edit_form = data.edit_form
@form_meta = data.form_meta
# get signature
@signature = data.signature
@ -181,7 +181,7 @@ class App.TicketZoom extends App.Controller
new Edit(
ticket: @ticket
el: @el.find('.edit')
edit_form: @edit_form
form_meta: @form_meta
task_key: @task_key
ui: @
)
@ -331,57 +331,55 @@ class Edit extends App.Controller
formChanged: !_.isEmpty( App.TaskManager.get(@task_key).state )
)
@configure_attributes_ticket = [
{ name: 'state_id', display: 'State', tag: 'select', multiple: false, null: true, relation: 'TicketState', filter: @edit_form, translate: true, class: 'span2', item_class: 'pull-left' },
{ name: 'priority_id', display: 'Priority', tag: 'select', multiple: false, null: true, relation: 'TicketPriority', filter: @edit_form, translate: true, class: 'span2', item_class: 'pull-left' },
{ name: 'group_id', display: 'Group', tag: 'select', multiple: false, null: true, relation: 'Group', filter: @edit_form, class: 'span2', item_class: 'pull-left' },
{ name: 'owner_id', display: 'Owner', tag: 'select', multiple: false, null: true, relation: 'User', filter: @edit_form, nulloption: true, class: 'span2', item_class: 'pull-left' },
]
if @isRole('Customer')
@configure_attributes_ticket = [
{ name: 'state_id', display: 'State', tag: 'select', multiple: false, null: true, relation: 'TicketState', filter: @edit_form, translate: true, class: 'span2', item_class: 'pull-left' },
{ name: 'priority_id', display: 'Priority', tag: 'select', multiple: false, null: true, relation: 'TicketPriority', filter: @edit_form, translate: true, class: 'span2', item_class: 'pull-left' },
]
@configure_attributes_article = [
{ name: 'type_id', display: 'Type', tag: 'select', multiple: false, null: true, relation: 'TicketArticleType', filter: @edit_form, default: '9', translate: true, class: 'medium' },
{ name: 'internal', display: 'Visibility', tag: 'select', null: true, options: { true: 'internal', false: 'public' }, class: 'medium', item_class: '', default: false },
{ name: 'to', display: 'To', tag: 'input', type: 'text', limit: 100, null: true, class: 'span7', hide: true },
{ name: 'cc', display: 'Cc', tag: 'input', type: 'text', limit: 100, null: true, class: 'span7', hide: true },
# { name: 'subject', display: 'Subject', tag: 'input', type: 'text', limit: 100, null: true, class: 'span7', hide: true },
{ name: 'in_reply_to', display: 'In Reply to', tag: 'input', type: 'text', limit: 100, null: true, class: 'span7', item_class: 'hide' },
{ name: 'body', display: 'Text', tag: 'textarea', rows: 6, limit: 100, null: true, class: 'span7', item_class: '', upload: true },
]
if @isRole('Customer')
@configure_attributes_article = [
{ name: 'to', display: 'To', tag: 'input', type: 'text', limit: 100, null: true, class: 'span7', hide: true },
{ name: 'cc', display: 'Cc', tag: 'input', type: 'text', limit: 100, null: true, class: 'span7', hide: true },
# { name: 'subject', display: 'Subject', tag: 'input', type: 'text', limit: 100, null: true, class: 'span7', hide: true },
{ name: 'in_reply_to', display: 'In Reply to', tag: 'input', type: 'text', limit: 100, null: true, class: 'span7', item_class: 'hide' },
{ name: 'body', display: 'Text', tag: 'textarea', rows: 6, limit: 100, null: true, class: 'span7', item_class: '', upload: true },
]
@form_id = App.ControllerForm.formId()
defaults = ticket
defaults = ticket.attributes()
if @isRole('Customer')
delete defaults['state_id']
delete defaults['state']
if !_.isEmpty( App.TaskManager.get(@task_key).state )
defaults = App.TaskManager.get(@task_key).state
new App.ControllerForm(
el: @el.find('.form-ticket-update')
form_id: @form_id
model:
configure_attributes: @configure_attributes_ticket
className: 'update_ticket_' + ticket.id
params: defaults
form_data: @edit_form
)
formChanges = (params, attribute, attributes, classname, form, ui) =>
if @form_meta.dependencies && @form_meta.dependencies[attribute.name]
dependency = @form_meta.dependencies[attribute.name][ parseInt(params[attribute.name]) ]
if dependency
for fieldNameToChange of dependency
filter = []
if dependency[fieldNameToChange]
filter = dependency[fieldNameToChange]
# find element to replace
for item in attributes
if item.name is fieldNameToChange
item.display = false
item['filter'] = {}
item['filter'][ fieldNameToChange ] = filter
item.default = params[item.name]
#if !item.default
# delete item['default']
newElement = ui.formGenItem( item, classname, form )
# replace new option list
form.find('[name="' + fieldNameToChange + '"]').replaceWith( newElement )
new App.ControllerForm(
el: @el.find('.form-ticket-update')
form_id: @form_id
model: App.Ticket
screen: 'edit'
handlers: [
formChanges
]
filter: @form_meta.filter
params: defaults
)
new App.ControllerForm(
el: @el.find('.form-article-update')
form_id: @form_id
model:
configure_attributes: @configure_attributes_article
className: 'update_ticket_' + ticket.id
form_data: @edit_form
model: App.TicketArticle
screen: 'edit'
filter:
type_id: [1,9,5]
params: defaults
dependency: [
{
@ -399,13 +397,24 @@ class Edit extends App.Controller
bind: {
name: 'type_id'
relation: 'TicketArticleType'
value: ['note', 'twitter status', 'twitter direct-message']
value: ['note', 'phone', 'twitter status']
},
change: {
action: 'hide'
name: ['to', 'cc'],
},
},
{
bind: {
name: 'type_id'
relation: 'TicketArticleType'
value: ['twitter direct-message']
},
change: {
action: 'show'
name: ['to'],
},
},
]
)
@ -453,10 +462,16 @@ class Edit extends App.Controller
@autosaveStop()
params = @formParam(e.target)
# get ticket
ticket = App.Ticket.fullLocal( @ticket.id )
@log 'notice', 'update', params, ticket
# update local ticket
# create local article
# find sender_id
if @isRole('Customer')
sender = App.TicketArticleSender.findByAttribute( 'name', 'Customer' )
@ -469,17 +484,16 @@ class Edit extends App.Controller
params.sender_id = sender.id
# update ticket
ticket_update = {}
for item in @configure_attributes_ticket
ticket_update[item.name] = params[item.name]
for key, value of params
ticket[key] = value
# check owner assignment
if !@isRole('Customer')
if !ticket_update['owner_id']
ticket_update['owner_id'] = 1
if !ticket['owner_id']
ticket['owner_id'] = 1
# check if title exists
if !ticket_update['title'] && !ticket.title
if !ticket['title']
alert( App.i18n.translateContent('Title needed') )
return
@ -505,22 +519,32 @@ class Edit extends App.Controller
@autosaveStart()
return
ticket.load( ticket_update )
@log 'notice', 'update ticket', ticket_update, ticket
# submit ticket & article
@log 'notice', 'update ticket', ticket
# disable form
@formDisable(e)
# validate ticket
errors = ticket.validate()
errors = ticket.validate(
screen: 'edit'
)
if errors
@log 'error', 'update', errors
@log 'error', errors
@formValidate(
form: e.target
errors: errors
screen: 'edit'
)
@formEnable(e)
@autosaveStart()
return
# validate article
if params['body']
articleAttributes = App.TicketArticle.attributesGet( 'edit' )
if params['body'] || ( articleAttributes['body'] && articleAttributes['body']['null'] is false )
article = new App.TicketArticle
params.from = @Session.get( 'firstname' ) + ' ' + @Session.get( 'lastname' )
params.ticket_id = ticket.id
@ -534,6 +558,11 @@ class Edit extends App.Controller
errors = article.validate()
if errors
@log 'error', 'update article', errors
@formValidate(
form: e.target
errors: errors
screen: 'edit'
)
@formEnable(e)
@autosaveStart()
return

View file

@ -109,13 +109,12 @@ class App.WidgetUser extends App.ControllerDrox
edit: (e) =>
e.preventDefault()
new App.ControllerGenericEdit(
id: @user_id,
genericObject: 'User',
required: 'quick',
pageData: {
title: 'Users',
object: 'User',
objects: 'Users',
},
id: @user_id
genericObject: 'User'
screen: 'edit'
pageData:
title: 'Users'
object: 'User'
objects: 'Users'
callback: @render
)

View file

@ -69,12 +69,26 @@ class App.Auth
App.Event.trigger( 'auth:logout' )
App.Event.trigger( 'ui:rerender' )
# update model definition
if data.models
for model, attributes of data.models
for attribute in attributes
App[model].attributes.push attribute.name
App[model].configure_attributes.push attribute
return false;
# clear local store
if type isnt 'check'
App.Event.trigger( 'clearStore' )
# update model definition
if data.models
for model, attributes of data.models
for attribute in attributes
App[model].attributes.push attribute.name
App[model].configure_attributes.push attribute
# update config
for key, value of data.config
App.Config.set( key, value )
@ -129,4 +143,3 @@ class App.Auth
App.Event.trigger( 'auth:logout' )
App.Event.trigger( 'ui:rerender' )
App.Event.trigger( 'clearStore' )

View file

@ -64,19 +64,17 @@ class App.Model extends Spine.Model
return '???'
@validate: ( data = {} ) ->
attributes = _.clone( data['model'].configure_attributes )
return if !attributes
# check params of screen if screen is requested
if data['screen']
for attribute in attributes
if attribute.screen
if attribute && attribute.screen && attribute.screen[ data['screen'] ] && !_.isEmpty(attribute.screen[ data['screen'] ])
for item, value of attribute.screen[ data['screen'] ]
attribute[item] = value
# based on model attrbutes
if App[ data['model'] ] && App[ data['model'] ].attributesGet
attributes = App[ data['model'] ].attributesGet( data['screen'] )
# based on custom attributes
else if data['model'].configure_attributes
attributes = App.Model.attributesGet( data['screen'], data['model'].configure_attributes )
# check required_if attributes
for attribute in attributes
for attributeName, attribute of attributes
if attribute['required_if']
for key, values of attribute['required_if']
@ -98,7 +96,7 @@ class App.Model extends Spine.Model
# check attributes/each attribute of object
errors = {}
for attribute in attributes
for attributeName, attribute of attributes
# only if attribute is not read only
if !attribute.readonly
@ -111,25 +109,25 @@ class App.Model extends Spine.Model
if parts[0] && !parts[1]
# key exists not in hash || value is '' || value is undefined
if !( attribute.name of data['params'] ) || data['params'][attribute.name] is '' || data['params'][attribute.name] is undefined
errors[attribute.name] = 'is required'
if !( attributeName of data['params'] ) || data['params'][attributeName] is '' || data['params'][attributeName] is undefined
errors[attributeName] = 'is required'
else if parts[0] && parts[1] && !parts[2]
# key exists not in hash || value is '' || value is undefined
if !data.params[parts[0]] || !( parts[1] of data.params[parts[0]] ) || data.params[parts[0]][parts[1]] is '' || data.params[parts[0]][parts[1]] is undefined
errors[attribute.name] = 'is required'
errors[attributeName] = 'is required'
else
throw "can't parse '#{attribute.name}'"
# check confirm password
if attribute.type is 'password' && data['params'][attribute.name] && "#{attribute.name}_confirm" of data['params']
if attribute.type is 'password' && data['params'][attributeName] && "#{attributeName}_confirm" of data['params']
# get confirm password
if data['params'][attribute.name] isnt data['params']["#{attribute.name}_confirm"]
errors[attribute.name] = 'didn\'t match'
errors["#{attribute.name}_confirm"] = ''
if data['params'][attributeName] isnt data['params']["#{attributeName}_confirm"]
errors[attributeName] = 'didn\'t match'
errors["#{attributeName}_confirm"] = ''
# return error object
if !_.isEmpty(errors)
@ -139,9 +137,41 @@ class App.Model extends Spine.Model
# return no errors
return
###
attributes = App.Model.attributesGet(optionalScreen, optionalAttributesList)
###
@attributesGet: (screen = undefined, attributes = false) ->
if !attributes
attributes = clone( App[ @.className ].configure_attributes )
else
attributes = clone( attributes )
# in case if no configure_attributes exist
return if !attributes
attributesNew = {}
# check params of screen if screen is requested
if screen
for attribute in attributes
if attribute.screen
if attribute && attribute.screen && attribute.screen[ screen ] && !_.isEmpty( attribute.screen[ screen ] )
for item, value of attribute.screen[ screen ]
attribute[item] = value
attributesNew[ attribute.name ] = attribute
if !screen || _.isEmpty( attributesNew )
console.log(attributesNew)
for attribute in attributes
attributesNew[ attribute.name ] = attribute
attributesNew
validate: (params = {}) ->
App.Model.validate(
model: @constructor
model: @constructor.className
params: @
screen: params.screen
)

View file

@ -6,20 +6,20 @@ class App.User extends App.Model
# @hasMany 'roles', 'App.Role'
@configure_attributes = [
{ name: 'login', display: 'Login', tag: 'input', type: 'text', limit: 100, null: false, class: 'span4', autocapitalize: false, signup: false, quick: false },
{ name: 'firstname', display: 'Firstname', tag: 'input', type: 'text', limit: 100, null: false, class: 'span4', signup: true, quick: true, info: true, invite_agent: true },
{ name: 'lastname', display: 'Lastname', tag: 'input', type: 'text', limit: 100, null: false, class: 'span4', signup: true, quick: true, info: true, invite_agent: true },
{ name: 'email', display: 'Email', tag: 'input', type: 'email', limit: 100, null: false, class: 'span4', signup: true, quick: true, info: true, invite_agent: true },
{ name: 'web', display: 'Web', tag: 'input', type: 'url', limit: 100, null: true, class: 'span4', signup: false, quick: true, info: true },
{ name: 'phone', display: 'Phone', tag: 'input', type: 'phone', limit: 100, null: true, class: 'span4', signup: false, quick: true, info: true },
{ name: 'mobile', display: 'Mobile', tag: 'input', type: 'phone', limit: 100, null: true, class: 'span4', signup: false, quick: true, info: true },
{ name: 'fax', display: 'Fax', tag: 'input', type: 'phone', limit: 100, null: true, class: 'span4', signup: false, quick: true, info: true },
{ name: 'organization_id', display: 'Organization', tag: 'select', multiple: false, nulloption: true, null: true, relation: 'Organization', class: 'span4', signup: false, quick: true, info: true },
{ name: 'department', display: 'Department', tag: 'input', type: 'text', limit: 200, null: true, class: 'span4', signup: false, quick: true, info: true },
{ name: 'street', display: 'Street', tag: 'input', type: 'text', limit: 100, null: true, class: 'span4', signup: false, quick: true, info: true },
{ name: 'zip', display: 'Zip', tag: 'input', type: 'text', limit: 100, null: true, class: 'span4', signup: false, quick: true, info: true },
{ name: 'city', display: 'City', tag: 'input', type: 'text', limit: 100, null: true, class: 'span4', signup: false, quick: true, info: true },
{ name: 'password', display: 'Password', tag: 'input', type: 'password', limit: 50, null: true, autocomplete: 'off', class: 'span4', signup: true, quick: false, },
{ name: 'note', display: 'Note', tag: 'textarea', note: 'Notes are visible to agents only, never to customers.', limit: 250, null: true, class: 'span4', quick: true, info: true },
{ name: 'firstname', display: 'Firstname', tag: 'input', type: 'text', limit: 100, null: false, class: 'span4', signup: true, info: true, invite_agent: true },
{ name: 'lastname', display: 'Lastname', tag: 'input', type: 'text', limit: 100, null: false, class: 'span4', signup: true, info: true, invite_agent: true },
{ name: 'email', display: 'Email', tag: 'input', type: 'email', limit: 100, null: false, class: 'span4', signup: true, info: true, invite_agent: true },
{ name: 'web', display: 'Web', tag: 'input', type: 'url', limit: 100, null: true, class: 'span4', signup: false, info: true },
{ name: 'phone', display: 'Phone', tag: 'input', type: 'phone', limit: 100, null: true, class: 'span4', signup: false, info: true },
{ name: 'mobile', display: 'Mobile', tag: 'input', type: 'phone', limit: 100, null: true, class: 'span4', signup: false, info: true },
{ name: 'fax', display: 'Fax', tag: 'input', type: 'phone', limit: 100, null: true, class: 'span4', signup: false, info: true },
{ name: 'organization_id', display: 'Organization', tag: 'select', multiple: false, nulloption: true, null: true, relation: 'Organization', class: 'span4', signup: false, info: true },
{ name: 'department', display: 'Department', tag: 'input', type: 'text', limit: 200, null: true, class: 'span4', signup: false, info: true },
{ name: 'street', display: 'Street', tag: 'input', type: 'text', limit: 100, null: true, class: 'span4', signup: false, info: true },
{ name: 'zip', display: 'Zip', tag: 'input', type: 'text', limit: 100, null: true, class: 'span4', signup: false, info: true },
{ name: 'city', display: 'City', tag: 'input', type: 'text', limit: 100, null: true, class: 'span4', signup: false, info: true },
{ name: 'password', display: 'Password', tag: 'input', type: 'password', limit: 50, null: true, autocomplete: 'off', class: 'span4', signup: true, },
{ name: 'note', display: 'Note', tag: 'textarea', note: 'Notes are visible to agents only, never to customers.', limit: 250, null: true, class: 'span4', info: true },
{ name: 'role_ids', display: 'Roles', tag: 'checkbox', multiple: true, null: false, relation: 'Role', class: 'span4' },
{ name: 'group_ids', display: 'Groups', tag: 'checkbox', multiple: true, null: true, relation: 'Group', class: 'span4', invite_agent: true },
{ name: 'active', display: 'Active', tag: 'boolean', default: true, null: true, class: 'span4' },

View file

@ -14,8 +14,8 @@
</div>
<form class="form-horizontal form-large ticket-create">
<input type="hidden" value="" name="article_type"/>
<div class="span9 ticket_create"></div>
<div class="ticket-form"></div>
<div class="article-form"></div>
<div class="form-actions">
<button type="reset" class="btn cancel"><%- @T( 'Cancel' ) %></button>&nbsp;<button type="submit" class="btn btn-primary submit"><%- @T( 'Create' ) %></button>
</div>

View file

@ -11,8 +11,8 @@
</div>
<div class="page-content">
<form class="form-horizontal form-large">
<input type="hidden" value="" name="article_type"/>
<div id="form_create"></div>
<div class="ticket-form"></div>
<div class="article-form"></div>
<div class="form-actions">
<button type="reset" class="btn btn-default cancel"><%- @T( 'Cancel' ) %></button>
<button type="submit" class="btn btn-primary submit"><%- @T( 'Create' ) %></button>

View file

@ -1,5 +1,5 @@
<div class="form-group <%= @attribute.item_class %>">
<label for="<%= @attribute.id %>"><%- @T( @attribute.display ) %><% if !@attribute.null: %> *<% end %></label>
<label for="<%= @attribute.id %>"><%- @T( @attribute.display ) %> <span><% if !@attribute.null: %>*<% end %></span></label>
<div class="controls">
<%- @item %><% if @attribute.note: %><span class="glyphicon glyphicon-question-sign help-message" title="<%- @Ti( @attribute.note ) + ' ' %>"></span><% end %>
<% if @attribute.remove: %><span><a href="#" class="glyphicon glyphicon-minus"></a></span><% end %>

View 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 %>>

View file

@ -33,8 +33,12 @@ class SessionsController < ApplicationController
# auto population of default collections
collections, assets = SessionHelper::default_collections(user)
# add session user assets
assets = user.assets(assets)
# get models
models = SessionHelper::models(user)
# check logon session
logon_session_key = nil
if params['logon_session']
@ -50,6 +54,7 @@ class SessionsController < ApplicationController
# return new session data
render :json => {
:session => user,
:models => models,
:collections => collections,
:assets => assets,
:logon_session => logon_session_key,
@ -75,9 +80,13 @@ class SessionsController < ApplicationController
end
if !user_id
# get models
models = SessionHelper::models()
render :json => {
:error => 'no valid session',
:config => config_frontend,
:models => models,
}
return
end
@ -89,13 +98,18 @@ class SessionsController < ApplicationController
# auto population of default collections
collections, assets = SessionHelper::default_collections(user)
# add session user assets
assets = user.assets(assets)
# get models
models = SessionHelper::models(user)
# return current session
render :json => {
:session => user,
:models => models,
:collections => collections,
:assets => assets,
:assets => assets,
:config => config_frontend,
}
end

View file

@ -255,24 +255,12 @@ class TicketsController < ApplicationController
)
end
# get related users
assets = {}
assets = ticket.assets(assets)
# get attributes to update
attributes_to_change = Ticket::ScreenOptions.attributes_to_change( :user => current_user, :ticket => ticket )
attributes_to_change[:owner_id].each { |user_id|
user = User.find(user_id)
assets = user.assets(assets)
}
attributes_to_change[:group_id__owner_id].each {|group_id, user_ids|
user_ids.each {|user_id|
user = User.find(user_id)
assets = user.assets(assets)
}
}
# get related users
assets = attributes_to_change[:assets]
assets = ticket.assets(assets)
# get related articles
articles = Ticket::Article.where( :ticket_id => params[:id] )
@ -297,6 +285,7 @@ class TicketsController < ApplicationController
:ticket_article_ids => article_ids,
:signature => signature,
:assets => assets,
:form_meta => attributes_to_change,
:edit_form => attributes_to_change,
}
end
@ -311,20 +300,7 @@ class TicketsController < ApplicationController
# :article_id => params[:article_id]
)
assets = {}
assets[ User.to_app_model ] = {}
attributes_to_change[:owner_id].each { |user_id|
user = User.find(user_id)
assets = user.assets(assets)
}
attributes_to_change[:group_id__owner_id].each {|group_id, user_ids|
user_ids.each {|user_id|
user = User.find(user_id)
assets = user.assets(assets)
}
}
assets = attributes_to_change[:assets]
# split data
split = {}
if params[:ticket_id] && params[:article_id]
@ -332,12 +308,6 @@ class TicketsController < ApplicationController
split[:ticket_id] = ticket.id
assets = ticket.assets(assets)
owner_ids = []
ticket.agent_of_group.each { |user|
owner_ids.push user.id
assets = user.assets(assets)
}
# get related articles
article = Ticket::Article.find( params[:article_id] )
split[:article_id] = article.id
@ -348,7 +318,7 @@ class TicketsController < ApplicationController
render :json => {
:split => split,
:assets => assets,
:edit_form => attributes_to_change,
:form_meta => attributes_to_change,
}
end

View 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

View file

@ -56,6 +56,8 @@ class Ticket < ApplicationModel
belongs_to :create_article_type, :class_name => 'Ticket::Article::Type'
belongs_to :create_article_sender, :class_name => 'Ticket::Article::Sender'
self.inheritance_column = nil
attr_accessor :callback_loop
=begin

View file

@ -50,6 +50,9 @@ returns
params[:article] = self.find( params[:article_id] )
end
filter = {}
assets = {}
# get ticket states
state_ids = []
if params[:ticket]
@ -63,44 +66,21 @@ returns
state_type = Ticket::StateType.where( :name => type ).first
if state_type
state_type.states.each {|state|
assets = state.assets(assets)
state_ids.push state.id
}
end
}
# get owner
owner_ids = []
if params[:ticket]
params[:ticket].agent_of_group.each { |user|
owner_ids.push user.id
}
end
# get group
group_ids = []
Group.where( :active => true ).each { |group|
group_ids.push group.id
}
# get group / user relations
agents = {}
Ticket::ScreenOptions.agents.each { |user|
agents[ user.id ] = 1
}
groups_users = {}
group_ids.each {|group_id|
groups_users[ group_id ] = []
Group.find( group_id ).users.each {|user|
next if !agents[ user.id ]
groups_users[ group_id ].push user.id
}
}
filter[:state_id] = state_ids
# get priorities
priority_ids = []
Ticket::Priority.where( :active => true ).each { |priority|
assets = priority.assets(assets)
priority_ids.push priority.id
}
filter[:priority_id] = priority_ids
type_ids = []
if params[:ticket]
@ -115,14 +95,29 @@ returns
end
}
end
filter[:type_id] = type_ids
# get group / user relations
agents = {}
Ticket::ScreenOptions.agents.each { |user|
agents[ user.id ] = 1
}
dependencies = { :group_id => { '' => [] } }
Group.where( :active => true ).each { |group|
assets = group.assets(assets)
dependencies[:group_id][group.id] = { :owner_id => [] }
group.users.each {|user|
next if !agents[ user.id ]
assets = user.assets(assets)
dependencies[:group_id][ group.id ][ :owner_id ].push user.id
}
}
return {
:type_id => type_ids,
:state_id => state_ids,
:priority_id => priority_ids,
:owner_id => owner_ids,
:group_id => group_ids,
:group_id__owner_id => groups_users,
:assets => assets,
:filter => filter,
:dependencies => dependencies,
}
end
@ -131,8 +126,8 @@ returns
list tickets by customer groupd in state categroie open and closed
result = Ticket::ScreenOptions.list_by_customer(
:customer_id => 123,
:limit => 15, # optional, default 15
:customer_id => 123,
:limit => 15, # optional, default 15
)
returns
@ -152,13 +147,13 @@ returns
# get tickets
tickets_open = Ticket.where(
:customer_id => data[:customer_id],
:state_id => state_list_open
:customer_id => data[:customer_id],
:state_id => state_list_open
).limit( data[:limit] || 15 ).order('created_at DESC')
tickets_closed = Ticket.where(
:customer_id => data[:customer_id],
:state_id => state_list_closed
:customer_id => data[:customer_id],
:state_id => state_list_closed
).limit( data[:limit] || 15 ).order('created_at DESC')
return {

File diff suppressed because it is too large Load diff

View file

@ -16,6 +16,16 @@ module SessionHelper
return default_collection, assets
end
def self.models(user = nil)
models = {}
objects = ObjectManager.listObjects
objects.each {|object|
attributes = ObjectManager::Attribute.by_object(object, user)
models[object] = attributes
}
models
end
def self.cleanup_expired
# web sessions

View file

@ -495,3 +495,54 @@ test( "form selector", function() {
deepEqual( params, test_params, 'form param check via $("#form").parent()' );
});
test( "form required_if + shown_if", function() {
$('#forms').append('<hr><h1>form required_if + shown_if</h1><div><form id="form7"></form></div>')
var el = $('#form7')
var defaults = {
input2: 'some name66',
}
new App.ControllerForm({
el: el,
model: {
configure_attributes: [
{ name: 'input1', display: 'Input1', tag: 'input', type: 'text', limit: 100, null: true, default: 'some not used default33' },
{ name: 'input2', display: 'Input2', tag: 'input', type: 'text', limit: 100, null: true, default: 'some used default', required_if: { active: true }, shown_if: { active: true } },
{ name: 'active', display: 'Active', tag: 'boolean', type: 'boolean', 'default': true, null: false },
],
},
params: defaults,
});
test_params = {
input1: "some not used default33",
input2: "some name66",
active: true
};
params = App.ControllerForm.params( el )
deepEqual( params, test_params, 'form param check via $("#form")' );
equal( el.find('[name="input2"]').attr('required'), 'required', 'check required attribute of input2 ')
equal( el.find('[name="input2"]').is(":visible"), true, 'check visible attribute of input2 ')
el.find('[name="active"]').val('{boolean}::false').trigger('change')
test_params = {
input1: "some not used default33",
active: false
};
params = App.ControllerForm.params( el )
deepEqual( params, test_params, 'form param check via $("#form")' );
equal( el.find('[name="input2"]').attr('required'), undefined, 'check required attribute of input2 ')
equal( el.find('[name="input2"]').is(":visible"), false, 'check visible attribute of input2 ')
el.find('[name="active"]').val('{boolean}::true').trigger('change')
test_params = {
input1: "some not used default33",
input2: "some name66",
active: true
};
params = App.ControllerForm.params( el )
deepEqual( params, test_params, 'form param check via $("#form")' );
equal( el.find('[name="input2"]').attr('required'), 'required', 'check required attribute of input2 ')
equal( el.find('[name="input2"]').is(":visible"), true, 'check visible attribute of input2 ')
});

View 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')
});

View file

@ -111,8 +111,9 @@ class AgentTicketActionsLevel3Test < TestCase
{
:where => :instance2,
:execute => 'match',
:css => '.content_permanent.active',
:value => 'Discard your unsaved changes.',
:css => '.content_permanent.active .reset-message',
:value => '(Discard your unsaved changes.|Verwerfen der)',
:no_quote => true,
:match_result => true,
},
{
@ -127,8 +128,9 @@ class AgentTicketActionsLevel3Test < TestCase
{
:where => :instance2,
:execute => 'match',
:css => '.content_permanent.active',
:value => 'Discard your unsaved changes.',
:css => '.content_permanent.active .reset-message',
:value => '(Discard your unsaved changes.|Verwerfen der)',
:no_quote => true,
:match_result => false,
},
@ -150,8 +152,9 @@ class AgentTicketActionsLevel3Test < TestCase
{
:where => :instance1,
:execute => 'match',
:css => '.content_permanent.active',
:value => 'Discard your unsaved changes.',
:css => '.content_permanent.active .reset-message',
:value => '(Discard your unsaved changes.|Verwerfen der)',
:no_quote => true,
:match_result => true,
},
@ -204,8 +207,9 @@ class AgentTicketActionsLevel3Test < TestCase
{
:where => :instance1,
:execute => 'match',
:css => '.content_permanent.active',
:value => 'Discard your unsaved changes.',
:css => '.content_permanent.active .reset-message',
:value => '(Discard your unsaved changes.|Verwerfen der)',
:no_quote => true,
:match_result => false,
},
{
@ -219,8 +223,9 @@ class AgentTicketActionsLevel3Test < TestCase
{
:where => :instance2,
:execute => 'match',
:css => '.content_permanent.active',
:value => 'Discard your unsaved changes.',
:css => '.content_permanent.active .reset-message',
:value => '(Discard your unsaved changes.|Verwerfen der)',
:no_quote => true,
:match_result => false,
},
@ -246,8 +251,9 @@ class AgentTicketActionsLevel3Test < TestCase
{
:where => :instance1,
:execute => 'match',
:css => '.content_permanent.active',
:value => 'Discard your unsaved changes.',
:css => '.content_permanent.active .reset-message',
:value => '(Discard your unsaved changes.|Verwerfen der)',
:no_quote => true,
:match_result => false,
},
{
@ -261,8 +267,9 @@ class AgentTicketActionsLevel3Test < TestCase
{
:where => :instance2,
:execute => 'match',
:css => '.content_permanent.active',
:value => 'Discard your unsaved changes.',
:css => '.content_permanent.active .reset-message',
:value => '(Discard your unsaved changes.|Verwerfen der)',
:no_quote => true,
:match_result => false,
},
@ -280,8 +287,9 @@ class AgentTicketActionsLevel3Test < TestCase
{
:where => :instance2,
:execute => 'match',
:css => '.content_permanent.active',
:value => 'Discard your unsaved changes.',
:css => '.content_permanent.active .reset-message',
:value => '(Discard your unsaved changes.|Verwerfen der)',
:no_quote => true,
:match_result => true,
},
{
@ -298,8 +306,9 @@ class AgentTicketActionsLevel3Test < TestCase
{
:where => :instance2,
:execute => 'match',
:css => '.content_permanent.active',
:value => 'Discard your unsaved changes.',
:css => '.content_permanent.active .reset-message',
:value => '(Discard your unsaved changes.|Verwerfen der)',
:no_quote => true,
:match_result => true,
},
{
@ -315,7 +324,9 @@ class AgentTicketActionsLevel3Test < TestCase
:where => :instance2,
:execute => 'match',
:css => '.content_permanent.active',
:value => 'Discard your unsaved changes.',
:css => '.content_permanent.active .reset-message',
:value => '(Discard your unsaved changes.|Verwerfen der)',
:no_quote => true,
:match_result => false,
},
{

View file

@ -3,8 +3,8 @@ require 'browser_test_helper'
class AgentTicketActionLevel5Test < TestCase
def test_I
random = 'text_module_test_' + rand(999999).to_s
random2 = 'text_module_test_' + rand(999999).to_s
random = 'text_module_test_' + rand(99999999).to_s
random2 = 'text_module_test_' + rand(99999999).to_s
# user
tests = [
@ -153,9 +153,9 @@ class AgentTicketActionLevel5Test < TestCase
browser_signle_test_with_login(tests, { :username => 'master@example.com' })
end
def test_II
random = 'text_II_module_test_' + rand(999999).to_s
random = 'text_II_module_test_' + rand(99999999).to_s
user_rand = rand(999999).to_s
user_rand = rand(99999999).to_s
login = 'agent-text-module-' + user_rand
firstname = 'Text' + user_rand
lastname = 'Module' + user_rand
@ -191,7 +191,7 @@ class AgentTicketActionLevel5Test < TestCase
{
:where => :instance2,
:execute => 'set',
:css => '.active input[name=subject]',
:css => '.active input[name=title]',
:value => 'A',
},
{
@ -207,7 +207,7 @@ class AgentTicketActionLevel5Test < TestCase
{
:where => :instance2,
:execute => 'set',
:css => '.active input[name=subject]',
:css => '.active input[name=title]',
:value => 'B',
},
@ -330,7 +330,7 @@ class AgentTicketActionLevel5Test < TestCase
{
:where => :instance2,
:execute => 'set',
:css => '.active .ticket_create input[name="customer_id_autocompletion"]',
:css => '.active .ticket-create input[name="customer_id_autocompletion"]',
:value => 'nicole',
},
{
@ -340,13 +340,13 @@ class AgentTicketActionLevel5Test < TestCase
{
:where => :instance2,
:execute => 'sendkey',
:css => '.active .ticket_create input[name="customer_id_autocompletion"]',
:css => '.active .ticket-create input[name="customer_id_autocompletion"]',
:value => :arrow_down,
},
{
:where => :instance2,
:execute => 'sendkey',
:css => '.active .ticket_create input[name="customer_id_autocompletion"]',
:css => '.active .ticket-create input[name="customer_id_autocompletion"]',
:value => :tab,
},
{
@ -425,7 +425,7 @@ class AgentTicketActionLevel5Test < TestCase
},
{
:execute => 'wait',
:value => 4,
:value => 2,
},
{
:where => :instance2,
@ -536,7 +536,7 @@ class AgentTicketActionLevel5Test < TestCase
},
{
:execute => 'wait',
:value => 0.2,
:value => 0.5,
},
# {
# :where => :instance2,

View file

@ -142,7 +142,7 @@ class AgentUserManageTest < TestCase
},
{
:execute => 'set',
:css => '.active .ticket_create input[name="customer_id_autocompletion"]',
:css => '.active .ticket-create input[name="customer_id_autocompletion"]',
:value => customer_user_email,
},
{
@ -151,12 +151,12 @@ class AgentUserManageTest < TestCase
},
{
:execute => 'sendkey',
:css => '.active .ticket_create input[name="customer_id_autocompletion"]',
:css => '.active .ticket-create input[name="customer_id_autocompletion"]',
:value => :arrow_down,
},
{
:execute => 'sendkey',
:css => '.active .ticket_create input[name="customer_id_autocompletion"]',
:css => '.active .ticket-create input[name="customer_id_autocompletion"]',
:value => :tab,
},
{

View file

@ -27,7 +27,7 @@ class CustomerTicketCreateTest < TestCase
},
{
:execute => 'set',
:css => '.ticket-create input[name="subject"]',
:css => '.ticket-create input[name="title"]',
:value => 'some subject 123äöü',
},
{

View file

@ -32,12 +32,12 @@ class TaskbarTaskTest < TestCase
},
{
:execute => 'check',
:css => '.active .ticket_create',
:css => '.active .ticket-create',
:result => true,
},
{
:execute => 'set',
:css => '.active .ticket_create input[name="subject"]',
:css => '.active .ticket-create input[name="title"]',
:value => 'some test AAA',
},
{
@ -113,7 +113,7 @@ class TaskbarTaskTest < TestCase
},
{
:execute => 'set',
:css => '.active .ticket_create input[name="subject"]',
:css => '.active .ticket-create input[name="title"]',
:value => 'INBOUND TEST#1',
},
{
@ -122,7 +122,7 @@ class TaskbarTaskTest < TestCase
},
{
:execute => 'set',
:css => '.active .ticket_create textarea[name="body"]',
:css => '.active .ticket-create textarea[name="body"]',
:value => 'INBOUND BODY TEST#1',
},
{
@ -139,7 +139,7 @@ class TaskbarTaskTest < TestCase
},
{
:execute => 'set',
:css => '.active .ticket_create input[name="subject"]',
:css => '.active .ticket-create input[name="title"]',
:value => 'OUTBOUND TEST#1',
},
{
@ -148,7 +148,7 @@ class TaskbarTaskTest < TestCase
},
{
:execute => 'set',
:css => '.active .ticket_create textarea[name="body"]',
:css => '.active .ticket-create textarea[name="body"]',
:value => 'OUTBOUND BODY TEST#1',
},
{

View file

@ -297,40 +297,40 @@ class TestCase < Test::Unit::TestCase
elsif action[:execute] == 'create_ticket'
instance.find_element( { :css => 'a[href="#new"]' } ).click
instance.find_element( { :css => 'a[href="#ticket/create/call_inbound"]' } ).click
element = instance.find_element( { :css => '.active .ticket_create' } )
element = instance.find_element( { :css => '.active .ticket-create' } )
if !element
assert( false, "(#{test[:name]}) no ticket create screen found!" )
return
end
sleep 2
element = instance.find_element( { :css => '.active .ticket_create input[name="customer_id_autocompletion"]' } )
element = instance.find_element( { :css => '.active .ticket-create input[name="customer_id_autocompletion"]' } )
element.clear
element.send_keys( 'nico*' )
sleep 4
element = instance.find_element( { :css => '.active .ticket_create input[name="customer_id_autocompletion"]' } )
element = instance.find_element( { :css => '.active .ticket-create input[name="customer_id_autocompletion"]' } )
element.send_keys( :arrow_down )
sleep 0.2
element = instance.find_element( { :css => '.active .ticket_create input[name="customer_id_autocompletion"]' } )
element = instance.find_element( { :css => '.active .ticket-create input[name="customer_id_autocompletion"]' } )
element.send_keys( :tab )
sleep 0.1
element = instance.find_element( { :css => '.active .ticket_create select[name="group_id"]' } )
element = instance.find_element( { :css => '.active .ticket-create select[name="group_id"]' } )
dropdown = Selenium::WebDriver::Support::Select.new(element)
dropdown.select_by( :text, action[:group])
sleep 0.1
element = instance.find_element( { :css => '.active .ticket_create input[name="subject"]' } )
element = instance.find_element( { :css => '.active .ticket-create input[name="title"]' } )
element.clear
element.send_keys( action[:subject] )
sleep 0.1
element = instance.find_element( { :css => '.active .ticket_create textarea[name="body"]' } )
element = instance.find_element( { :css => '.active .ticket-create textarea[name="body"]' } )
element.clear
element.send_keys( action[:body] )
if action[:do_not_submit]
assert( true, "(#{test[:name]}) ticket created without submit" )
return
end
sleep 0.5
sleep 0.8
instance.find_element( { :css => '.active .form-actions button[type="submit"]' } ).click
sleep 2
sleep 1
(1..14).each {|loop|
if instance.current_url =~ /#{Regexp.quote('#ticket/zoom/')}/
assert( true, "(#{test[:name]}) ticket created" )
@ -338,7 +338,7 @@ class TestCase < Test::Unit::TestCase
end
sleep 0.5
}
assert( true, "(#{test[:name]}) ticket creation failed, can't get zoom url" )
assert( false, "(#{test[:name]}) ticket creation failed, can't get zoom url" )
return
elsif action[:execute] == 'close_all_tasks'
for i in 1..100