Merge branch 'develop' of github.com:martini/zammad into develop

This commit is contained in:
Felix Niklas 2015-11-17 15:52:54 +01:00
commit fe572ae54b
15 changed files with 191 additions and 220 deletions

View file

@ -505,10 +505,10 @@ class App.Controller extends Spine.Controller
# central method, is getting called on every ticket form change # central method, is getting called on every ticket form change
ticketFormChanges: (params, attribute, attributes, classname, form, ui) => ticketFormChanges: (params, attribute, attributes, classname, form, ui) =>
if @form_meta.dependencies && @form_meta.dependencies[attribute.name] if @formMeta.dependencies && @formMeta.dependencies[attribute.name]
dependency = @form_meta.dependencies[attribute.name][ parseInt(params[attribute.name]) ] dependency = @formMeta.dependencies[attribute.name][ parseInt(params[attribute.name]) ]
if !dependency if !dependency
dependency = @form_meta.dependencies[attribute.name][ params[attribute.name] ] dependency = @formMeta.dependencies[attribute.name][ params[attribute.name] ]
if dependency if dependency
for fieldNameToChange of dependency for fieldNameToChange of dependency
filter = [] filter = []

View file

@ -12,12 +12,9 @@ class App.TicketCreate extends App.Controller
# check authentication # check authentication
if !@authenticate() if !@authenticate()
App.TaskManager.remove( @task_key ) App.TaskManager.remove(@task_key)
return return
# set title
@form_meta = undefined
# define default type # define default type
@default_type = 'phone-in' @default_type = 'phone-in'
@ -29,8 +26,6 @@ class App.TicketCreate extends App.Controller
# update navbar highlighting # update navbar highlighting
@navupdate '#ticket/create/id/' + @id + split @navupdate '#ticket/create/id/' + @id + split
@fetch(params)
# lisen if view need to be rerendered # lisen if view need to be rerendered
@bind 'ticket_create_rerender', (defaults) => @bind 'ticket_create_rerender', (defaults) =>
@log 'notice', 'error', defaults @log 'notice', 'error', defaults
@ -41,9 +36,11 @@ class App.TicketCreate extends App.Controller
return if !@authenticate(true) return if !@authenticate(true)
@render() @render()
# bind on new ticket_create_attributes updates load = (data) =>
@bind 'ticket_create_attributes', (data) => App.Collection.loadAssets(data.assets)
App.SessionStorage.set('ticket_create_attributes', data) @formMeta = data.form_meta
@buildScreen(params)
@bindId = App.TicketCreateCollection.one(load)
changeFormType: (e) => changeFormType: (e) =>
type = $(e.target).data('type') type = $(e.target).data('type')
@ -121,9 +118,6 @@ class App.TicketCreate extends App.Controller
return false if !diff || _.isEmpty( diff ) return false if !diff || _.isEmpty( diff )
return true return true
release: ->
# nothing
autosave: => autosave: =>
update = => update = =>
data = @formParam( @el.find('.ticket-create') ) data = @formParam( @el.find('.ticket-create') )
@ -135,42 +129,27 @@ class App.TicketCreate extends App.Controller
@interval( update, 3000, @id ) @interval( update, 3000, @id )
# get data / in case also ticket data for split # get data / in case also ticket data for split
fetch: (params) -> buildScreen: (params) =>
# use cache
cache = App.SessionStorage.get('ticket_create_attributes')
if cache && !params.ticket_id && !params.article_id
# get edit form attributes
@form_meta = cache.form_meta
# load assets
App.Collection.loadAssets(cache.assets)
if !params.ticket_id && !params.article_id
@render() @render()
else return
# fetch split ticket data
@ajax( @ajax(
id: 'ticket_create' + @task_key id: 'ticket_split' + @task_key
type: 'GET' type: 'GET'
url: @apiPath + '/ticket_create' url: @apiPath + '/ticket_split'
data: data:
ticket_id: params.ticket_id ticket_id: params.ticket_id
article_id: params.article_id article_id: params.article_id
processData: true processData: true
success: (data, status, xhr) => success: (data, status, xhr) =>
# cache request
App.SessionStorage.set('ticket_create_attributes', data)
# get edit form attributes
@form_meta = data.form_meta
# load assets # load assets
App.Collection.loadAssets(data.assets) App.Collection.loadAssets(data.assets)
# split ticket # prefill with split ticket
if data.split && data.split.ticket_id && data.split.article_id
t = App.Ticket.find( params.ticket_id ).attributes() t = App.Ticket.find( params.ticket_id ).attributes()
a = App.TicketArticle.find( params.article_id ) a = App.TicketArticle.find( params.article_id )
@ -259,7 +238,7 @@ class App.TicketCreate extends App.Controller
@ticketFormChanges, @ticketFormChanges,
signatureChanges, signatureChanges,
] ]
filter: @form_meta.filter filter: @formMeta.filter
autofocus: true autofocus: true
params: params params: params
) )
@ -282,7 +261,7 @@ class App.TicketCreate extends App.Controller
@ticketFormChanges, @ticketFormChanges,
signatureChanges, signatureChanges,
] ]
filter: @form_meta.filter filter: @formMeta.filter
params: params params: params
noFieldset: true noFieldset: true
) )
@ -297,7 +276,7 @@ class App.TicketCreate extends App.Controller
@ticketFormChanges, @ticketFormChanges,
signatureChanges, signatureChanges,
] ]
filter: @form_meta.filter filter: @formMeta.filter
params: params params: params
) )

