diff --git a/Gemfile b/Gemfile index b9bdabe0d..ee1d14e34 100644 --- a/Gemfile +++ b/Gemfile @@ -14,7 +14,7 @@ gem 'json' # Gems used only for assets and not required # in production environments by default. group :assets do - gem 'sass-rails' + gem 'sass-rails', github: 'rails/sass-rails' gem 'coffee-rails' gem 'uglifier' end diff --git a/README.md b/README.md index e42ffcc81..a2149ca5b 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ Getting Started ``` zammad@shell> cd zammad - zammad@shell> gem install rails + zammad@shell> gem install rails zammad@shell> vi Gemfile # enable libv8, execjs and therubyracer if needed! zammad@shell> sudo bundle install ``` diff --git a/app/assets/javascripts/app/controllers/_application_controller.js.coffee b/app/assets/javascripts/app/controllers/_application_controller.js.coffee index 5ebdb6fb6..df5353287 100644 --- a/app/assets/javascripts/app/controllers/_application_controller.js.coffee +++ b/app/assets/javascripts/app/controllers/_application_controller.js.coffee @@ -223,11 +223,11 @@ class App.Controller extends Spine.Controller placement: position title: -> ticket_id = $(@).data('id') - ticket = App.Ticket.retrieve( ticket_id ) + ticket = App.Ticket.fullLocal( ticket_id ) App.i18n.escape( ticket.title ) content: -> ticket_id = $(@).data('id') - ticket = App.Ticket.retrieve( ticket_id ) + ticket = App.Ticket.fullLocal( ticket_id ) ticket.humanTime = ui.humanTime(ticket.created_at) # insert data App.view('popover/ticket')( @@ -257,11 +257,11 @@ class App.Controller extends Spine.Controller placement: position title: -> user_id = $(@).data('id') - user = App.User.find( user_id ) - App.i18n.escape( user.displayName() ) + user = App.User.fullLocal( user_id ) + App.i18n.escape( user.displayName() ) content: -> user_id = $(@).data('id') - user = App.User.find( user_id ) + user = App.User.fullLocal( user_id ) # get display data data = [] @@ -303,11 +303,11 @@ class App.Controller extends Spine.Controller placement: position title: -> organization_id = $(@).data('id') - organization = App.Organization.find( organization_id ) + organization = App.Organization.fullLocal( organization_id ) App.i18n.escape( organization.name ) content: -> organization_id = $(@).data('id') - organization = App.Organization.find( organization_id ) + organization = App.Organization.fullLocal( organization_id ) # insert data App.view('popover/organization')( organization: organization, @@ -523,3 +523,31 @@ class App.SessionMessage extends App.ControllerModal throw "Cant reload page!" +class App.UpdateHeader extends App.Controller + constructor: -> + super + + # subscribe and reload data / fetch new data if triggered + @subscribeId = @genericObject.subscribe( @render ) + + release: => + App[ @genericObject.constructor.className ].unsubscribe(@subscribeId) + + render: (genericObject) => + @el.find( '.page-header h1' ).html( genericObject.displayName() ) + + +class App.UpdateTastbar extends App.Controller + constructor: -> + super + + # subscribe and reload data / fetch new data if triggered + @subscribeId = @genericObject.subscribe( @update ) + + release: => + App[ @genericObject.constructor.className ].unsubscribe(@subscribeId) + + update: (genericObject) => + + # update taskbar with new meta data + App.Event.trigger 'task:render' 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 35728f3cc..342e8aefb 100644 --- a/app/assets/javascripts/app/controllers/_application_controller_form.js.coffee +++ b/app/assets/javascripts/app/controllers/_application_controller_form.js.coffee @@ -990,7 +990,7 @@ class App.ControllerForm extends App.Controller remove: true } itemSub = @formGenItem( attribute_config ) - itemSub.find('.icon-minus').bind('click', (e) -> + itemSub.find('.glyphicon-minus').bind('click', (e) -> e.preventDefault() $(@).parent().parent().parent().remove() ) @@ -1019,18 +1019,19 @@ class App.ControllerForm extends App.Controller selected: false disable: true }, -# { -# value: 'tickets.number' -# name: 'Number' -# selected: true -# disable: false -# }, -# { -# value: 'tickets.title' -# name: 'Title' -# selected: true -# disable: false -# }, + # + #{ + # value: 'tickets.number' + # name: 'Number' + # selected: true + # disable: false + #}, + #{ + # value: 'tickets.title' + # name: 'Title' + # selected: true + # disable: false + #}, { value: 'tickets.group_id' name: 'Group' @@ -1055,68 +1056,55 @@ class App.ControllerForm extends App.Controller selected: true disable: false }, - { - value: 'tickets.customer_id' - name: 'Customer' - selected: true - disable: false - }, - { - value: 'tickets.organization_id' - name: 'Organization' - selected: true - disable: false - }, - { - value: 'tickets.created_at::<>' - name: 'Created (before/last)' - selected: true - disable: false - }, - { - value: 'tickets.created_at::><' - name: 'Created (between)' - selected: true - disable: false - }, - { - value: 'tickets.close_time::<>' - name: 'Closed (before/last)' - selected: true - disable: false - }, - { - value: 'tickets.close_time::><' - name: 'Closed (between)' - selected: true - disable: false - }, - { - value: 'tickets.updated_at::<>' - name: 'Updated (before/last)' - selected: true - disable: false - }, - { - value: 'tickets.updated_at::><' - name: 'Updated (between)' - selected: true - disable: false - }, - { - value: 'tickets.escalation_time::<>' - name: 'Escalation (before/last)' - selected: true - disable: false - }, - { - value: 'tickets.escalation_time::><' - name: 'Escalation (between)' - selected: true - disable: false - }, - -# { + #{ + # value: 'tickets.created_at::<>' + # name: 'Created (before/last)' + # selected: true + # disable: false + #}, + #{ + # value: 'tickets.created_at::><' + # name: 'Created (between)' + # selected: true + # disable: false + #}, + #{ + # value: 'tickets.close_time::<>' + # name: 'Closed (before/last)' + # selected: true + # disable: false + #}, + #{ + # value: 'tickets.close_time::><' + # name: 'Closed (between)' + # selected: true + # disable: false + #}, + #{ + # value: 'tickets.updated_at::<>' + # name: 'Updated (before/last)' + # selected: true + # disable: false + #}, + #{ + # value: 'tickets.updated_at::><' + # name: 'Updated (between)' + # selected: true + # disable: false + #}, + #{ + # value: 'tickets.escalation_time::<>' + # name: 'Escalation (before/last)' + # selected: true + # disable: false + #}, + #{ + # value: 'tickets.escalation_time::><' + # name: 'Escalation (between)' + # selected: true + # disable: false + #}, +# # { # value: 'tag' # name: 'Tag' # selected: true @@ -1194,24 +1182,24 @@ class App.ControllerForm extends App.Controller # selected: true # disable: false # }, -# { -# value: '-c' -# name: '-- ' + App.i18n.translateInline('Customer') + ' --' -# selected: false -# disable: true -# }, -# { -# value: 'customers.id' -# name: 'Kunde' -# selected: true -# disable: false -# }, -# { -# value: 'organization.id' -# name: 'Organization' -# selected: true -# disable: false -# }, + { + value: '-c' + name: '-- ' + App.i18n.translateInline('Customer') + ' --' + selected: false + disable: true + }, + { + value: 'customers.id' + name: 'Customer' + selected: true + disable: false + }, + { + value: 'organization.id' + name: 'Organization' + selected: true + disable: false + }, ] default: '' translate: true @@ -1220,7 +1208,7 @@ class App.ControllerForm extends App.Controller } list = @formGenItem( attribute_config ) - list.find('.icon-plus').bind('click', (e) -> + list.find('.glyphicon-plus').bind('click', (e) -> e.preventDefault() value = $(e.target).parents().find('[name=ticket_attribute_list]').val() diff --git a/app/assets/javascripts/app/controllers/_application_controller_generic.js.coffee b/app/assets/javascripts/app/controllers/_application_controller_generic.js.coffee index e6a8d492d..259554e34 100644 --- a/app/assets/javascripts/app/controllers/_application_controller_generic.js.coffee +++ b/app/assets/javascripts/app/controllers/_application_controller_generic.js.coffee @@ -37,7 +37,7 @@ class App.ControllerGenericNew extends App.ControllerModal object.save( done: -> if ui.callback - item = App[ ui.genericObject ].retrieve(@id) + item = App[ ui.genericObject ].fullLocal(@id) ui.callback( item ) ui.modalHide() @@ -84,7 +84,7 @@ class App.ControllerGenericEdit extends App.ControllerModal @item.save( done: -> if ui.callback - item = App[ ui.genericObject ].retrieve(@id) + item = App[ ui.genericObject ].fullLocal(@id) ui.callback( item ) ui.modalHide() @@ -269,14 +269,17 @@ class App.ControllerLevel2 extends App.ControllerContent # window.scrollTo(0,0) class App.ControllerTabs extends App.Controller + events: + 'click .nav-tabs [data-toggle="tab"]': 'tabRemember', + constructor: -> super render: -> + @html App.view('generic/tabs')( tabs: @tabs ) - @el.find('.nav-tabs li:first').addClass('active') for tab in @tabs @el.find('.tab-content').append('
') @@ -285,7 +288,15 @@ class App.ControllerTabs extends App.Controller params.el = @el.find( '#' + tab.target ) new tab.controller( params ) - @el.find('.tab-content .tab-pane:first').addClass('active') + @lastActiveTab = @Config.get('lastTab') + if @lastActiveTab && @el.find('.nav-tabs li a[href="' + @lastActiveTab + '"]')[0] + @el.find('.nav-tabs li a[href="' + @lastActiveTab + '"]').tab('show') + else + @el.find('.nav-tabs li:first a').tab('show') + + tabRemember: (e) => + @lastActiveTab = $(e.target).attr('href') + @Config.set('lastTab', @lastActiveTab) class App.ControllerNavSidbar extends App.ControllerContent constructor: (params) -> diff --git a/app/assets/javascripts/app/controllers/_dashboard/ticket.js.coffee b/app/assets/javascripts/app/controllers/_dashboard/ticket.js.coffee index 049d119f1..6d39a9884 100644 --- a/app/assets/javascripts/app/controllers/_dashboard/ticket.js.coffee +++ b/app/assets/javascripts/app/controllers/_dashboard/ticket.js.coffee @@ -96,7 +96,7 @@ class App.DashboardTicket extends App.Controller i = i + 1 openTicket = (id,e) => - ticket = App.Ticket.retrieve(id) + ticket = App.Ticket.fullLocal(id) @navigate ticket.uiUrl() callbackTicketTitleAdd = (value, object, attribute, attributes, refObject) => attribute.title = object.title diff --git a/app/assets/javascripts/app/controllers/_profile/language.js.coffee b/app/assets/javascripts/app/controllers/_profile/language.js.coffee index ee378377f..3cc8ede1c 100644 --- a/app/assets/javascripts/app/controllers/_profile/language.js.coffee +++ b/app/assets/javascripts/app/controllers/_profile/language.js.coffee @@ -45,7 +45,7 @@ class Index extends App.Controller ) success: (data, status, xhr) => - App.User.retrieve( + App.User.full( App.Session.get( 'id' ), => App.i18n.set( @locale ) diff --git a/app/assets/javascripts/app/controllers/agent_ticket_create.js.coffee b/app/assets/javascripts/app/controllers/agent_ticket_create.js.coffee index 805efa59d..1e6c81660 100644 --- a/app/assets/javascripts/app/controllers/agent_ticket_create.js.coffee +++ b/app/assets/javascripts/app/controllers/agent_ticket_create.js.coffee @@ -370,7 +370,7 @@ class UserNew extends App.ControllerModal # start customer info controller ui.userInfo( user_id: user.id ) ui.modalHide() - App.User.retrieve( @id, callbackReload , true ) + App.User.full( @id, callbackReload , true ) fail: -> ui.modalHide() diff --git a/app/assets/javascripts/app/controllers/agent_ticket_merge.js.coffee b/app/assets/javascripts/app/controllers/agent_ticket_merge.js.coffee index cf5c3e263..af8a1dd63 100644 --- a/app/assets/javascripts/app/controllers/agent_ticket_merge.js.coffee +++ b/app/assets/javascripts/app/controllers/agent_ticket_merge.js.coffee @@ -29,7 +29,7 @@ class App.TicketMerge extends App.ControllerModal list = [] for ticket_id in @ticket_ids_by_customer if ticket_id isnt @ticket.id - ticketItem = App.Ticket.retrieve( ticket_id ) + ticketItem = App.Ticket.fullLocal( ticket_id ) list.push ticketItem new App.ControllerTable( el: @el.find('#ticket-merge-customer-tickets'), @@ -42,7 +42,7 @@ class App.TicketMerge extends App.ControllerModal list = [] for ticket_id in @ticket_ids_recent_viewed if ticket_id isnt @ticket.id - ticketItem = App.Ticket.retrieve( ticket_id ) + ticketItem = App.Ticket.fullLocal( ticket_id ) list.push ticketItem new App.ControllerTable( el: @el.find('#ticket-merge-recent-tickets'), @@ -59,7 +59,7 @@ class App.TicketMerge extends App.ControllerModal @el.delegate('[name="radio"]', 'click', (e) -> if $(e.target).prop('checked') ticket_id = $(e.target).val() - ticket = App.Ticket.retrieve( ticket_id ) + ticket = App.Ticket.fullLocal( ticket_id ) $(e.target).parents().find('[name="master_ticket_number"]').val( ticket.number ) ) diff --git a/app/assets/javascripts/app/controllers/organization_zoom.js.coffee b/app/assets/javascripts/app/controllers/organization_zoom.js.coffee index 6674e9f13..f1f50a851 100644 --- a/app/assets/javascripts/app/controllers/organization_zoom.js.coffee +++ b/app/assets/javascripts/app/controllers/organization_zoom.js.coffee @@ -7,21 +7,17 @@ class App.OrganizationZoom extends App.Controller @navupdate '#' - start = (organization) => - @organization = organization - @render() - - App.Organization.retrieve( @organization_id, start, true ) + App.Organization.full( @organization_id, @render ) meta: => meta = url: @url() id: @organization_id - if @organization - meta.head = @organization.displayName() - meta.title = @organization.displayName() - meta.iconClass = @organization.icon() + organization = App.Organization.find( @organization_id ) + if organization + meta.head = organization.displayName() + meta.title = organization.displayName() meta url: => @@ -36,27 +32,31 @@ class App.OrganizationZoom extends App.Controller return false if !diff || _.isEmpty( diff ) return true - release: => - # nothing - - render: => - # update taskbar with new meta data - App.Event.trigger 'task:render' + render: (organization) => @html App.view('organization_zoom')( - organization: @organization + organization: organization + ) + + new App.UpdateTastbar( + genericObject: organization + ) + + new App.UpdateHeader( + el: @el + genericObject: organization ) # start action controller new ActionRow( el: @el.find('.action') - organization: @organization + organization: organization ui: @ ) new Widgets( el: @el.find('.widgets') - organization: @organization + organization: organization ui: @ ) diff --git a/app/assets/javascripts/app/controllers/ticket_customer.js.coffee b/app/assets/javascripts/app/controllers/ticket_customer.js.coffee index 2f827f489..1841b9f88 100644 --- a/app/assets/javascripts/app/controllers/ticket_customer.js.coffee +++ b/app/assets/javascripts/app/controllers/ticket_customer.js.coffee @@ -38,4 +38,4 @@ class App.TicketCustomer extends App.ControllerModal ) # load user if not already exists - App.User.retrieve( @customer_id, callback ) + App.User.full( @customer_id, callback ) diff --git a/app/assets/javascripts/app/controllers/ticket_overview.js.coffee b/app/assets/javascripts/app/controllers/ticket_overview.js.coffee index 343afb69a..05a484ed3 100644 --- a/app/assets/javascripts/app/controllers/ticket_overview.js.coffee +++ b/app/assets/javascripts/app/controllers/ticket_overview.js.coffee @@ -109,7 +109,7 @@ class Table extends App.ControllerContent @ticket_list_show = [] for ticket_id in @ticket_ids - @ticket_list_show.push App.Ticket.retrieve( ticket_id ) + @ticket_list_show.push App.Ticket.fullLocal( ticket_id ) # remeber bulk attributes @bulk = data.bulk @@ -185,7 +185,7 @@ class Table extends App.ControllerContent @el.find('.table-overview').append(table) else openTicket = (id,e) => - ticket = App.Ticket.retrieve(id) + ticket = App.Ticket.fullLocal(id) @navigate ticket.uiUrl() callbackTicketTitleAdd = (value, object, attribute, attributes, refObject) => attribute.title = object.title diff --git a/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee b/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee index a450d3627..e8d169326 100644 --- a/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee +++ b/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee @@ -44,9 +44,9 @@ class App.TicketZoom extends App.Controller id: @ticket_id iconClass: "priority" if @ticket - @ticket = App.Ticket.retrieve( @ticket.id ) - meta.head = @ticket.title - meta.title = '#' + @ticket.number + ' - ' + @ticket.title + @ticket = App.Ticket.fullLocal( @ticket.id ) + meta.head = @ticket.title + meta.title = '#' + @ticket.number + ' - ' + @ticket.title meta.class = "level-#{@ticket.priority_id}" meta @@ -125,7 +125,7 @@ class App.TicketZoom extends App.Controller App.Collection.loadAssets( data.assets ) # get data - @ticket = App.Ticket.retrieve( @ticket_id ) + @ticket = App.Ticket.fullLocal( @ticket_id ) # render page @render(force) @@ -224,7 +224,7 @@ class TicketTitle extends App.Controller constructor: -> super - @ticket = App.Ticket.retrieve( @ticket.id ) + @ticket = App.Ticket.fullLocal( @ticket.id ) @subscribeId = @ticket.subscribe(@render) @render(@ticket) @@ -334,7 +334,7 @@ class Edit extends App.Controller render: -> - ticket = App.Ticket.retrieve( @ticket.id ) + ticket = App.Ticket.fullLocal( @ticket.id ) @html App.view('ticket_zoom/edit')( ticket: ticket @@ -451,7 +451,7 @@ class Edit extends App.Controller @autosaveStop() params = @formParam(e.target) - ticket = App.Ticket.retrieve( @ticket.id ) + ticket = App.Ticket.fullLocal( @ticket.id ) @log 'notice', 'update', params, ticket @@ -581,7 +581,7 @@ class ArticleView extends App.Controller # get all articles @articles = [] for article_id in @ticket_article_ids - article = App.TicketArticle.retrieve( article_id ) + article = App.TicketArticle.fullLocal( article_id ) @articles.push article # rework articles diff --git a/app/assets/javascripts/app/controllers/user_zoom.js.coffee b/app/assets/javascripts/app/controllers/user_zoom.js.coffee index 839d0807d..3aca70da5 100644 --- a/app/assets/javascripts/app/controllers/user_zoom.js.coffee +++ b/app/assets/javascripts/app/controllers/user_zoom.js.coffee @@ -5,20 +5,20 @@ class App.UserZoom extends App.Controller # check authentication return if !@authenticate() - start = (user) => - @user = user - @render() - App.User.retrieve( @user_id, start, true ) + @navupdate '#' + + App.User.full( @user_id, @render ) meta: => meta = url: @url() id: @user_id - if @user - meta.head = @user.displayName() - meta.title = @user.displayName() + user = App.User.find( @user_id ) + if user + meta.head = user.displayName() + meta.title = user.displayName() meta.iconClass = @user.icon() meta @@ -34,31 +34,34 @@ class App.UserZoom extends App.Controller return false if !diff || _.isEmpty( diff ) return true - release: => - # nothing - - render: => - # update taskbar with new meta data - App.Event.trigger 'task:render' + render: (user) => @html App.view('user_zoom')( - user: @user + user: user + ) + + new App.UpdateTastbar( + genericObject: user + ) + + new App.UpdateHeader( + el: @el + genericObject: user ) # start action controller new ActionRow( el: @el.find('.action') - user: @user + user: user ui: @ ) new Widgets( el: @el.find('.widgets') - user: @user + user: user ui: @ ) - class Widgets extends App.Controller constructor: -> super diff --git a/app/assets/javascripts/app/controllers/widget/link.js.coffee b/app/assets/javascripts/app/controllers/widget/link.js.coffee index 3136828ec..5169c696a 100644 --- a/app/assets/javascripts/app/controllers/widget/link.js.coffee +++ b/app/assets/javascripts/app/controllers/widget/link.js.coffee @@ -40,7 +40,7 @@ class App.WidgetLink extends App.ControllerDrox list[ item['link_type'] ] = [] if item['link_object'] is 'Ticket' - ticket = App.Ticket.retrieve( item['link_object_value'] ) + ticket = App.Ticket.fullLocal( item['link_object_value'] ) if ticket.state.name is 'merged' ticket.css = 'merged' list[ item['link_type'] ].push ticket diff --git a/app/assets/javascripts/app/controllers/widget/organization.js.coffee b/app/assets/javascripts/app/controllers/widget/organization.js.coffee index 529d88c8d..fb0b59445 100644 --- a/app/assets/javascripts/app/controllers/widget/organization.js.coffee +++ b/app/assets/javascripts/app/controllers/widget/organization.js.coffee @@ -6,16 +6,8 @@ class App.WidgetOrganization extends App.Controller constructor: -> super - # show organization - callback = (organization) => - @render(organization) - if @callback - @callback(organization) - - # subscribe and reload data / fetch new data if triggered - @subscribeId = organization.subscribe(@render) - - App.Organization.retrieve( @organization_id, callback ) + # subscribe and reload data / fetch new data if triggered + @subscribeId = App.Organization.full( @organization_id, @render, false, true ) release: => App.Organization.unsubscribe(@subscribeId) @@ -56,6 +48,9 @@ class App.WidgetOrganization extends App.Controller ) @delay( a, 80 ) + # enable user popups + @userPopups() + ### @userTicketPopups( selector: '.user-tickets' @@ -65,7 +60,7 @@ class App.WidgetOrganization extends App.Controller ### update: (e) => - note = $(e.target).parent().find('[data-type=update]').val() + note = $(e.target).val() organization = App.Organization.find( @organization_id ) if organization.note isnt note organization.updateAttributes( note: note ) diff --git a/app/assets/javascripts/app/controllers/widget/user.js.coffee b/app/assets/javascripts/app/controllers/widget/user.js.coffee index 27ce2da85..23d41cd65 100644 --- a/app/assets/javascripts/app/controllers/widget/user.js.coffee +++ b/app/assets/javascripts/app/controllers/widget/user.js.coffee @@ -6,16 +6,8 @@ class App.WidgetUser extends App.ControllerDrox constructor: -> super - # show user - callback = (user) => - @render(user) - if @callback - @callback(user) - - # subscribe and reload data / fetch new data if triggered - @subscribeId = user.subscribe(@render) - - App.User.retrieve( @user_id, callback ) + # subscribe and reload data / fetch new data if triggered + @subscribeId = App.User.full( @user_id, @render, false, true ) release: => App.User.unsubscribe(@subscribeId) @@ -41,6 +33,34 @@ class App.WidgetUser extends App.ControllerDrox if item.info userData.push item + if user.preferences + items = [] + if user.preferences.tickets_open > 0 + item = + url: '' + name: 'open' + count: user.preferences.tickets_open + title: 'Open Tickets' + class: 'user-tickets' + data: 'open' + items.push item + if user.preferences.tickets_closed > 0 + item = + url: '' + name: 'closed' + count: user.preferences.tickets_closed + title: 'Closed Tickets' + class: 'user-tickets' + data: 'closed' + items.push item + + if items[0] + topic = + title: 'Tickets' + items: items + user['links'] = [] + user['links'].push topic + # insert userData @html @template( file: 'widget/user' @@ -72,7 +92,7 @@ class App.WidgetUser extends App.ControllerDrox ) update: (e) => - note = $(e.target).parent().find('[data-type=update]').val() + note = $(e.target).val() user = App.User.find( @user_id ) if user.note isnt note user.updateAttributes( note: note ) diff --git a/app/assets/javascripts/app/lib/app_post/auth.js.coffee b/app/assets/javascripts/app/lib/app_post/auth.js.coffee index 081517825..20e1bf495 100644 --- a/app/assets/javascripts/app/lib/app_post/auth.js.coffee +++ b/app/assets/javascripts/app/lib/app_post/auth.js.coffee @@ -75,21 +75,23 @@ class App.Auth if type isnt 'check' App.Event.trigger( 'clearStore' ) - # set avatar - data.session.image = App.Config.get('api_path') + '/users/image/' + data.session.image - # update config for key, value of data.config App.Config.set( key, value ) - # store user data - for key, value of data.session - App.Session.set( key, value ) - # refresh default collections if data.collections App.Collection.resetCollections( data.collections ) + # load assets + if data.assets + App.Collection.loadAssets( data.assets ) + + # store user data + session = App.User.fullLocal(data.session.id) + for key, value of session + App.Session.set( key, value ) + # trigger auth ok with new session data App.Event.trigger( 'auth', data.session ) diff --git a/app/assets/javascripts/app/lib/app_post/collection.js.coffee b/app/assets/javascripts/app/lib/app_post/collection.js.coffee index 36ab85d26..0f1f2beb4 100644 --- a/app/assets/javascripts/app/lib/app_post/collection.js.coffee +++ b/app/assets/javascripts/app/lib/app_post/collection.js.coffee @@ -68,7 +68,7 @@ class _collectionSingleton extends Spine.Module reset: (params) -> if !App[ params.type ] - @log 'error', 'reset', 'no such collection', params + @log 'error', 'reset', "no such collection #{params.type}", params return @log 'debug', 'reset', params diff --git a/app/assets/javascripts/app/lib/app_post/i18n.js.coffee b/app/assets/javascripts/app/lib/app_post/i18n.js.coffee index 5e3b17761..5840c1c8b 100644 --- a/app/assets/javascripts/app/lib/app_post/i18n.js.coffee +++ b/app/assets/javascripts/app/lib/app_post/i18n.js.coffee @@ -143,19 +143,22 @@ class _i18nSingleton extends Spine.Module translate: ( string, args... ) => + # type convertation + if typeof string isnt 'string' + if string && string.toString + string = string.toString() + # return '' on undefined - if typeof string is 'boolean' - string = string.toString() return '' if string is undefined return '' if string is '' # return translation if @map[string] isnt undefined @_translated = true - translated = @map[string] + translated = @map[string] else @_translated = false - translated = string + translated = string # search %s for arg in args diff --git a/app/assets/javascripts/app/models/_application_model.js.coffee b/app/assets/javascripts/app/models/_application_model.js.coffee index 15b6db98b..67218ebff 100644 --- a/app/assets/javascripts/app/models/_application_model.js.coffee +++ b/app/assets/javascripts/app/models/_application_model.js.coffee @@ -126,6 +126,66 @@ class App.Model extends Spine.Model return true if @id[0] isnt 'c' return false + @fullLocal: (id) -> + @_fillUp( App[ @className ].find( id ) ) + + @full: (id, callback = false, force = false, bind = false) -> + url = "#{@url}/#{id}?full=true" + + # subscribe and reload data / fetch new data if triggered + subscribeId = undefined + if bind + subscribeId = App[ @className ].subscribe_item(id, callback) + + # execute if object already exists + if !force && App[ @className ].exists( id ) + data = App[ @className ].find( id ) + data = @_fillUp( data ) + if callback + callback( data ) + return subscribeId + + # store callback and requested id + if !@FULL_CALLBACK + @FULL_CALLBACK = {} + if !@FULL_CALLBACK[id] + @FULL_CALLBACK[id] = {} + if callback + key = @className + '-' + Math.floor( Math.random() * 99999 ) + @FULL_CALLBACK[id][key] = callback + + if !@FULL_FETCH + @FULL_FETCH = {} + if !@FULL_FETCH[id] + @FULL_FETCH[id] = true + App.Ajax.request( + type: 'GET' + url: url + processData: true, + success: (data, status, xhr) => + @FULL_FETCH[ data.id ] = false + + # full / load assets + if data.assets + App.Collection.loadAssets( data.assets ) + + # find / load object + else + App[ @className ].refresh( data ) + + # execute callbacks + if @FULL_CALLBACK[ data.id ] + for key, callback of @FULL_CALLBACK[ data.id ] + callback( @_fillUp( App[ @className ].find( data.id ) ) ) + delete @FULL_CALLBACK[ data.id ][ key ] + if _.isEmpty @FULL_CALLBACK[ data.id ] + delete @FULL_CALLBACK[ data.id ] + + error: (xhr, statusText, error) => + console.log(statusText, error) + ) + subscribeId + @retrieve: ( id, callback, force ) -> if !force && App[ @className ].exists( id ) data = App[ @className ].find( id ) @@ -229,42 +289,56 @@ class App.Model extends Spine.Model subscribe: (callback, type) -> + # remember record id and callback + App[ @constructor.className ].subscribe_item(@id, callback) + + @subscribe_item: (id, callback) -> + # init bind - if !App[ @constructor.className ]['SUBSCRIPTION_ITEM'] - App[ @constructor.className ]['SUBSCRIPTION_ITEM'] = {} + if !@_subscribe_item_bindDone + @_subscribe_item_bindDone = true # subscribe and render data after local change - App[ @constructor.className ].bind( + @bind( 'refresh change' - (item) => - #console.log('BIND', item) - for key, callback of App[ @constructor.className ]['SUBSCRIPTION_ITEM'][ item.id ] - item = App[ @constructor.className ]._fillUp( item ) - callback(item, 'local') + (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 ] + item = App[ @className ]._fillUp( item ) + callback(item) ) # subscribe and render data after server change - events = "#{@constructor.className}:create #{@constructor.className}:update #{@constructor.className}:destroy" + events = "#{@className}:create #{@className}:update #{@className}:destroy" App.Event.bind( events (item) => - #console.log('SERVER BIND try', item) - if App[ @constructor.className ]['SUBSCRIPTION_ITEM'] && App[ @constructor.className ]['SUBSCRIPTION_ITEM'][ item.id ] - #console.log('SERVER BIND', item) - for key, callback of App[ @constructor.className ]['SUBSCRIPTION_ITEM'][ item.id ] - callbackRetrieve = (item) -> - callback(item, 'server') - App[ @constructor.className ].retrieve( item.id, callbackRetrieve, true ) - 'Item::Subscribe::' + @constructor.className + if @SUBSCRIPTION_ITEM && @SUBSCRIPTION_ITEM[ item.id ] + genericObject = undefined + if App[ @className ].exists( item.id ) + genericObject = App[ @className ].find( item.id ) + + callback = => + if !genericObject || ( new Date(item.updated_at).toString() isnt new Date(genericObject.updated_at).toString() ) + @full( item.id, false, true ) + + App.Delay.set(callback, 800, item.id, "full-#{@className}") + + 'Item::Subscribe::' + @className ) - # remember record id and callback - if !App[ @constructor.className ]['SUBSCRIPTION_ITEM'][ @id ] - App[ @constructor.className ]['SUBSCRIPTION_ITEM'][ @id ] = {} - key = @constructor.className + '-' + Math.floor( Math.random() * 99999 ) - App[ @constructor.className ]['SUBSCRIPTION_ITEM'][ @id ][key] = callback - - # return key + # remember item callback + if !@SUBSCRIPTION_ITEM + @SUBSCRIPTION_ITEM = {} + if !@SUBSCRIPTION_ITEM[id] + @SUBSCRIPTION_ITEM[id] = {} + key = @className + '-' + Math.floor( Math.random() * 99999 ) + @SUBSCRIPTION_ITEM[id][key] = callback key ### @@ -275,15 +349,15 @@ class App.Model extends Spine.Model ### - @unsubscribe: (data) -> + @unsubscribe: (subscribeId) -> if @SUBSCRIPTION_ITEM for id, keys of @SUBSCRIPTION_ITEM - if keys[data] - delete keys[data] + if keys[subscribeId] + delete keys[subscribeId] if @SUBSCRIPTION_COLLECTION - if @SUBSCRIPTION_COLLECTION[data] - delete @SUBSCRIPTION_COLLECTION[data] + if @SUBSCRIPTION_COLLECTION[subscribeId] + delete @SUBSCRIPTION_COLLECTION[subscribeId] @_bindsEmpty: -> if @SUBSCRIPTION_ITEM diff --git a/app/assets/javascripts/app/models/organization.js.coffee b/app/assets/javascripts/app/models/organization.js.coffee index dd72581d1..c0d05d039 100644 --- a/app/assets/javascripts/app/models/organization.js.coffee +++ b/app/assets/javascripts/app/models/organization.js.coffee @@ -23,10 +23,10 @@ class App.Organization extends App.Model @_fillUp: (data) -> # addd users of organization - if data['user_ids'] - data['user_ids'] = [] - for user_id in data['user_ids'] + if data['member_ids'] + data['members'] = [] + for user_id in data['member_ids'] if App.User.exists( user_id ) user = App.User.find( user_id ) - data['user_ids'].push user + data['members'].push user data diff --git a/app/assets/javascripts/app/models/user.js.coffee b/app/assets/javascripts/app/models/user.js.coffee index b7fc0ada9..8837a5f90 100644 --- a/app/assets/javascripts/app/models/user.js.coffee +++ b/app/assets/javascripts/app/models/user.js.coffee @@ -47,10 +47,23 @@ class App.User extends App.Model data['accounts'][account]['link'] = 'https://www.facebook.com/profile.php?id=' + data['accounts'][account]['uid'] # set image url - data.image = @apiPath + '/users/image/' + data.image + data.imageUrl = @apiPath + '/users/image/' + data.image if data.organization_id data.organization = App.Organization.find(data.organization_id) - data + if data['role_ids'] + data['roles'] = [] + for role_id in data['role_ids'] + if App.Role.exists( role_id ) + role = App.Role.find( role_id ) + data['roles'].push role + if data['group_ids'] + data['groups'] = [] + for group_id in data['group_ids'] + if App.Group.exists( group_id ) + group = App.Group.find( group_id ) + data['groups'].push group + + data diff --git a/app/assets/javascripts/app/views/agent_ticket_view/detail.jst.eco b/app/assets/javascripts/app/views/agent_ticket_view/detail.jst.eco index 9d6af49b8..b370be5f8 100644 --- a/app/assets/javascripts/app/views/agent_ticket_view/detail.jst.eco +++ b/app/assets/javascripts/app/views/agent_ticket_view/detail.jst.eco @@ -11,7 +11,7 @@ - +

<%= ticket.title %> <%= ticket.number %> ?

diff --git a/app/assets/javascripts/app/views/generic/tabs.jst.eco b/app/assets/javascripts/app/views/generic/tabs.jst.eco index 03a62d8a1..d8042c453 100644 --- a/app/assets/javascripts/app/views/generic/tabs.jst.eco +++ b/app/assets/javascripts/app/views/generic/tabs.jst.eco @@ -1,6 +1,6 @@ -