diff --git a/app/assets/javascripts/app/controllers/_application_controller.coffee b/app/assets/javascripts/app/controllers/_application_controller.coffee index c2accd8cc..f51d9094b 100644 --- a/app/assets/javascripts/app/controllers/_application_controller.coffee +++ b/app/assets/javascripts/app/controllers/_application_controller.coffee @@ -77,10 +77,6 @@ class App.Controller extends Spine.Controller if @ajaxCalls for callId in @ajaxCalls App.Ajax.abort(callId) - @userTicketPopupsDestroy() - @ticketPopupsDestroy() - @userPopupsDestroy() - @organizationPopupsDestroy() release: -> # release custom bindings after it got removed from dom @@ -295,228 +291,6 @@ class App.Controller extends Spine.Controller item.attr('title', App.i18n.translateTimestamp(timestamp)) item.html(time) - ticketPopups: (position = 'right') -> - - # open ticket in new task if curent user agent - if @permissionCheck('ticket.agent') - @$('div.ticket-popover, span.ticket-popover').bind('click', (e) => - id = $(e.target).data('id') - return if !id - ticket = App.Ticket.findNative(id) - @navigate ticket.uiUrl() - ) - - @ticketPopupsDestroy() - - # show ticket popup - ui = @ - @ticketPopupsList = @el.find('.ticket-popover').popover( - trigger: 'hover' - container: 'body' - html: true - animation: false - delay: 100 - placement: position - title: -> - ticketId = $(@).data('id') - ticket = App.Ticket.find(ticketId) - App.Utils.htmlEscape(ticket.title) - content: -> - ticketId = $(@).data('id') - ticket = App.Ticket.fullLocal(ticketId) - html = $(App.view('popover/ticket')( - ticket: ticket - )) - html.find('.humanTimeFromNow').each(-> - ui.frontendTimeUpdateItem($(@)) - ) - html - ) - - ticketPopupsDestroy: => - if @ticketPopupsList - @ticketPopupsList.popover('destroy') - - userPopups: (position = 'right') -> - - # open user in new task if current user is agent - return if !@permissionCheck('ticket.agent') - @$('div.user-popover, span.user-popover').bind('click', (e) => - id = $(e.target).data('id') - return if !id - user = App.User.findNative(id) - @navigate user.uiUrl() - ) - - @userPopupsDestroy() - - # show user popup - @userPopupsList = @el.find('.user-popover').popover( - trigger: 'hover' - container: 'body' - html: true - animation: false - delay: 100 - placement: "auto #{position}" - title: -> - userId = $(@).data('id') - user = App.User.find(userId) - headline = App.Utils.htmlEscape(user.displayName()) - if user.isOutOfOffice() - headline += " (#{App.Utils.htmlEscape(user.outOfOfficeText())})" - headline - content: -> - userId = $(@).data('id') - user = App.User.fullLocal(userId) - - # get display data - userData = [] - for attributeName, attributeConfig of App.User.attributesGet('view') - - # check if value for _id exists - name = attributeName - nameNew = name.substr(0, name.length - 3) - if nameNew of user - name = nameNew - - # add to show if value exists - if user[name] && attributeConfig.shown - - # do not show firstname and lastname / already show via diplayName() - if name isnt 'firstname' && name isnt 'lastname' && name isnt 'organization' - userData.push attributeConfig - - # insert data - App.view('popover/user')( - user: user - userData: userData - ) - ) - - userPopupsDestroy: => - if @userPopupsList - @userPopupsList.popover('destroy') - - organizationPopups: (position = 'right') -> - - # open org in new task if current user agent - return if !@permissionCheck('ticket.agent') - - @$('div.organization-popover, span.organization-popover').bind('click', (e) => - id = $(e.target).data('id') - return if !id - organization = App.Organization.find(id) - @navigate organization.uiUrl() - ) - - @organizationPopupsDestroy() - - # show organization popup - @organizationPopupsList = @el.find('.organization-popover').popover( - trigger: 'hover' - container: 'body' - html: true - animation: false - delay: 100 - placement: "auto #{position}" - title: -> - organization_id = $(@).data('id') - organization = App.Organization.find(organization_id) - App.Utils.htmlEscape(organization.name) - content: -> - organization_id = $(@).data('id') - organization = App.Organization.fullLocal(organization_id) - - # get display data - organizationData = [] - for attributeName, attributeConfig of App.Organization.attributesGet('view') - - # check if value for _id exists - name = attributeName - nameNew = name.substr(0, name.length - 3) - if nameNew of organization - name = nameNew - - # add to show if value exists - if organization[name] && attributeConfig.shown - - # do not show firstname and lastname / already show via diplayName() - if name isnt 'name' - organizationData.push attributeConfig - - # insert data - App.view('popover/organization')( - organization: organization, - organizationData: organizationData, - ) - ) - - organizationPopupsDestroy: => - if @organizationPopupsList - @organizationPopupsList.popover('destroy') - - userTicketPopups: (params) -> - - show = (data, ticket_list) => - - if !data.position - data.position = 'left' - - @userTicketPopupsDestroy() - - # show user popup - ui = @ - @userTicketPopupsList = @el.find(data.selector).popover( - trigger: 'hover' - container: 'body' - html: true - animation: false - delay: 100 - placement: "auto #{data.position}" - title: -> - $(@).find('[title="*"]').val() - - content: -> - type = $(@).filter('[data-type]').data('type') - tickets = [] - if ticket_list[type] - for ticketId in ticket_list[type] - tickets.push App.Ticket.fullLocal(ticketId) - - # insert data - html = $(App.view('popover/user_ticket_list')( - tickets: tickets - )) - html.find('.humanTimeFromNow').each( -> - ui.frontendTimeUpdateItem($(@)) - ) - html - ) - - fetch = (params) => - @ajax( - type: 'GET' - url: "#{@Config.get('api_path')}/ticket_customer" - data: - customer_id: params.user_id - processData: true - success: (data, status, xhr) -> - App.Collection.loadAssets(data.assets) - show(params, { open: data.ticket_ids_open, closed: data.ticket_ids_closed }) - ) - - # get data - fetch(params) - - userTicketPopupsDestroy: => - if @userTicketPopupsList - @userTicketPopupsList.popover('destroy') - - anyPopoversDestroy: -> - - # do not remove permanent .popover--notifications widget - $('.popover:not(.popover--notifications)').remove() - recentView: (object, o_id) => params = object: object diff --git a/app/assets/javascripts/app/controllers/_application_controller_generic.coffee b/app/assets/javascripts/app/controllers/_application_controller_generic.coffee index 9a9855a45..2f9bff2fc 100644 --- a/app/assets/javascripts/app/controllers/_application_controller_generic.coffee +++ b/app/assets/javascripts/app/controllers/_application_controller_generic.coffee @@ -545,6 +545,9 @@ class App.ControllerNavSidbar extends App.Controller sidebar: @$('.sidebar').scrollTop() class App.GenericHistory extends App.ControllerModal + @extend App.PopoverProvidable + @registerPopovers 'User' + buttonClose: true buttonCancel: false buttonSubmit: false @@ -568,7 +571,7 @@ class App.GenericHistory extends App.ControllerModal content onShown: => - @userPopups() + @renderPopovers() sortorder: => @items = @items.reverse() @@ -1403,4 +1406,4 @@ class App.ImportResult extends App.ControllerModal content onSubmit: (e) => - @close() \ No newline at end of file + @close() diff --git a/app/assets/javascripts/app/controllers/cti.coffee b/app/assets/javascripts/app/controllers/cti.coffee index 2689bc2df..5ae318b38 100644 --- a/app/assets/javascripts/app/controllers/cti.coffee +++ b/app/assets/javascripts/app/controllers/cti.coffee @@ -1,4 +1,7 @@ class App.CTI extends App.Controller + @extend App.PopoverProvidable + @registerPopovers 'User' + elements: '.js-callerLog': 'callerLog' events: @@ -160,9 +163,10 @@ class App.CTI extends App.Controller if diff_in_min > 1 item.disabled = false - @userPopupsDestroy() + @removePopovers() @callerLog.html( App.view('cti/caller_log')(list: @list)) - @userPopups() + @renderPopovers() + @updateNavMenu() done: (e) => diff --git a/app/assets/javascripts/app/controllers/navigation.coffee b/app/assets/javascripts/app/controllers/navigation.coffee index 55ad1234c..d3b0efbe6 100644 --- a/app/assets/javascripts/app/controllers/navigation.coffee +++ b/app/assets/javascripts/app/controllers/navigation.coffee @@ -1,4 +1,7 @@ class App.Navigation extends App.ControllerWidgetPermanent + @extend App.PopoverProvidable + @registerAllPopovers() + className: 'navigation vertical' elements: @@ -157,6 +160,7 @@ class App.Navigation extends App.ControllerWidgetPermanent ) renderResult: (result = []) => + @removePopovers() # remove result if not result exists if _.isEmpty(result) @@ -174,14 +178,7 @@ class App.Navigation extends App.ControllerWidgetPermanent # show result list @searchContainer.addClass('open') - # start ticket popups - @ticketPopups() - - # start user popups - @userPopups() - - # start oorganization popups - @organizationPopups() + @renderPopovers() render: -> @@ -206,7 +203,7 @@ class App.Navigation extends App.ControllerWidgetPermanent searchFocus: (e) => @query = '' # reset query cache @searchContainer.addClass('focused') - @anyPopoversDestroy() + App.PopoverProvidable.anyPopoversDestroy() @search() searchBlur: (e) => @@ -288,14 +285,14 @@ class App.Navigation extends App.ControllerWidgetPermanent @searchContainer.removeClass('filled').removeClass('open').removeClass('focused') @globalSearch.close() - # remove not needed popovers - @delay(@anyPopoversDestroy, 100, 'removePopovers') + @delayedRemoveAnyPopover() andClose: => @searchInput.blur() @searchContainer.removeClass('open') @globalSearch.close() - @delay(@anyPopoversDestroy, 100, 'removePopovers') + + @delayedRemoveAnyPopover() search: => query = @searchInput.val().trim() diff --git a/app/assets/javascripts/app/controllers/search.coffee b/app/assets/javascripts/app/controllers/search.coffee index 4c66dcf2f..acd4b492f 100644 --- a/app/assets/javascripts/app/controllers/search.coffee +++ b/app/assets/javascripts/app/controllers/search.coffee @@ -1,4 +1,6 @@ class App.Search extends App.Controller + @extend App.PopoverProvidable + elements: '.js-search': 'searchInput' @@ -112,8 +114,7 @@ class App.Search extends App.Controller @updateFilledClass() @updateTask() - # remove not needed popovers - @delay(@anyPopoversDestroy, 100, 'removePopovers') + @delayedRemoveAnyPopover() search: (force = false) => query = @searchInput.val().trim() diff --git a/app/assets/javascripts/app/controllers/ticket_overview.coffee b/app/assets/javascripts/app/controllers/ticket_overview.coffee index 1bc014fca..06d958ee9 100644 --- a/app/assets/javascripts/app/controllers/ticket_overview.coffee +++ b/app/assets/javascripts/app/controllers/ticket_overview.coffee @@ -926,6 +926,9 @@ class Navbar extends App.Controller @autoFoldTabs() class Table extends App.Controller + @extend App.PopoverProvidable + @registerPopovers 'Organization', 'User' + events: 'click [data-type=settings]': 'settings' 'click [data-type=viewmode]': 'viewmode' @@ -1174,11 +1177,7 @@ class Table extends App.Controller 'click': callbackCheckbox ) - # start user popups - @userPopups() - - # start organization popups - @organizationPopups() + @renderPopovers() @bulkForm = new BulkForm( holder: @el diff --git a/app/assets/javascripts/app/controllers/widget/avatar.coffee b/app/assets/javascripts/app/controllers/widget/avatar.coffee index e6bc84d35..9dae76b9a 100644 --- a/app/assets/javascripts/app/controllers/widget/avatar.coffee +++ b/app/assets/javascripts/app/controllers/widget/avatar.coffee @@ -1,4 +1,7 @@ class App.WidgetAvatar extends App.ObserverController + @extend App.PopoverProvidable + @registerPopovers 'User' + model: 'User' observe: login: true @@ -17,4 +20,4 @@ class App.WidgetAvatar extends App.ObserverController render: (user) => @html(user.avatar(@size, @position, @cssClass, false, false, @type)) - @userPopups(@position) + @renderPopovers() diff --git a/app/assets/javascripts/app/controllers/widget/link.coffee b/app/assets/javascripts/app/controllers/widget/link.coffee index 20dab6a91..7af8f6d6d 100644 --- a/app/assets/javascripts/app/controllers/widget/link.coffee +++ b/app/assets/javascripts/app/controllers/widget/link.coffee @@ -1,4 +1,10 @@ class App.WidgetLink extends App.Controller + @extend App.PopoverProvidable + @registerPopovers 'Ticket' + + @popoversDefaults: + position: 'left' + events: 'click .js-add': 'add' 'click .js-delete': 'delete' @@ -54,7 +60,8 @@ class App.WidgetLink extends App.Controller @html App.view('link/info')( links: list ) - @ticketPopups('left') + + @renderPopovers() delete: (e) => e.preventDefault() diff --git a/app/assets/javascripts/app/controllers/widget/organization.coffee b/app/assets/javascripts/app/controllers/widget/organization.coffee index 64e63a44b..106a444a3 100644 --- a/app/assets/javascripts/app/controllers/widget/organization.coffee +++ b/app/assets/javascripts/app/controllers/widget/organization.coffee @@ -1,4 +1,7 @@ class App.WidgetOrganization extends App.Controller + @extend App.PopoverProvidable + @registerPopovers 'User' + events: 'focusout [contenteditable]': 'update' @@ -44,16 +47,7 @@ class App.WidgetOrganization extends App.Controller maxlength: 250 ) - # enable user popups - @userPopups() - - ### - @userTicketPopups( - selector: '.user-tickets' - user_id: user.id - position: 'right' - ) - ### + @renderPopovers() update: (e) => name = $(e.target).attr('data-name') diff --git a/app/assets/javascripts/app/controllers/widget/ticket_list.coffee b/app/assets/javascripts/app/controllers/widget/ticket_list.coffee index 9ab9ef4c1..d4a994059 100644 --- a/app/assets/javascripts/app/controllers/widget/ticket_list.coffee +++ b/app/assets/javascripts/app/controllers/widget/ticket_list.coffee @@ -1,4 +1,7 @@ class App.TicketList extends App.Controller + @extend App.PopoverProvidable + @registerPopovers 'Organization', 'User' + constructor: -> super @@ -85,8 +88,4 @@ class App.TicketList extends App.Controller radio: @radio ) - # start user popups - @userPopups() - - # start organization popups - @organizationPopups() + @renderPopovers() diff --git a/app/assets/javascripts/app/controllers/widget/ticket_stats.coffee b/app/assets/javascripts/app/controllers/widget/ticket_stats.coffee index 67d8b4b5b..44c1d2726 100644 --- a/app/assets/javascripts/app/controllers/widget/ticket_stats.coffee +++ b/app/assets/javascripts/app/controllers/widget/ticket_stats.coffee @@ -138,6 +138,9 @@ class App.TicketStats extends App.Controller ) class App.TicketStatsList extends App.Controller + @extend App.PopoverProvidable + @registerPopovers 'Ticket' + events: 'click .js-showAll': 'showAll' @@ -166,7 +169,7 @@ class App.TicketStatsList extends App.Controller limit: @limit ) - @ticketPopups() + @renderPopovers() showAll: (e) => e.preventDefault() diff --git a/app/assets/javascripts/app/controllers/widget/user.coffee b/app/assets/javascripts/app/controllers/widget/user.coffee index d7836e23a..5131cd0a8 100644 --- a/app/assets/javascripts/app/controllers/widget/user.coffee +++ b/app/assets/javascripts/app/controllers/widget/user.coffee @@ -1,4 +1,7 @@ class App.WidgetUser extends App.Controller + @extend App.PopoverProvidable + @registerPopovers 'UserTicket' + events: 'focusout [contenteditable]': 'update' @@ -76,10 +79,9 @@ class App.WidgetUser extends App.Controller maxlength: 250 ) - @userTicketPopups( - selector: '.user-tickets' + @renderPopovers( + selector: '.user-tickets', user_id: user.id - position: 'right' ) update: (e) => diff --git a/app/assets/javascripts/app/index.coffee b/app/assets/javascripts/app/index.coffee index 4c2852680..64e60859c 100644 --- a/app/assets/javascripts/app/index.coffee +++ b/app/assets/javascripts/app/index.coffee @@ -85,6 +85,10 @@ class App extends Spine.Controller S: (key) -> App.Session.get(key) + # define view helper for rendering partial views + V: (name, params) -> + App.view(name)(params) + # define address line helper AddressLine: (line) -> return '' if !line diff --git a/app/assets/javascripts/app/lib/app_post/popover_provider/_popover_provider.coffee b/app/assets/javascripts/app/lib/app_post/popover_provider/_popover_provider.coffee new file mode 100644 index 000000000..75def93ae --- /dev/null +++ b/app/assets/javascripts/app/lib/app_post/popover_provider/_popover_provider.coffee @@ -0,0 +1,77 @@ +class App.PopoverProvider + @selectorCssClassPrefix = null # needs to be overrided + @templateName = null # needs to be overrided + @permission = 'ticket.agent' + + @providers = {} + + @providersConfigKey = 'PopoverProviders' + + @registerProvider: (key, klass) -> + @providers[key] = klass + App.Config.set(key, klass, @providersConfigKey) + + @defaults = + position: 'right' + parentController: null + popovers = null + + constructor: (params) -> + if params.parentController is null + throw 'Parent controller needs to be set' + + @params = _.extend {}, @constructor.defaults, params + + build: (buildParams) -> + return if !@checkPermissions() + @clear(@popovers) + @bind() + @popovers = @buildPopovers() + + checkPermissions: -> + @params.parentController.permissionCheck(@constructor.permission) + + cssClass: -> + "#{@constructor.selectorCssClassPrefix}-popover" + + bind: -> + + buildPopovers: (supplementaryData = {}) -> + context = @ + + selector = supplementaryData.selector || ".#{@cssClass()}" + + @params.parentController.el.find(selector).popover( + trigger: 'hover' + container: 'body' + html: true + animation: false + delay: 100 + placement: "auto #{@params.position}" + title: -> + context.buildTitleFor(@, supplementaryData) + content: -> + context.buildContentFor(@, supplementaryData) + ) + + clear: -> + return if !@popovers + @popovers.popover('destroy') + + buildTitleFor: (elem) -> + 'title' + + buildContentFor: (elem) -> + 'content' + + buildHtmlContent: (params) -> + html = $(App.view("popover/#{@constructor.templateName}")(params)) + + html.find('.humanTimeFromNow').each => + @params.parentController.frontendTimeUpdateItem($(@)) + + html + + displayTitleUsing: (object) -> + throw 'please override' + diff --git a/app/assets/javascripts/app/lib/app_post/popover_provider/_single_object_popover_provider.coffee b/app/assets/javascripts/app/lib/app_post/popover_provider/_single_object_popover_provider.coffee new file mode 100644 index 000000000..70caa45b1 --- /dev/null +++ b/app/assets/javascripts/app/lib/app_post/popover_provider/_single_object_popover_provider.coffee @@ -0,0 +1,45 @@ +class App.SingleObjectPopoverProvider extends App.PopoverProvider + @klass = null # needs to be overrided + @ignoredAttributes = [] + @includeData = true + @templateName = 'single_object_generic' + + fullCssSelector: -> + "div.#{@cssClass()}, span.#{@cssClass()}" + + bind: -> + @params.parentController.$(@fullCssSelector()).bind('click', (e) => + id = @objectIdFor(e.target) + return if !id + object = @constructor.klass.find(id) + @params.parentController.navigate object.uiUrl() + ) + + objectIdFor: (elem) -> + $(elem).data('id') + + buildTitleFor: (elem) -> + object = @constructor.klass.find(@objectIdFor(elem)) + App.Utils.htmlEscape(@displayTitleUsing(object)) + + buildContentFor: (elem) -> + id = @objectIdFor(elem) + object = @constructor.klass.fullLocal(id) + + # get display data + data = _.values(@constructor.klass.attributesGet('view')) + .filter (attr) -> + # check if value for _id exists + name = attr.name + nameNew = name.substr(0, name.length - 3) + if nameNew of object + name = nameNew + + # add to show if value exists + # do not show ignroed attributes + object[name] && attr.shown && !_.include(@constructor.ignoredAttributes, name) + + @buildHtmlContent( + object: object + attributes: data + ) diff --git a/app/assets/javascripts/app/lib/app_post/popover_provider/organization_popover_provider.coffee b/app/assets/javascripts/app/lib/app_post/popover_provider/organization_popover_provider.coffee new file mode 100644 index 000000000..7e275de1f --- /dev/null +++ b/app/assets/javascripts/app/lib/app_post/popover_provider/organization_popover_provider.coffee @@ -0,0 +1,10 @@ +class Organization extends App.SingleObjectPopoverProvider + @klass = App.Organization + @selectorCssClassPrefix = 'organization' + @templateName = 'organization' + @ignoredAttributes = ['name'] + + displayTitleUsing: (object) -> + object.name + +App.PopoverProvider.registerProvider('Organization', Organization) diff --git a/app/assets/javascripts/app/lib/app_post/popover_provider/ticket_popover_provider.coffee b/app/assets/javascripts/app/lib/app_post/popover_provider/ticket_popover_provider.coffee new file mode 100644 index 000000000..50160b4a7 --- /dev/null +++ b/app/assets/javascripts/app/lib/app_post/popover_provider/ticket_popover_provider.coffee @@ -0,0 +1,10 @@ +class Ticket extends App.SingleObjectPopoverProvider + @klass = App.Ticket + @selectorCssClassPrefix = 'ticket' + @templateName = 'ticket' + @includeData = false + + displayTitleUsing: (object) -> + object.title + +App.PopoverProvider.registerProvider('Ticket', Ticket) diff --git a/app/assets/javascripts/app/lib/app_post/popover_provider/user_popover_provider.coffee b/app/assets/javascripts/app/lib/app_post/popover_provider/user_popover_provider.coffee new file mode 100644 index 000000000..7a608c0f3 --- /dev/null +++ b/app/assets/javascripts/app/lib/app_post/popover_provider/user_popover_provider.coffee @@ -0,0 +1,13 @@ +class User extends App.SingleObjectPopoverProvider + @klass = App.User + @selectorCssClassPrefix = 'user' + @templateName = 'user' + @ignoredAttributes = ['firstname', 'lastname', 'organization'] + + displayTitleUsing: (object) -> + output = object.displayName() + if object.isOutOfOffice() + output += " (#{object.outOfOfficeText()})" + output + +App.PopoverProvider.registerProvider('User', User) diff --git a/app/assets/javascripts/app/lib/app_post/popover_provider/user_ticket_popover_provider.coffee b/app/assets/javascripts/app/lib/app_post/popover_provider/user_ticket_popover_provider.coffee new file mode 100644 index 000000000..5cecf064b --- /dev/null +++ b/app/assets/javascripts/app/lib/app_post/popover_provider/user_ticket_popover_provider.coffee @@ -0,0 +1,37 @@ +class App.UserTicketPopoverProvider extends App.PopoverProvider + @templateName = 'user_ticket_list' + + fetch: (buildParams) -> + @params.parentController.ajax( + type: 'GET' + url: "#{App.Config.get('api_path')}/ticket_customer" + data: + customer_id: buildParams.user_id + processData: true + success: (data, status, xhr) => + App.Collection.loadAssets(data.assets) + + ticketsList = { open: data.ticket_ids_open, closed: data.ticket_ids_closed } + @callback(ticketsList: ticketsList, selector: buildParams.selector) + ) + + build: (buildParams) -> + return if !@checkPermissions() + @fetch(buildParams) + + callback: (supplementaryData) -> + @clear(@popovers) + @popovers = @buildPopovers(supplementaryData) + + buildTitleFor: (elem) -> + $(elem).find('[title="*"]').val() + + buildContentFor: (elem, supplementaryData) -> + type = $(elem).filter('[data-type]').data('type') + ticket_ids = supplementaryData.ticketsList[type] || [] + + tickets = ticket_ids.map (ticketId) -> App.Ticket.fullLocal(ticketId) + + # insert data + @buildHtmlContent(tickets: tickets) + diff --git a/app/assets/javascripts/app/lib/app_post/task_manager.coffee b/app/assets/javascripts/app/lib/app_post/task_manager.coffee index 3696c2dae..6dcd1c987 100644 --- a/app/assets/javascripts/app/lib/app_post/task_manager.coffee +++ b/app/assets/javascripts/app/lib/app_post/task_manager.coffee @@ -96,6 +96,7 @@ class App.TaskManager _instance.maxTaskCount = key class _taskManagerSingleton extends App.Controller + @extend App.PopoverProvidable @include App.LogInclude constructor: (params = {}) -> @@ -394,7 +395,7 @@ class _taskManagerSingleton extends App.Controller if controller.hide && _.isFunction(controller.hide) controller.hide() - @anyPopoversDestroy() + @delayedRemoveAnyPopover() true diff --git a/app/assets/javascripts/app/lib/app_post/user_ticket_popover_provider.coffee b/app/assets/javascripts/app/lib/app_post/user_ticket_popover_provider.coffee new file mode 100644 index 000000000..b5c1f1cd4 --- /dev/null +++ b/app/assets/javascripts/app/lib/app_post/user_ticket_popover_provider.coffee @@ -0,0 +1,38 @@ +class UserTicket extends App.PopoverProvider + @templateName = 'user_ticket_list' + + fetch: (buildParams) -> + @params.parentController.ajax( + type: 'GET' + url: "#{App.Config.get('api_path')}/ticket_customer" + data: + customer_id: buildParams.user_id + processData: true + success: (data, status, xhr) => + App.Collection.loadAssets(data.assets) + + ticketsList = { open: data.ticket_ids_open, closed: data.ticket_ids_closed } + @callback(ticketsList: ticketsList, selector: buildParams.selector) + ) + + build: (buildParams) -> + return if !@checkPermissions() + @fetch(buildParams) + + callback: (supplementaryData) -> + @clear(@popovers) + @popovers = @buildPopovers(supplementaryData) + + buildTitleFor: (elem) -> + $(elem).find('[title="*"]').val() + + buildContentFor: (elem, supplementaryData) -> + type = $(elem).filter('[data-type]').data('type') + ticket_ids = supplementaryData.ticketsList[type] || [] + + tickets = ticket_ids.map (ticketId) -> App.Ticket.fullLocal(ticketId) + + # insert data + @buildHtmlContent(tickets: tickets) + +App.PopoverProvider.registerProvider('UserTicket', UserTicket) diff --git a/app/assets/javascripts/app/lib/mixins/popover_providable.coffee b/app/assets/javascripts/app/lib/mixins/popover_providable.coffee new file mode 100644 index 000000000..40e013f21 --- /dev/null +++ b/app/assets/javascripts/app/lib/mixins/popover_providable.coffee @@ -0,0 +1,56 @@ +InstanceMethods = + # do not call directly + initializePopovers: -> + @el.on('remove', @removePopovers) + + params = _.extend {}, @constructor.popoversDefaults, + parentController: @ + + @initializedPopovers = @selectedPopovers().map (key) -> + klass = App.Config.get(App.PopoverProvider.providersConfigKey)[key] + new klass(params) + + # returns all or selected popovers + selectedPopovers: -> + if @constructor.allPopovers + popoversConfig = App.Config.get(App.PopoverProvider.providersConfigKey) + return Object.keys(popoversConfig) + + return @constructor.registeredPopovers || [] + + # do not call directly + buildPopovers: (buildParams) -> + for popover in @initializedPopovers + popover.build(buildParams) + + renderPopovers: (buildParams = {}) -> + if !@initializedPopovers + @initializePopovers() + + @buildPopovers(buildParams) + + removePopovers: -> + return if !@initializedPopovers + + for popover in @initializedPopovers + popover.clear() + + @initializedPopovers = undefined + + delayedRemoveAnyPopover: -> + @delay(@constructor.anyPopoversDestroy, 100, 'removePopovers') + +App.PopoverProvidable = + registerPopovers: (klasses...) -> + @allPopovers = undefined + @registeredPopovers = klasses + + registerAllPopovers: -> + @allPopovers = true + + anyPopoversDestroy: -> + # do not remove permanent .popover--notifications widget + $('.popover:not(.popover--notifications)').remove() + + extended: -> + @include InstanceMethods diff --git a/app/assets/javascripts/app/views/popover/organization.jst.eco b/app/assets/javascripts/app/views/popover/organization.jst.eco index 1a25b08b5..9f6bbef46 100644 --- a/app/assets/javascripts/app/views/popover/organization.jst.eco +++ b/app/assets/javascripts/app/views/popover/organization.jst.eco @@ -1,19 +1,11 @@ -
-<% for row in @organizationData: %> - <% if @organization[row.name]: %> -
- - <%- @P( @organization, row.name ) %> -
- <% end %> -<% end %> - -<% if @organization.members: %> +<%- @V('popover/single_object_generic', object: @object, attributes: @attributes) %> + +<% if @object.members: %>
- <% for user in @organization.members: %> + <% for user in @object.members: %>
<%= user.displayName() %>
<% end %>
-<% end %> \ No newline at end of file +<% end %> diff --git a/app/assets/javascripts/app/views/popover/single_object_generic.jst.eco b/app/assets/javascripts/app/views/popover/single_object_generic.jst.eco new file mode 100644 index 000000000..b317a4e6a --- /dev/null +++ b/app/assets/javascripts/app/views/popover/single_object_generic.jst.eco @@ -0,0 +1,12 @@ +<% if !_.isEmpty(@attributes): %> +
+<% end %> + +<% for row in @attributes: %> + <% if @object[row.name]: %> +
+ + <%- @P( @object, row.name ) %> +
+ <% end %> +<% end %> diff --git a/app/assets/javascripts/app/views/popover/ticket.jst.eco b/app/assets/javascripts/app/views/popover/ticket.jst.eco index 819ffdaa7..b124eb3b7 100644 --- a/app/assets/javascripts/app/views/popover/ticket.jst.eco +++ b/app/assets/javascripts/app/views/popover/ticket.jst.eco @@ -1,22 +1,22 @@
- <%- @Icon(@ticket.icon(), @ticket.iconClass()) %> <%- @ticket.iconTitle() %> + <%- @Icon(@object.icon(), @object.iconClass()) %> <%- @object.iconTitle() %>

