diff --git a/app/assets/javascripts/app/controllers/_application_controller.coffee b/app/assets/javascripts/app/controllers/_application_controller.coffee index a27118268..877d2ba95 100644 --- a/app/assets/javascripts/app/controllers/_application_controller.coffee +++ b/app/assets/javascripts/app/controllers/_application_controller.coffee @@ -130,6 +130,11 @@ class App.Controller extends Spine.Controller return if !$('#navigation').is(':visible') $('#navigation').addClass('hide') + updateNavMenu: => + delay = -> + App.Event.trigger('menu:render') + @delay(delay, 200) + scrollTo: (x = 0, y = 0, delay = 0) -> a = -> window.scrollTo(x, y) diff --git a/app/assets/javascripts/app/controllers/_channel/chat.coffee b/app/assets/javascripts/app/controllers/_channel/chat.coffee index 357cf6c55..accde2115 100644 --- a/app/assets/javascripts/app/controllers/_channel/chat.coffee +++ b/app/assets/javascripts/app/controllers/_channel/chat.coffee @@ -6,7 +6,7 @@ class App.ChannelChat extends App.Controller 'click .js-selectBrowserWidth': 'selectBrowserWidth' 'click .js-swatch': 'usePaletteColor' 'click .js-toggle-chat': 'toggleChat' - 'click .js-chatSetting': 'toggleChatSetting' + 'change .js-chatSetting input': 'toggleChatSetting' 'click .js-eyedropper': 'pickColor' elements: @@ -307,12 +307,7 @@ class App.ChannelChat extends App.Controller toggleChatSetting: => value = @chatSetting.prop('checked') - setting = App.Setting.findByAttribute('name', 'chat') - setting.state_current = { value: value } - setting.save() - @Config.set('chat', value) - delay = -> App.Event.trigger('ui:rerender') - @delay(delay, 200) + App.Setting.set('chat', value) updateParams: => quote = (value) -> diff --git a/app/assets/javascripts/app/controllers/_channel/form.coffee b/app/assets/javascripts/app/controllers/_channel/form.coffee index 73ffd4274..a4a3ad74d 100644 --- a/app/assets/javascripts/app/controllers/_channel/form.coffee +++ b/app/assets/javascripts/app/controllers/_channel/form.coffee @@ -3,7 +3,7 @@ class App.ChannelForm extends App.Controller events: 'change form.js-params': 'updateParams' 'keyup form.js-params': 'updateParams' - 'click .js-formSetting': 'toggleFormSetting' + 'change .js-formSetting input': 'toggleFormSetting' elements: '.js-paramsBlock': 'paramsBlock' @@ -16,10 +16,11 @@ class App.ChannelForm extends App.Controller render: => App.Setting.unsubscribe(@subscribeId) - setting = App.Setting.findByAttribute('name', 'form_ticket_create') + + setting = App.Setting.get('form_ticket_create') @html App.view('channel/form')( baseurl: window.location.origin - formSetting: setting.state_current.value + formSetting: setting ) @paramsBlock.each (i, block) -> @@ -49,8 +50,6 @@ class App.ChannelForm extends App.Controller toggleFormSetting: => value = @formSetting.prop('checked') - setting = App.Setting.findByAttribute('name', 'form_ticket_create') - setting.state_current = { value: value } - setting.save() + App.Setting.set('form_ticket_create', value) App.Config.set( 'Form', { prio: 2000, name: 'Form', parent: '#channels', target: '#channels/form', controller: App.ChannelForm, role: ['Admin'] }, 'NavBarAdmin' ) diff --git a/app/assets/javascripts/app/controllers/_integration/_base.coffee b/app/assets/javascripts/app/controllers/_integration/_base.coffee index dfe224a8d..fdc9befdc 100644 --- a/app/assets/javascripts/app/controllers/_integration/_base.coffee +++ b/app/assets/javascripts/app/controllers/_integration/_base.coffee @@ -55,12 +55,7 @@ class App.ControllerIntegrationBase extends App.Controller msg: App.i18n.translateContent('Update successful!') timeout: 2000 } - if @preferences - if @preferences.render - App.Event.trigger( 'ui:rerender' ) - - if @preferences.session_check - App.Auth.loginCheck() + App.Setting.preferencesPost(@) fail: (settings, details) -> App.Event.trigger 'notify', { @@ -73,25 +68,4 @@ class App.ControllerIntegrationBase extends App.Controller value = items: [params] - App.Setting.set( - @featureConfig, - value, - done: -> - App.Event.trigger 'notify', { - type: 'success' - msg: App.i18n.translateContent('Update successful!') - timeout: 2000 - } - if @preferences - if @preferences.render - App.Event.trigger( 'ui:rerender' ) - - if @preferences.session_check - App.Auth.loginCheck() - fail: (settings, details) -> - App.Event.trigger 'notify', { - type: 'error' - msg: App.i18n.translateContent(details.error_human || details.error || 'Unable to update object!') - timeout: 2000 - } - ) + App.Setting.set(@featureConfig, value) diff --git a/app/assets/javascripts/app/controllers/_settings/area.coffee b/app/assets/javascripts/app/controllers/_settings/area.coffee index cffbb750c..d36cc13d4 100644 --- a/app/assets/javascripts/app/controllers/_settings/area.coffee +++ b/app/assets/javascripts/app/controllers/_settings/area.coffee @@ -108,13 +108,8 @@ class App.SettingsAreaItem extends App.Controller } # rerender ui || get new collections and session data - if @setting.preferences - if @setting.preferences.render - ui.render() - App.Event.trigger( 'ui:rerender' ) + App.Setting.preferencesPost(@setting) - if @setting.preferences.session_check - App.Auth.loginCheck() fail: (settings, details) -> ui.formEnable(e) App.Event.trigger 'notify', { @@ -158,10 +153,10 @@ class App.SettingsAreaLogo extends App.Controller if file.size && file.size > 1024 * 1024 * maxSiteInMb App.Event.trigger 'notify', { type: 'error' - msg: App.i18n.translateContent('File too big, max. %s MB allowed.', maxSiteInMb ) + msg: App.i18n.translateContent('File too big, max. %s MB allowed.', maxSiteInMb) timeout: 2000 } - @logoPreview.attr( 'src', '' ) + @logoPreview.attr('src', '') return reader.readAsDataURL(file) @@ -209,4 +204,4 @@ class App.SettingsAreaLogo extends App.Controller ) # add resized image - App.ImageService.resizeForApp( @params.logo, @logoPreview.width(), @logoPreview.height(), store ) + App.ImageService.resizeForApp(@params.logo, @logoPreview.width(), @logoPreview.height(), store) diff --git a/app/assets/javascripts/app/controllers/_settings/form.coffee b/app/assets/javascripts/app/controllers/_settings/form.coffee index f3ed764ed..a50528936 100644 --- a/app/assets/javascripts/app/controllers/_settings/form.coffee +++ b/app/assets/javascripts/app/controllers/_settings/form.coffee @@ -72,13 +72,8 @@ class App.SettingsForm extends App.Controller timeout: 2000 } - # rerender ui || get new collections and session data - if @preferences - if @preferences.render - App.Event.trigger( 'ui:rerender' ) - - if @preferences.session_check - App.Auth.loginCheck() + # rerender ui || get new collections and session data + App.Setting.preferencesPost(@) fail: (settings, details) -> App.Event.trigger 'notify', { diff --git a/app/assets/javascripts/app/controllers/chat.coffee b/app/assets/javascripts/app/controllers/chat.coffee index 4081293e9..c515353c5 100644 --- a/app/assets/javascripts/app/controllers/chat.coffee +++ b/app/assets/javascripts/app/controllers/chat.coffee @@ -86,8 +86,7 @@ class App.CustomerChat extends App.Controller ) featureActive: => - if @Config.get('chat') - return true + return true if @Config.get('chat') false render: -> @@ -164,6 +163,10 @@ class App.CustomerChat extends App.Controller @title 'Customer Chat', true @navupdate '#customer_chat' + active: (state) => + return @shown if state is undefined + @shown = state + counter: => counter = 0 @@ -239,11 +242,6 @@ class App.CustomerChat extends App.Controller @stopPushState() @pushState() - updateNavMenu: => - delay = -> - App.Event.trigger('menu:render') - @delay(delay, 200, 'updateNavMenu') - updateMeta: => if @meta.waiting_chat_count && @maxChatWindows > @windowCount() @acceptChatElement.addClass('is-clickable is-blinking') diff --git a/app/assets/javascripts/app/controllers/cti.coffee b/app/assets/javascripts/app/controllers/cti.coffee index aa4a6ad54..c65900f1f 100644 --- a/app/assets/javascripts/app/controllers/cti.coffee +++ b/app/assets/javascripts/app/controllers/cti.coffee @@ -8,6 +8,7 @@ class App.CTI extends App.Controller return if !@isRole('CTI') @list = [] + @backends = [] @meta = active: false counter: 0 @@ -18,40 +19,39 @@ class App.CTI extends App.Controller @load() - App.Event.bind( + @bind('cti_event', (data) => + if data.direction is 'in' + if data.state is 'newCall' + if @switch() + @notify(data) + return if @meta.state[data.id] + @meta.state[data.id] = true + @meta.counter += 1 + @updateNavMenu() + if data.state is 'answer' || data.state is 'hangup' + return if !@meta.state[data.id] + delete @meta.state[data.id] + @meta.counter -= 1 + @updateNavMenu() 'cti_event' - (data) => - console.log('cti_event', data) - if data.direction is 'in' - if data.state is 'newCall' - if @switch() - @notify(data) - return if @meta.state[data.id] - @meta.state[data.id] = true - @meta.counter += 1 - @updateNavMenu() - if data.state is 'answer' || data.state is 'hangup' - return if !@meta.state[data.id] - delete @meta.state[data.id] - @meta.counter -= 1 - @updateNavMenu() + ) + @bind('cti_list_push', (data) => + if data.assets + App.Collection.loadAssets(data.assets) + if data.backends + @backends = data.backends + if data.list + @list = data.list + @render() + 'cti_list_push' + ) + @bind('auth', (data) => + @meta.counter = 0 + ) - 'cti_event' - ) - App.Event.bind( - 'cti_list_push' - (data) => - if data.assets - App.Collection.loadAssets(data.assets) - if data.list - @list = data.list - @render() - 'cti_list_push' - ) - App.Event.bind( - 'auth' - (data) => - @meta.counter = 0 + @bind('cti:reload', => + @load() + 'cti_reload' ) # rerender view, e. g. on langauge change @@ -69,6 +69,8 @@ class App.CTI extends App.Controller success: (data) => if data.assets App.Collection.loadAssets(data.assets) + if data.backends + @backends = data.backends if data.list @list = data.list @render() @@ -82,16 +84,27 @@ class App.CTI extends App.Controller title: title ) - featureActive: => - return true - return true if @Config.get('sipgate_integration') - false + featureActive: -> + true render: -> if !@isRole('CTI') @renderScreenUnauthorized(objectName: 'CTI') return + # check if min one backend is enabled + backendEnabled = false + for backend in @backends + if backend.enabled + backendEnabled = true + if !backendEnabled + @html App.view('cti/not_configured')( + backends: @backends + isAdmin: @isRole('Admin') + ) + @updateNavMenu() + return + format = (time) -> # Minutes and seconds mins = ~~(time / 60) @@ -158,6 +171,10 @@ class App.CTI extends App.Controller @title 'CTI', true @navupdate '#cti' + active: (state) => + return @shown if state is undefined + @shown = state + counter: => count = 0 for item in @list @@ -182,11 +199,6 @@ class App.CTI extends App.Controller processData: true ) - updateNavMenu: => - delay = -> - App.Event.trigger('menu:render') - @delay(delay, 200, 'updateNavMenu') - class CTIRouter extends App.ControllerPermanent constructor: (params) -> super diff --git a/app/assets/javascripts/app/controllers/dashboard.coffee b/app/assets/javascripts/app/controllers/dashboard.coffee index 35d54c302..8493c3585 100644 --- a/app/assets/javascripts/app/controllers/dashboard.coffee +++ b/app/assets/javascripts/app/controllers/dashboard.coffee @@ -59,13 +59,11 @@ class App.Dashboard extends App.Controller @navigate '#clues' active: (state) => - @activeState = state + return @shown if state is undefined + @shown = state if state @mayBeClues() - isActive: => - @activeState - url: -> '#dashboard' @@ -81,9 +79,6 @@ class App.Dashboard extends App.Controller # highlight navbar @navupdate '#dashboard' - hide: -> - # no - changed: -> false @@ -112,6 +107,6 @@ class DashboardRouter extends App.ControllerPermanent persistent: true ) -App.Config.set( 'dashboard', DashboardRouter, 'Routes' ) -App.Config.set( 'Dashboard', { prio: 100, parent: '', name: 'Dashboard', target: '#dashboard', role: ['Agent'], class: 'dashboard' }, 'NavBar' ) -App.Config.set( 'Dashboard', { controller: 'Dashboard', authentication: true }, 'permanentTask' ) +App.Config.set('dashboard', DashboardRouter, 'Routes') +App.Config.set('Dashboard', { prio: 100, parent: '', name: 'Dashboard', target: '#dashboard', key: 'Dashboard', role: ['Agent'], class: 'dashboard' }, 'NavBar') +App.Config.set('Dashboard', { controller: 'Dashboard', authentication: true }, 'permanentTask') diff --git a/app/assets/javascripts/app/controllers/layout_ref.coffee b/app/assets/javascripts/app/controllers/layout_ref.coffee index 8813525e1..794d8a196 100644 --- a/app/assets/javascripts/app/controllers/layout_ref.coffee +++ b/app/assets/javascripts/app/controllers/layout_ref.coffee @@ -1801,11 +1801,6 @@ class CustomerChatRef extends App.Controller # write state App.SessionStorage.set('chat_layout_ref', state) - updateNavMenu: => - delay = -> - App.Event.trigger('menu:render') - @delay(delay, 200) - testChat: (chat, count) -> for i in [0..count] text = @questions[Math.floor(Math.random() * @questions.length)].question diff --git a/app/assets/javascripts/app/controllers/navigation.coffee b/app/assets/javascripts/app/controllers/navigation.coffee index fef0b53e2..d57086efb 100644 --- a/app/assets/javascripts/app/controllers/navigation.coffee +++ b/app/assets/javascripts/app/controllers/navigation.coffee @@ -55,9 +55,10 @@ class App.Navigation extends App.ControllerWidgetPermanent @notificationWidget = undefined renderMenu: => - items = @getItems( navbar: @Config.get( 'NavBar' ) ) + items = @getItems( navbar: @Config.get('NavBar') ) # apply counter and switch info from persistant controllers (if exists) + activeTab = {} itemsNew = [] for item in items shown = true @@ -70,6 +71,8 @@ class App.Navigation extends App.ControllerWidgetPermanent item.counter = worker.counter() if worker.switch item.switch = worker.switch() + if worker.active && worker.active() + activeTab[item.target] = true if worker.featureActive if worker.featureActive() shown = true @@ -80,16 +83,17 @@ class App.Navigation extends App.ControllerWidgetPermanent items = itemsNew # get open tabs to repopen on rerender - open_tab = {} + openTab = {} @$('.open').children('a').each( (i,d) -> href = $(d).attr('href') - open_tab[href] = true + openTab[href] = true ) # render menu @$('.js-menu').html App.view('navigation/menu')( - items: items - open_tab: open_tab + items: items + openTab: openTab + activeTab: activeTab ) # bind on switch changes and execute it on controller diff --git a/app/assets/javascripts/app/controllers/organization_profile.coffee b/app/assets/javascripts/app/controllers/organization_profile.coffee index af55c134a..764833e2f 100644 --- a/app/assets/javascripts/app/controllers/organization_profile.coffee +++ b/app/assets/javascripts/app/controllers/organization_profile.coffee @@ -26,7 +26,6 @@ class App.OrganizationProfile extends App.Controller meta.head = organization.displayName() meta.title = organization.displayName() meta.iconClass = organization.icon() - meta url: => @@ -41,9 +40,6 @@ class App.OrganizationProfile extends App.Controller render: (organization) => - # update taskbar with new meta data - App.TaskManager.touch(@task_key) - if !@doNotLog @doNotLog = 1 @recentView('Organization', @organization_id) @@ -55,6 +51,7 @@ class App.OrganizationProfile extends App.Controller new Object( el: elLocal.find('.js-object-container') organization: organization + task_key: @task_key ) new App.TicketStats( @@ -83,6 +80,9 @@ class Object extends App.Controller render: (organization) => + # update taskbar with new meta data + App.TaskManager.touch(@task_key) + # get display data organizationData = [] for attributeName, attributeConfig of App.Organization.attributesGet('view') @@ -117,6 +117,7 @@ class Object extends App.Controller organization_id: organization.id container: @el.closest('.content') ) + editOrganization = => new App.ControllerGenericEdit( id: organization.id diff --git a/app/assets/javascripts/app/controllers/ticket_overview.coffee b/app/assets/javascripts/app/controllers/ticket_overview.coffee index a493c67c8..6606e94c1 100644 --- a/app/assets/javascripts/app/controllers/ticket_overview.coffee +++ b/app/assets/javascripts/app/controllers/ticket_overview.coffee @@ -29,10 +29,8 @@ class App.TicketOverview extends App.Controller @delay(update, 2800, 'overview:fetch') active: (state) => - @activeState = state - - isActive: => - @activeState + return @shown if state is undefined + @shown = state url: => "#ticket/view/#{@view}" @@ -399,7 +397,7 @@ class Table extends App.Controller view: @view # start bulk action observ - @el.append( @bulkForm.el ) + @el.append(@bulkForm.el) if @$('.table-overview').find('input[name="bulk"]:checked').length isnt 0 @bulkForm.show() @@ -431,7 +429,7 @@ class Table extends App.Controller ticket_id = $(element).val() for ticket_id_selected in ticketIDs if ticket_id_selected is ticket_id - $(element).attr( 'checked', true ) + $(element).attr('checked', true) ) viewmode: (e) => @@ -591,8 +589,8 @@ class BulkForm extends App.Controller params.ticket_id = ticket.id params.form_id = @form_id - sender = App.TicketArticleSender.findByAttribute( 'name', 'Agent' ) - type = App.TicketArticleType.find( params['type_id'] ) + sender = App.TicketArticleSender.findByAttribute('name', 'Agent') + type = App.TicketArticleType.find(params['type_id']) params.sender_id = sender.id if !params['internal'] @@ -789,7 +787,7 @@ class TicketOverviewRouter extends App.ControllerPermanent persistent: true ) -App.Config.set( 'ticket/view', TicketOverviewRouter, 'Routes' ) -App.Config.set( 'ticket/view/:view', TicketOverviewRouter, 'Routes' ) -App.Config.set( 'TicketOverview', { controller: 'TicketOverview', authentication: true }, 'permanentTask' ) -App.Config.set( 'TicketOverview', { prio: 1000, parent: '', name: 'Overviews', target: '#ticket/view', role: ['Agent', 'Customer'], class: 'overviews' }, 'NavBar' ) +App.Config.set('ticket/view', TicketOverviewRouter, 'Routes') +App.Config.set('ticket/view/:view', TicketOverviewRouter, 'Routes') +App.Config.set('TicketOverview', { controller: 'TicketOverview', authentication: true }, 'permanentTask') +App.Config.set('TicketOverview', { prio: 1000, parent: '', name: 'Overviews', target: '#ticket/view', key: 'TicketOverview', role: ['Agent', 'Customer'], class: 'overviews' }, 'NavBar') diff --git a/app/assets/javascripts/app/controllers/user_profile.coffee b/app/assets/javascripts/app/controllers/user_profile.coffee index b110ce32c..5e448a589 100644 --- a/app/assets/javascripts/app/controllers/user_profile.coffee +++ b/app/assets/javascripts/app/controllers/user_profile.coffee @@ -8,16 +8,13 @@ class App.UserProfile extends App.Controller return # fetch new data if needed - @subscribeId = App.User.full(@user_id, @render) + App.User.full(@user_id, @render) # rerender view, e. g. on langauge change @bind 'ui:rerender', => return if !@authenticate(true) @render(App.User.fullLocal(@user_id)) - release: => - App.User.unsubscribe(@subscribeId) - meta: => meta = url: @url() @@ -43,9 +40,6 @@ class App.UserProfile extends App.Controller render: (user) => - # update taskbar with new meta data - App.TaskManager.touch(@task_key) - if !@doNotLog @doNotLog = 1 @recentView('User', @user_id) @@ -55,8 +49,9 @@ class App.UserProfile extends App.Controller )) new Object( - el: elLocal.find('.js-object-container') - user: user + el: elLocal.find('.js-object-container') + user: user + task_key: @task_key ) new App.TicketStats( @@ -70,7 +65,6 @@ class App.UserProfile extends App.Controller genericObject: user ) - class Object extends App.Controller events: 'focusout [contenteditable]': 'update' @@ -86,6 +80,9 @@ class Object extends App.Controller render: (user) => + # update taskbar with new meta data + App.TaskManager.touch(@task_key) + # get display data userData = [] for attributeName, attributeConfig of App.User.attributesGet('view') diff --git a/app/assets/javascripts/app/models/setting.coffee b/app/assets/javascripts/app/models/setting.coffee index baedf47f0..57180b5e3 100644 --- a/app/assets/javascripts/app/models/setting.coffee +++ b/app/assets/javascripts/app/models/setting.coffee @@ -10,5 +10,29 @@ class App.Setting extends App.Model @set: (name, value, options = {}) -> setting = App.Setting.findByAttribute('name', name) setting.state_current.value = value + if !options.done + options.done = -> + App.Setting.preferencesPost(@) + + if !options.fail + options.fail = (settings, details) -> + App.Event.trigger 'notify', { + type: 'error' + msg: App.i18n.translateContent(details.error_human || details.error || 'Unable to update object!') + timeout: 2000 + } setting.save(options) App.Config.set(name, value) + + @preferencesPost: (setting) -> + return if !setting.preferences + if setting.preferences.render + App.Event.trigger('ui:rerender') + + if setting.preferences.trigger + trigger = setting.preferences.trigger + delay = -> App.Event.trigger(trigger) + App.Delay.set(delay, 20) + + if setting.preferences.session_check + App.Auth.loginCheck() diff --git a/app/assets/javascripts/app/views/cti/not_configured.jst.eco b/app/assets/javascripts/app/views/cti/not_configured.jst.eco new file mode 100644 index 000000000..70f05cffa --- /dev/null +++ b/app/assets/javascripts/app/views/cti/not_configured.jst.eco @@ -0,0 +1,10 @@ +
+

<%- @T('Caller log') %>

+

<%- @T('Sorry, currently is no CTI backend enabled!') %>

+

<%- @T('We support') %>:

+ +
\ No newline at end of file diff --git a/app/assets/javascripts/app/views/navigation/menu.jst.eco b/app/assets/javascripts/app/views/navigation/menu.jst.eco index 218303897..e3ed64a40 100644 --- a/app/assets/javascripts/app/views/navigation/menu.jst.eco +++ b/app/assets/javascripts/app/views/navigation/menu.jst.eco @@ -1,6 +1,6 @@ <% for item in @items: %> <% if item.child: %> -