-
- <% for tab in @tabs: %>
-
- <%- @T( tab.name ) %> + <% if @tabs.length > 1: %> +
- <%- @T( tab.name ) %> + <% end %> +
-
+ <% for tab in @tabs: %>
+
diff --git a/app/assets/javascripts/app/controllers/_application_controller_generic.coffee b/app/assets/javascripts/app/controllers/_application_controller_generic.coffee index 53358b21e..26f371286 100644 --- a/app/assets/javascripts/app/controllers/_application_controller_generic.coffee +++ b/app/assets/javascripts/app/controllers/_application_controller_generic.coffee @@ -170,7 +170,7 @@ class App.ControllerGenericIndex extends App.Controller # append content table params = _.extend( { - el: @el.find('.table-overview') + el: @$('.table-overview') model: App[ @genericObject ] objects: objects bindRow: @@ -301,9 +301,9 @@ class App.ControllerDrox extends App.Controller inline: (data) -> @html App.view('generic/drox')(data) if data.text - @el.find('.drox-body').text(data.text) + @$('.drox-body').text(data.text) if data.html - @el.find('.drox-body').html(data.html) + @$('.drox-body').html(data.html) template: (data) -> drox = $( App.view('generic/drox')(data) ) @@ -311,50 +311,6 @@ class App.ControllerDrox extends App.Controller drox.find('.drox-body').append(content) drox -class App.ControllerLevel2 extends App.ControllerContent - events: - 'click [data-toggle="tabnav"]': 'toggle', - - constructor: -> - super - - render: -> - - # set title - @title @page.title - @navupdate @page.nav - - @html App.view('generic/admin_level2/index')( - page: @page - menus: @menu - type: @type - target: @target - ) - - if !@target - @target = @menu[0]['target'] - - for menu in @menu - @el.find('.nav-tab-content').append('
') - if menu.controller && ( @toggleable is true || ( @toggleable is false && menu.target is @target ) ) - params = menu.params || {} - params.el = @el.find( '#' + menu.target ) - new menu.controller( params ) - - @el.find('.tabbable').addClass('hide') - @el.find( '#' + @target ).removeClass('hide') - @el.find('[data-toggle="tabnav"][href*="/' + @target + '"]').parent().addClass('active') - - toggle: (e) -> - return true if @toggleable is false - e.preventDefault() - target = $(e.target).data('target') - $(e.target).parents('ul').find('li').removeClass('active') - $(e.target).parents('li').addClass('active') - @el.find('.tabbable').addClass('hide') - @el.find('#' + target).removeClass('hide') -# window.scrollTo(0,0) - class App.ControllerTabs extends App.Controller events: 'click .nav-tabs [data-toggle="tab"]': 'tabRemember', @@ -372,24 +328,25 @@ class App.ControllerTabs extends App.Controller # insert content for tab in @tabs - @el.find('.tab-content').append("") + @$('.tab-content').append("") if tab.controller params = tab.params || {} params.name = tab.name params.target = tab.target - params.el = @el.find( "##{tab.target}" ) + params.el = @$( "##{tab.target}" ) new tab.controller( params ) - # check if tabs need to be hidden - # if @tabs.length <= 1 - # @el.find('.page-tabs').addClass('hide') + # check if tabs need to be show / cant' use .tab(), because tabs are note shown (only one tab exists) + if @tabs.length <= 1 + @$('.tab-pane').addClass('active') + return # set last or first tab to 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') + if @lastActiveTab && @$(".nav-tabs li a[href=#{@lastActiveTab}]")[0] + @$(".nav-tabs li a[href=#{@lastActiveTab}]").tab('show') else - @el.find('.nav-tabs li:first a').tab('show') + @$('.nav-tabs li:first a').tab('show') tabRemember: (e) => @lastActiveTab = $(e.target).attr('href') @@ -439,15 +396,22 @@ class App.ControllerNavSidbar extends App.ControllerContent else item.active = false - @render(selectedItem) + @renderContainer(selectedItem) + @renderNavBar(selectedItem) @bind( 'ui:rerender' => - @render(selectedItem, true) + @renderNavBar(selectedItem) ) - render: (selectedItem, force) => + renderContainer: => + return if $( ".#{@configKey}" )[0] + @html App.view('generic/navbar_level2/index')( + className: @configKey + ) + + renderNavBar: (selectedItem) => # remember latest selected item selectedItemMeta = @@ -455,17 +419,24 @@ class App.ControllerNavSidbar extends App.ControllerContent date: new Date App.Config.set("Runtime::#{@configKey}", selectedItemMeta) - if !$( ".#{@configKey}" )[0] || force - @html App.view('generic/navbar_l2')( - groups: @groupsSorted - className: @configKey - ) + @$('.sidebar').html App.view('generic/navbar_level2/navbar')( + groups: @groupsSorted + className: @configKey + ) if selectedItem - @el.find('li').removeClass('active') - @el.find("a[href=\"#{selectedItem.target}\"]").parent().addClass('active') + @$('li').removeClass('active') + @$("a[href=\"#{selectedItem.target}\"]").parent().addClass('active') + @executeController(selectedItem) - new selectedItem.controller( - el: @el.find('.main') + executeController: (selectedItem) => + + # in case of rerendering + if @activeController && @activeController.render + @activeController.render() + return + + @activeController = new selectedItem.controller( + el: @$('.main') ) class App.GenericHistory extends App.ControllerModal @@ -580,7 +551,7 @@ class App.ActionRow extends App.Controller for item in @items do (item) => - @el.find('[data-type="' + item.name + '"]').on( + @$('[data-type="' + item.name + '"]').on( 'click', (e) -> e.preventDefault() @@ -624,13 +595,13 @@ class App.Sidebar extends App.Controller # init content callback for item in @items if item.callback - item.callback( @el.find( '.sidebar[data-tab="' + item.name + '"] .sidebar-content' ) ) + item.callback( @$( '.sidebar[data-tab="' + item.name + '"] .sidebar-content' ) ) # add item acctions for item in @items if item.actions new App.ActionRow( - el: @el.find('.sidebar[data-tab="' + item.name + '"] .js-actions') + el: @$('.sidebar[data-tab="' + item.name + '"] .js-actions') items: item.actions type: 'small' ) @@ -675,13 +646,13 @@ class App.Sidebar extends App.Controller @tabs.removeClass('active') # add active state - @el.find('.tabsSidebar-tab[data-tab=' + name + ']').addClass('active') + @$('.tabsSidebar-tab[data-tab=' + name + ']').addClass('active') # hide all content tabs @sidebars.addClass('hide') # show active tab content - tabContent = @el.find('.sidebar[data-tab=' + name + ']') + tabContent = @$('.sidebar[data-tab=' + name + ']') tabContent.removeClass('hide') # remember current tab diff --git a/app/assets/javascripts/app/controllers/package.coffee b/app/assets/javascripts/app/controllers/package.coffee index 52abab74f..123621a7a 100644 --- a/app/assets/javascripts/app/controllers/package.coffee +++ b/app/assets/javascripts/app/controllers/package.coffee @@ -16,15 +16,16 @@ class Index extends App.ControllerContent @ajax( id: 'packages', type: 'GET', - url: @apiPath + '/packages', + url: "#{@apiPath}/packages", processData: true, success: (data) => - @render(data) + @packages = data + @render() ) - render: (data) -> + render: -> - for item in data.packages + for item in @packages item.action = [] if item.state == 'installed' # item.action = ['uninstall', 'deactivate'] @@ -36,7 +37,7 @@ class Index extends App.ControllerContent @html App.view('package')( head: 'Dashboard' - packages: data.packages + packages: @packages ) action: (e) -> @@ -48,13 +49,13 @@ class Index extends App.ControllerContent if httpType @ajax( - id: 'packages', - type: httpType, - url: @apiPath + '/packages', - data: JSON.stringify( { id: id } ), - processData: false, - success: (data) => + id: 'packages' + type: httpType + url: "#{@apiPath}/packages", + data: JSON.stringify( { id: id } ) + processData: false + success: => @load() ) -App.Config.set( 'Packages', { prio: 1000, name: 'Packages', parent: '#system', target: '#system/package', controller: Index, role: ['Admin'] }, 'NavBarAdmin' ) \ No newline at end of file +App.Config.set( 'Packages', { prio: 1000, name: 'Packages', parent: '#system', target: '#system/package', controller: Index, role: ['Admin'] }, 'NavBarAdmin' ) diff --git a/app/assets/javascripts/app/controllers/session.coffee b/app/assets/javascripts/app/controllers/session.coffee index f149c081b..c69e5be51 100644 --- a/app/assets/javascripts/app/controllers/session.coffee +++ b/app/assets/javascripts/app/controllers/session.coffee @@ -1,7 +1,6 @@ class Index extends App.ControllerContent - divClass: 'lala' events: - 'click [data-type="delete"]': 'destroy' + 'click .js-delete': 'destroy' constructor: -> super @@ -27,26 +26,25 @@ class Index extends App.ControllerContent url: @apiPath + '/sessions' success: (data) => @stopLoading() - @render(data) + App.Collection.loadAssets(data.assets) + @sessions = data.sessions + @render() ) - render: (data) -> - - # load assets - App.Collection.loadAssets( data.assets ) + render: -> # fill users - for session in data.sessions + for session in @sessions if session.data && session.data.user_id - session.data.user = App.User.find( session.data.user_id ) + session.data.user = App.User.find(session.data.user_id) @html App.view('session')( - sessions: data.sessions + sessions: @sessions ) destroy: (e) -> e.preventDefault() - sessionId = $( e.target ).closest('a').data('session-id') + sessionId = $(e.target ).closest('a').data('session-id') @ajax( id: 'sessions/' + sessionId type: 'DELETE' @@ -55,4 +53,4 @@ class Index extends App.ControllerContent @load() ) -App.Config.set( 'Session', { prio: 3700, name: 'Sessions', parent: '#system', target: '#system/sessions', controller: Index, role: ['Admin'] }, 'NavBarAdmin' ) \ No newline at end of file +App.Config.set('Session', { prio: 3700, name: 'Sessions', parent: '#system', target: '#system/sessions', controller: Index, role: ['Admin'] }, 'NavBarAdmin' ) \ No newline at end of file diff --git a/app/assets/javascripts/app/controllers/translation.coffee b/app/assets/javascripts/app/controllers/translation.coffee index 5362752f2..393971d0d 100644 --- a/app/assets/javascripts/app/controllers/translation.coffee +++ b/app/assets/javascripts/app/controllers/translation.coffee @@ -11,47 +11,87 @@ class Index extends App.ControllerContent return if !@authenticate() @title 'Translations', true - + @locale = App.i18n.get() @render() + @bind( + 'i18n:translation_update', + => + @load() + ) render: => - @html App.view('translation/index')() - options = {} locales = App.Locale.all() + currentLanguage = @locale for locale in locales - options[locale.locale] = locale.name - configure_attributes = [ - { name: 'locale', display: '', tag: 'select', null: false, class: 'input', options: options, default: App.i18n.get() }, - ] - load = (params) => - @translationToDo = new TranslationToDo( - el: @$('.js-ToDo') - locale: params.locale - ) - @translationList = new TranslationList( - el: @$('.js-List') - locale: params.locale - ) - - new App.ControllerForm( - el: @$('.language') - model: { configure_attributes: configure_attributes } - autofocus: false - handlers: [load] + if locale.locale is @locale + currentLanguage = locale.name + @html App.view('translation/index')( + currentLanguage: currentLanguage ) + @load() + + load: => + @ajax( + id: 'translations_admin' + type: 'GET' + url: "#{@apiPath}/translations/admin/lang/#{@locale}" + processData: true + success: (data, status, xhr) => + @times = [] + @stringsNotTranslated = [] + @stringsTranslated = [] + for item in data.list + + # if item has changed + if item[2] isnt item[3] + @showAction() + + # collect items + if item[4] is 'time' + @times.push item + else + if item[2] is '' + @stringsNotTranslated.push item + else + @stringsTranslated.push item + + if !@translationToDo + @translationToDo = new TranslationToDo( + el: @$('.js-ToDo') + locale: @locale + ) + @translationToDo.update( + stringsNotTranslated: @stringsNotTranslated + stringsTranslated: @stringsTranslated + times: @times + ) + if !@translationList + @translationList = new TranslationList( + el: @$('.js-List') + locale: @locale + ) + @translationList.update( + stringsNotTranslated: @stringsNotTranslated + stringsTranslated: @stringsTranslated + times: @times + ) + ) + + showAction: => + @$('.js-changes').removeClass('hidden') release: => rerender = -> App.Event.trigger('ui:rerender') - if @translationToDo.changes() || @translationList.changes() + console.log('rr') + if @translationList.changes() App.Delay.set(rerender, 400) + console.log('111', @translationList.changes()) hideAction: => @el.closest('.content').find('.js-changes').addClass('hidden') pushChanges: => - locale = @$('[name="locale"]').val() - @loader = new App.ControllerModalLoading( head: 'Push my changes' message: 'Pushing translations to i18n.zammad.com' @@ -62,7 +102,7 @@ class Index extends App.ControllerContent id: 'translations' type: 'PUT' url: "#{@apiPath}/translations/push" - data: JSON.stringify(locale: locale) + data: JSON.stringify(locale: @locale) processData: false success: (data, status, xhr) => @loader.update('Thanks for contributing!') @@ -73,8 +113,6 @@ class Index extends App.ControllerContent ) resetChanges: => - locale = @$('[name="locale"]').val() - @loader = new App.ControllerModalLoading( head: 'Reset changes' message: 'Reseting changes...' @@ -85,11 +123,10 @@ class Index extends App.ControllerContent id: 'translations' type: 'POST' url: "#{@apiPath}/translations/reset" - data: JSON.stringify(locale: locale) + data: JSON.stringify(locale: @locale) processData: false success: (data, status, xhr) => - App.Event.trigger('i18n:translation_todo_reload') - App.Event.trigger('i18n:translation_list_reload') + App.Event.trigger('i18n:translation_update') @hideAction() @loader.hide() error: => @@ -97,8 +134,6 @@ class Index extends App.ControllerContent ) syncChanges: => - locale = @$('[name="locale"]').val() - @loader = new App.ControllerModalLoading( head: 'Get latest translations' message: 'Getting latest translations from i18n.zammad.com' @@ -106,8 +141,7 @@ class Index extends App.ControllerContent ) hide = => - App.Event.trigger('i18n:translation_todo_reload') - App.Event.trigger('i18n:translation_list_reload') + App.Event.trigger('i18n:translation_update') @hideAction() @loader.hide(1) @@ -131,19 +165,17 @@ class Index extends App.ControllerContent ) class TranslationToDo extends App.Controller - hasChanges: false events: 'click .js-create': 'create' 'click .js-theSame': 'same' constructor: -> super + + update: (data) => + for key, value of data + @[key] = value @render() - @bind( - 'i18n:translation_todo_reload', - => - @render() - ) render: => @@ -151,42 +183,37 @@ class TranslationToDo extends App.Controller @html App.view('translation/english')() return - if !App.i18n.getNotTranslated(@locale) + if !App.i18n.getNotTranslated(@locale) && _.isEmpty(@stringsNotTranslated) @html '' return - listNotTranslated = [] - for key, value of App.i18n.getNotTranslated(@locale) - item = [ '', key, '', ''] - listNotTranslated.push item + if App.i18n.getNotTranslated(@locale) + for key, value of App.i18n.getNotTranslated(@locale) + item = [ '', key, '', ''] + @stringsNotTranslated.push item @html App.view('translation/todo')( - list: listNotTranslated + list: @stringsNotTranslated ) - showAction: => - @el.closest('.content').find('.js-changes').removeClass('hidden') - - changes: => - @hasChanges - create: (e) => e.preventDefault() - @hasChanges = true - @showAction() field = $(e.target).closest('tr').find('.js-Item') + id = field.data('id') source = field.data('source') + format = 'string' target = field.val() + return if !target # remove from not translated list $(e.target).closest('tr').remove() # local update - App.i18n.removeNotTranslated( @locale, source ) + App.i18n.removeNotTranslated(@locale, source) # update runtime if same language is used if App.i18n.get() is @locale - App.i18n.setMap( source, target, 'string' ) + App.i18n.setMap(source, target, 'string') # remote update params = @@ -195,20 +222,27 @@ class TranslationToDo extends App.Controller target: target target_initial: '' + if id + method = 'PUT' + params.id = id + url = "#{@apiPath}/translations/#{id}" + else + method = 'POST' + url = "#{@apiPath}/translations" + @ajax( id: 'translations' - type: 'POST' - url: @apiPath + '/translations' + type: method + url: url data: JSON.stringify(params) processData: false success: (data, status, xhr) -> - App.Event.trigger('i18n:translation_list_reload') + App.Event.trigger('i18n:translation_update') ) same: (e) => e.preventDefault() @hasChanges = true - @showAction() field = $(e.target).closest('tr').find('.js-Item') source = field.data('source') @@ -216,11 +250,11 @@ class TranslationToDo extends App.Controller $(e.target).closest('tr').remove() # local update - App.i18n.removeNotTranslated( @locale, source ) + App.i18n.removeNotTranslated(@locale, source) # update runtime if same language is used if App.i18n.get() is @locale - App.i18n.setMap( source, source, 'string' ) + App.i18n.setMap(source, source, 'string') # remote update params = @@ -236,65 +270,33 @@ class TranslationToDo extends App.Controller data: JSON.stringify(params) processData: false success: (data, status, xhr) -> - App.Event.trigger('i18n:translation_list_reload') + App.Event.trigger('i18n:translation_update') ) class TranslationList extends App.Controller hasChanges: false events: - 'blur .js-translated input': 'update' - 'click .js-translated .js-Reset': 'reset' + 'blur .js-translated input': 'updateItem' + 'click .js-translated .js-Reset': 'resetItem' constructor: -> super - @load() - @bind( - 'i18n:translation_list_reload', - => - @load() - ) - load: => - @startLoading() - @ajax( - id: 'translations_admin' - type: 'GET' - url: @apiPath + "/translations/admin/lang/#{@locale}" - processData: true - success: (data, status, xhr) => - @stopLoading() - @render(data) - ) - - render: (data = {}) => - @strings = [] - @times = [] - for item in data.list - if item[4] is 'time' - @times.push item - else - @strings.push item + update: (data) => + for key, value of data + @[key] = value + @render() + render: => @html App.view('translation/list')( times: @times - strings: @strings + strings: @stringsTranslated ) - ui = @ - @changesAvailable = false - @$('.js-Item').each( (e) -> - id = $(@).data('id') - ui.updateRow(id) - ) - if @changesAvailable - @showAction() - - showAction: => - @el.closest('.content').find('.js-changes').removeClass('hidden') changes: => @hasChanges - reset: (e) -> + resetItem: (e) -> e.preventDefault() @hasChanges = true field = $(e.target).closest('tr').find('.js-Item') @@ -303,38 +305,12 @@ class TranslationList extends App.Controller initial = field.data('initial') format = field.data('format') - # if it's translated by user it self, delete it - if !initial || initial is '' - - # locale reset - $(e.target).closest('tr').remove() - - # update runtime if same language is used - if App.i18n.get() is @locale - App.i18n.setMap( source, '', format ) - - # remote reset - params = - id: id - @ajax( - id: 'translations' - type: 'DELETE' - url: @apiPath + '/translations/' + id - data: JSON.stringify(params) - processData: false - success: => - App.i18n.setNotTranslated( @locale, source ) - App.Event.trigger('i18n:translation_todo_reload') - ) - return - - # update runtime if same language is used if App.i18n.get() is @locale - App.i18n.setMap( source, initial, format ) + App.i18n.setMap(source, initial, format) # locale reset - field.val( initial ) + field.val(initial) @updateRow(id) # remote reset @@ -345,24 +321,29 @@ class TranslationList extends App.Controller @ajax( id: 'translations' type: 'PUT' - url: @apiPath + '/translations/' + id + url: "#{@apiPath}/translations/#{id}" data: JSON.stringify(params) processData: false + success: (data, status, xhr) -> + App.Event.trigger('i18n:translation_update') ) - update: (e) -> + updateItem: (e) -> e.preventDefault() - id = $( e.target ).data('id') - source = $( e.target ).data('source') - format = $( e.target ).data('format') - target = $( e.target ).val() + @hasChanges = true + field = $(e.target).closest('tr').find('.js-Item') + id = field.data('id') + source = field.data('source') + format = field.data('format') + target = field.val() + return if !target # local update @updateRow(id) # update runtime if same language is used if App.i18n.get() is @locale - App.i18n.setMap( source, target, format ) + App.i18n.setMap(source, target, format) # remote update params = @@ -372,9 +353,11 @@ class TranslationList extends App.Controller @ajax( id: 'translations' type: 'PUT' - url: @apiPath + '/translations/' + id + url: "#{@apiPath}/translations/#{id}" data: JSON.stringify(params) processData: false + success: (data, status, xhr) -> + App.Event.trigger('i18n:translation_update') ) updateRow: (id) => @@ -384,11 +367,10 @@ class TranslationList extends App.Controller reset = field.closest('tr').find('.js-Reset') if current isnt initial @changesAvailable = true - @showAction() - reset.show() + reset.removeClass('hidden') reset.closest('tr').addClass('warning') else - reset.hide() + reset.addClass('hidden') reset.closest('tr').removeClass('warning') -App.Config.set( 'Translation', { prio: 1800, parent: '#system', name: 'Translations', target: '#system/translation', controller: Index, role: ['Admin'] }, 'NavBarAdmin' ) +App.Config.set('Translation', { prio: 1800, parent: '#system', name: 'Translations', target: '#system/translation', controller: Index, role: ['Admin'] }, 'NavBarAdmin' ) diff --git a/app/assets/javascripts/app/views/generic/navbar_l2.jst.eco b/app/assets/javascripts/app/views/generic/navbar_l2.jst.eco deleted file mode 100644 index 81a10f246..000000000 --- a/app/assets/javascripts/app/views/generic/navbar_l2.jst.eco +++ /dev/null @@ -1,17 +0,0 @@ - - \ No newline at end of file diff --git a/app/assets/javascripts/app/views/generic/navbar_level2/index.jst.eco b/app/assets/javascripts/app/views/generic/navbar_level2/index.jst.eco new file mode 100644 index 000000000..e5df2f0fe --- /dev/null +++ b/app/assets/javascripts/app/views/generic/navbar_level2/index.jst.eco @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/app/assets/javascripts/app/views/generic/navbar_level2/navbar.jst.eco b/app/assets/javascripts/app/views/generic/navbar_level2/navbar.jst.eco new file mode 100644 index 000000000..17ab75490 --- /dev/null +++ b/app/assets/javascripts/app/views/generic/navbar_level2/navbar.jst.eco @@ -0,0 +1,12 @@ +<% if @groups: %> + <% for group in @groups: %> +