- <%= @ticket.owner.displayName() %> - <% if @ticket.owner.organization: %> - <%= @ticket.owner.organization.displayName() %> + <%= @object.owner.displayName() %> + <% if @object.owner.organization: %> + <%= @object.owner.organization.displayName() %> <% end %>
- <%= @ticket.customer.displayName() %> - <% if @ticket.customer.organization: %> - <%= @ticket.customer.organization.displayName() %> + <%= @object.customer.displayName() %> + <% if @object.customer.organization: %> + <%= @object.customer.organization.displayName() %> <% end %>
@@ -24,18 +24,18 @@
-
<%- @P(@ticket, 'number') %>
+
<%- @P(@object, 'number') %>
-
<%- @P(@ticket, 'priority') %>
+
<%- @P(@object, 'priority') %>
-
<%- @P(@ticket, 'created_at') %>
+
<%- @P(@object, 'created_at') %>
-
<%- @P(@ticket, 'group') %>
+
<%- @P(@object, 'group') %>
-
\ No newline at end of file + diff --git a/app/assets/javascripts/app/views/popover/user.jst.eco b/app/assets/javascripts/app/views/popover/user.jst.eco index 7fcc636ee..b2bc622c7 100644 --- a/app/assets/javascripts/app/views/popover/user.jst.eco +++ b/app/assets/javascripts/app/views/popover/user.jst.eco @@ -1,25 +1,20 @@ -<% if @user['organization']: %> -
<%= @user.organization.displayName() %>
+<% if @object['organization']: %> +
<%= @object.organization.displayName() %>
<% end %> -
-<% for row in @userData: %> - <% if @user[row.name]: %> + +<%- @V('popover/single_object_generic', object: @object, attributes: @attributes) %> +<% if !_.isEmpty(@object['accounts']): %> +
- - <%- @P(@user, row.name) %> + + <% for account of @object['accounts']: %> + <%= account %> + <% end %>
- <% end %> <% end %> -<% if !_.isEmpty(@user['accounts']): %> -
- - <% for account of @user['accounts']: %> - <%= account %> - <% end %> -
-<% end %> -<% if !_.isEmpty(@user['links']): %> - <% for link in @user['links']: %> +<% if !_.isEmpty(@object['links']): %> +
+ <% for link in @object['links']: %>
<% for item in link['items']: %> @@ -37,4 +32,4 @@ <% end %>
<% end %> -<% end %> \ No newline at end of file +<% end %>