Splited ticket sidebar into separate backend to make it pluggable.

This commit is contained in:
Martin Edenhofer 2017-03-15 11:29:56 +01:00
parent 6ce85513f9
commit 22e8836cff
10 changed files with 272 additions and 202 deletions

View file

@ -621,10 +621,10 @@ class App.ActionRow extends App.Controller
for item in @items for item in @items
do (item) => do (item) =>
@$('[data-type="' + item.name + '"]').on( @$('[data-type="' + item.name + '"]').on(
'click', 'click'
(e) -> (e) =>
e.preventDefault() e.preventDefault()
item.callback() item.callback(@el)
) )
class App.Sidebar extends App.Controller class App.Sidebar extends App.Controller
@ -657,24 +657,25 @@ class App.Sidebar extends App.Controller
@toggleTabAction(name) @toggleTabAction(name)
render: => render: =>
@html App.view('generic/sidebar_tabs') localEl = $(App.view('generic/sidebar_tabs')(
items: @items items: @items
scrollbarWidth: App.Utils.getScrollBarWidth() scrollbarWidth: App.Utils.getScrollBarWidth()
))
# init content callback # init content callback
for item in @items for item in @items
area = localEl.filter('.sidebar[data-tab="' + item.name + '"]')
if item.callback if item.callback
item.callback( @$( '.sidebar[data-tab="' + item.name + '"] .sidebar-content' ) ) item.callback( area.find('.sidebar-content') )
# add item acctions
for item in @items
if item.actions if item.actions
new App.ActionRow( new App.ActionRow(
el: @$('.sidebar[data-tab="' + item.name + '"] .js-actions') el: area.find('.js-actions')
items: item.actions items: item.actions
type: 'small' type: 'small'
) )
@html localEl
toggleDropdown: (e) -> toggleDropdown: (e) ->
e.stopPropagation() e.stopPropagation()
$(e.currentTarget).next('.js-actions').find('.dropdown-toggle').dropdown('toggle') $(e.currentTarget).next('.js-actions').find('.dropdown-toggle').dropdown('toggle')

View file

@ -486,14 +486,10 @@ class App.TicketZoom extends App.Controller
) )
if @sidebar if @sidebar
@sidebar.reload(
# update tags tags: @tags
if @sidebar.tagWidget links: @links
@sidebar.tagWidget.reload(@tags) )
# update links
if @sidebar.linkWidget
@sidebar.linkWidget.reload(@links)
if !@initDone if !@initDone
if @article_id if @article_id
@ -681,12 +677,12 @@ class App.TicketZoom extends App.Controller
callback: callback:
tagAdd: (tag) => tagAdd: (tag) =>
return if !@sidebar return if !@sidebar
return if !@sidebar.tagWidget return if !@sidebar.reload
@sidebar.tagWidget.add(tag) @sidebar.reload(tagAdd: tag)
tagRemove: (tag) => tagRemove: (tag) =>
return if !@sidebar return if !@sidebar
return if !@sidebar.tagWidget return if !@sidebar.reload
@sidebar.tagWidget.remove(tag) @sidebar.reload(tagRemove: tag)
) )
# set defaults # set defaults

View file