View file

@ -13,45 +13,14 @@ 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)
@navupdate '#customer_ticket_new' @navupdate '#customer_ticket_new'
# get data / in case also ticket data for split load = (data) =>
fetch: (params) -> App.Collection.loadAssets(data.assets)
@formMeta = data.form_meta
# use cache
cache = App.SessionStorage.get( 'ticket_create_attributes' )
if cache
# get edit form attributes
@form_meta = cache.form_meta
# load assets
App.Collection.loadAssets( cache.assets )
@render() @render()
else @bindId = App.TicketCreateCollection.one(load)
@ajax(
id: 'ticket_create',
type: 'GET',
url: @apiPath + '/ticket_create',
processData: true,
success: (data, status, xhr) =>
# cache request
App.SessionStorage.set( 'ticket_create_attributes', data )
# get edit form attributes
@form_meta = data.form_meta
# load assets
App.Collection.loadAssets( data.assets )
@render()
)
render: (template = {}) -> render: (template = {}) ->
@ -62,7 +31,7 @@ class Index extends App.ControllerContent
if groupFilter if groupFilter
if !_.isArray(groupFilter) if !_.isArray(groupFilter)
groupFilter = [groupFilter] groupFilter = [groupFilter]
@form_meta.filter.group_id = groupFilter @formMeta.filter.group_id = groupFilter
@html App.view('customer_ticket_create')( @html App.view('customer_ticket_create')(
head: 'New Ticket' head: 'New Ticket'
@ -77,7 +46,7 @@ class Index extends App.ControllerContent
handlers: [ handlers: [
@ticketFormChanges @ticketFormChanges
] ]
filter: @form_meta.filter filter: @formMeta.filter
autofocus: true autofocus: true
params: defaults params: defaults
) )
@ -97,7 +66,7 @@ class Index extends App.ControllerContent
handlers: [ handlers: [
@ticketFormChanges @ticketFormChanges
] ]
filter: @form_meta.filter filter: @formMeta.filter
params: defaults params: defaults
noFieldset: true noFieldset: true
) )
@ -109,7 +78,7 @@ class Index extends App.ControllerContent
# handlers: [ # handlers: [
# formChanges # formChanges
# ] # ]
# filter: @form_meta.filter # filter: @formMeta.filter
# params: defaults # params: defaults
#) #)

View file

@ -17,7 +17,7 @@ class App.TicketZoom extends App.Controller
App.TaskManager.remove(@task_key) App.TaskManager.remove(@task_key)
return return
@form_meta = undefined @formMeta = undefined
@ticket_id = params.ticket_id @ticket_id = params.ticket_id
@article_id = params.article_id @article_id = params.article_id
@sidebarState = {} @sidebarState = {}
@ -235,7 +235,7 @@ class App.TicketZoom extends App.Controller
@tags = data.tags @tags = data.tags
# get edit form attributes # get edit form attributes
@form_meta = data.form_meta @formMeta = data.form_meta
# load assets # load assets
App.Collection.loadAssets(data.assets) App.Collection.loadAssets(data.assets)
@ -331,7 +331,7 @@ class App.TicketZoom extends App.Controller
ticket: @ticket ticket: @ticket
ticket_id: @ticket.id ticket_id: @ticket.id
el: @$('.article-new') el: @$('.article-new')
form_meta: @form_meta formMeta: @formMeta
form_id: @form_id form_id: @form_id
defaults: @taskGet('article') defaults: @taskGet('article')
task_key: @task_key task_key: @task_key
@ -365,7 +365,7 @@ class App.TicketZoom extends App.Controller
task_key: @task_key task_key: @task_key
tags: @tags tags: @tags
links: @links links: @links
form_meta: @form_meta formMeta: @formMeta
) )
# show article # show article

View file

@ -33,7 +33,7 @@ class App.TicketZoomSidebar extends App.Controller
handlers: [ handlers: [
@ticketFormChanges @ticketFormChanges
] ]
filter: @form_meta.filter filter: @formMeta.filter
params: defaults params: defaults
#bookmarkable: true #bookmarkable: true
) )

