From a062370869f1db89318d85de67e50a003299b642 Mon Sep 17 00:00:00 2001 From: Martin Edenhofer Date: Tue, 30 Jul 2013 15:58:33 +0200 Subject: [PATCH 01/88] Init move to BS3. --- .../_application_controller.js.coffee | 6 +- .../_application_controller_form.js.coffee | 16 +- .../controllers/_channel/facebook.js.coffee | 3 - .../controllers/_channel/twitter.js.coffee | 5 - .../app/controllers/_channel/web.js.coffee | 2 +- .../app/controllers/_default_navbar.js.coffee | 3 +- .../app/controllers/channel.js.coffee | 35 +- .../app/controllers/chat_widget.js.coffee | 2 + .../app/controllers/footer.js.coffee | 4 +- .../app/controllers/groups.js.coffee | 6 +- .../app/controllers/maintenance.js.coffee | 6 +- .../app/controllers/manage.js.coffee | 76 + .../app/controllers/navigation.js.coffee | 8 +- .../app/controllers/organizations.js.coffee | 9 +- .../app/controllers/overview.js.coffee | 10 +- .../app/controllers/package.js.coffee | 4 +- .../app/controllers/scheduler.js.coffee | 8 +- .../app/controllers/session.js.coffee | 20 +- .../app/controllers/settings.js.coffee | 125 +- .../javascripts/app/controllers/sla.js.coffee | 10 +- .../app/controllers/template_widget.js.coffee | 4 +- .../app/controllers/text_module.js.coffee | 10 +- .../app/controllers/ticket_overview.js.coffee | 66 +- .../app/controllers/ticket_zoom.js.coffee | 1 + .../app/controllers/trigger.js.coffee | 8 +- .../controllers/user_info_widget.js.coffee | 9 +- .../app/controllers/users.js.coffee | 34 +- .../lib/app_post/interface_handle.js.coffee | 2 +- .../app/lib/app_post/task_manager.js.coffee | 2 +- .../javascripts/app/lib/bootstrap/modal.js | 241 + .../javascripts/app/models/overview.js.coffee | 8 +- .../app/views/agent_ticket_create.jst.eco | 35 +- .../app/views/agent_ticket_customer.jst.eco | 20 +- .../app/views/agent_ticket_history.jst.eco | 21 +- .../app/views/agent_ticket_merge.jst.eco | 38 +- .../app/views/agent_ticket_view.jst.eco | 45 +- .../views/agent_ticket_view/content.jst.eco | 35 + .../views/agent_ticket_view/navbar.jst.eco | 7 + .../app/views/agent_user_create.jst.eco | 22 +- .../javascripts/app/views/chat_widget.jst.eco | 4 +- .../javascripts/app/views/dashboard.jst.eco | 4 +- .../views/dashboard/activity_stream.jst.eco | 6 +- .../app/views/dashboard/rss.jst.eco | 6 +- .../app/views/dashboard/ticket.jst.eco | 14 +- .../views/dashboard/ticket_settings.jst.eco | 26 +- .../app/views/generic/admin/edit.jst.eco | 21 +- .../app/views/generic/admin/index.jst.eco | 29 +- .../app/views/generic/admin/new.jst.eco | 20 +- .../views/generic/admin_level2/index.jst.eco | 21 +- .../app/views/generic/attribute.jst.eco | 10 +- .../app/views/generic/autocompletion.jst.eco | 2 +- .../app/views/generic/input.jst.eco | 2 +- .../app/views/generic/navbar_l2.jst.eco | 19 + .../app/views/generic/radio.jst.eco | 2 +- .../app/views/generic/select.jst.eco | 4 +- .../app/views/generic/textarea.jst.eco | 2 +- .../javascripts/app/views/link/add.jst.eco | 22 +- .../javascripts/app/views/link/info.jst.eco | 8 +- .../javascripts/app/views/login.jst.eco | 21 +- .../javascripts/app/views/maintenance.jst.eco | 28 +- .../javascripts/app/views/modal.jst.eco | 30 +- .../javascripts/app/views/navigation.jst.eco | 131 +- .../app/views/profile/language.jst.eco | 2 +- .../app/views/profile/password.jst.eco | 4 +- .../app/views/reset_password.jst.eco | 6 +- .../app/views/reset_password_change.jst.eco | 10 +- .../javascripts/app/views/session.jst.eco | 3 +- .../javascripts/app/views/signup.jst.eco | 8 +- .../javascripts/app/views/tag_widget.jst.eco | 4 +- .../app/views/task_widget_tasks.jst.eco | 2 +- .../app/views/template_widget.jst.eco | 24 +- .../app/views/ticket_action.jst.eco | 4 +- .../javascripts/app/views/ticket_zoom.jst.eco | 34 +- .../views/ticket_zoom/article_view.jst.eco | 7 +- .../app/views/ticket_zoom/edit.jst.eco | 31 +- .../app/views/ticket_zoom/ticket_info.jst.eco | 2 +- .../javascripts/app/views/user_info.jst.eco | 4 +- app/assets/stylesheets/application.css | 3 +- .../stylesheets/bootstrap-glyphicons.css | 2 + app/assets/stylesheets/bootstrap.css | 7452 +++++++---------- app/assets/stylesheets/zzz.css | 465 +- .../fonts/glyphiconshalflings-regular.eot | Bin 0 -> 33358 bytes .../fonts/glyphiconshalflings-regular.otf | Bin 0 -> 18116 bytes .../fonts/glyphiconshalflings-regular.svg | 175 + .../fonts/glyphiconshalflings-regular.ttf | Bin 0 -> 32896 bytes .../fonts/glyphiconshalflings-regular.woff | Bin 0 -> 18944 bytes 86 files changed, 4536 insertions(+), 5104 deletions(-) create mode 100644 app/assets/javascripts/app/controllers/manage.js.coffee create mode 100644 app/assets/javascripts/app/lib/bootstrap/modal.js create mode 100644 app/assets/javascripts/app/views/agent_ticket_view/content.jst.eco create mode 100644 app/assets/javascripts/app/views/agent_ticket_view/navbar.jst.eco create mode 100644 app/assets/javascripts/app/views/generic/navbar_l2.jst.eco create mode 100755 app/assets/stylesheets/bootstrap-glyphicons.css create mode 100755 public/assets/fonts/glyphiconshalflings-regular.eot create mode 100755 public/assets/fonts/glyphiconshalflings-regular.otf create mode 100755 public/assets/fonts/glyphiconshalflings-regular.svg create mode 100755 public/assets/fonts/glyphiconshalflings-regular.ttf create mode 100755 public/assets/fonts/glyphiconshalflings-regular.woff diff --git a/app/assets/javascripts/app/controllers/_application_controller.js.coffee b/app/assets/javascripts/app/controllers/_application_controller.js.coffee index a9392af40..dca67a5c1 100644 --- a/app/assets/javascripts/app/controllers/_application_controller.js.coffee +++ b/app/assets/javascripts/app/controllers/_application_controller.js.coffee @@ -426,7 +426,7 @@ class App.ControllerContent extends App.Controller $('#content_permanent').hide() class App.ControllerModal extends App.Controller - className: 'modal hide fade', + className: 'modal fade', tag: 'div', events: @@ -476,8 +476,8 @@ class App.ControllerModal extends App.Controller @el.bind('hidden', => # navigate back to home page - if @pageData && @pageData.home - @navigate @pageData.home +# if @pageData && @pageData.home +# @navigate @pageData.home # navigate back if params && params.navigateBack 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 b70c44dec..a2e1f6d29 100644 --- a/app/assets/javascripts/app/controllers/_application_controller_form.js.coffee +++ b/app/assets/javascripts/app/controllers/_application_controller_form.js.coffee @@ -362,10 +362,10 @@ class App.ControllerForm extends App.Controller params: form_id: @form_id text: - uploadButton: '' + uploadButton: '' template: '
' + '
{dragZoneText}
' + - '
{uploadButtonText}
' + + '
{uploadButtonText}
' + '' + '
', classes: @@ -1051,14 +1051,14 @@ class App.ControllerForm extends App.Controller if !_.isArray(name) name = [name] for key in name - el.find('[name="' + key + '"]').parents('.control-group').removeClass('hide') + el.find('[name="' + key + '"]').parents('.form-group').removeClass('hide') el.find('[name="' + key + '"]').removeClass('is-hidden') _hide: (name, el = @el) -> if !_.isArray(name) name = [name] for key in name - el.find('[name="' + key + '"]').parents('.control-group').addClass('hide') + el.find('[name="' + key + '"]').parents('.form-group').addClass('hide') el.find('[name="' + key + '"]').addClass('is-hidden') # sort attribute.options @@ -1347,18 +1347,18 @@ class App.ControllerForm extends App.Controller @validate: (data) -> # remove all errors - $(data.form).parents().find('.error').removeClass('error') + $(data.form).parents().find('.has-error').removeClass('has-error') $(data.form).parents().find('.help-inline').html('') # show new errors for key, msg of data.errors - $(data.form).parents().find('[name*="' + key + '"]').parents('div .control-group').addClass('error') + $(data.form).parents().find('[name*="' + key + '"]').parents('div .form-group').addClass('has-error') $(data.form).parents().find('[name*="' + key + '"]').parent().find('.help-inline').html(msg) # set autofocus - $(data.form).parents().find('.error').find('input, textarea').first().focus() + $(data.form).parents().find('.has-error').find('input, textarea').first().focus() # # enable form again -# if $(data.form).parents().find('.error').html() +# if $(data.form).parents().find('.has-error').html() # @formEnable(data.form) diff --git a/app/assets/javascripts/app/controllers/_channel/facebook.js.coffee b/app/assets/javascripts/app/controllers/_channel/facebook.js.coffee index 27b59b39f..4041a968a 100644 --- a/app/assets/javascripts/app/controllers/_channel/facebook.js.coffee +++ b/app/assets/javascripts/app/controllers/_channel/facebook.js.coffee @@ -1,7 +1,4 @@ class App.ChannelFacebook extends App.Controller - events: - 'click [data-toggle="tabnav"]': 'toggle', - constructor: -> super diff --git a/app/assets/javascripts/app/controllers/_channel/twitter.js.coffee b/app/assets/javascripts/app/controllers/_channel/twitter.js.coffee index 363b2c7c0..b26961453 100644 --- a/app/assets/javascripts/app/controllers/_channel/twitter.js.coffee +++ b/app/assets/javascripts/app/controllers/_channel/twitter.js.coffee @@ -1,7 +1,4 @@ class App.ChannelTwitter extends App.Controller - events: - 'click [data-toggle="tabnav"]': 'toggle', - constructor: -> super @@ -9,8 +6,6 @@ class App.ChannelTwitter extends App.Controller @render() render: -> - @html App.view('channel/twitter')( head: 'some header' ) - diff --git a/app/assets/javascripts/app/controllers/_channel/web.js.coffee b/app/assets/javascripts/app/controllers/_channel/web.js.coffee index 4311d394b..b40c97ea4 100644 --- a/app/assets/javascripts/app/controllers/_channel/web.js.coffee +++ b/app/assets/javascripts/app/controllers/_channel/web.js.coffee @@ -10,4 +10,4 @@ class App.ChannelWeb extends App.ControllerTabs }, ] - @render() + @render() diff --git a/app/assets/javascripts/app/controllers/_default_navbar.js.coffee b/app/assets/javascripts/app/controllers/_default_navbar.js.coffee index 4c80707cd..317f4e168 100644 --- a/app/assets/javascripts/app/controllers/_default_navbar.js.coffee +++ b/app/assets/javascripts/app/controllers/_default_navbar.js.coffee @@ -9,6 +9,5 @@ App.Config.set( 'User', { role: [ 'Agent', 'Customer' ] }, 'NavBarRight' ) -App.Config.set( 'Admin', { prio: 10000, parent: '', name: 'Manage', target: '#admin', role: ['Admin'] }, 'NavBar' ) -App.Config.set( 'Setting', { prio: 20000, parent: '', name: 'Settings', target: '#settings', role: ['Admin'] }, 'NavBar' ) +App.Config.set( 'Admin', { prio: 10000, parent: '', name: 'Admin', target: '#manage', role: ['Admin'] }, 'NavBar' ) App.Config.set( 'Misc', { prio: 90000, parent: '', name: 'Tools', target: '#tools', child: true }, 'NavBar' ) diff --git a/app/assets/javascripts/app/controllers/channel.js.coffee b/app/assets/javascripts/app/controllers/channel.js.coffee index fbd779725..49b79fe54 100644 --- a/app/assets/javascripts/app/controllers/channel.js.coffee +++ b/app/assets/javascripts/app/controllers/channel.js.coffee @@ -1,30 +1,13 @@ -class Index extends App.ControllerLevel2 -# toggleable: true - toggleable: false +#App.Config.set( 'channels/:target', Index, 'Routes' ) +#App.Config.set( 'channels', Index, 'Routes' ) - menu: [ - { name: 'Web', target: 'web', controller: App.ChannelWeb }, - { name: 'Mail', target: 'email', controller: App.ChannelEmail }, - { name: 'Chat', target: 'chat', controller: App.ChannelChat }, - { name: 'Twitter', target: 'twitter', controller: App.ChannelTwitter }, - { name: 'Facebook', target: 'facebook', controller: App.ChannelFacebook }, - ] - page: { - title: 'Channels', - head: 'Channels', - sub_title: 'Management' - nav: '#channels', - } +#App.Config.set( 'Channels', { prio: 2500, name: 'Channels', target: '#channels', role: ['Admin'] }, 'NavBarLevel4' ) - constructor: -> - super +#App.Config.set( 'Channels', { prio: 2500, parent: '#admin', name: 'Channels', target: '#channels', role: ['Admin'] }, 'NavBar' ) - return if !@authenticate() +App.Config.set( 'Web', { prio: 1000, name: 'Web', parent: '#channels', target: '#channels/web', controller: App.ChannelWeb, role: ['Admin'] }, 'NavBarLevel44' ) +App.Config.set( 'Email', { prio: 2000, name: 'Email', parent: '#channels', target: '#channels/email', controller: App.ChannelEmail, role: ['Admin'] }, 'NavBarLevel44' ) +App.Config.set( 'Chat', { prio: 3000, name: 'Chat', parent: '#channels', target: '#channels/chat', controller: App.ChannelChat, role: ['Admin'] }, 'NavBarLevel44' ) +App.Config.set( 'Twitter', { prio: 4000, name: 'Twitter', parent: '#channels', target: '#channels/twitter', controller: App.ChannelTwitter, role: ['Admin'] }, 'NavBarLevel44' ) +App.Config.set( 'Facebook', { prio: 5000, name: 'Facebook', parent: '#channels', target: '#channels/facebook', controller: App.ChannelFacebook, role: ['Admin'] }, 'NavBarLevel44' ) - # render page - @render() - -App.Config.set( 'channels/:target', Index, 'Routes' ) -App.Config.set( 'channels', Index, 'Routes' ) - -App.Config.set( 'Channels', { prio: 2500, parent: '#admin', name: 'Channels', target: '#channels', role: ['Admin'] }, 'NavBar' ) \ No newline at end of file diff --git a/app/assets/javascripts/app/controllers/chat_widget.js.coffee b/app/assets/javascripts/app/controllers/chat_widget.js.coffee index dcc3c02e5..33dd3893d 100644 --- a/app/assets/javascripts/app/controllers/chat_widget.js.coffee +++ b/app/assets/javascripts/app/controllers/chat_widget.js.coffee @@ -130,6 +130,7 @@ class App.ChatWidget extends App.Controller 'chat-message-new' ) @el.find('#chat_content').show(100) + @el.find('#chat_content').removeClass('hide') @newMessage = false # hide @@ -142,6 +143,7 @@ class App.ChatWidget extends App.Controller hide: => @isShown = false @el.find('#chat_content').hide(100) + @el.find('#chat_content').addClass('hide') @el.find('#chat_toogle').html('♦'); focusIn: => diff --git a/app/assets/javascripts/app/controllers/footer.js.coffee b/app/assets/javascripts/app/controllers/footer.js.coffee index 0772a27d5..5008873af 100644 --- a/app/assets/javascripts/app/controllers/footer.js.coffee +++ b/app/assets/javascripts/app/controllers/footer.js.coffee @@ -1,6 +1,4 @@ class App.Footer extends App.Controller - className: 'container' - constructor: -> super @render() @@ -12,4 +10,4 @@ class App.Footer extends App.Controller render: () -> @html App.view('footer')() -App.Config.set( 'footer', App.Footer, 'Footers' ) +#App.Config.set( 'footer', App.Footer, 'Footers' ) diff --git a/app/assets/javascripts/app/controllers/groups.js.coffee b/app/assets/javascripts/app/controllers/groups.js.coffee index ab7a44436..3519c7c76 100644 --- a/app/assets/javascripts/app/controllers/groups.js.coffee +++ b/app/assets/javascripts/app/controllers/groups.js.coffee @@ -24,6 +24,8 @@ class Index extends App.ControllerContent }, ) -App.Config.set( 'groups', Index, 'Routes' ) +#App.Config.set( 'groups', Index, 'Routes' ) +#App.Config.set( 'Group', { prio: 1500, parent: '#admin', name: 'Groups', target: '#groups', role: ['Admin'] }, 'NavBar' ) + +App.Config.set( 'Group', { prio: 1500, name: 'Groups', parent: '#manage', target: '#manage/groups', controller: Index, role: ['Admin'] }, 'NavBarLevel44' ) -App.Config.set( 'Group', { prio: 1500, parent: '#admin', name: 'Groups', target: '#groups', role: ['Admin'] }, 'NavBar' ) diff --git a/app/assets/javascripts/app/controllers/maintenance.js.coffee b/app/assets/javascripts/app/controllers/maintenance.js.coffee index bcb2a2e58..bb46d9230 100644 --- a/app/assets/javascripts/app/controllers/maintenance.js.coffee +++ b/app/assets/javascripts/app/controllers/maintenance.js.coffee @@ -1,4 +1,4 @@ -class App.Maintenance extends App.ControllerContent +class Index extends App.ControllerContent events: 'submit form': 'sendMessage' @@ -23,5 +23,5 @@ class App.Maintenance extends App.ControllerContent ) @render() -App.Config.set( 'maintenance', App.Maintenance, 'Routes' ) -App.Config.set( 'maintenance', { prio: 3600, parent: '#admin', name: 'Maintenance Message', target: '#maintenance', role: ['Admin'] }, 'NavBar' ) +App.Config.set( 'Maintenance', { prio: 3600, name: 'Maintenances', parent: '#system', target: '#system/maintenances', controller: Index, role: ['Admin'] }, 'NavBarLevel44' ) + diff --git a/app/assets/javascripts/app/controllers/manage.js.coffee b/app/assets/javascripts/app/controllers/manage.js.coffee new file mode 100644 index 000000000..1733a33f4 --- /dev/null +++ b/app/assets/javascripts/app/controllers/manage.js.coffee @@ -0,0 +1,76 @@ +class IndexRouter extends App.Controller + constructor: (params) -> + super + + # get groups + groups = App.Config.get('NavBarLevel4') + groupsUnsorted = [] + for key, value of groups + groupsUnsorted.push value + + @groupsSorted = _.sortBy( groupsUnsorted, (item) -> return item.prio ) + + # get items of group + for group in @groupsSorted + items = App.Config.get('NavBarLevel44') + itemsUnsorted = [] + for key, value of items + if value.parent is group.target + itemsUnsorted.push value + + group.items = _.sortBy( itemsUnsorted, (item) -> return item.prio ) + + + # set active item + selectedItem = undefined + for group in @groupsSorted + if group.items + for item in group.items + if !@target && !selectedItem + item.active = true + selectedItem = item + else if @target && item.target is '#manage/' + @target + item.active = true + selectedItem = item + else if @target && item.target is '#settings/' + @target + item.active = true + selectedItem = item + else if @target && item.target is '#channels/' + @target + item.active = true + selectedItem = item + else if @target && item.target is '#system/' + @target + item.active = true + selectedItem = item + else + item.active = false + + @render(selectedItem) + + if selectedItem + new selectedItem.controller( + el: @el.find('.main') + ) + + render: (selectedItem) -> + + if !$('.nav-manage')[0] + @html App.view('generic/navbar_l2')( + groups: @groupsSorted + className: 'nav-manage' + ) + if selectedItem + @el.find('li').removeClass('active') + @el.find('a[href="' + selectedItem.target + '"]').parent().addClass('active') + + +App.Config.set( 'manage', IndexRouter, 'Routes' ) +App.Config.set( 'manage/:target', IndexRouter, 'Routes' ) +App.Config.set( 'settings/:target', IndexRouter, 'Routes' ) +App.Config.set( 'channels/:target', IndexRouter, 'Routes' ) +App.Config.set( 'system/:target', IndexRouter, 'Routes' ) + +App.Config.set( 'Manage', { prio: 1000, name: 'Manage', target: '#manage', role: ['Admin'] }, 'NavBarLevel4' ) +App.Config.set( 'Channels', { prio: 2500, name: 'Channels', target: '#channels', role: ['Admin'] }, 'NavBarLevel4' ) +App.Config.set( 'Settings', { prio: 7000, name: 'Settings', target: '#settings', role: ['Admin'] }, 'NavBarLevel4' ) +App.Config.set( 'System', { prio: 8000, name: 'System', target: '#system', role: ['Admin'] }, 'NavBarLevel4' ) + diff --git a/app/assets/javascripts/app/controllers/navigation.js.coffee b/app/assets/javascripts/app/controllers/navigation.js.coffee index 4b5e1c546..1b747d7a4 100644 --- a/app/assets/javascripts/app/controllers/navigation.js.coffee +++ b/app/assets/javascripts/app/controllers/navigation.js.coffee @@ -66,13 +66,13 @@ class App.Navigation extends App.Controller ) # start ticket popups - @ticketPopups('right') + @ticketPopups('left') # start user popups - @userPopups('right') + @userPopups('left') # start oorganization popups - @organizationPopups('right') + @organizationPopups('left') # set focus to search box if @searchFocus @@ -279,8 +279,8 @@ class App.Navigation extends App.Controller @el.find("[href=\"#{url}\"]").parents('li').addClass('active') ticket_overview_build: (data) => - App.Store.write( 'navupdate_ticket_overview', data ) + return # remove old views NavBar = @Config.get( 'NavBar' ) || {} diff --git a/app/assets/javascripts/app/controllers/organizations.js.coffee b/app/assets/javascripts/app/controllers/organizations.js.coffee index 976c19ed4..7dd4022b2 100644 --- a/app/assets/javascripts/app/controllers/organizations.js.coffee +++ b/app/assets/javascripts/app/controllers/organizations.js.coffee @@ -1,10 +1,10 @@ class Index extends App.ControllerContent constructor: -> super - + # check authentication return if !@authenticate() - + new App.ControllerGenericIndex( el: @el, id: @id, @@ -24,7 +24,8 @@ class Index extends App.ControllerContent }, ) -App.Config.set( 'organizations', Index, 'Routes' ) +#App.Config.set( 'organizations', Index, 'Routes' ) +#App.Config.set( 'Organization', { prio: 2000, parent: '#admin', name: 'Organizations', target: '#organizations', role: ['Admin'] }, 'NavBar' ) -App.Config.set( 'Organization', { prio: 2000, parent: '#admin', name: 'Organizations', target: '#organizations', role: ['Admin'] }, 'NavBar' ) +App.Config.set( 'Organization', { prio: 2000, name: 'Organizations', parent: '#manage', target: '#manage/organizations', controller: Index, role: ['Admin'] }, 'NavBarLevel44' ) diff --git a/app/assets/javascripts/app/controllers/overview.js.coffee b/app/assets/javascripts/app/controllers/overview.js.coffee index ed794fa39..585ba787a 100644 --- a/app/assets/javascripts/app/controllers/overview.js.coffee +++ b/app/assets/javascripts/app/controllers/overview.js.coffee @@ -1,10 +1,10 @@ class Index extends App.ControllerContent constructor: -> super - + # check authentication return if !@authenticate() - + new App.ControllerGenericIndex( el: @el, id: @id, @@ -24,6 +24,8 @@ class Index extends App.ControllerContent }, ) -App.Config.set( 'overviews', Index, 'Routes' ) -App.Config.set( 'Overview', { prio: 2300, parent: '#admin', name: 'Overviews', target: '#overviews', role: ['Admin'] }, 'NavBar' ) +#App.Config.set( 'overviews', Index, 'Routes' ) +#App.Config.set( 'Overview', { prio: 2300, parent: '#admin', name: 'Overviews', target: '#overviews', role: ['Admin'] }, 'NavBar' ) + +App.Config.set( 'Overview', { prio: 2300, name: 'Overviews', parent: '#manage', target: '#manage/overviews', controller: Index, role: ['Admin'] }, 'NavBarLevel44' ) diff --git a/app/assets/javascripts/app/controllers/package.js.coffee b/app/assets/javascripts/app/controllers/package.js.coffee index 50b8ceb0b..85506d9fe 100644 --- a/app/assets/javascripts/app/controllers/package.js.coffee +++ b/app/assets/javascripts/app/controllers/package.js.coffee @@ -58,5 +58,5 @@ class Index extends App.ControllerContent @load() ) -App.Config.set( 'package', Index, 'Routes' ) -App.Config.set( 'Packages', { prio: 1800, parent: '#settings', name: 'Packages', target: '#package', role: ['Admin'] }, 'NavBar' ) +App.Config.set( 'Packages', { prio: 1000, name: 'Packages', parent: '#system', target: '#system/package', controller: Index, role: ['Admin'] }, 'NavBarLevel44' ) + diff --git a/app/assets/javascripts/app/controllers/scheduler.js.coffee b/app/assets/javascripts/app/controllers/scheduler.js.coffee index 356554ae1..ebfbec38f 100644 --- a/app/assets/javascripts/app/controllers/scheduler.js.coffee +++ b/app/assets/javascripts/app/controllers/scheduler.js.coffee @@ -13,11 +13,13 @@ class Index extends App.ControllerContent @render() render: -> - + @html App.view('scheduler')( head: 'some header' ) -App.Config.set( 'scheduler', Index, 'Routes' ) +#App.Config.set( 'scheduler', Index, 'Routes' ) +#App.Config.set( 'Scheduler', { prio: 3500, parent: '#admin', name: 'Scheduler', target: '#scheduler', role: ['Admin'] }, 'NavBar' ) + +App.Config.set( 'Scheduler', { prio: 2000, name: 'Schedulers', parent: '#manage', target: '#manage/schedulers', controller: Index, role: ['Admin'] }, 'NavBarLevel44' ) -App.Config.set( 'Scheduler', { prio: 3500, parent: '#admin', name: 'Scheduler', target: '#scheduler', role: ['Admin'] }, 'NavBar' ) diff --git a/app/assets/javascripts/app/controllers/session.js.coffee b/app/assets/javascripts/app/controllers/session.js.coffee index 9b704a006..e98efae44 100644 --- a/app/assets/javascripts/app/controllers/session.js.coffee +++ b/app/assets/javascripts/app/controllers/session.js.coffee @@ -1,4 +1,5 @@ -class Session extends App.ControllerContent +class Index extends App.ControllerContent + divClass: 'lala' events: 'click [data-type="delete"]': 'destroy' @@ -8,11 +9,11 @@ class Session extends App.ControllerContent return if !@authenticate() @load() - @interval( - => - @load() - 10000 - ) +# @interval( +# => +# @load() +# 10000 +# ) # fetch data, render view load: -> @@ -51,5 +52,8 @@ class Session extends App.ControllerContent ) -App.Config.set( 'session', Session, 'Routes' ) -App.Config.set( 'session', { prio: 3700, parent: '#admin', name: 'Sessions', target: '#session', role: ['Admin'] }, 'NavBar' ) +#App.Config.set( 'session', Session, 'Routes' ) +#App.Config.set( 'session', { prio: 3700, parent: '#admin', name: 'Sessions', target: '#session', role: ['Admin'] }, 'NavBar' ) + +App.Config.set( 'Session', { prio: 3700, name: 'Sessions', parent: '#system', target: '#system/sessions', controller: Index, role: ['Admin'] }, 'NavBarLevel44' ) + diff --git a/app/assets/javascripts/app/controllers/settings.js.coffee b/app/assets/javascripts/app/controllers/settings.js.coffee index b4f51c0b0..1e3841893 100644 --- a/app/assets/javascripts/app/controllers/settings.js.coffee +++ b/app/assets/javascripts/app/controllers/settings.js.coffee @@ -1,78 +1,67 @@ -class Index extends App.ControllerLevel2 - toggleable: false -# toggleable: true - +class System extends App.ControllerTabs constructor: -> super return if !@authenticate() - # system - if @type is 'system' - @menu = [ - { name: 'Base', 'target': 'base', controller: App.SettingsArea, params: { area: 'System::Base' } }, - # { name: 'Language', 'target': 'language', controller: App.SettingsSystem, params: { area: 'System::Language' } }, - # { name: 'Log', 'target': 'log', controller: App.SettingsSystem, params: { area: 'System::Log' } }, - { name: 'Storage', 'target': 'storage', controller: App.SettingsArea, params: { area: 'System::Storage' } }, - ] - @page = { - title: 'System', - head: 'System', - sub_title: 'Settings' - nav: '#settings/system', - } - - # security - if @type is 'security' - @menu = [ - { name: 'Base', 'target': 'base', controller: App.SettingsArea, params: { area: 'Security::Base' } }, -# { name: 'Authentication', 'target': 'auth', controller: App.SettingsArea, params: { area: 'Security::Authentication' } }, - { name: 'Password', 'target': 'password', controller: App.SettingsArea, params: { area: 'Security::Password' } }, - { name: 'Third-Party Applications', 'target': 'third_party_auth', controller: App.SettingsArea, params: { area: 'Security::ThirdPartyAuthentication' } }, -# { name: 'Session', 'target': 'session', controller: '' }, - ] - @page = { - title: 'Security', - head: 'Security', - sub_title: 'Settings' - nav: '#settings/security', - } - - # import - if @type is 'import' - @menu = [ - { name: 'Base', 'target': 'base', controller: App.SettingsArea, params: { area: 'Import::Base' } }, - { name: 'OTRS', 'target': 'otrs', controller: App.SettingsArea, params: { area: 'Import::OTRS' } }, - ] - @page = { - title: 'Import', - head: 'Import', - sub_title: 'System' - nav: '#settings/import', - } - - # ticket - if @type is 'ticket' - @menu = [ - { name: 'Base', 'target': 'base', controller: App.SettingsArea, params: { area: 'Ticket::Base' } }, - { name: 'Number', 'target': 'number', controller: App.SettingsArea, params: { area: 'Ticket::Number' } }, -# { name: 'Sender Format', 'target': 'sender-format', controller: App.SettingsArea, params: { area: 'Ticket::SenderFormat' } }, - ] - @page = { - title: 'Ticket', - head: 'Ticket', - sub_title: 'Settings' - nav: '#settings/ticket', - } + @tabs = [ + { name: 'Base', 'target': 'base', controller: App.SettingsArea, params: { area: 'System::Base' } }, + # { name: 'Language', 'target': 'language', controller: App.SettingsSystem, params: { area: 'System::Language' } }, + # { name: 'Log', 'target': 'log', controller: App.SettingsSystem, params: { area: 'System::Log' } }, + { name: 'Storage', 'target': 'storage', controller: App.SettingsArea, params: { area: 'System::Storage' } }, + ] # render page @render() -App.Config.set( 'settings/:type/:target', Index, 'Routes' ) -App.Config.set( 'settings/:type', Index, 'Routes' ) +class Security extends App.ControllerTabs + constructor: -> + super -App.Config.set( 'System', { prio: 1400, parent: '#settings', name: 'System', target: '#settings/system', role: ['Admin'] }, 'NavBar' ) -App.Config.set( 'Security', { prio: 1500, parent: '#settings', name: 'Security', target: '#settings/security', role: ['Admin'] }, 'NavBar' ) -App.Config.set( 'Import', { prio: 1550, parent: '#settings', name: 'Import', target: '#settings/import', role: ['Admin'] }, 'NavBar' ) -App.Config.set( 'Ticket', { prio: 1600, parent: '#settings', name: 'Ticket', target: '#settings/ticket', role: ['Admin'] }, 'NavBar' ) -App.Config.set( 'Object', { prio: 1700, parent: '#settings', name: 'Objects', target: '#settings/objects', role: ['Admin'] }, 'NavBar' ) + return if !@authenticate() + + @tabs = [ + { name: 'Base', 'target': 'base', controller: App.SettingsArea, params: { area: 'Security::Base' } }, +# { name: 'Authentication', 'target': 'auth', controller: App.SettingsArea, params: { area: 'Security::Authentication' } }, + { name: 'Password', 'target': 'password', controller: App.SettingsArea, params: { area: 'Security::Password' } }, + { name: 'Third-Party Applications', 'target': 'third_party_auth', controller: App.SettingsArea, params: { area: 'Security::ThirdPartyAuthentication' } }, +# { name: 'Session', 'target': 'session', controller: '' }, + ] + + @render() + +class Import extends App.ControllerTabs + constructor: -> + super + + return if !@authenticate() + + # import + @tabs = [ + { name: 'Base', 'target': 'base', controller: App.SettingsArea, params: { area: 'Import::Base' } }, + { name: 'OTRS', 'target': 'otrs', controller: App.SettingsArea, params: { area: 'Import::OTRS' } }, + ] + + @render() + +class Ticket extends App.ControllerTabs + constructor: -> + super + + return if !@authenticate() + + # ticket + @tabs = [ + { name: 'Base', 'target': 'base', controller: App.SettingsArea, params: { area: 'Ticket::Base' } }, + { name: 'Number', 'target': 'number', controller: App.SettingsArea, params: { area: 'Ticket::Number' } }, +# { name: 'Sender Format', 'target': 'sender-format', controller: App.SettingsArea, params: { area: 'Ticket::SenderFormat' } }, + ] + + @render() + +App.Config.set( 'System', { prio: 1400, parent: '#settings', name: 'System', target: '#settings/system', controller: System, role: ['Admin'] }, 'NavBarLevel44' ) +App.Config.set( 'Security', { prio: 1500, parent: '#settings', name: 'Security', target: '#settings/security', controller: Security, role: ['Admin'] }, 'NavBarLevel44' ) +App.Config.set( 'Import', { prio: 1550, parent: '#settings', name: 'Import', target: '#settings/import', controller: Import, role: ['Admin'] }, 'NavBarLevel44' ) +App.Config.set( 'Ticket', { prio: 1600, parent: '#settings', name: 'Ticket', target: '#settings/ticket', controller: Ticket, role: ['Admin'] }, 'NavBarLevel44' ) + +#App.Config.set( 'Object', { prio: 1700, parent: '#settings', name: 'Objects', target: '#settings/objects', role: ['Admin'] }, 'NavBar' ) diff --git a/app/assets/javascripts/app/controllers/sla.js.coffee b/app/assets/javascripts/app/controllers/sla.js.coffee index 333eabe93..e35a8c843 100644 --- a/app/assets/javascripts/app/controllers/sla.js.coffee +++ b/app/assets/javascripts/app/controllers/sla.js.coffee @@ -1,10 +1,10 @@ class Index extends App.ControllerContent constructor: -> super - + # check authentication return if !@authenticate() - + new App.ControllerGenericIndex( el: @el, id: @id, @@ -24,6 +24,8 @@ class Index extends App.ControllerContent }, ) -App.Config.set( 'slas', Index, 'Routes' ) -App.Config.set( 'Sla', { prio: 2900, parent: '#admin', name: 'SLAs', target: '#slas', role: ['Admin'] }, 'NavBar' ) +#App.Config.set( 'slas', Index, 'Routes' ) +#App.Config.set( 'Sla', { prio: 2900, parent: '#admin', name: 'SLAs', target: '#slas', role: ['Admin'] }, 'NavBar' ) + +App.Config.set( 'Sla', { prio: 2900, name: 'SLAs', target: '#manage/slas', controller: Index, role: ['Admin'] }, 'NavBarLevel2' ) diff --git a/app/assets/javascripts/app/controllers/template_widget.js.coffee b/app/assets/javascripts/app/controllers/template_widget.js.coffee index c24661ba1..26971643f 100644 --- a/app/assets/javascripts/app/controllers/template_widget.js.coffee +++ b/app/assets/javascripts/app/controllers/template_widget.js.coffee @@ -54,6 +54,7 @@ class App.TemplateUI extends App.Controller e.preventDefault() # get params + form = @formParam( $('.ticket-create') ) params = @formParam(e.target) name = params['template_name'] # delete params['template_name'] @@ -62,10 +63,9 @@ class App.TemplateUI extends App.Controller if !template template = new App.Template - options = params template.load( name: params['template_name'] - options: options + options: form ) # validate form diff --git a/app/assets/javascripts/app/controllers/text_module.js.coffee b/app/assets/javascripts/app/controllers/text_module.js.coffee index 8ebc17bad..2b533b240 100644 --- a/app/assets/javascripts/app/controllers/text_module.js.coffee +++ b/app/assets/javascripts/app/controllers/text_module.js.coffee @@ -1,10 +1,10 @@ class Index extends App.ControllerContent constructor: -> super - + # check authentication return if !@authenticate() - + new App.ControllerGenericIndex( el: @el, id: @id, @@ -24,6 +24,8 @@ class Index extends App.ControllerContent }, ) -App.Config.set( 'text_modules', Index, 'Routes' ) -App.Config.set( 'TextModule', { prio: 2300, parent: '#admin', name: 'Text Modules', target: '#text_modules', role: ['Admin'] }, 'NavBar' ) +#App.Config.set( 'text_modules', Index, 'Routes' ) +#App.Config.set( 'TextModule', { prio: 2300, parent: '#admin', name: 'Text Modules', target: '#text_modules', role: ['Admin'] }, 'NavBar' ) + +App.Config.set( 'TextModule', { prio: 2300, name: 'TextModules', parent: '#manage', target: '#manage/text_modules', controller: Index, role: ['Admin'] }, 'NavBarLevel44' ) diff --git a/app/assets/javascripts/app/controllers/ticket_overview.js.coffee b/app/assets/javascripts/app/controllers/ticket_overview.js.coffee index 81438e2c3..46ece1a5d 100644 --- a/app/assets/javascripts/app/controllers/ticket_overview.js.coffee +++ b/app/assets/javascripts/app/controllers/ticket_overview.js.coffee @@ -1,4 +1,29 @@ -class Index extends App.ControllerContent +class Index extends App.Controller + constructor: -> + super + + @render() + + render: -> + + @html App.view('agent_ticket_view')() + + if !@view + cache = App.Store.get( 'navupdate_ticket_overview' ) + if cache && cache[0] + @view = cache[0].link + + new Navbar( + el: @el.find('.sidebar') + view: @view + ) + + new Table( + el: @el.find('.main') + view: @view + ) + +class Table extends App.ControllerContent events: 'click [data-type=edit]': 'zoom' 'click [data-type=settings]': 'settings' @@ -131,7 +156,7 @@ class Index extends App.ControllerContent ] if @isRole('Customer') view_modes = [] - html = App.view('agent_ticket_view')( + html = App.view('agent_ticket_view/content')( overview: @overview view_modes: view_modes checkbox: checkbox @@ -140,6 +165,7 @@ class Index extends App.ControllerContent html = $(html) # html.find('li').removeClass('active') # html.find("[data-id=\"#{@start_page}\"]").parents('li').addClass('active') + @html html # create table/overview @@ -486,6 +512,39 @@ class Settings extends App.ControllerModal ) @modalHide() +class Navbar extends App.Controller + constructor: -> + super + + # rebuild ticket overview data + @bind 'navupdate_ticket_overview', (data) => + if !_.isEmpty(data) + App.Store.write( 'navupdate_ticket_overview', data ) + @render(data) + + cache = App.Store.get( 'navupdate_ticket_overview' ) + if cache + @render( cache ) + else + @render( [] ) + + render: (dataOrig) -> + + data = _.clone(dataOrig) + + # add new views + for item in data + item.target = '#ticket_view/' + item.link + if item.link is @view + item.active = true + else + item.active = false + + @html App.view('agent_ticket_view/navbar')( + items: data + ) + + class Router extends App.Controller constructor: -> super @@ -538,8 +597,9 @@ class Router extends App.Controller else @navigate 'ticket/zoom/' + @ticket_list[ @position - 1 ] + '/nav/true' +App.Config.set( 'ticket_view', Index, 'Routes' ) App.Config.set( 'ticket_view/:view', Index, 'Routes' ) -App.Config.set( 'ticket_view/:view/:position/:direction', Router, 'Routes' ) +#App.Config.set( 'ticket_view/:view/:position/:direction', Router, 'Routes' ) App.Config.set( 'TicketOverview', { prio: 1000, parent: '', name: 'Overviews', target: '#ticket_view', role: ['Agent', 'Customer'] }, 'NavBar' ) #App.Config.set( '', { prio: 1000, parent: '#ticket_view', name: 'My assigned Tickets (51)', target: '#ticket_view/my_assigned', role: ['Agent'] } diff --git a/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee b/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee index 97f90457b..9c9a2466a 100644 --- a/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee +++ b/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee @@ -433,6 +433,7 @@ class Edit extends App.Controller @log 'notice', 'form hash changed', diff, currentData @el.find('.ticket-update').parent().addClass('form-changed') @el.find('.ticket-update').parent().parent().find('.reset-message').show() + @el.find('.ticket-update').parent().parent().find('.reset-message').removeClass('hide') App.TaskManager.update( @task_key, { 'state': currentData }) @interval( update, 1500, 'autosave' ) diff --git a/app/assets/javascripts/app/controllers/trigger.js.coffee b/app/assets/javascripts/app/controllers/trigger.js.coffee index a3266e683..7733907c8 100644 --- a/app/assets/javascripts/app/controllers/trigger.js.coffee +++ b/app/assets/javascripts/app/controllers/trigger.js.coffee @@ -13,11 +13,13 @@ class Index extends App.ControllerContent @render() render: -> - + @html App.view('trigger')( head: 'some header' ) -App.Config.set( 'trigger', Index, 'Routes' ) +#App.Config.set( 'trigger', Index, 'Routes' ) +#App.Config.set( 'Trigger', { prio: 3000, parent: '#admin', name: 'Trigger', target: '#trigger', role: ['Admin'] }, 'NavBar' ) + +App.Config.set( 'Trigger', { prio: 3000, name: 'Triggers', target: '#manage/triggers', controller: Index, role: ['Admin'] }, 'NavBarLevel2' ) -App.Config.set( 'Trigger', { prio: 3000, parent: '#admin', name: 'Trigger', target: '#trigger', role: ['Admin'] }, 'NavBar' ) \ No newline at end of file diff --git a/app/assets/javascripts/app/controllers/user_info_widget.js.coffee b/app/assets/javascripts/app/controllers/user_info_widget.js.coffee index 326da3233..5734a3661 100644 --- a/app/assets/javascripts/app/controllers/user_info_widget.js.coffee +++ b/app/assets/javascripts/app/controllers/user_info_widget.js.coffee @@ -45,13 +45,14 @@ class App.UserInfo extends App.Controller # insert data @html App.view('user_info')( - user: user, - data: data, + user: user + data: data ) @userTicketPopups( - selector: '.user-tickets', - user_id: user.id, + selector: '.user-tickets' + user_id: user.id + position: 'right' ) # update changes diff --git a/app/assets/javascripts/app/controllers/users.js.coffee b/app/assets/javascripts/app/controllers/users.js.coffee index b6754b747..3297aab64 100644 --- a/app/assets/javascripts/app/controllers/users.js.coffee +++ b/app/assets/javascripts/app/controllers/users.js.coffee @@ -1,4 +1,4 @@ -class Index extends App.ControllerContent +class Index extends App.Controller constructor: -> super @@ -6,26 +6,24 @@ class Index extends App.ControllerContent return if !@authenticate() new App.ControllerGenericIndex( - el: @el, - id: @id, - genericObject: 'User', - defaultSortBy: 'login', - ignoreObjectIDs: [1], - pageData: { - title: 'Users', - home: 'users', - object: 'User', - objects: 'Users', - navupdate: '#users', + el: @el + id: @id + genericObject: 'User' + defaultSortBy: 'login' + ignoreObjectIDs: [1] + pageData: + title: 'Users' + home: 'users' + object: 'User' + objects: 'Users' + navupdate: '#users' notes: [ 'Users are for any person in the system. Agents (Owners, Resposbiles, ...) and Customers.' - ], + ] buttons: [ # { name: 'List', 'data-type': '', class: 'active' }, - { name: 'New User', 'data-type': 'new', class: 'primary' }, - ], - } + { name: 'New User', 'data-type': 'new', class: 'primary' } + ] ) -App.Config.set( 'users', Index, 'Routes' ) -App.Config.set( 'User', { prio: 1000, parent: '#admin', name: 'Users', target: '#users', role: ['Admin'] }, 'NavBar' ) +App.Config.set( 'User', { prio: 1000, name: 'Users', parent: '#manage', target: '#manage/users', controller: Index, role: ['Admin'] }, 'NavBarLevel44' ) diff --git a/app/assets/javascripts/app/lib/app_post/interface_handle.js.coffee b/app/assets/javascripts/app/lib/app_post/interface_handle.js.coffee index e46a890f0..49c372518 100644 --- a/app/assets/javascripts/app/lib/app_post/interface_handle.js.coffee +++ b/app/assets/javascripts/app/lib/app_post/interface_handle.js.coffee @@ -47,7 +47,7 @@ class App.Run extends App.Controller App.Event.trigger( event + ':ready') class App.Content extends App.Controller - className: 'container' + className: 'content' constructor: -> super diff --git a/app/assets/javascripts/app/lib/app_post/task_manager.js.coffee b/app/assets/javascripts/app/lib/app_post/task_manager.js.coffee index e9cff4d04..66c624fb4 100644 --- a/app/assets/javascripts/app/lib/app_post/task_manager.js.coffee +++ b/app/assets/javascripts/app/lib/app_post/task_manager.js.coffee @@ -156,7 +156,7 @@ class _taskManagerSingleton extends App.Controller # create div for permanent content if !$("#content_permanent")[0] - $('#app section').append('
') + $('#app section').append('
') # empty static content if task is shown if active diff --git a/app/assets/javascripts/app/lib/bootstrap/modal.js b/app/assets/javascripts/app/lib/bootstrap/modal.js new file mode 100644 index 000000000..83095e8ff --- /dev/null +++ b/app/assets/javascripts/app/lib/bootstrap/modal.js @@ -0,0 +1,241 @@ +/* ======================================================================== + * Bootstrap: modal.js v3.0.0 + * http://twbs.github.com/bootstrap/javascript.html#modals + * ======================================================================== + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ======================================================================== */ + + ++function ($) { "use strict"; + + // MODAL CLASS DEFINITION + // ====================== + + var Modal = function (element, options) { + this.options = options + this.$element = $(element).on('click.dismiss.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this)) + this.$backdrop = + this.isShown = null + + if (this.options.remote) this.$element.find('.modal-body').load(this.options.remote) + } + + Modal.DEFAULTS = { + backdrop: true + , keyboard: true + , show: true + } + + Modal.prototype.toggle = function () { + return this[!this.isShown ? 'show' : 'hide']() + } + + Modal.prototype.show = function () { + var that = this + var e = $.Event('show.bs.modal') + + this.$element.trigger(e) + + if (this.isShown || e.isDefaultPrevented()) return + + this.isShown = true + + this.escape() + + this.backdrop(function () { + var transition = $.support.transition && that.$element.hasClass('fade') + + if (!that.$element.parent().length) { + that.$element.appendTo(document.body) // don't move modals dom position + } + + that.$element.show() + + if (transition) { + that.$element[0].offsetWidth // force reflow + } + + that.$element + .addClass('in') + .attr('aria-hidden', false) + + that.enforceFocus() + + transition ? + that.$element + .one($.support.transition.end, function () { + that.$element.focus().trigger('shown.bs.modal') + }) + .emulateTransitionEnd(300) : + that.$element.focus().trigger('shown.bs.modal') + }) + } + + Modal.prototype.hide = function (e) { + if (e) e.preventDefault() + + e = $.Event('hide.bs.modal') + + this.$element.trigger(e) + + if (!this.isShown || e.isDefaultPrevented()) return + + this.isShown = false + + this.escape() + + $(document).off('focusin.bs.modal') + + this.$element + .removeClass('in') + .attr('aria-hidden', true) + + $.support.transition && this.$element.hasClass('fade') ? + this.$element + .one($.support.transition.end, $.proxy(this.hideModal, this)) + .emulateTransitionEnd(300) : + this.hideModal() + } + + Modal.prototype.enforceFocus = function () { + $(document) + .off('focusin.bs.modal') // guard against infinite focus loop + .on('focusin.bs.modal', $.proxy(function (e) { + if (this.$element[0] !== e.target && !this.$element.has(e.target).length) { + this.$element.focus() + } + }, this)) + } + + Modal.prototype.escape = function () { + if (this.isShown && this.options.keyboard) { + this.$element.on('keyup.dismiss.bs.modal', $.proxy(function (e) { + e.which == 27 && this.hide() + }, this)) + } else if (!this.isShown) { + this.$element.off('keyup.dismiss.bs.modal') + } + } + + Modal.prototype.hideModal = function () { + var that = this + this.$element.hide() + this.backdrop(function () { + that.removeBackdrop() + that.$element.trigger('hidden.bs.modal') + }) + } + + Modal.prototype.removeBackdrop = function () { + this.$backdrop && this.$backdrop.remove() + this.$backdrop = null + } + + Modal.prototype.backdrop = function (callback) { + var that = this + var animate = this.$element.hasClass('fade') ? 'fade' : '' + + if (this.isShown && this.options.backdrop) { + var doAnimate = $.support.transition && animate + + this.$backdrop = $('