@ -1,182 +1,30 @@
class Edit extends App.ObserverController
model: 'Ticket'
observeNot:
created_at: true
updated_at: true
globalRerender: false
render: (ticket, diff) =>
defaults = ticket.attributes()
delete defaults.article # ignore article infos
taskState = @taskGet('ticket')
if !_.isEmpty(taskState)
defaults = _.extend(defaults, taskState)
new App.ControllerForm(
elReplace: @el
model: App.Ticket
screen: 'edit'
handlers: [
@ticketFormChanges
]
filter: @formMeta.filter
params: defaults
#bookmarkable: true
)
@markForm(true)
return if @resetBind
@resetBind = true
@bind('ui::ticket::taskReset', (data) =>
return if data.ticket_id.toString() isnt ticket.id.toString()
@render(ticket)
)
class App.TicketZoomSidebar extends App.ObserverController class App.TicketZoomSidebar extends App.ObserverController
model: 'Ticket' model: 'Ticket'
observe: observe:
customer_id: true customer_id: true
organization_id: true organization_id: true
render: (ticket) => reload: (args) =>
editTicket = (el) => for key, backend of @sidebarBackends
el.append(App.view('ticket_zoom/sidebar_ticket')()) if backend && backend.reload
backend.reload(args)
@edit = new Edit( render: (ticket) =>
object_id: ticket.id @sidebarBackends = {}
el: el.find('.edit') @sidebarItems = []
sidebarBackends = App.Config.get('TicketZoomSidebar')
keys = _.keys(sidebarBackends).sort()
for key in keys
@sidebarBackends[key] = new sidebarBackends[key](
ticket: ticket
taskGet: @taskGet taskGet: @taskGet
formMeta: @formMeta formMeta: @formMeta
markForm: @markForm markForm: @markForm
) )
item = @sidebarBackends[key].sidebarItem()
if item
@sidebarItems.push item
if @permissionCheck('ticket.agent')
@tagWidget = new App.WidgetTag(
el: @el.find('.tags')
object_type: 'Ticket'
object: ticket
tags: @tags
)
@linkWidget = new App.WidgetLink(
el: @el.find('.links')
object_type: 'Ticket'
object: ticket
links: @links
)
@timeUnitWidget = new App.TicketZoomTimeUnit(
el: @el.find('.js-timeUnit')
object_id: ticket.id
)
showTicketHistory = =>
new App.TicketHistory(
ticket_id: ticket.id
container: @el.closest('.content')
)
showTicketMerge = =>
new App.TicketMerge(
ticket: ticket
task_key: @task_key
container: @el.closest('.content')
)
changeCustomer = (e, el) =>
new App.TicketCustomer(
ticket_id: ticket.id
container: @el.closest('.content')
)
@sidebarItems = [
{
head: 'Ticket'
name: 'ticket'
icon: 'message'
callback: editTicket
}
]
if @permissionCheck('ticket.agent')
@sidebarItems[0]['actions'] = [
{
name: 'ticket-history'
title: 'History'
callback: showTicketHistory
},
{
name: 'ticket-merge'
title: 'Merge'
callback: showTicketMerge
},
{
title: 'Change Customer'
name: 'customer-change'
callback: changeCustomer
},
]
if @permissionCheck('ticket.agent')
editCustomer = (e, el) =>
new App.ControllerGenericEdit(
id: ticket.customer_id
genericObject: 'User'
screen: 'edit'
pageData:
title: 'Users'
object: 'User'
objects: 'Users'
container: @el.closest('.content')
)
showCustomer = (el) ->
new App.WidgetUser(
el: el
user_id: ticket.customer_id
)
@sidebarItems.push {
head: 'Customer'
name: 'customer'
icon: 'person'
actions: [
{
title: 'Change Customer'
name: 'customer-change'
callback: changeCustomer
},
{
title: 'Edit Customer'
name: 'customer-edit'
callback: editCustomer
},
]
callback: showCustomer
}
if ticket.organization_id
editOrganization = (e, el) =>
new App.ControllerGenericEdit(
id: ticket.organization_id,
genericObject: 'Organization'
pageData:
title: 'Organizations'
object: 'Organization'
objects: 'Organizations'
container: @el.closest('.content')
)
showOrganization = (el) ->
new App.WidgetOrganization(
el: el
organization_id: ticket.organization_id
)
@sidebarItems.push {
head: 'Organization'
name: 'organization'
icon: 'group'
actions: [
{
title: 'Edit Organization'
name: 'organization-edit'
callback: editOrganization
},
]
callback: showOrganization
}
new App.Sidebar( new App.Sidebar(
el: @el.find('.tabsSidebar') el: @el.find('.tabsSidebar')
sidebarState: @sidebarState sidebarState: @sidebarState

View file

@ -0,0 +1,48 @@
class SidebarCustomer extends App.Controller
sidebarItem: =>
return if !@permissionCheck('ticket.agent')
{
head: 'Customer'
name: 'customer'
icon: 'person'
actions: [
{
title: 'Change Customer'
name: 'customer-change'
callback: @changeCustomer
},
{
title: 'Edit Customer'
name: 'customer-edit'
callback: @editCustomer
},
]
callback: @showCustomer
}
showCustomer: (el) =>
@el = el
new App.WidgetUser(
el: @el
user_id: @ticket.customer_id
)
editCustomer: =>
new App.ControllerGenericEdit(
id: @ticket.customer_id
genericObject: 'User'
screen: 'edit'
pageData:
title: 'Users'
object: 'User'
objects: 'Users'
container: @el.closest('.content')
)
changeCustomer: =>
new App.TicketCustomer(
ticket_id: @ticket.id
container: @el.closest('.content')
)
App.Config.set('200-Customer', SidebarCustomer, 'TicketZoomSidebar')

View file

@ -0,0 +1,36 @@
class SidebarOrganization extends App.Controller
sidebarItem: =>
return if !@ticket.organization_id
{
head: 'Organization'
name: 'organization'
icon: 'group'
actions: [
{
title: 'Edit Organization'
name: 'organization-edit'
callback: @editOrganization
},
]
callback: @showOrganization
}
showOrganization: (el) =>
@el = el
new App.WidgetOrganization(
el: @el
organization_id: @ticket.organization_id
)
editOrganization: =>
new App.ControllerGenericEdit(
id: @ticket.organization_id,
genericObject: 'Organization'
pageData:
title: 'Organizations'
object: 'Organization'
objects: 'Organizations'
container: @el.closest('.content')
)
App.Config.set('300-Organization', SidebarOrganization, 'TicketZoomSidebar')

View file

@ -0,0 +1,130 @@
class Edit extends App.ObserverController
model: 'Ticket'
observeNot:
created_at: true
updated_at: true
globalRerender: false
render: (ticket, diff) =>
defaults = ticket.attributes()
delete defaults.article # ignore article infos
taskState = @taskGet('ticket')
if !_.isEmpty(taskState)
defaults = _.extend(defaults, taskState)
new App.ControllerForm(
elReplace: @el
model: App.Ticket
screen: 'edit'
handlers: [
@ticketFormChanges
]
filter: @formMeta.filter
params: defaults
#bookmarkable: true
)
@markForm(true)
return if @resetBind
@resetBind = true
@bind('ui::ticket::taskReset', (data) =>
return if data.ticket_id.toString() isnt ticket.id.toString()
@render(ticket)
)
class SidebarTicket extends App.Controller
sidebarItem: =>
sidebarItem = {
head: 'Ticket'
name: 'ticket'
icon: 'message'
callback: @editTicket
}
if @permissionCheck('ticket.agent')
sidebarItem['actions'] = [
{
title: 'History'
name: 'ticket-history'
callback: @showTicketHistory
},
{
title: 'Merge'
name: 'ticket-merge'
callback: @showTicketMerge
},
{
title: 'Change Customer'
name: 'customer-change'
callback: @changeCustomer
},
]
sidebarItem
reload: (args) =>
# apply tag changes
if @tagWidget
if args.tags
@tagWidget.reload(args.tags)
if args.tagAdd
@tagWidget.add(args.tagAdd)
if args.tagRemove
@tagWidget.remove(args.tagRemove)
# apply link changes
if @linkWidget && args.links
@linkWidget.reload(args.links)
editTicket: (el) =>
@el = el
localEl = $( App.view('ticket_zoom/sidebar_ticket')() )
@edit = new Edit(
object_id: @ticket.id
el: localEl.find('.edit')
taskGet: @taskGet
formMeta: @formMeta
markForm: @markForm
)
if @permissionCheck('ticket.agent')
@tagWidget = new App.WidgetTag(
el: localEl.filter('.tags')
object_type: 'Ticket'
object: @ticket
tags: @tags
)
@linkWidget = new App.WidgetLink(
el: localEl.filter('.links')
object_type: 'Ticket'
object: @ticket
links: @links
)
@timeUnitWidget = new App.TicketZoomTimeUnit(
el: localEl.filter('.js-timeUnit')
object_id: @ticket.id
)
@html localEl
showTicketHistory: =>
new App.TicketHistory(
ticket_id: @ticket.id
container: @el.closest('.content')
)
showTicketMerge: =>
new App.TicketMerge(
ticket: @ticket
task_key: @task_key
container: @el.closest('.content')
)
changeCustomer: =>
new App.TicketCustomer(
ticket_id: @ticket.id
container: @el.closest('.content')
)
App.Config.set('100-TicketEdit', SidebarTicket, 'TicketZoomSidebar')

View file

@ -185,4 +185,14 @@ class App.LinkAdd extends App.ControllerModal
success: (data, status, xhr) => success: (data, status, xhr) =>
@close() @close()
@parent.fetch() @parent.fetch()
error: (xhr, statusText, error) =>
detailsRaw = xhr.responseText
details = {}
if !_.isEmpty(detailsRaw)
details = JSON.parse(detailsRaw)
@notify(
type: 'error'
msg: App.i18n.translateContent(details.error)
removeAll: true
)
) )