View file

@ -0,0 +1,69 @@
class App._CollectionSingletonBase
event: 'to_be_defined'
restEndpoint: '/to_be_defined'
constructor: ->
@callbacks = {}
@counter = 0
# read from cache
cache = App.SessionStorage.get("collection-#{@event}")
if cache
@set(cache)
# websocket updates
App.Event.bind @event, (data) =>
@set(data)
@callback(data)
get: ->
@collection_data
set: (data) ->
App.SessionStorage.set("collection-#{@event}", data)
@collection_data = data
bind: (callback, init = true, one = false) ->
@counter += 1
# start init call if needed
if init
if @collection_data is undefined
@fetch()
else
callback(@collection_data)
return if one
@callbacks[@counter] =
callback: callback
one: one
unbind: (callback) ->
for counter, attr of @callbacks
if callback is attr.callback
delete @callbacks[counter]
fetch: =>
return if @fetchActive
@fetchActive = true
App.Ajax.request(
id: "collection-#{@event}"
type: 'GET'
url: App.Config.get('api_path') + @restEndpoint
processData: true
success: (data) =>
@fetchActive = false
@set(data)
@callback(data)
error: =>
@fetchActive = false
)
trigger: =>
@callback(@get())
callback: (data) =>
for counter, attr of @callbacks
attr.callback(data)
if attr.one
delete @callbacks[counter]

View file

@ -1,81 +1,24 @@
class _Singleton extends App._CollectionSingletonBase
event: 'ticket_overview_index'
restEndpoint: '/ticket_overviews'
class App.OverviewIndexCollection class App.OverviewIndexCollection
_instance = undefined # Must be declared here to force the closure on the class _instance = new _Singleton
@get: -> @get: ->
if _instance == undefined
_instance ?= new _Singleton
_instance.get() _instance.get()
@bind: (callback) -> @one: (callback, init = true) ->
if _instance == undefined _instance.bind(callback, init, true)
_instance ?= new _Singleton
_instance.bind(callback) @bind: (callback, init = true) ->
_instance.bind(callback, init, false)
@unbind: (callback) -> @unbind: (callback) ->
if _instance == undefined
_instance ?= new _Singleton
_instance.unbind(callback) _instance.unbind(callback)
@trigger: -> @trigger: ->
if _instance == undefined
_instance ?= new _Singleton
_instance.trigger() _instance.trigger()
@fetch: -> @fetch: ->
if _instance == undefined
_instance ?= new _Singleton
_instance.fetch() _instance.fetch()
# The actual Singleton class
class _Singleton
constructor: ->
@callbacks = {}
@counter = 0
# websocket updates
App.Event.bind 'ticket_overview_index', (data) =>
@overview_index = data
@callback(data)
get: ->
@overview_index
bind: (callback, init = true) ->
@counter += 1
# start init call if needed
if init
if @overview_index is undefined
@fetch()
else
@callback(@overview_index)
@callbacks[@counter] = callback
unbind: (callback) ->
for counter, localCallback of @callbacks
if callback is localCallback
delete @callbacks[counter]
fetch: =>
return if @fetchActive
@fetchActive = true
App.Ajax.request(
id: 'ticket_overviews',
type: 'GET',
url: App.Config.get('api_path') + '/ticket_overviews',
processData: true,
success: (data) =>
@fetchActive = false
@overview_index = data
@callback(data)
error: =>
@fetchActive = false
)
trigger: =>
@callback(@get())
callback: (data) =>
for counter, callback of @callbacks
callback(data)

View file

@ -0,0 +1,24 @@
class _Singleton extends App._CollectionSingletonBase
event: 'ticket_create_attributes'
restEndpoint: '/ticket_create'
class App.TicketCreateCollection
_instance = new _Singleton
@get: ->
_instance.get()
@one: (callback, init = true) ->
_instance.bind(callback, init, true)
@bind: (callback, init = true) ->
_instance.bind(callback, init, false)
@unbind: (callback) ->
_instance.unbind(callback)
@trigger: ->
_instance.trigger()
@fetch: ->
_instance.fetch()

View file

