diff --git a/app/assets/javascripts/app/controllers/_application_controller_form.js.coffee b/app/assets/javascripts/app/controllers/_application_controller_form.js.coffee index baa108aaf..56450de6b 100644 --- a/app/assets/javascripts/app/controllers/_application_controller_form.js.coffee +++ b/app/assets/javascripts/app/controllers/_application_controller_form.js.coffee @@ -654,9 +654,13 @@ class App.ControllerForm extends App.Controller item = $( App.view('generic/textarea')( attribute: attribute ) + '
' ) a = => - $( item[0] ).expanding() - $( item[0] ).on('focus', -> + visible = $( item[0] ).is(":visible") + if visible && !$( item[0] ).expanding('active') $( item[0] ).expanding() + $( item[0] ).on('focus', -> + visible = $( item[0] ).is(":visible") + if visible && !$( item[0] ).expanding('active') + $( item[0] ).expanding() ) App.Delay.set( a, 80 ) diff --git a/app/assets/javascripts/app/controllers/_dashboard/ticket_search.js.coffee b/app/assets/javascripts/app/controllers/_dashboard/ticket_search.js.coffee new file mode 100644 index 000000000..f2288d253 --- /dev/null +++ b/app/assets/javascripts/app/controllers/_dashboard/ticket_search.js.coffee @@ -0,0 +1,132 @@ +class App.DashboardTicketSearch extends App.Controller + events: + 'click [data-type=page]': 'page' + + constructor: -> + super + @start_page = 1 + @navupdate '#' + + # render + @fetch() + + fetch: (force) => + + @ajax( + id: 'dashboard_ticket_search' + @name, + type: 'GET', + url: @apiPath + '/tickets/search', + data: + condition: @condition + order: @order + detail: true + limit: 200 + processData: true, + success: (data) => + + @load( data, true ) + ) + + load: (data = false, ajax = false) => + + if ajax + App.Store.write( 'dashboard_ticket_search' + @name, data ) + + # load assets + App.Collection.loadAssets( data.assets ) + + @render( data ) + + else + data = App.Store.get( 'dashboard_ticket_search' + @name ) + if data + @render( data ) + + + render: (data) -> + return if !data + return if !data.tickets + + @overview = + name: @name + @tickets_count = data.tickets_count + @ticket_ids = data.tickets + per_page = @per_page || 5 + pages_total = parseInt( ( @tickets_count / per_page ) + 0.99999 ) || 1 + html = App.view('dashboard/ticket')( + overview: @overview, + pages_total: pages_total, + start_page: @start_page, + ) + html = $(html) + html.find('li').removeClass('active') + html.find(".page [data-id=\"#{@start_page}\"]").parents('li').addClass('active') + + @tickets_in_table = [] + start = ( @start_page-1 ) * 5 + end = ( @start_page ) * 5 + i = start + while i < end + i = i + 1 + if @ticket_ids[ i - 1 ] + @tickets_in_table.push App.Ticket.fullLocal( @ticket_ids[ i - 1 ] ) + + openTicket = (id,e) => + ticket = App.Ticket.fullLocal(id) + @navigate ticket.uiUrl() + callbackTicketTitleAdd = (value, object, attribute, attributes, refObject) => + attribute.title = object.title + value + callbackLinkToTicket = (value, object, attribute, attributes, refObject) => + attribute.link = object.uiUrl() + value + callbackResetLink = (value, object, attribute, attributes, refObject) => + attribute.link = undefined + value + callbackUserPopover = (value, object, attribute, attributes, refObject) => + attribute.class = 'user-popover' + attribute.data = + id: refObject.id + value + + new App.ControllerTable( + overview: @view.d + el: html.find('.table-overview'), + model: App.Ticket + objects: @tickets_in_table, + checkbox: false + groupBy: @group_by + bindRow: + events: + 'click': openTicket + callbackAttributes: + customer_id: + [ callbackResetLink, callbackUserPopover ] + owner_id: + [ callbackResetLink, callbackUserPopover ] + title: + [ callbackLinkToTicket, callbackTicketTitleAdd ] + number: + [ callbackLinkToTicket, callbackTicketTitleAdd ] + ) + + @html html + + # show frontend times + @frontendTimeUpdate() + + # start user popups + @userPopups() + + zoom: (e) => + e.preventDefault() + id = $(e.target).parents('[data-id]').data('id') + + @navigate 'ticket/zoom/' + id + + page: (e) => + e.preventDefault() + id = $(e.target).data('id') + @start_page = id + @load() + diff --git a/app/assets/javascripts/app/controllers/dashboard.js.coffee b/app/assets/javascripts/app/controllers/dashboard.js.coffee index 009b71b1b..cba98dee8 100644 --- a/app/assets/javascripts/app/controllers/dashboard.js.coffee +++ b/app/assets/javascripts/app/controllers/dashboard.js.coffee @@ -2,7 +2,7 @@ class Index extends App.ControllerContent constructor: -> super - + # check authentication return if !@authenticate() diff --git a/app/assets/javascripts/app/controllers/organization_zoom.js.coffee b/app/assets/javascripts/app/controllers/organization_zoom.js.coffee index f1f50a851..027f370a7 100644 --- a/app/assets/javascripts/app/controllers/organization_zoom.js.coffee +++ b/app/assets/javascripts/app/controllers/organization_zoom.js.coffee @@ -38,6 +38,11 @@ class App.OrganizationZoom extends App.Controller organization: organization ) + new Overviews( + el: @el + organization: organization + ) + new App.UpdateTastbar( genericObject: organization ) @@ -60,6 +65,55 @@ class App.OrganizationZoom extends App.Controller ui: @ ) +class Overviews extends App.Controller + constructor: -> + super + + # subscribe and reload data / fetch new data if triggered + @subscribeId = App.Organization.full( @organization.id, @render, false, true ) + + release: => + App.Organization.unsubscribe(@subscribeId) + + render: (organization) => + + plugins = + main: + my_organization: + controller: App.DashboardTicketSearch, + params: + name: 'Tickets of Organization' + condition: + 'tickets.state_id': [ 1,2,3,4,6 ] + 'tickets.organization_id': organization.id + order: + by: 'created_at' + direction: 'DESC' + view: + d: [ 'number', 'title', 'customer', 'state', 'priority', 'created_at' ] + view_mode_default: 'd' + + for area, plugins of plugins + for name, plugin of plugins + target = area + '_' + name + @el.find('.' + area + '-overviews').append('') + if plugin.controller + params = plugin.params || {} + params.el = @el.find( '#' + target ) + new plugin.controller( params ) + + dndOptions = + handle: 'h2.can-move' + placeholder: 'can-move-plcaeholder' + tolerance: 'pointer' + distance: 15 + opacity: 0.6 + forcePlaceholderSize: true + + @el.find( '#sortable' ).sortable( dndOptions ) + @el.find( '#sortable-sidebar' ).sortable( dndOptions ) + + class Widgets extends App.Controller constructor: -> super diff --git a/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee b/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee index c6f6f9e88..2e508a65c 100644 --- a/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee +++ b/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee @@ -150,14 +150,6 @@ class App.TicketZoom extends App.Controller if !@editWidget || _.isEmpty( App.TaskManager.get(@task_key).state ) @editWidget = @Edit() - # show text module UI - if !@isRole('Customer') - new App.WidgetTextModule( - el: @el.find('textarea') - data: - ticket: @ticket - ) - # scroll to article if given if @article_id && document.getElementById( 'article-' + @article_id ) offset = document.getElementById( 'article-' + @article_id ).offsetTop @@ -324,6 +316,8 @@ class Edit extends App.Controller release: => @autosaveStop() + if @subscribeIdTextModule + App.Ticket.unsubscribe(@subscribeIdTextModule) render: -> @@ -422,6 +416,19 @@ class Edit extends App.Controller # enable user popups @userPopups() + # show text module UI + if !@isRole('Customer') + textModule = new App.WidgetTextModule( + el: @el.find('textarea') + data: + ticket: ticket + ) + callback = (ticket) => + textModule.reload( + ticket: ticket + ) + @subscribeIdTextModule = ticket.subscribe( callback ) + autosaveStop: => @clearInterval( 'autosave' ) diff --git a/app/assets/javascripts/app/controllers/user_zoom.js.coffee b/app/assets/javascripts/app/controllers/user_zoom.js.coffee index d5360887c..a63ba95ff 100644 --- a/app/assets/javascripts/app/controllers/user_zoom.js.coffee +++ b/app/assets/javascripts/app/controllers/user_zoom.js.coffee @@ -34,10 +34,16 @@ class App.UserZoom extends App.Controller render: (user) => + @html App.view('user_zoom')( user: user ) + new Overviews( + el: @el + user: user + ) + new App.UpdateTastbar( genericObject: user ) @@ -60,6 +66,74 @@ class App.UserZoom extends App.Controller ui: @ ) +class Overviews extends App.Controller + constructor: -> + super + + # subscribe and reload data / fetch new data if triggered + @subscribeId = App.User.full( @user.id, @render, false, true ) + + release: => + App.User.unsubscribe(@subscribeId) + + render: (user) => + + plugins = { + main: { + my_assigned: { + controller: App.DashboardTicketSearch, + params: { + name: 'Tickets of User' + condition: + 'tickets.state_id': [ 1,2,3,4,6 ] + 'tickets.customer_id': user.id + order: + by: 'created_at' + direction: 'DESC' + view: + d: [ 'number', 'title', 'state', 'priority', 'created_at' ] + view_mode_default: 'd' + }, + }, + }, + } + if user.organization_id + plugins.main.my_organization = { + controller: App.DashboardTicketSearch, + params: { + name: 'Tickets of Organization' + condition: + 'tickets.state_id': [ 1,2,3,4,6 ] + 'tickets.organization_id': user.organization_id + order: + by: 'created_at' + direction: 'DESC' + view: + d: [ 'number', 'title', 'customer', 'state', 'priority', 'created_at' ] + view_mode_default: 'd' + }, + } + + for area, plugins of plugins + for name, plugin of plugins + target = area + '_' + name + @el.find('.' + area + '-overviews').append('') + if plugin.controller + params = plugin.params || {} + params.el = @el.find( '#' + target ) + new plugin.controller( params ) + + dndOptions = + handle: 'h2.can-move' + placeholder: 'can-move-plcaeholder' + tolerance: 'pointer' + distance: 15 + opacity: 0.6 + forcePlaceholderSize: true + + @el.find( '#sortable' ).sortable( dndOptions ) + @el.find( '#sortable-sidebar' ).sortable( dndOptions ) + class Widgets extends App.Controller constructor: -> super diff --git a/app/assets/javascripts/app/controllers/widget/organization.js.coffee b/app/assets/javascripts/app/controllers/widget/organization.js.coffee index fb0b59445..82a386080 100644 --- a/app/assets/javascripts/app/controllers/widget/organization.js.coffee +++ b/app/assets/javascripts/app/controllers/widget/organization.js.coffee @@ -42,11 +42,15 @@ class App.WidgetOrganization extends App.Controller ) a = => - @el.find('textarea').expanding() - @el.find('textarea').on('focus', => + visible = @el.find('textarea').is(":visible") + if visible && !@el.find('textarea').expanding('active') @el.find('textarea').expanding() + @el.find('textarea').on('focus', (e) => + visible = @el.find('textarea').is(":visible") + if visible && !@el.find('textarea').expanding('active') + @el.find('textarea').expanding() ) - @delay( a, 80 ) + @delay( a, 40 ) # enable user popups @userPopups() diff --git a/app/assets/javascripts/app/controllers/widget/user.js.coffee b/app/assets/javascripts/app/controllers/widget/user.js.coffee index 23d41cd65..ac8b48d0d 100644 --- a/app/assets/javascripts/app/controllers/widget/user.js.coffee +++ b/app/assets/javascripts/app/controllers/widget/user.js.coffee @@ -14,6 +14,10 @@ class App.WidgetUser extends App.ControllerDrox render: (user) => + # execute callback on render/rerender + if @callback + @callback(user) + # get display data userData = [] for item2 in App.User.configure_attributes @@ -72,11 +76,15 @@ class App.WidgetUser extends App.ControllerDrox ) a = => - @el.find('textarea').expanding() - @el.find('textarea').on('focus', => + visible = @el.find('textarea').is(":visible") + if visible && !@el.find('textarea').expanding('active') @el.find('textarea').expanding() + @el.find('textarea').on('focus', (e) => + visible = @el.find('textarea').is(":visible") + if visible && !@el.find('textarea').expanding('active') + @el.find('textarea').expanding() ) - @delay( a, 80 ) + @delay( a, 40 ) @userTicketPopups( selector: '.user-tickets' diff --git a/app/assets/javascripts/app/models/_application_model.js.coffee b/app/assets/javascripts/app/models/_application_model.js.coffee index 1f705e942..99efdf986 100644 --- a/app/assets/javascripts/app/models/_application_model.js.coffee +++ b/app/assets/javascripts/app/models/_application_model.js.coffee @@ -291,7 +291,7 @@ class App.Model extends Spine.Model # subscribe and render data after local change @bind( - 'refresh change' + 'change' (items) => # check if result is array or singel item @@ -301,7 +301,26 @@ class App.Model extends Spine.Model for item in items for key, callback of App[ @className ].SUBSCRIPTION_ITEM[ item.id ] item = App[ @className ]._fillUp( item ) - callback(item) + callback(item, 'change') + ) + + @changeTable = {} + @bind( + 'refresh' + (items) => + + # check if result is array or singel item + if !_.isArray(items) + items = [items] + + for item in items + for key, callback of App[ @className ].SUBSCRIPTION_ITEM[ item.id ] + + # only trigger callbacks if object has changed + if !@changeTable[key] || @changeTable[key] isnt item.updated_at + @changeTable[key] = item.updated_at + item = App[ @className ]._fillUp( item ) + callback(item, 'refresh') ) # subscribe and render data after server change diff --git a/app/assets/javascripts/app/views/dashboard/ticket.jst.eco b/app/assets/javascripts/app/views/dashboard/ticket.jst.eco index 34387c912..a18c37ad1 100644 --- a/app/assets/javascripts/app/views/dashboard/ticket.jst.eco +++ b/app/assets/javascripts/app/views/dashboard/ticket.jst.eco @@ -1,7 +1,7 @@