View file

@ -53,9 +53,8 @@ class App.WidgetTag extends App.Controller
@html App.view('widget/tag')( @html App.view('widget/tag')(
tags: @localTags || [], tags: @localTags || [],
) )
source = "#{App.Config.get('api_path')}/tag_search" source = "#{App.Config.get('api_path')}/tag_search"
@el.find('.js-newTagInput').autocomplete( @$('.js-newTagInput').autocomplete(
source: source source: source
minLength: 2 minLength: 2
response: (e, ui) => response: (e, ui) =>

View file

@ -8,9 +8,7 @@
</div> </div>
</div> </div>
<hr> <hr>
<div class="sidebar-content"></div> <div class="sidebar-content"></div>
</div> </div>
<% end %> <% end %>
<div class="tabsSidebar-tabs" style="margin-left: -<%- @scrollbarWidth %>px"> <div class="tabsSidebar-tabs" style="margin-left: -<%- @scrollbarWidth %>px">

View file

@ -30,14 +30,18 @@ class LinksController < ApplicationController
# POST /api/v1/links/add # POST /api/v1/links/add
def add def add
# lookup object id object = Ticket.find_by(number: params[:link_object_source_number])
object_id = Ticket.where( number: params[:link_object_source_number] ).first.id if !object
render json: { error: 'No such object!' }, status: :unprocessable_entity
return
end
link = Link.add( link = Link.add(
link_type: params[:link_type], link_type: params[:link_type],
link_object_target: params[:link_object_target], link_object_target: params[:link_object_target],
link_object_target_value: params[:link_object_target_value], link_object_target_value: params[:link_object_target_value],
link_object_source: params[:link_object_source], link_object_source: params[:link_object_source],
link_object_source_value: object_id link_object_source_value: object.id,
) )
if link if link