Popovers refactoring
This commit is contained in:
parent
254c8c1e4b
commit
9d5b83169d
26 changed files with 391 additions and 315 deletions
|
@ -77,10 +77,6 @@ class App.Controller extends Spine.Controller
|
||||||
if @ajaxCalls
|
if @ajaxCalls
|
||||||
for callId in @ajaxCalls
|
for callId in @ajaxCalls
|
||||||
App.Ajax.abort(callId)
|
App.Ajax.abort(callId)
|
||||||
@userTicketPopupsDestroy()
|
|
||||||
@ticketPopupsDestroy()
|
|
||||||
@userPopupsDestroy()
|
|
||||||
@organizationPopupsDestroy()
|
|
||||||
|
|
||||||
release: ->
|
release: ->
|
||||||
# release custom bindings after it got removed from dom
|
# 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.attr('title', App.i18n.translateTimestamp(timestamp))
|
||||||
item.html(time)
|
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) =>
|
recentView: (object, o_id) =>
|
||||||
params =
|
params =
|
||||||
object: object
|
object: object
|
||||||
|
|
|
@ -545,6 +545,9 @@ class App.ControllerNavSidbar extends App.Controller
|
||||||
sidebar: @$('.sidebar').scrollTop()
|
sidebar: @$('.sidebar').scrollTop()
|
||||||
|
|
||||||
class App.GenericHistory extends App.ControllerModal
|
class App.GenericHistory extends App.ControllerModal
|
||||||
|
@extend App.PopoverProvidable
|
||||||
|
@registerPopovers 'User'
|
||||||
|
|
||||||
buttonClose: true
|
buttonClose: true
|
||||||
buttonCancel: false
|
buttonCancel: false
|
||||||
buttonSubmit: false
|
buttonSubmit: false
|
||||||
|
@ -568,7 +571,7 @@ class App.GenericHistory extends App.ControllerModal
|
||||||
content
|
content
|
||||||
|
|
||||||
onShown: =>
|
onShown: =>
|
||||||
@userPopups()
|
@renderPopovers()
|
||||||
|
|
||||||
sortorder: =>
|
sortorder: =>
|
||||||
@items = @items.reverse()
|
@items = @items.reverse()
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
class App.CTI extends App.Controller
|
class App.CTI extends App.Controller
|
||||||
|
@extend App.PopoverProvidable
|
||||||
|
@registerPopovers 'User'
|
||||||
|
|
||||||
elements:
|
elements:
|
||||||
'.js-callerLog': 'callerLog'
|
'.js-callerLog': 'callerLog'
|
||||||
events:
|
events:
|
||||||
|
@ -160,9 +163,10 @@ class App.CTI extends App.Controller
|
||||||
if diff_in_min > 1
|
if diff_in_min > 1
|
||||||
item.disabled = false
|
item.disabled = false
|
||||||
|
|
||||||
@userPopupsDestroy()
|
@removePopovers()
|
||||||
@callerLog.html( App.view('cti/caller_log')(list: @list))
|
@callerLog.html( App.view('cti/caller_log')(list: @list))
|
||||||
@userPopups()
|
@renderPopovers()
|
||||||
|
|
||||||
@updateNavMenu()
|
@updateNavMenu()
|
||||||
|
|
||||||
done: (e) =>
|
done: (e) =>
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
class App.Navigation extends App.ControllerWidgetPermanent
|
class App.Navigation extends App.ControllerWidgetPermanent
|
||||||
|
@extend App.PopoverProvidable
|
||||||
|
@registerAllPopovers()
|
||||||
|
|
||||||
className: 'navigation vertical'
|
className: 'navigation vertical'
|
||||||
|
|
||||||
elements:
|
elements:
|
||||||
|
@ -157,6 +160,7 @@ class App.Navigation extends App.ControllerWidgetPermanent
|
||||||
)
|
)
|
||||||
|
|
||||||
renderResult: (result = []) =>
|
renderResult: (result = []) =>
|
||||||
|
@removePopovers()
|
||||||
|
|
||||||
# remove result if not result exists
|
# remove result if not result exists
|
||||||
if _.isEmpty(result)
|
if _.isEmpty(result)
|
||||||
|
@ -174,14 +178,7 @@ class App.Navigation extends App.ControllerWidgetPermanent
|
||||||
# show result list
|
# show result list
|
||||||
@searchContainer.addClass('open')
|
@searchContainer.addClass('open')
|
||||||
|
|
||||||
# start ticket popups
|
@renderPopovers()
|
||||||
@ticketPopups()
|
|
||||||
|
|
||||||
# start user popups
|
|
||||||
@userPopups()
|
|
||||||
|
|
||||||
# start oorganization popups
|
|
||||||
@organizationPopups()
|
|
||||||
|
|
||||||
render: ->
|
render: ->
|
||||||
|
|
||||||
|
@ -206,7 +203,7 @@ class App.Navigation extends App.ControllerWidgetPermanent
|
||||||
searchFocus: (e) =>
|
searchFocus: (e) =>
|
||||||
@query = '' # reset query cache
|
@query = '' # reset query cache
|
||||||
@searchContainer.addClass('focused')
|
@searchContainer.addClass('focused')
|
||||||
@anyPopoversDestroy()
|
App.PopoverProvidable.anyPopoversDestroy()
|
||||||
@search()
|
@search()
|
||||||
|
|
||||||
searchBlur: (e) =>
|
searchBlur: (e) =>
|
||||||
|
@ -288,14 +285,14 @@ class App.Navigation extends App.ControllerWidgetPermanent
|
||||||
@searchContainer.removeClass('filled').removeClass('open').removeClass('focused')
|
@searchContainer.removeClass('filled').removeClass('open').removeClass('focused')
|
||||||
@globalSearch.close()
|
@globalSearch.close()
|
||||||
|
|
||||||
# remove not needed popovers
|
@delayedRemoveAnyPopover()
|
||||||
@delay(@anyPopoversDestroy, 100, 'removePopovers')
|
|
||||||
|
|
||||||
andClose: =>
|
andClose: =>
|
||||||
@searchInput.blur()
|
@searchInput.blur()
|
||||||
@searchContainer.removeClass('open')
|
@searchContainer.removeClass('open')
|
||||||
@globalSearch.close()
|
@globalSearch.close()
|
||||||
@delay(@anyPopoversDestroy, 100, 'removePopovers')
|
|
||||||
|
@delayedRemoveAnyPopover()
|
||||||
|
|
||||||
search: =>
|
search: =>
|
||||||
query = @searchInput.val().trim()
|
query = @searchInput.val().trim()
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
class App.Search extends App.Controller
|
class App.Search extends App.Controller
|
||||||
|
@extend App.PopoverProvidable
|
||||||
|
|
||||||
elements:
|
elements:
|
||||||
'.js-search': 'searchInput'
|
'.js-search': 'searchInput'
|
||||||
|
|
||||||
|
@ -112,8 +114,7 @@ class App.Search extends App.Controller
|
||||||
@updateFilledClass()
|
@updateFilledClass()
|
||||||
@updateTask()
|
@updateTask()
|
||||||
|
|
||||||
# remove not needed popovers
|
@delayedRemoveAnyPopover()
|
||||||
@delay(@anyPopoversDestroy, 100, 'removePopovers')
|
|
||||||
|
|
||||||
search: (force = false) =>
|
search: (force = false) =>
|
||||||
query = @searchInput.val().trim()
|
query = @searchInput.val().trim()
|
||||||
|
|
|
@ -926,6 +926,9 @@ class Navbar extends App.Controller
|
||||||
@autoFoldTabs()
|
@autoFoldTabs()
|
||||||
|
|
||||||
class Table extends App.Controller
|
class Table extends App.Controller
|
||||||
|
@extend App.PopoverProvidable
|
||||||
|
@registerPopovers 'Organization', 'User'
|
||||||
|
|
||||||
events:
|
events:
|
||||||
'click [data-type=settings]': 'settings'
|
'click [data-type=settings]': 'settings'
|
||||||
'click [data-type=viewmode]': 'viewmode'
|
'click [data-type=viewmode]': 'viewmode'
|
||||||
|
@ -1174,11 +1177,7 @@ class Table extends App.Controller
|
||||||
'click': callbackCheckbox
|
'click': callbackCheckbox
|
||||||
)
|
)
|
||||||
|
|
||||||
# start user popups
|
@renderPopovers()
|
||||||
@userPopups()
|
|
||||||
|
|
||||||
# start organization popups
|
|
||||||
@organizationPopups()
|
|
||||||
|
|
||||||
@bulkForm = new BulkForm(
|
@bulkForm = new BulkForm(
|
||||||
holder: @el
|
holder: @el
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
class App.WidgetAvatar extends App.ObserverController
|
class App.WidgetAvatar extends App.ObserverController
|
||||||
|
@extend App.PopoverProvidable
|
||||||
|
@registerPopovers 'User'
|
||||||
|
|
||||||
model: 'User'
|
model: 'User'
|
||||||
observe:
|
observe:
|
||||||
login: true
|
login: true
|
||||||
|
@ -17,4 +20,4 @@ class App.WidgetAvatar extends App.ObserverController
|
||||||
|
|
||||||
render: (user) =>
|
render: (user) =>
|
||||||
@html(user.avatar(@size, @position, @cssClass, false, false, @type))
|
@html(user.avatar(@size, @position, @cssClass, false, false, @type))
|
||||||
@userPopups(@position)
|
@renderPopovers()
|
||||||
|
|
|
@ -1,4 +1,10 @@
|
||||||
class App.WidgetLink extends App.Controller
|
class App.WidgetLink extends App.Controller
|
||||||
|
@extend App.PopoverProvidable
|
||||||
|
@registerPopovers 'Ticket'
|
||||||
|
|
||||||
|
@popoversDefaults:
|
||||||
|
position: 'left'
|
||||||
|
|
||||||
events:
|
events:
|
||||||
'click .js-add': 'add'
|
'click .js-add': 'add'
|
||||||
'click .js-delete': 'delete'
|
'click .js-delete': 'delete'
|
||||||
|
@ -54,7 +60,8 @@ class App.WidgetLink extends App.Controller
|
||||||
@html App.view('link/info')(
|
@html App.view('link/info')(
|
||||||
links: list
|
links: list
|
||||||
)
|
)
|
||||||
@ticketPopups('left')
|
|
||||||
|
@renderPopovers()
|
||||||
|
|
||||||
delete: (e) =>
|
delete: (e) =>
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
class App.WidgetOrganization extends App.Controller
|
class App.WidgetOrganization extends App.Controller
|
||||||
|
@extend App.PopoverProvidable
|
||||||
|
@registerPopovers 'User'
|
||||||
|
|
||||||
events:
|
events:
|
||||||
'focusout [contenteditable]': 'update'
|
'focusout [contenteditable]': 'update'
|
||||||
|
|
||||||
|
@ -44,16 +47,7 @@ class App.WidgetOrganization extends App.Controller
|
||||||
maxlength: 250
|
maxlength: 250
|
||||||
)
|
)
|
||||||
|
|
||||||
# enable user popups
|
@renderPopovers()
|
||||||
@userPopups()
|
|
||||||
|
|
||||||
###
|
|
||||||
@userTicketPopups(
|
|
||||||
selector: '.user-tickets'
|
|
||||||
user_id: user.id
|
|
||||||
position: 'right'
|
|
||||||
)
|
|
||||||
###
|
|
||||||
|
|
||||||
update: (e) =>
|
update: (e) =>
|
||||||
name = $(e.target).attr('data-name')
|
name = $(e.target).attr('data-name')
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
class App.TicketList extends App.Controller
|
class App.TicketList extends App.Controller
|
||||||
|
@extend App.PopoverProvidable
|
||||||
|
@registerPopovers 'Organization', 'User'
|
||||||
|
|
||||||
constructor: ->
|
constructor: ->
|
||||||
super
|
super
|
||||||
|
|
||||||
|
@ -85,8 +88,4 @@ class App.TicketList extends App.Controller
|
||||||
radio: @radio
|
radio: @radio
|
||||||
)
|
)
|
||||||
|
|
||||||
# start user popups
|
@renderPopovers()
|
||||||
@userPopups()
|
|
||||||
|
|
||||||
# start organization popups
|
|
||||||
@organizationPopups()
|
|
||||||
|
|
|
@ -138,6 +138,9 @@ class App.TicketStats extends App.Controller
|
||||||
)
|
)
|
||||||
|
|
||||||
class App.TicketStatsList extends App.Controller
|
class App.TicketStatsList extends App.Controller
|
||||||
|
@extend App.PopoverProvidable
|
||||||
|
@registerPopovers 'Ticket'
|
||||||
|
|
||||||
events:
|
events:
|
||||||
'click .js-showAll': 'showAll'
|
'click .js-showAll': 'showAll'
|
||||||
|
|
||||||
|
@ -166,7 +169,7 @@ class App.TicketStatsList extends App.Controller
|
||||||
limit: @limit
|
limit: @limit
|
||||||
)
|
)
|
||||||
|
|
||||||
@ticketPopups()
|
@renderPopovers()
|
||||||
|
|
||||||
showAll: (e) =>
|
showAll: (e) =>
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
class App.WidgetUser extends App.Controller
|
class App.WidgetUser extends App.Controller
|
||||||
|
@extend App.PopoverProvidable
|
||||||
|
@registerPopovers 'UserTicket'
|
||||||
|
|
||||||
events:
|
events:
|
||||||
'focusout [contenteditable]': 'update'
|
'focusout [contenteditable]': 'update'
|
||||||
|
|
||||||
|
@ -76,10 +79,9 @@ class App.WidgetUser extends App.Controller
|
||||||
maxlength: 250
|
maxlength: 250
|
||||||
)
|
)
|
||||||
|
|
||||||
@userTicketPopups(
|
@renderPopovers(
|
||||||
selector: '.user-tickets'
|
selector: '.user-tickets',
|
||||||
user_id: user.id
|
user_id: user.id
|
||||||
position: 'right'
|
|
||||||
)
|
)
|
||||||
|
|
||||||
update: (e) =>
|
update: (e) =>
|
||||||
|
|
|
@ -85,6 +85,10 @@ class App extends Spine.Controller
|
||||||
S: (key) ->
|
S: (key) ->
|
||||||
App.Session.get(key)
|
App.Session.get(key)
|
||||||
|
|
||||||
|
# define view helper for rendering partial views
|
||||||
|
V: (name, params) ->
|
||||||
|
App.view(name)(params)
|
||||||
|
|
||||||
# define address line helper
|
# define address line helper
|
||||||
AddressLine: (line) ->
|
AddressLine: (line) ->
|
||||||
return '' if !line
|
return '' if !line
|
||||||
|
|
|
@ -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'
|
||||||
|
|
|
@ -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
|
||||||
|
)
|
|
@ -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)
|
|
@ -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)
|
|
@ -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)
|
|
@ -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)
|
||||||
|
|
|
@ -96,6 +96,7 @@ class App.TaskManager
|
||||||
_instance.maxTaskCount = key
|
_instance.maxTaskCount = key
|
||||||
|
|
||||||
class _taskManagerSingleton extends App.Controller
|
class _taskManagerSingleton extends App.Controller
|
||||||
|
@extend App.PopoverProvidable
|
||||||
@include App.LogInclude
|
@include App.LogInclude
|
||||||
|
|
||||||
constructor: (params = {}) ->
|
constructor: (params = {}) ->
|
||||||
|
@ -394,7 +395,7 @@ class _taskManagerSingleton extends App.Controller
|
||||||
if controller.hide && _.isFunction(controller.hide)
|
if controller.hide && _.isFunction(controller.hide)
|
||||||
controller.hide()
|
controller.hide()
|
||||||
|
|
||||||
@anyPopoversDestroy()
|
@delayedRemoveAnyPopover()
|
||||||
|
|
||||||
true
|
true
|
||||||
|
|
||||||
|
|
|
@ -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)
|
|
@ -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
|
|
@ -1,18 +1,10 @@
|
||||||
<hr>
|
<%- @V('popover/single_object_generic', object: @object, attributes: @attributes) %>
|
||||||
<% for row in @organizationData: %>
|
|
||||||
<% if @organization[row.name]: %>
|
<% if @object.members: %>
|
||||||
<div class="popover-block">
|
|
||||||
<label><%- @T( row.display ) %></label>
|
|
||||||
<%- @P( @organization, row.name ) %>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
|
||||||
<% end %>
|
|
||||||
</div>
|
|
||||||
<% if @organization.members: %>
|
|
||||||
<hr>
|
<hr>
|
||||||
<div class="popover-block">
|
<div class="popover-block">
|
||||||
<label><%- @T('Members') %></label>
|
<label><%- @T('Members') %></label>
|
||||||
<% for user in @organization.members: %>
|
<% for user in @object.members: %>
|
||||||
<div class="person"><%= user.displayName() %></div>
|
<div class="person"><%= user.displayName() %></div>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
<% if !_.isEmpty(@attributes): %>
|
||||||
|
<hr>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<% for row in @attributes: %>
|
||||||
|
<% if @object[row.name]: %>
|
||||||
|
<div class="popover-block">
|
||||||
|
<label><%- @T( row.display ) %></label>
|
||||||
|
<%- @P( @object, row.name ) %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
|
@ -1,22 +1,22 @@
|
||||||
<div>
|
<div>
|
||||||
<%- @Icon(@ticket.icon(), @ticket.iconClass()) %> <span class="<%- @T(@ticket.iconTextClass()) %>"><%- @ticket.iconTitle() %></span>
|
<%- @Icon(@object.icon(), @object.iconClass()) %> <span class="<%- @T(@object.iconTextClass()) %>"><%- @object.iconTitle() %></span>
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
<div class="popover-block">
|
<div class="popover-block">
|
||||||
<label><%- @T('Agent') %></label>
|
<label><%- @T('Agent') %></label>
|
||||||
<div class="person">
|
<div class="person">
|
||||||
<%= @ticket.owner.displayName() %>
|
<%= @object.owner.displayName() %>
|
||||||
<% if @ticket.owner.organization: %>
|
<% if @object.owner.organization: %>
|
||||||
<span class="organization"><%= @ticket.owner.organization.displayName() %></span>
|
<span class="organization"><%= @object.owner.organization.displayName() %></span>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="popover-block">
|
<div class="popover-block">
|
||||||
<label><%- @T('Customer') %></label>
|
<label><%- @T('Customer') %></label>
|
||||||
<div class="person">
|
<div class="person">
|
||||||
<%= @ticket.customer.displayName() %>
|
<%= @object.customer.displayName() %>
|
||||||
<% if @ticket.customer.organization: %>
|
<% if @object.customer.organization: %>
|
||||||
<span class="organization"><%= @ticket.customer.organization.displayName() %></span>
|
<span class="organization"><%= @object.customer.organization.displayName() %></span>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -24,18 +24,18 @@
|
||||||
<div class="horizontal two-columns">
|
<div class="horizontal two-columns">
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<label>#</label>
|
<label>#</label>
|
||||||
<div class="u-textTruncate"><%- @P(@ticket, 'number') %></div>
|
<div class="u-textTruncate"><%- @P(@object, 'number') %></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<label><%- @T('Priority') %></label>
|
<label><%- @T('Priority') %></label>
|
||||||
<div class="u-textTruncate"><%- @P(@ticket, 'priority') %></div>
|
<div class="u-textTruncate"><%- @P(@object, 'priority') %></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<label><%- @T('Created') %></label>
|
<label><%- @T('Created') %></label>
|
||||||
<div class="u-textTruncate"><%- @P(@ticket, 'created_at') %></div>
|
<div class="u-textTruncate"><%- @P(@object, 'created_at') %></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<label><%- @T('Group') %></label>
|
<label><%- @T('Group') %></label>
|
||||||
<div class="u-textTruncate"><%- @P(@ticket, 'group') %></div>
|
<div class="u-textTruncate"><%- @P(@object, 'group') %></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
|
@ -1,25 +1,20 @@
|
||||||
<% if @user['organization']: %>
|
<% if @object['organization']: %>
|
||||||
<div class="user-organization"><a href="<%- @user.organization.uiUrl() %>"><%= @user.organization.displayName() %></a></div>
|
<div class="user-organization"><a href="<%- @object.organization.uiUrl() %>"><%= @object.organization.displayName() %></a></div>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
|
<%- @V('popover/single_object_generic', object: @object, attributes: @attributes) %>
|
||||||
|
<% if !_.isEmpty(@object['accounts']): %>
|
||||||
<hr>
|
<hr>
|
||||||
<% for row in @userData: %>
|
|
||||||
<% if @user[row.name]: %>
|
|
||||||
<div class="popover-block">
|
|
||||||
<label><%- @T(row.display) %></label>
|
|
||||||
<%- @P(@user, row.name) %>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
|
||||||
<% end %>
|
|
||||||
<% if !_.isEmpty(@user['accounts']): %>
|
|
||||||
<div class="popover-block">
|
<div class="popover-block">
|
||||||
<label><%- @T('Linked Accounts') %></label>
|
<label><%- @T('Linked Accounts') %></label>
|
||||||
<% for account of @user['accounts']: %>
|
<% for account of @object['accounts']: %>
|
||||||
<a href="<%= @user['accounts'][account]['link'] %>" target="_blank"><%= account %></a>
|
<a href="<%= @object['accounts'][account]['link'] %>" target="_blank"><%= account %></a>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% if !_.isEmpty(@user['links']): %>
|
<% if !_.isEmpty(@object['links']): %>
|
||||||
<% for link in @user['links']: %>
|
<hr>
|
||||||
|
<% for link in @object['links']: %>
|
||||||
<div class="popover-block">
|
<div class="popover-block">
|
||||||
<label><%- @T(link['title']) %></label>
|
<label><%- @T(link['title']) %></label>
|
||||||
<% for item in link['items']: %>
|
<% for item in link['items']: %>
|
||||||
|
|
Loading…
Reference in a new issue