From 22e8836cff3342dde15eedfdeb6cd319be0a8380 Mon Sep 17 00:00:00 2001 From: Martin Edenhofer Date: Wed, 15 Mar 2017 11:29:56 +0100 Subject: [PATCH] Splited ticket sidebar into separate backend to make it pluggable. --- .../_application_controller_generic.coffee | 23 ++- .../app/controllers/ticket_zoom.coffee | 20 +- .../controllers/ticket_zoom/sidebar.coffee | 188 ++---------------- .../ticket_zoom/sidebar_customer.coffee | 48 +++++ .../ticket_zoom/sidebar_organization.coffee | 36 ++++ .../ticket_zoom/sidebar_ticket.coffee | 130 ++++++++++++ .../app/controllers/widget/link.coffee | 10 + .../app/controllers/widget/tag.coffee | 3 +- .../app/views/generic/sidebar_tabs.jst.eco | 4 +- app/controllers/links_controller.rb | 12 +- 10 files changed, 272 insertions(+), 202 deletions(-) create mode 100644 app/assets/javascripts/app/controllers/ticket_zoom/sidebar_customer.coffee create mode 100644 app/assets/javascripts/app/controllers/ticket_zoom/sidebar_organization.coffee create mode 100644 app/assets/javascripts/app/controllers/ticket_zoom/sidebar_ticket.coffee diff --git a/app/assets/javascripts/app/controllers/_application_controller_generic.coffee b/app/assets/javascripts/app/controllers/_application_controller_generic.coffee index d2f1f8df8..553a7df9d 100644 --- a/app/assets/javascripts/app/controllers/_application_controller_generic.coffee +++ b/app/assets/javascripts/app/controllers/_application_controller_generic.coffee @@ -95,8 +95,8 @@ class App.ControllerGenericEdit extends App.ControllerModal class App.ControllerGenericIndex extends App.Controller events: 'click [data-type=edit]': 'edit' - 'click [data-type=new]': 'new' - 'click .js-description': 'description' + 'click [data-type=new]': 'new' + 'click .js-description': 'description' constructor: -> super @@ -621,10 +621,10 @@ class App.ActionRow extends App.Controller for item in @items do (item) => @$('[data-type="' + item.name + '"]').on( - 'click', - (e) -> + 'click' + (e) => e.preventDefault() - item.callback() + item.callback(@el) ) class App.Sidebar extends App.Controller @@ -657,24 +657,25 @@ class App.Sidebar extends App.Controller @toggleTabAction(name) render: => - @html App.view('generic/sidebar_tabs') + localEl = $(App.view('generic/sidebar_tabs')( items: @items scrollbarWidth: App.Utils.getScrollBarWidth() + )) # init content callback for item in @items + area = localEl.filter('.sidebar[data-tab="' + item.name + '"]') if item.callback - item.callback( @$( '.sidebar[data-tab="' + item.name + '"] .sidebar-content' ) ) - - # add item acctions - for item in @items + item.callback( area.find('.sidebar-content') ) if item.actions new App.ActionRow( - el: @$('.sidebar[data-tab="' + item.name + '"] .js-actions') + el: area.find('.js-actions') items: item.actions type: 'small' ) + @html localEl + toggleDropdown: (e) -> e.stopPropagation() $(e.currentTarget).next('.js-actions').find('.dropdown-toggle').dropdown('toggle') diff --git a/app/assets/javascripts/app/controllers/ticket_zoom.coffee b/app/assets/javascripts/app/controllers/ticket_zoom.coffee index e196d002e..ad3ddaf15 100644 --- a/app/assets/javascripts/app/controllers/ticket_zoom.coffee +++ b/app/assets/javascripts/app/controllers/ticket_zoom.coffee @@ -486,14 +486,10 @@ class App.TicketZoom extends App.Controller ) if @sidebar - - # update tags - if @sidebar.tagWidget - @sidebar.tagWidget.reload(@tags) - - # update links - if @sidebar.linkWidget - @sidebar.linkWidget.reload(@links) + @sidebar.reload( + tags: @tags + links: @links + ) if !@initDone if @article_id @@ -681,12 +677,12 @@ class App.TicketZoom extends App.Controller callback: tagAdd: (tag) => return if !@sidebar - return if !@sidebar.tagWidget - @sidebar.tagWidget.add(tag) + return if !@sidebar.reload + @sidebar.reload(tagAdd: tag) tagRemove: (tag) => return if !@sidebar - return if !@sidebar.tagWidget - @sidebar.tagWidget.remove(tag) + return if !@sidebar.reload + @sidebar.reload(tagRemove: tag) ) # set defaults diff --git a/app/assets/javascripts/app/controllers/ticket_zoom/sidebar.coffee b/app/assets/javascripts/app/controllers/ticket_zoom/sidebar.coffee index 2dd77dcb2..874922998 100644 --- a/app/assets/javascripts/app/controllers/ticket_zoom/sidebar.coffee +++ b/app/assets/javascripts/app/controllers/ticket_zoom/sidebar.coffee @@ -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 model: 'Ticket' observe: customer_id: true organization_id: true + reload: (args) => + for key, backend of @sidebarBackends + if backend && backend.reload + backend.reload(args) + render: (ticket) => - editTicket = (el) => - el.append(App.view('ticket_zoom/sidebar_ticket')()) - - @edit = new Edit( - object_id: ticket.id - el: el.find('.edit') - taskGet: @taskGet - formMeta: @formMeta - markForm: @markForm + @sidebarBackends = {} + @sidebarItems = [] + sidebarBackends = App.Config.get('TicketZoomSidebar') + keys = _.keys(sidebarBackends).sort() + for key in keys + @sidebarBackends[key] = new sidebarBackends[key]( + ticket: ticket + taskGet: @taskGet + formMeta: @formMeta + 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( el: @el.find('.tabsSidebar') sidebarState: @sidebarState diff --git a/app/assets/javascripts/app/controllers/ticket_zoom/sidebar_customer.coffee b/app/assets/javascripts/app/controllers/ticket_zoom/sidebar_customer.coffee new file mode 100644 index 000000000..701a151b6 --- /dev/null +++ b/app/assets/javascripts/app/controllers/ticket_zoom/sidebar_customer.coffee @@ -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') diff --git a/app/assets/javascripts/app/controllers/ticket_zoom/sidebar_organization.coffee b/app/assets/javascripts/app/controllers/ticket_zoom/sidebar_organization.coffee new file mode 100644 index 000000000..ad612da6b --- /dev/null +++ b/app/assets/javascripts/app/controllers/ticket_zoom/sidebar_organization.coffee @@ -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') diff --git a/app/assets/javascripts/app/controllers/ticket_zoom/sidebar_ticket.coffee b/app/assets/javascripts/app/controllers/ticket_zoom/sidebar_ticket.coffee new file mode 100644 index 000000000..52ea11299 --- /dev/null +++ b/app/assets/javascripts/app/controllers/ticket_zoom/sidebar_ticket.coffee @@ -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') diff --git a/app/assets/javascripts/app/controllers/widget/link.coffee b/app/assets/javascripts/app/controllers/widget/link.coffee index e7bbb9f90..98a45b1af 100644 --- a/app/assets/javascripts/app/controllers/widget/link.coffee +++ b/app/assets/javascripts/app/controllers/widget/link.coffee @@ -185,4 +185,14 @@ class App.LinkAdd extends App.ControllerModal success: (data, status, xhr) => @close() @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 + ) ) diff --git a/app/assets/javascripts/app/controllers/widget/tag.coffee b/app/assets/javascripts/app/controllers/widget/tag.coffee index 774e62eaa..f148746fa 100644 --- a/app/assets/javascripts/app/controllers/widget/tag.coffee +++ b/app/assets/javascripts/app/controllers/widget/tag.coffee @@ -53,9 +53,8 @@ class App.WidgetTag extends App.Controller @html App.view('widget/tag')( tags: @localTags || [], ) - source = "#{App.Config.get('api_path')}/tag_search" - @el.find('.js-newTagInput').autocomplete( + @$('.js-newTagInput').autocomplete( source: source minLength: 2 response: (e, ui) => diff --git a/app/assets/javascripts/app/views/generic/sidebar_tabs.jst.eco b/app/assets/javascripts/app/views/generic/sidebar_tabs.jst.eco index cadc8e0ce..30a3ada73 100644 --- a/app/assets/javascripts/app/views/generic/sidebar_tabs.jst.eco +++ b/app/assets/javascripts/app/views/generic/sidebar_tabs.jst.eco @@ -1,16 +1,14 @@ <% for item in @items: %> <% end %>
diff --git a/app/controllers/links_controller.rb b/app/controllers/links_controller.rb index 35904dba5..929e21eb4 100644 --- a/app/controllers/links_controller.rb +++ b/app/controllers/links_controller.rb @@ -15,7 +15,7 @@ class LinksController < ApplicationController links.each { |item| link_list.push item if item['link_object'] == 'Ticket' - ticket = Ticket.lookup( id: item['link_object_value'] ) + ticket = Ticket.lookup(id: item['link_object_value']) assets = ticket.assets(assets) end } @@ -30,14 +30,18 @@ class LinksController < ApplicationController # POST /api/v1/links/add def add - # lookup object id - object_id = Ticket.where( number: params[:link_object_source_number] ).first.id + object = Ticket.find_by(number: params[:link_object_source_number]) + if !object + render json: { error: 'No such object!' }, status: :unprocessable_entity + return + end + link = Link.add( link_type: params[:link_type], link_object_target: params[:link_object_target], link_object_target_value: params[:link_object_target_value], link_object_source: params[:link_object_source], - link_object_source_value: object_id + link_object_source_value: object.id, ) if link