@ -169,7 +169,7 @@ class TicketsController < ApplicationController
def ticket_merge def ticket_merge
# check master ticket # check master ticket
ticket_master = Ticket.where( number: params[:master_ticket_number] ).first ticket_master = Ticket.find_by(number: params[:master_ticket_number])
if !ticket_master if !ticket_master
render json: { render json: {
result: 'faild', result: 'faild',
@ -182,7 +182,7 @@ class TicketsController < ApplicationController
return if !ticket_permission(ticket_master) return if !ticket_permission(ticket_master)
# check slave ticket # check slave ticket
ticket_slave = Ticket.where( id: params[:slave_ticket_id] ).first ticket_slave = Ticket.find_by(id: params[:slave_ticket_id] )
if !ticket_slave if !ticket_slave
render json: { render json: {
result: 'faild', result: 'faild',
@ -282,39 +282,31 @@ class TicketsController < ApplicationController
} }
end end
# GET /api/v1/ticket_create/1 # GET /api/v1/ticket_split
def ticket_split
# permission check
ticket = Ticket.find(params[:ticket_id])
return if !ticket_permission(ticket)
assets = ticket.assets({})
# get related articles
article = Ticket::Article.find(params[:article_id])
assets = article.assets(assets)
render json: {
assets: assets
}
end
# GET /api/v1/ticket_create
def ticket_create def ticket_create
# 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],
article_id: params[:article_id]
) )
render json: attributes_to_change
assets = attributes_to_change[:assets]
# split data
split = {}
if params[:ticket_id] && params[:article_id]
ticket = Ticket.find( params[:ticket_id] )
split[:ticket_id] = ticket.id
assets = ticket.assets(assets)
# get related articles
article = Ticket::Article.find( params[:article_id] )
split[:article_id] = article.id
assets = article.assets(assets)
end
# return result
render json: {
split: split,
assets: assets,
form_meta: {
filter: attributes_to_change[:filter],
dependencies: attributes_to_change[:dependencies],
}
}
end end
# GET /api/v1/tickets/search # GET /api/v1/tickets/search

View file

@ -27,10 +27,10 @@ returns
def self.attributes_to_change(params) def self.attributes_to_change(params)
if params[:ticket_id] if params[:ticket_id]
params[:ticket] = Ticket.find( params[:ticket_id] ) params[:ticket] = Ticket.find(params[:ticket_id])
end end
if params[:article_id] if params[:article_id]
params[:article] = Ticket::Article.find( params[:article_id] ) params[:article] = Ticket::Article.find(params[:article_id])
end end
filter = {} filter = {}
@ -46,7 +46,7 @@ returns
state_ids.push params[:ticket].state.id state_ids.push params[:ticket].state.id
end end
state_types.each {|type| state_types.each {|type|
state_type = Ticket::StateType.find_by( name: type ) state_type = Ticket::StateType.find_by(name: type)
next if !state_type next if !state_type
@ -59,7 +59,7 @@ returns
# 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) assets = priority.assets(assets)
priority_ids.push priority.id priority_ids.push priority.id
} }
@ -99,9 +99,11 @@ returns
{ {
assets: assets, assets: assets,
form_meta: {
filter: filter, filter: filter,
dependencies: dependencies, dependencies: dependencies,
} }
}
end end
=begin =begin

View file

@ -9,6 +9,7 @@ Zammad::Application.routes.draw do
match api_path + '/tickets', to: 'tickets#create', via: :post match api_path + '/tickets', to: 'tickets#create', via: :post
match api_path + '/tickets/:id', to: 'tickets#update', via: :put match api_path + '/tickets/:id', to: 'tickets#update', via: :put
match api_path + '/ticket_create', to: 'tickets#ticket_create', via: :get match api_path + '/ticket_create', to: 'tickets#ticket_create', via: :get
match api_path + '/ticket_split', to: 'tickets#ticket_split', via: :get
match api_path + '/ticket_full/:id', to: 'tickets#ticket_full', via: :get match api_path + '/ticket_full/:id', to: 'tickets#ticket_full', via: :get
match api_path + '/ticket_history/:id', to: 'tickets#ticket_history', via: :get match api_path + '/ticket_history/:id', to: 'tickets#ticket_history', via: :get
match api_path + '/ticket_customer', to: 'tickets#ticket_customer', via: :get match api_path + '/ticket_customer', to: 'tickets#ticket_customer', via: :get

View file

@ -39,17 +39,9 @@ class Sessions::Backend::TicketCreate
# set new timeout # set new timeout
Sessions::CacheIn.set( client_key, true, { expires_in: @ttl.seconds } ) Sessions::CacheIn.set( client_key, true, { expires_in: @ttl.seconds } )
ticket_create_attributes = load data = load
return if !ticket_create_attributes return if !data
data = {
assets: ticket_create_attributes[:assets],
form_meta: {
filter: ticket_create_attributes[:filter],
dependencies: ticket_create_attributes[:dependencies],
}
}
if !@client if !@client
return { return {

View file

@ -291,7 +291,7 @@ class TestCase < Test::Unit::TestCase
execute( execute(
browser: instance, browser: instance,
js: "\$('#{params[:css]}').get(0).scrollIntoView(true)", js: "\$('#{params[:css]}').get(0).scrollIntoView(false)",
mute_log: params[:mute_log] mute_log: params[:mute_log]
) )
sleep 0.4 sleep 0.4