Refactoring of ticket zoom (less rerendering, just rerender particular area's instant of whole view). Added live broadcasting of tag and links.
This commit is contained in:
parent
65e06eb614
commit
3d878a5547
19 changed files with 449 additions and 276 deletions
|
@ -1117,7 +1117,7 @@ class App.ObserverController extends App.Controller
|
||||||
currentAttributes[key] = object[key]
|
currentAttributes[key] = object[key]
|
||||||
if @observeNot
|
if @observeNot
|
||||||
for key, value of object
|
for key, value of object
|
||||||
if !@observeNot[key] && !_.isFunction(value) && !_.isObject(value)
|
if key isnt 'cid' && !@observeNot[key] && !_.isFunction(value) && !_.isObject(value)
|
||||||
currentAttributes[key] = value
|
currentAttributes[key] = value
|
||||||
|
|
||||||
if !@lastAttributres
|
if !@lastAttributres
|
||||||
|
@ -1128,13 +1128,13 @@ class App.ObserverController extends App.Controller
|
||||||
@log 'debug', 'maybeRender no diff, no rerender'
|
@log 'debug', 'maybeRender no diff, no rerender'
|
||||||
return
|
return
|
||||||
|
|
||||||
@log 'debug', 'maybeRender.diff', diff
|
@log 'debug', 'maybeRender.diff', diff, @observe, @model
|
||||||
@lastAttributres = currentAttributes
|
@lastAttributres = currentAttributes
|
||||||
|
|
||||||
@render(object)
|
@render(object, diff)
|
||||||
|
|
||||||
render: (object) =>
|
render: (object, diff) =>
|
||||||
@log 'debug', 'render', @template, object
|
@log 'debug', 'render', @template, object, diff
|
||||||
@html App.view(@template)(
|
@html App.view(@template)(
|
||||||
object: object
|
object: object
|
||||||
)
|
)
|
||||||
|
@ -1144,5 +1144,5 @@ class App.ObserverController extends App.Controller
|
||||||
|
|
||||||
release: =>
|
release: =>
|
||||||
#console.trace()
|
#console.trace()
|
||||||
@log 'debug', 'release', @object_id, @model
|
@log 'debug', 'release', @object_id, @model, @subscribeId
|
||||||
App[@model].unsubscribe(@subscribeId)
|
App[@model].unsubscribe(@subscribeId)
|
||||||
|
|
|
@ -18,11 +18,10 @@ class App.TicketZoom extends App.Controller
|
||||||
App.TaskManager.remove(@task_key)
|
App.TaskManager.remove(@task_key)
|
||||||
return
|
return
|
||||||
|
|
||||||
@formMeta = undefined
|
@formMeta = undefined
|
||||||
@ticket_id = params.ticket_id
|
@ticket_id = params.ticket_id
|
||||||
@article_id = params.article_id
|
@article_id = params.article_id
|
||||||
@sidebarState = {}
|
@sidebarState = {}
|
||||||
@ticketLastAttributes = {}
|
|
||||||
|
|
||||||
# if we are in init task startup, ignore overview_id
|
# if we are in init task startup, ignore overview_id
|
||||||
if !params.init
|
if !params.init
|
||||||
|
@ -51,7 +50,7 @@ class App.TicketZoom extends App.Controller
|
||||||
update = =>
|
update = =>
|
||||||
@fetch(@ticket_id, false)
|
@fetch(@ticket_id, false)
|
||||||
if !@ticketUpdatedAtLastCall || ( new Date(data.updated_at).toString() isnt new Date(@ticketUpdatedAtLastCall).toString() )
|
if !@ticketUpdatedAtLastCall || ( new Date(data.updated_at).toString() isnt new Date(@ticketUpdatedAtLastCall).toString() )
|
||||||
@delay(update, 1200, "ticket-zoom-#{@ticket_id}")
|
@delay(update, 1100, "ticket-zoom-#{@ticket_id}")
|
||||||
)
|
)
|
||||||
|
|
||||||
# rerender view, e. g. on langauge change
|
# rerender view, e. g. on langauge change
|
||||||
|
@ -59,6 +58,98 @@ class App.TicketZoom extends App.Controller
|
||||||
@fetch(@ticket_id, true)
|
@fetch(@ticket_id, true)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
fetch: (ticket_id, force) ->
|
||||||
|
return if !@Session.get()
|
||||||
|
|
||||||
|
# get data
|
||||||
|
@ajax(
|
||||||
|
id: "ticket_zoom_#{ticket_id}"
|
||||||
|
type: 'GET'
|
||||||
|
url: "#{@apiPath}/tickets/#{ticket_id}?all=true"
|
||||||
|
processData: true
|
||||||
|
success: (data, status, xhr) =>
|
||||||
|
|
||||||
|
# check if ticket has changed
|
||||||
|
newTicketRaw = data.assets.Ticket[ticket_id]
|
||||||
|
if @ticketUpdatedAtLastCall && !force
|
||||||
|
|
||||||
|
# return if ticket hasnt changed
|
||||||
|
return if @ticketUpdatedAtLastCall is newTicketRaw.updated_at
|
||||||
|
|
||||||
|
# notify if ticket changed not by my self
|
||||||
|
if newTicketRaw.updated_by_id isnt @Session.get('id')
|
||||||
|
App.TaskManager.notify(@task_key)
|
||||||
|
|
||||||
|
# remember current data
|
||||||
|
@ticketUpdatedAtLastCall = newTicketRaw.updated_at
|
||||||
|
|
||||||
|
@load(data)
|
||||||
|
App.SessionStorage(@key, data)
|
||||||
|
|
||||||
|
if !@doNotLog
|
||||||
|
@doNotLog = 1
|
||||||
|
@recentView('Ticket', ticket_id)
|
||||||
|
|
||||||
|
error: (xhr) =>
|
||||||
|
@renderDone = false
|
||||||
|
statusText = xhr.statusText
|
||||||
|
status = xhr.status
|
||||||
|
detail = xhr.responseText
|
||||||
|
|
||||||
|
# ignore if request is aborted
|
||||||
|
return if statusText is 'abort'
|
||||||
|
|
||||||
|
# if ticket is already loaded, ignore status "0" - network issues e. g. temp. not connection
|
||||||
|
if @ticketUpdatedAtLastCall && status is 0
|
||||||
|
console.log('network issues e. g. temp. not connection', status, statusText, detail)
|
||||||
|
return
|
||||||
|
|
||||||
|
# show error message
|
||||||
|
if status is 401 || statusText is 'Unauthorized'
|
||||||
|
@taskHead = '» ' + App.i18n.translateInline('Unauthorized') + ' «'
|
||||||
|
@taskIconClass = 'diagonal-cross'
|
||||||
|
@renderScreenUnauthorized(objectName: 'Ticket')
|
||||||
|
else if status is 404 || statusText is 'Not Found'
|
||||||
|
@taskHead = '» ' + App.i18n.translateInline('Not Found') + ' «'
|
||||||
|
@taskIconClass = 'diagonal-cross'
|
||||||
|
@renderScreenNotFound(objectName: 'Ticket')
|
||||||
|
else
|
||||||
|
@taskHead = '» ' + App.i18n.translateInline('Error') + ' «'
|
||||||
|
@taskIconClass = 'diagonal-cross'
|
||||||
|
|
||||||
|
if !detail
|
||||||
|
detail = 'General communication error, maybe internet is not available!'
|
||||||
|
@renderScreenError(
|
||||||
|
status: status
|
||||||
|
detail: detail
|
||||||
|
objectName: 'Ticket'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
load: (data) =>
|
||||||
|
|
||||||
|
# remember article ids
|
||||||
|
@ticket_article_ids = data.ticket_article_ids
|
||||||
|
|
||||||
|
# remember link
|
||||||
|
@links = data.links
|
||||||
|
|
||||||
|
# remember tags
|
||||||
|
@tags = data.tags
|
||||||
|
|
||||||
|
# get edit form attributes
|
||||||
|
@formMeta = data.form_meta
|
||||||
|
|
||||||
|
# load assets
|
||||||
|
App.Collection.loadAssets(data.assets)
|
||||||
|
|
||||||
|
# get data
|
||||||
|
@ticket = App.Ticket.fullLocal(@ticket_id)
|
||||||
|
@ticket.article = undefined
|
||||||
|
|
||||||
|
# render page
|
||||||
|
@render()
|
||||||
|
|
||||||
meta: =>
|
meta: =>
|
||||||
|
|
||||||
# default attributes
|
# default attributes
|
||||||
|
@ -73,14 +164,14 @@ class App.TicketZoom extends App.Controller
|
||||||
meta.head = @taskHead
|
meta.head = @taskHead
|
||||||
|
|
||||||
# set icon and title based on ticket
|
# set icon and title based on ticket
|
||||||
if @ticket
|
if @ticket_id && App.Ticket.exists(@ticket_id)
|
||||||
@ticket = App.Ticket.fullLocal(@ticket.id)
|
ticket = App.Ticket.find(@ticket_id)
|
||||||
meta.head = @ticket.title
|
meta.head = ticket.title
|
||||||
meta.title = '#' + @ticket.number + ' - ' + @ticket.title
|
meta.title = "##{ticket.number} - #{ticket.title}"
|
||||||
meta.class = "task-state-#{ @ticket.getState() }"
|
meta.class = "task-state-#{ ticket.getState() }"
|
||||||
meta.type = 'task'
|
meta.type = 'task'
|
||||||
meta.iconTitle = @ticket.iconTitle()
|
meta.iconTitle = ticket.iconTitle()
|
||||||
meta.iconClass = @ticket.iconClass()
|
meta.iconClass = ticket.iconClass()
|
||||||
meta
|
meta
|
||||||
|
|
||||||
url: =>
|
url: =>
|
||||||
|
@ -137,107 +228,9 @@ class App.TicketZoom extends App.Controller
|
||||||
@autosaveStop()
|
@autosaveStop()
|
||||||
@positionPageHeaderStop()
|
@positionPageHeaderStop()
|
||||||
|
|
||||||
fetch: (ticket_id, force) ->
|
|
||||||
return if !@Session.get()
|
|
||||||
|
|
||||||
# get data
|
|
||||||
@ajax(
|
|
||||||
id: "ticket_zoom_#{ticket_id}"
|
|
||||||
type: 'GET'
|
|
||||||
url: "#{@apiPath}/tickets/#{ticket_id}?full=true"
|
|
||||||
processData: true
|
|
||||||
success: (data, status, xhr) =>
|
|
||||||
|
|
||||||
# check if ticket has changed
|
|
||||||
newTicketRaw = data.assets.Ticket[ticket_id]
|
|
||||||
if @ticketUpdatedAtLastCall && !force
|
|
||||||
|
|
||||||
# return if ticket hasnt changed
|
|
||||||
return if @ticketUpdatedAtLastCall is newTicketRaw.updated_at
|
|
||||||
|
|
||||||
# notify if ticket changed not by my self
|
|
||||||
if newTicketRaw.updated_by_id isnt @Session.get('id')
|
|
||||||
App.TaskManager.notify(@task_key)
|
|
||||||
|
|
||||||
# remember current data
|
|
||||||
@ticketUpdatedAtLastCall = newTicketRaw.updated_at
|
|
||||||
|
|
||||||
@load(data, force)
|
|
||||||
App.SessionStorage(@key, data)
|
|
||||||
|
|
||||||
if !@doNotLog
|
|
||||||
@doNotLog = 1
|
|
||||||
@recentView('Ticket', ticket_id)
|
|
||||||
|
|
||||||
# scroll to end of page
|
|
||||||
if force
|
|
||||||
@scrollToBottom()
|
|
||||||
@positionPageHeaderUpdate()
|
|
||||||
|
|
||||||
error: (xhr) =>
|
|
||||||
statusText = xhr.statusText
|
|
||||||
status = xhr.status
|
|
||||||
detail = xhr.responseText
|
|
||||||
|
|
||||||
# ignore if request is aborted
|
|
||||||
if statusText is 'abort'
|
|
||||||
return
|
|
||||||
|
|
||||||
# if ticket is already loaded, ignore status "0" - network issues e. g. temp. not connection
|
|
||||||
if @ticketUpdatedAtLastCall && status is 0
|
|
||||||
console.log('network issues e. g. temp. not connection', status, statusText, detail)
|
|
||||||
return
|
|
||||||
|
|
||||||
# show error message
|
|
||||||
if status is 401 || statusText is 'Unauthorized'
|
|
||||||
@taskHead = '» ' + App.i18n.translateInline('Unauthorized') + ' «'
|
|
||||||
@taskIconClass = 'diagonal-cross'
|
|
||||||
@renderScreenUnauthorized(objectName: 'Ticket')
|
|
||||||
else if status is 404 || statusText is 'Not Found'
|
|
||||||
@taskHead = '» ' + App.i18n.translateInline('Not Found') + ' «'
|
|
||||||
@taskIconClass = 'diagonal-cross'
|
|
||||||
@renderScreenNotFound(objectName: 'Ticket')
|
|
||||||
else
|
|
||||||
@taskHead = '» ' + App.i18n.translateInline('Error') + ' «'
|
|
||||||
@taskIconClass = 'diagonal-cross'
|
|
||||||
|
|
||||||
if !detail
|
|
||||||
detail = 'General communication error, maybe internet is not available!'
|
|
||||||
@renderScreenError(
|
|
||||||
status: status
|
|
||||||
detail: detail
|
|
||||||
objectName: 'Ticket'
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
muteTask: =>
|
muteTask: =>
|
||||||
App.TaskManager.mute(@task_key)
|
App.TaskManager.mute(@task_key)
|
||||||
|
|
||||||
load: (data, force) =>
|
|
||||||
|
|
||||||
# remember article ids
|
|
||||||
@ticket_article_ids = data.ticket_article_ids
|
|
||||||
|
|
||||||
# remember link
|
|
||||||
@links = data.links
|
|
||||||
|
|
||||||
# remember tags
|
|
||||||
@tags = data.tags
|
|
||||||
|
|
||||||
# get edit form attributes
|
|
||||||
@formMeta = data.form_meta
|
|
||||||
|
|
||||||
# load assets
|
|
||||||
App.Collection.loadAssets(data.assets)
|
|
||||||
|
|
||||||
# get data
|
|
||||||
@ticket = App.Ticket.fullLocal(@ticket_id)
|
|
||||||
@ticket.article = undefined
|
|
||||||
|
|
||||||
# render page
|
|
||||||
@render()
|
|
||||||
|
|
||||||
positionPageHeaderStart: =>
|
positionPageHeaderStart: =>
|
||||||
|
|
||||||
# init header update needed for safari, scroll event is fired
|
# init header update needed for safari, scroll event is fired
|
||||||
|
@ -281,10 +274,9 @@ class App.TicketZoom extends App.Controller
|
||||||
# update taskbar with new meta data
|
# update taskbar with new meta data
|
||||||
App.TaskManager.touch(@task_key)
|
App.TaskManager.touch(@task_key)
|
||||||
|
|
||||||
@formEnable( @$('.submit') )
|
|
||||||
|
|
||||||
if !@renderDone
|
if !@renderDone
|
||||||
@renderDone = true
|
@renderDone = true
|
||||||
|
@autosaveLast = {}
|
||||||
elLocal = $(App.view('ticket_zoom')
|
elLocal = $(App.view('ticket_zoom')
|
||||||
ticket: @ticket
|
ticket: @ticket
|
||||||
nav: @nav
|
nav: @nav
|
||||||
|
@ -294,24 +286,23 @@ class App.TicketZoom extends App.Controller
|
||||||
|
|
||||||
new App.TicketZoomOverviewNavigator(
|
new App.TicketZoomOverviewNavigator(
|
||||||
el: elLocal.find('.overview-navigator')
|
el: elLocal.find('.overview-navigator')
|
||||||
ticket_id: @ticket.id
|
ticket_id: @ticket_id
|
||||||
overview_id: @overview_id
|
overview_id: @overview_id
|
||||||
)
|
)
|
||||||
|
|
||||||
new App.TicketZoomTitle(
|
new App.TicketZoomTitle(
|
||||||
object_id: @ticket.id
|
object_id: @ticket_id
|
||||||
overview_id: @overview_id
|
overview_id: @overview_id
|
||||||
el: elLocal.find('.ticket-title')
|
el: elLocal.find('.ticket-title')
|
||||||
task_key: @task_key
|
task_key: @task_key
|
||||||
)
|
)
|
||||||
|
|
||||||
new App.TicketZoomMeta(
|
new App.TicketZoomMeta(
|
||||||
object_id: @ticket.id
|
object_id: @ticket_id
|
||||||
el: elLocal.find('.ticket-meta')
|
el: elLocal.find('.ticket-meta')
|
||||||
)
|
)
|
||||||
|
|
||||||
new App.TicketZoomAttributeBar(
|
new App.TicketZoomAttributeBar(
|
||||||
ticket: @ticket
|
|
||||||
el: elLocal.find('.js-attributeBar')
|
el: elLocal.find('.js-attributeBar')
|
||||||
overview_id: @overview_id
|
overview_id: @overview_id
|
||||||
callback: @submit
|
callback: @submit
|
||||||
|
@ -322,7 +313,7 @@ class App.TicketZoom extends App.Controller
|
||||||
|
|
||||||
@articleNew = new App.TicketZoomArticleNew(
|
@articleNew = new App.TicketZoomArticleNew(
|
||||||
ticket: @ticket
|
ticket: @ticket
|
||||||
ticket_id: @ticket.id
|
ticket_id: @ticket_id
|
||||||
el: elLocal.find('.article-new')
|
el: elLocal.find('.article-new')
|
||||||
formMeta: @formMeta
|
formMeta: @formMeta
|
||||||
form_id: @form_id
|
form_id: @form_id
|
||||||
|
@ -333,7 +324,7 @@ class App.TicketZoom extends App.Controller
|
||||||
|
|
||||||
@highligher = new App.TicketZoomHighlighter(
|
@highligher = new App.TicketZoomHighlighter(
|
||||||
el: elLocal.find('.highlighter')
|
el: elLocal.find('.highlighter')
|
||||||
ticket_id: @ticket.id
|
ticket_id: @ticket_id
|
||||||
)
|
)
|
||||||
|
|
||||||
@articleView = new App.TicketZoomArticleView(
|
@articleView = new App.TicketZoomArticleView(
|
||||||
|
@ -344,27 +335,20 @@ class App.TicketZoom extends App.Controller
|
||||||
ticket_article_ids: @ticket_article_ids
|
ticket_article_ids: @ticket_article_ids
|
||||||
)
|
)
|
||||||
|
|
||||||
# rerender whole sidebar if customer or organization has changed
|
new App.TicketCustomerAvatar(
|
||||||
if @ticketLastAttributes.customer_id isnt @ticket.customer_id || @ticketLastAttributes.organization_id isnt @ticket.organization_id
|
object_id: @ticket_id
|
||||||
if elLocal
|
el: elLocal.find('.ticketZoom-header')
|
||||||
el = elLocal
|
|
||||||
else
|
|
||||||
el = @el
|
|
||||||
new App.WidgetAvatar(
|
|
||||||
el: el.find('.ticketZoom-header .js-avatar')
|
|
||||||
object_id: @ticket.customer_id
|
|
||||||
size: 50
|
|
||||||
)
|
)
|
||||||
|
|
||||||
@sidebar = new App.TicketZoomSidebar(
|
@sidebar = new App.TicketZoomSidebar(
|
||||||
el: el.find('.tabsSidebar')
|
el: elLocal
|
||||||
sidebarState: @sidebarState
|
sidebarState: @sidebarState
|
||||||
object_id: @ticket.id
|
object_id: @ticket_id
|
||||||
model: 'Ticket'
|
model: 'Ticket'
|
||||||
taskGet: @taskGet
|
taskGet: @taskGet
|
||||||
task_key: @task_key
|
task_key: @task_key
|
||||||
tags: @tags
|
|
||||||
links: @links
|
|
||||||
formMeta: @formMeta
|
formMeta: @formMeta
|
||||||
|
markForm: @markForm
|
||||||
)
|
)
|
||||||
|
|
||||||
# render init content
|
# render init content
|
||||||
|
@ -377,25 +361,35 @@ class App.TicketZoom extends App.Controller
|
||||||
ticket_article_ids: @ticket_article_ids
|
ticket_article_ids: @ticket_article_ids
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if @sidebar
|
||||||
|
|
||||||
|
# update tags
|
||||||
|
if @sidebar.tagWidget
|
||||||
|
@sidebar.tagWidget.reload(@tags)
|
||||||
|
|
||||||
|
# update links
|
||||||
|
if @sidebar.linkWidget
|
||||||
|
@sidebar.linkWidget.reload(@links)
|
||||||
|
|
||||||
# scroll to article if given
|
# scroll to article if given
|
||||||
if @article_id && document.getElementById('article-' + @article_id)
|
if @article_id && document.getElementById("article-#{@article_id}")
|
||||||
offset = document.getElementById('article-' + @article_id).offsetTop
|
offset = document.getElementById("article-#{@article_id}").offsetTop
|
||||||
offset = offset - 45
|
offset = offset - 45
|
||||||
scrollTo = ->
|
scrollTo = ->
|
||||||
@scrollTo(0, offset)
|
@scrollTo(0, offset)
|
||||||
@delay(scrollTo, 100, false)
|
@delay(scrollTo, 100, false)
|
||||||
|
|
||||||
@ticketLastAttributes = @ticket.attributes()
|
if @shown
|
||||||
|
|
||||||
if @shown && !@initDone
|
# scroll to end if new article has been added
|
||||||
|
if !@last_ticket_article_ids || !_.isEqual(_.sortBy(@last_ticket_article_ids), _.sortBy(@ticket_article_ids))
|
||||||
|
@last_ticket_article_ids = @ticket_article_ids
|
||||||
|
@scrollToBottom()
|
||||||
|
@positionPageHeaderUpdate()
|
||||||
|
|
||||||
|
return if @initDone
|
||||||
@initDone = true
|
@initDone = true
|
||||||
|
|
||||||
# scroll to end of page
|
|
||||||
@scrollToBottom()
|
|
||||||
|
|
||||||
# observe content header position
|
|
||||||
@positionPageHeaderStart()
|
|
||||||
|
|
||||||
# trigger shown if init shown render
|
# trigger shown if init shown render
|
||||||
App.Event.trigger('ui::ticket::shown', { ticket_id: @ticket_id })
|
App.Event.trigger('ui::ticket::shown', { ticket_id: @ticket_id })
|
||||||
|
|
||||||
|
@ -403,32 +397,34 @@ class App.TicketZoom extends App.Controller
|
||||||
@main.scrollTop( @main.prop('scrollHeight') )
|
@main.scrollTop( @main.prop('scrollHeight') )
|
||||||
|
|
||||||
autosaveStop: =>
|
autosaveStop: =>
|
||||||
|
console.log('autosaveStop')
|
||||||
@clearDelay('ticket-zoom-form-update')
|
@clearDelay('ticket-zoom-form-update')
|
||||||
@autosaveLast = {}
|
@autosaveLast = {}
|
||||||
@el.off('change.local blur.local keyup.local paste.local input.local')
|
@el.off('change.local blur.local keyup.local paste.local input.local')
|
||||||
|
|
||||||
autosaveStart: =>
|
autosaveStart: =>
|
||||||
|
console.log('autosaveStart')
|
||||||
|
@el.on('change.local blur.local keyup.local paste.local input.local', 'form, .js-textarea', (e) =>
|
||||||
|
@delay(@markForm, 250, 'ticket-zoom-form-update')
|
||||||
|
)
|
||||||
|
@delay(@markForm, 800, 'ticket-zoom-form-update')
|
||||||
|
|
||||||
|
markForm: (force) =>
|
||||||
if !@autosaveLast
|
if !@autosaveLast
|
||||||
@autosaveLast = @taskGet()
|
@autosaveLast = @taskGet()
|
||||||
update = =>
|
return if !@ticket
|
||||||
return if !@ticket
|
currentParams = @formCurrent()
|
||||||
currentParams = @formCurrent()
|
|
||||||
|
|
||||||
# check changed between last autosave
|
# check changed between last autosave
|
||||||
sameAsLastSave = _.isEqual(currentParams, @autosaveLast)
|
sameAsLastSave = _.isEqual(currentParams, @autosaveLast)
|
||||||
return if sameAsLastSave
|
return if !force && sameAsLastSave
|
||||||
@autosaveLast = clone(currentParams)
|
@autosaveLast = clone(currentParams)
|
||||||
|
|
||||||
# update changes in ui
|
# update changes in ui
|
||||||
currentStore = @currentStore()
|
currentStore = @currentStore()
|
||||||
modelDiff = @formDiff(currentParams, currentStore)
|
modelDiff = @formDiff(currentParams, currentStore)
|
||||||
@markFormDiff(modelDiff)
|
@markFormDiff(modelDiff)
|
||||||
@taskUpdateAll(modelDiff)
|
@taskUpdateAll(modelDiff)
|
||||||
|
|
||||||
@el.on('change.local blur.local keyup.local paste.local input.local', 'form, .js-textarea', (e) =>
|
|
||||||
@delay(update, 250, 'ticket-zoom-form-update')
|
|
||||||
)
|
|
||||||
@delay(update, 800, 'ticket-zoom-form-update')
|
|
||||||
|
|
||||||
currentStore: =>
|
currentStore: =>
|
||||||
return if !@ticket
|
return if !@ticket
|
||||||
|
@ -534,7 +530,7 @@ class App.TicketZoom extends App.Controller
|
||||||
ticketParams = @formParam( @$('.edit') )
|
ticketParams = @formParam( @$('.edit') )
|
||||||
|
|
||||||
# validate ticket
|
# validate ticket
|
||||||
ticket = App.Ticket.fullLocal(@ticket.id)
|
ticket = App.Ticket.find(@ticket_id)
|
||||||
|
|
||||||
# reset article - should not be resubmited on next ticket update
|
# reset article - should not be resubmited on next ticket update
|
||||||
ticket.article = undefined
|
ticket.article = undefined
|
||||||
|
@ -550,13 +546,13 @@ class App.TicketZoom extends App.Controller
|
||||||
|
|
||||||
# apply tag changes
|
# apply tag changes
|
||||||
if attributes[1] is 'tags'
|
if attributes[1] is 'tags'
|
||||||
if @sidebar && @sidebar.tagWidget
|
if @sidebar && @sidebar.edit && @sidebar.edit.tagWidget
|
||||||
tags = content.value.split(',')
|
tags = content.value.split(',')
|
||||||
for tag in tags
|
for tag in tags
|
||||||
if content.operator is 'remove'
|
if content.operator is 'remove'
|
||||||
@sidebar.tagWidget.remove(tag)
|
@sidebar.edit.tagWidget.remove(tag)
|
||||||
else
|
else
|
||||||
@sidebar.tagWidget.add(tag)
|
@sidebar.edit.tagWidget.add(tag)
|
||||||
|
|
||||||
# apply user changes
|
# apply user changes
|
||||||
else if attributes[1] is 'owner_id'
|
else if attributes[1] is 'owner_id'
|
||||||
|
@ -671,7 +667,7 @@ class App.TicketZoom extends App.Controller
|
||||||
|
|
||||||
@autosaveStart()
|
@autosaveStart()
|
||||||
@muteTask()
|
@muteTask()
|
||||||
@fetch(ticket.id, true)
|
@fetch(ticket.id, false)
|
||||||
|
|
||||||
# enable form
|
# enable form
|
||||||
@formEnable(e)
|
@formEnable(e)
|
||||||
|
@ -701,7 +697,7 @@ class App.TicketZoom extends App.Controller
|
||||||
@$('.js-reset').addClass('hide')
|
@$('.js-reset').addClass('hide')
|
||||||
|
|
||||||
# reset edit ticket / reset new article
|
# reset edit ticket / reset new article
|
||||||
App.Event.trigger('ui::ticket::taskReset', { ticket_id: @ticket.id })
|
App.Event.trigger('ui::ticket::taskReset', { ticket_id: @ticket_id })
|
||||||
|
|
||||||
# remove change flag on tab
|
# remove change flag on tab
|
||||||
@$('.tabsSidebar-tab[data-tab="ticket"]').removeClass('is-changed')
|
@$('.tabsSidebar-tab[data-tab="ticket"]').removeClass('is-changed')
|
||||||
|
@ -744,7 +740,7 @@ class TicketZoomRouter extends App.ControllerPermanent
|
||||||
shown: true
|
shown: true
|
||||||
|
|
||||||
App.TaskManager.execute(
|
App.TaskManager.execute(
|
||||||
key: 'Ticket-' + @ticket_id
|
key: "Ticket-#{@ticket_id}"
|
||||||
controller: 'TicketZoom'
|
controller: 'TicketZoom'
|
||||||
params: clean_params
|
params: clean_params
|
||||||
show: true
|
show: true
|
||||||
|
|
|
@ -257,7 +257,8 @@ class App.TicketZoomArticleNew extends App.Controller
|
||||||
ticket: ticket
|
ticket: ticket
|
||||||
user: App.Session.get()
|
user: App.Session.get()
|
||||||
)
|
)
|
||||||
@subscribeIdTextModule = ticket.subscribe(callback)
|
if !@subscribeIdTextModule
|
||||||
|
@subscribeIdTextModule = ticket.subscribe(callback)
|
||||||
|
|
||||||
params: =>
|
params: =>
|
||||||
params = @formParam( @$('.article-add') )
|
params = @formParam( @$('.article-add') )
|
||||||
|
|
|
@ -86,6 +86,8 @@ class ArticleViewItem extends App.ObserverController
|
||||||
@el.attr('id', "article-#{article.id}")
|
@el.attr('id', "article-#{article.id}")
|
||||||
if article.internal
|
if article.internal
|
||||||
@el.addClass('is-internal')
|
@el.addClass('is-internal')
|
||||||
|
else
|
||||||
|
@el.removeClass('is-internal')
|
||||||
|
|
||||||
# prepare html body
|
# prepare html body
|
||||||
if article.content_type is 'text/html'
|
if article.content_type is 'text/html'
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
class App.TicketCustomerAvatar extends App.ObserverController
|
||||||
|
model: 'Ticket'
|
||||||
|
observe:
|
||||||
|
customer_id: true
|
||||||
|
|
||||||
|
render: (ticket) =>
|
||||||
|
new App.WidgetAvatar(
|
||||||
|
el: @el.find('.js-avatar')
|
||||||
|
object_id: ticket.customer_id
|
||||||
|
size: 50
|
||||||
|
)
|
|
@ -1,59 +1,66 @@
|
||||||
class App.TicketZoomSidebar extends App.ObserverController
|
class Edit extends App.ObserverController
|
||||||
model: 'Ticket'
|
model: 'Ticket'
|
||||||
observeNot:
|
observeNot:
|
||||||
created_at: true
|
created_at: true
|
||||||
updated_at: true
|
updated_at: true
|
||||||
|
|
||||||
|
render: (ticket, diff) =>
|
||||||
|
defaults = ticket.attributes()
|
||||||
|
delete defaults.article # ignore article infos
|
||||||
|
taskState = @taskGet('ticket')
|
||||||
|
|
||||||
|
if !_.isEmpty(taskState)
|
||||||
|
defaults = _.extend(defaults, taskState)
|
||||||
|
|
||||||
|
form = new App.ControllerForm(
|
||||||
|
model: App.Ticket
|
||||||
|
screen: 'edit'
|
||||||
|
handlers: [
|
||||||
|
@ticketFormChanges
|
||||||
|
]
|
||||||
|
filter: @formMeta.filter
|
||||||
|
params: defaults
|
||||||
|
#bookmarkable: true
|
||||||
|
)
|
||||||
|
@html form.html()
|
||||||
|
|
||||||
|
@markForm(true)
|
||||||
|
|
||||||
|
return if @resetBind
|
||||||
|
@resetBind = true
|
||||||
|
@bind('ui::ticket::taskReset', (data) =>
|
||||||
|
return if data.ticket_id isnt ticket.id
|
||||||
|
@render(ticket)
|
||||||
|
)
|
||||||
|
|
||||||
|
class App.TicketZoomSidebar extends App.ObserverController
|
||||||
|
model: 'Ticket'
|
||||||
|
observe:
|
||||||
|
customer_id: true
|
||||||
|
organization_id: true
|
||||||
|
|
||||||
render: (ticket) =>
|
render: (ticket) =>
|
||||||
|
|
||||||
editTicket = (el) =>
|
editTicket = (el) =>
|
||||||
el.append('<form class="edit"></form>')
|
el.append('<form><fieldset class="edit"></fieldset></form><div class="tags"></div><div class="links"></div>')
|
||||||
@editEl = el
|
|
||||||
|
|
||||||
show = (ticket) =>
|
@edit = new Edit(
|
||||||
el.find('.edit').html('')
|
object_id: ticket.id
|
||||||
|
el: el.find('.edit')
|
||||||
defaults = ticket.attributes()
|
taskGet: @taskGet
|
||||||
delete defaults.article # ignore article infos
|
formMeta: @formMeta
|
||||||
taskState = @taskGet('ticket')
|
markForm: @markForm
|
||||||
modelDiff = App.Utils.formDiff(taskState, defaults)
|
|
||||||
|
|
||||||
if !_.isEmpty(taskState)
|
|
||||||
defaults = _.extend(defaults, taskState)
|
|
||||||
|
|
||||||
new App.ControllerForm(
|
|
||||||
el: el.find('.edit')
|
|
||||||
model: App.Ticket
|
|
||||||
screen: 'edit'
|
|
||||||
handlers: [
|
|
||||||
@ticketFormChanges
|
|
||||||
]
|
|
||||||
filter: @formMeta.filter
|
|
||||||
params: defaults
|
|
||||||
#bookmarkable: true
|
|
||||||
)
|
|
||||||
#console.log('Ichanges', modelDiff, taskState, ticket.attributes(), defaults)
|
|
||||||
#@markFormDiff( modelDiff )
|
|
||||||
|
|
||||||
show(ticket)
|
|
||||||
@bind(
|
|
||||||
'ui::ticket::taskReset'
|
|
||||||
(data) ->
|
|
||||||
if data.ticket_id is ticket.id
|
|
||||||
show(ticket)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if !@isRole('Customer')
|
if !@isRole('Customer')
|
||||||
el.append('<div class="tags"></div>')
|
|
||||||
@tagWidget = new App.WidgetTag(
|
@tagWidget = new App.WidgetTag(
|
||||||
el: el.find('.tags')
|
el: @el.find('.tags')
|
||||||
object_type: 'Ticket'
|
object_type: 'Ticket'
|
||||||
object: ticket
|
object: ticket
|
||||||
tags: @tags
|
tags: @tags
|
||||||
)
|
)
|
||||||
el.append('<div class="links"></div>')
|
|
||||||
@linkWidget = new App.WidgetLink(
|
@linkWidget = new App.WidgetLink(
|
||||||
el: el.find('.links')
|
el: @el.find('.links')
|
||||||
object_type: 'Ticket'
|
object_type: 'Ticket'
|
||||||
object: ticket
|
object: ticket
|
||||||
links: @links
|
links: @links
|
||||||
|
@ -166,7 +173,7 @@ class App.TicketZoomSidebar extends App.ObserverController
|
||||||
callback: showOrganization
|
callback: showOrganization
|
||||||
}
|
}
|
||||||
new App.Sidebar(
|
new App.Sidebar(
|
||||||
el: @el
|
el: @el.find('.tabsSidebar')
|
||||||
sidebarState: @sidebarState
|
sidebarState: @sidebarState
|
||||||
items: @sidebarItems
|
items: @sidebarItems
|
||||||
)
|
)
|
||||||
|
|
|
@ -30,7 +30,13 @@ class App.WidgetLink extends App.Controller
|
||||||
@render()
|
@render()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
reload: (links) ->
|
||||||
|
@links = links
|
||||||
|
@render()
|
||||||
|
|
||||||
render: =>
|
render: =>
|
||||||
|
return if @lastLinks && _.isEqual(@lastLinks, @links)
|
||||||
|
lastLinks = @links
|
||||||
list = {}
|
list = {}
|
||||||
for item in @links
|
for item in @links
|
||||||
if !list[ item['link_type'] ]
|
if !list[ item['link_type'] ]
|
||||||
|
|
|
@ -29,7 +29,7 @@ class App.WidgetTag extends App.Controller
|
||||||
@ajax(
|
@ajax(
|
||||||
id: @key
|
id: @key
|
||||||
type: 'GET'
|
type: 'GET'
|
||||||
url: @apiPath + '/tags'
|
url: "#{@apiPath}/tags"
|
||||||
data:
|
data:
|
||||||
object: @object_type
|
object: @object_type
|
||||||
o_id: @object.id
|
o_id: @object.id
|
||||||
|
@ -39,7 +39,13 @@ class App.WidgetTag extends App.Controller
|
||||||
@render()
|
@render()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
reload: (tags) ->
|
||||||
|
@tags = tags
|
||||||
|
@render()
|
||||||
|
|
||||||
render: ->
|
render: ->
|
||||||
|
return if @lastTags && _.isEqual(@lastTags, @tags)
|
||||||
|
lastTags = @tags
|
||||||
@html App.view('widget/tag')(
|
@html App.view('widget/tag')(
|
||||||
tags: @tags || [],
|
tags: @tags || [],
|
||||||
)
|
)
|
||||||
|
@ -87,7 +93,7 @@ class App.WidgetTag extends App.Controller
|
||||||
|
|
||||||
@ajax(
|
@ajax(
|
||||||
type: 'GET'
|
type: 'GET'
|
||||||
url: @apiPath + '/tags/add'
|
url: "#{@apiPath}/tags/add"
|
||||||
data:
|
data:
|
||||||
object: @object_type
|
object: @object_type
|
||||||
o_id: @object.id
|
o_id: @object.id
|
||||||
|
@ -110,7 +116,7 @@ class App.WidgetTag extends App.Controller
|
||||||
|
|
||||||
@ajax(
|
@ajax(
|
||||||
type: 'GET'
|
type: 'GET'
|
||||||
url: @apiPath + '/tags/remove'
|
url: "#{@apiPath}/tags/remove"
|
||||||
data:
|
data:
|
||||||
object: @object_type
|
object: @object_type
|
||||||
o_id: @object.id
|
o_id: @object.id
|
||||||
|
|
|
@ -65,8 +65,17 @@ class _collectionSingleton extends Spine.Module
|
||||||
|
|
||||||
loadAssets: (assets) ->
|
loadAssets: (assets) ->
|
||||||
@log 'debug', 'loadAssets', assets
|
@log 'debug', 'loadAssets', assets
|
||||||
|
|
||||||
|
# proess not existing assets / to avoid not exising ref errors
|
||||||
|
loadAssetsLater = []
|
||||||
for type, collections of assets
|
for type, collections of assets
|
||||||
@load(type: type, data: collections)
|
later = @load(type: type, data: collections, later: true)
|
||||||
|
if later
|
||||||
|
loadAssetsLater[type] = later
|
||||||
|
|
||||||
|
# proess existing assets
|
||||||
|
for type, collections of loadAssetsLater
|
||||||
|
App[type].refresh(collections)
|
||||||
|
|
||||||
load: (params) ->
|
load: (params) ->
|
||||||
|
|
||||||
|
@ -81,11 +90,13 @@ class _collectionSingleton extends Spine.Module
|
||||||
|
|
||||||
# load full array once
|
# load full array once
|
||||||
if _.isArray(params.data)
|
if _.isArray(params.data)
|
||||||
|
@log 'debug', 'refresh', params.data
|
||||||
appObject.refresh(params.data)
|
appObject.refresh(params.data)
|
||||||
return
|
return
|
||||||
|
|
||||||
# load data from object
|
# load data from object
|
||||||
listToRefresh = []
|
listToRefresh = []
|
||||||
|
listToRefreshLater = []
|
||||||
for key, object of params.data
|
for key, object of params.data
|
||||||
if !params.refresh && appObject
|
if !params.refresh && appObject
|
||||||
@log 'debug', 'refrest try', params.type, key
|
@log 'debug', 'refrest try', params.type, key
|
||||||
|
@ -93,15 +104,22 @@ class _collectionSingleton extends Spine.Module
|
||||||
# check if new object is newer, just load newer objects
|
# check if new object is newer, just load newer objects
|
||||||
if object.updated_at && appObject.exists(key)
|
if object.updated_at && appObject.exists(key)
|
||||||
exists = appObject.find(key)
|
exists = appObject.find(key)
|
||||||
|
objectToLoad = undefined
|
||||||
if exists.updated_at
|
if exists.updated_at
|
||||||
if exists.updated_at < object.updated_at
|
if exists.updated_at < object.updated_at
|
||||||
listToRefresh.push object
|
objectToLoad = object
|
||||||
@log 'debug', 'refrest newser', params.type, key
|
@log 'debug', 'refrest newser', params.type, key
|
||||||
else
|
else
|
||||||
listToRefresh.push object
|
objectToLoad = object
|
||||||
@log 'debug', 'refrest try no updated_at', params.type, key
|
@log 'debug', 'refrest try no updated_at', params.type, key
|
||||||
|
if objectToLoad
|
||||||
|
if params.later
|
||||||
|
listToRefreshLater.push objectToLoad
|
||||||
|
else
|
||||||
|
listToRefresh.push object
|
||||||
else
|
else
|
||||||
listToRefresh.push object
|
listToRefresh.push object
|
||||||
@log 'debug', 'refrest new', params.type, key
|
@log 'debug', 'refrest new', params.type, key
|
||||||
return if _.isEmpty(listToRefresh)
|
return listToRefreshLater if _.isEmpty(listToRefresh)
|
||||||
appObject.refresh(listToRefresh)
|
appObject.refresh(listToRefresh)
|
||||||
|
listToRefreshLater
|
||||||
|
|
|
@ -347,7 +347,7 @@ class App.Model extends Spine.Model
|
||||||
clear: true
|
clear: true
|
||||||
)
|
)
|
||||||
|
|
||||||
'Collection::Subscribe::' + @className
|
"Collection::Subscribe::#{@className}"
|
||||||
)
|
)
|
||||||
|
|
||||||
key = @className + '-' + Math.floor( Math.random() * 99999 )
|
key = @className + '-' + Math.floor( Math.random() * 99999 )
|
||||||
|
@ -454,9 +454,9 @@ class App.Model extends Spine.Model
|
||||||
if !genericObject || new Date(item.updated_at) >= new Date(genericObject.updated_at)
|
if !genericObject || new Date(item.updated_at) >= new Date(genericObject.updated_at)
|
||||||
App.Log.debug('Model', "request #{@className}.find(#{item.id}) from server")
|
App.Log.debug('Model', "request #{@className}.find(#{item.id}) from server")
|
||||||
@full(item.id, false, true)
|
@full(item.id, false, true)
|
||||||
App.Delay.set(callback, 500, item.id, "full-#{@className}")
|
App.Delay.set(callback, 500, item.id, "full-#{@className}-#{item.id}")
|
||||||
|
|
||||||
'Item::Subscribe::' + @className
|
"Item::Subscribe::#{@className}"
|
||||||
)
|
)
|
||||||
|
|
||||||
# remember item callback
|
# remember item callback
|
||||||
|
|
|
@ -339,6 +339,13 @@ class ApplicationController < ActionController::Base
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def article_permission(article)
|
||||||
|
ticket = Ticket.lookup(id: article.ticket_id)
|
||||||
|
return true if ticket.permission(current_user: current_user)
|
||||||
|
response_access_deny
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
def deny_if_not_role(role_name)
|
def deny_if_not_role(role_name)
|
||||||
return false if role?(role_name)
|
return false if role?(role_name)
|
||||||
response_access_deny
|
response_access_deny
|
||||||
|
@ -445,6 +452,12 @@ class ApplicationController < ActionController::Base
|
||||||
|
|
||||||
def model_show_render (object, params)
|
def model_show_render (object, params)
|
||||||
|
|
||||||
|
if params[:expand]
|
||||||
|
generic_object = object.find(params[:id])
|
||||||
|
model_show_render_item(generic_object)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
if params[:full]
|
if params[:full]
|
||||||
generic_object_full = object.full(params[:id])
|
generic_object_full = object.full(params[:id])
|
||||||
render json: generic_object_full, status: :ok
|
render json: generic_object_full, status: :ok
|
||||||
|
|
|
@ -113,7 +113,7 @@ curl http://localhost/api/v1/organizations/#{id} -v -u #{login}:#{password}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if params[:full]
|
if params[:full]
|
||||||
full = Organization.full( params[:id] )
|
full = Organization.full(params[:id])
|
||||||
render json: full
|
render json: full
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,13 +5,13 @@ class TaskbarController < ApplicationController
|
||||||
|
|
||||||
def index
|
def index
|
||||||
|
|
||||||
current_user_tasks = Taskbar.where( user_id: current_user.id )
|
current_user_tasks = Taskbar.where(user_id: current_user.id)
|
||||||
model_index_render_result(current_user_tasks)
|
model_index_render_result(current_user_tasks)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
taskbar = Taskbar.find( params[:id] )
|
taskbar = Taskbar.find(params[:id])
|
||||||
return if !access(taskbar)
|
return if !access(taskbar)
|
||||||
|
|
||||||
model_show_render_item(taskbar)
|
model_show_render_item(taskbar)
|
||||||
|
@ -22,15 +22,15 @@ class TaskbarController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
taskbar = Taskbar.find( params[:id] )
|
taskbar = Taskbar.find(params[:id])
|
||||||
return if !access(taskbar)
|
return if !access(taskbar)
|
||||||
|
|
||||||
taskbar.update_attributes!( Taskbar.param_cleanup(params) )
|
taskbar.update_attributes!(Taskbar.param_cleanup(params))
|
||||||
model_update_render_item(taskbar)
|
model_update_render_item(taskbar)
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
taskbar = Taskbar.find( params[:id] )
|
taskbar = Taskbar.find(params[:id])
|
||||||
return if !access(taskbar)
|
return if !access(taskbar)
|
||||||
|
|
||||||
taskbar.destroy
|
taskbar.destroy
|
||||||
|
|
|
@ -19,19 +19,24 @@ class TicketArticlesController < ApplicationController
|
||||||
|
|
||||||
# POST /articles
|
# POST /articles
|
||||||
def create
|
def create
|
||||||
form_id = params[:ticket_article][:form_id]
|
form_id = params[:form_id]
|
||||||
params[:ticket_article].delete(:form_id)
|
|
||||||
@article = Ticket::Article.new(Ticket::Article.param_validation( params[:ticket_article]))
|
clean_params = Ticket::Article.param_association_lookup(params)
|
||||||
|
clean_params = Ticket::Article.param_cleanup(clean_params, true)
|
||||||
|
article = Ticket::Article.new(clean_params)
|
||||||
|
|
||||||
|
# permission check
|
||||||
|
return if !article_permission(article)
|
||||||
|
|
||||||
# find attachments in upload cache
|
# find attachments in upload cache
|
||||||
if form_id
|
if form_id
|
||||||
@article.attachments = Store.list(
|
article.attachments = Store.list(
|
||||||
object: 'UploadCache',
|
object: 'UploadCache',
|
||||||
o_id: form_id,
|
o_id: form_id,
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
if @article.save
|
if article.save
|
||||||
|
|
||||||
# remove attachments from upload cache
|
# remove attachments from upload cache
|
||||||
Store.remove(
|
Store.remove(
|
||||||
|
@ -39,27 +44,34 @@ class TicketArticlesController < ApplicationController
|
||||||
o_id: form_id,
|
o_id: form_id,
|
||||||
)
|
)
|
||||||
|
|
||||||
render json: @article, status: :created
|
render json: article, status: :created
|
||||||
else
|
else
|
||||||
render json: @article.errors, status: :unprocessable_entity
|
render json: article.errors, status: :unprocessable_entity
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# PUT /articles/1
|
# PUT /articles/1
|
||||||
def update
|
def update
|
||||||
@article = Ticket::Article.find(params[:id])
|
|
||||||
|
|
||||||
if @article.update_attributes(Ticket::Article.param_validation(params[:ticket_article]))
|
# permission check
|
||||||
render json: @article, status: :ok
|
article = Ticket::Article.find(params[:id])
|
||||||
|
return if !article_permission(article)
|
||||||
|
|
||||||
|
clean_params = Ticket::Article.param_association_lookup(params)
|
||||||
|
clean_params = Ticket::Article.param_cleanup(clean_params, true)
|
||||||
|
|
||||||
|
if article.update_attributes(clean_params)
|
||||||
|
render json: article, status: :ok
|
||||||
else
|
else
|
||||||
render json: @article.errors, status: :unprocessable_entity
|
render json: article.errors, status: :unprocessable_entity
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# DELETE /articles/1
|
# DELETE /articles/1
|
||||||
def destroy
|
def destroy
|
||||||
@article = Ticket::Article.find(params[:id])
|
article = Ticket::Article.find(params[:id])
|
||||||
@article.destroy
|
return if !article_permission(article)
|
||||||
|
article.destroy
|
||||||
|
|
||||||
head :ok
|
head :ok
|
||||||
end
|
end
|
||||||
|
@ -121,18 +133,18 @@ class TicketArticlesController < ApplicationController
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
# GET /ticket_attachment/1
|
# GET /ticket_attachment/:ticket_id/:article_id/:id
|
||||||
def attachment
|
def attachment
|
||||||
|
|
||||||
# permission check
|
# permission check
|
||||||
ticket = Ticket.lookup(id: params[:ticket_id])
|
ticket = Ticket.lookup(id: params[:ticket_id])
|
||||||
if !ticket_permission(ticket)
|
if !ticket_permission(ticket)
|
||||||
render(json: 'No such ticket.', status: :unauthorized)
|
render json: 'No such ticket.', status: :unauthorized
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
article = Ticket::Article.find(params[:article_id])
|
article = Ticket::Article.find(params[:article_id])
|
||||||
if ticket.id != article.ticket_id
|
if ticket.id != article.ticket_id
|
||||||
render(json: 'No access, article_id/ticket_id is not matching.', status: :unauthorized)
|
render json: 'No access, article_id/ticket_id is not matching.', status: :unauthorized
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -144,7 +156,7 @@ class TicketArticlesController < ApplicationController
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
if !access
|
if !access
|
||||||
render(json: 'Requested file id is not linked with article_id.', status: :unauthorized)
|
render json: 'Requested file id is not linked with article_id.', status: :unauthorized
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -163,7 +175,7 @@ class TicketArticlesController < ApplicationController
|
||||||
|
|
||||||
# permission check
|
# permission check
|
||||||
article = Ticket::Article.find(params[:id])
|
article = Ticket::Article.find(params[:id])
|
||||||
return if !ticket_permission(article.ticket)
|
return if !article_permission(article)
|
||||||
|
|
||||||
list = Store.list(
|
list = Store.list(
|
||||||
object: 'Ticket::Article::Mail',
|
object: 'Ticket::Article::Mail',
|
||||||
|
|
|
@ -41,7 +41,13 @@ class TicketsController < ApplicationController
|
||||||
return if !ticket_permission(ticket)
|
return if !ticket_permission(ticket)
|
||||||
|
|
||||||
if params[:full]
|
if params[:full]
|
||||||
render json: ticket_full(ticket)
|
full = Ticket.full(params[:id])
|
||||||
|
render json: full
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if params[:all]
|
||||||
|
render json: ticket_all(ticket)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -555,7 +561,7 @@ class TicketsController < ApplicationController
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def ticket_full(ticket)
|
def ticket_all(ticket)
|
||||||
|
|
||||||
# get attributes to update
|
# get attributes to update
|
||||||
attributes_to_change = Ticket::ScreenOptions.attributes_to_change(user: current_user, ticket: ticket)
|
attributes_to_change = Ticket::ScreenOptions.attributes_to_change(user: current_user, ticket: ticket)
|
||||||
|
|
|
@ -1280,6 +1280,24 @@ get assets and record_ids of selector
|
||||||
assets
|
assets
|
||||||
end
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
touch references by params
|
||||||
|
|
||||||
|
Model.touch_reference_by_params(
|
||||||
|
object: 'Ticket',
|
||||||
|
o_id: 123,
|
||||||
|
)
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def self.touch_reference_by_params(data)
|
||||||
|
object_class = Kernel.const_get(data[:object])
|
||||||
|
object = object_class.lookup(id: data[:o_id])
|
||||||
|
return if !object
|
||||||
|
object.touch
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def attachments_buffer
|
def attachments_buffer
|
||||||
|
|
|
@ -75,21 +75,29 @@ class Link < ApplicationModel
|
||||||
def self.add(data)
|
def self.add(data)
|
||||||
|
|
||||||
if data.key?(:link_type)
|
if data.key?(:link_type)
|
||||||
linktype = link_type_get( name: data[:link_type] )
|
linktype = link_type_get(name: data[:link_type])
|
||||||
data[:link_type_id] = linktype.id
|
data[:link_type_id] = linktype.id
|
||||||
data.delete( :link_type )
|
data.delete(:link_type)
|
||||||
end
|
end
|
||||||
|
|
||||||
if data.key?(:link_object_source)
|
if data.key?(:link_object_source)
|
||||||
linkobject = link_object_get( name: data[:link_object_source] )
|
linkobject = link_object_get(name: data[:link_object_source])
|
||||||
data[:link_object_source_id] = linkobject.id
|
data[:link_object_source_id] = linkobject.id
|
||||||
data.delete( :link_object_source )
|
touch_reference_by_params(
|
||||||
|
object: data[:link_object_source],
|
||||||
|
o_id: data[:link_object_source_value],
|
||||||
|
)
|
||||||
|
data.delete(:link_object_source)
|
||||||
end
|
end
|
||||||
|
|
||||||
if data.key?(:link_object_target)
|
if data.key?(:link_object_target)
|
||||||
linkobject = link_object_get( name: data[:link_object_target] )
|
linkobject = link_object_get(name: data[:link_object_target])
|
||||||
data[:link_object_target_id] = linkobject.id
|
data[:link_object_target_id] = linkobject.id
|
||||||
data.delete( :link_object_target )
|
touch_reference_by_params(
|
||||||
|
object: data[:link_object_target],
|
||||||
|
o_id: data[:link_object_target_value],
|
||||||
|
)
|
||||||
|
data.delete(:link_object_target)
|
||||||
end
|
end
|
||||||
|
|
||||||
Link.create(data)
|
Link.create(data)
|
||||||
|
@ -109,18 +117,18 @@ class Link < ApplicationModel
|
||||||
|
|
||||||
def self.remove(data)
|
def self.remove(data)
|
||||||
if data.key?(:link_object_source)
|
if data.key?(:link_object_source)
|
||||||
linkobject = link_object_get( name: data[:link_object_source] )
|
linkobject = link_object_get(name: data[:link_object_source])
|
||||||
data[:link_object_source_id] = linkobject.id
|
data[:link_object_source_id] = linkobject.id
|
||||||
end
|
end
|
||||||
|
|
||||||
if data.key?(:link_object_target)
|
if data.key?(:link_object_target)
|
||||||
linkobject = link_object_get( name: data[:link_object_target] )
|
linkobject = link_object_get(name: data[:link_object_target])
|
||||||
data[:link_object_target_id] = linkobject.id
|
data[:link_object_target_id] = linkobject.id
|
||||||
end
|
end
|
||||||
|
|
||||||
# from one site
|
# from one site
|
||||||
if data.key?(:link_type)
|
if data.key?(:link_type)
|
||||||
linktype = link_type_get( name: data[:link_type] )
|
linktype = link_type_get(name: data[:link_type])
|
||||||
data[:link_type_id] = linktype.id
|
data[:link_type_id] = linktype.id
|
||||||
end
|
end
|
||||||
links = Link.where(
|
links = Link.where(
|
||||||
|
@ -130,11 +138,23 @@ class Link < ApplicationModel
|
||||||
link_object_target_id: data[:link_object_target_id],
|
link_object_target_id: data[:link_object_target_id],
|
||||||
link_object_target_value: data[:link_object_target_value]
|
link_object_target_value: data[:link_object_target_value]
|
||||||
)
|
)
|
||||||
links.each(&:destroy)
|
|
||||||
|
# touch references
|
||||||
|
links.each {|link|
|
||||||
|
link.destroy
|
||||||
|
touch_reference_by_params(
|
||||||
|
object: Link::Object.lookup(id: link.link_object_source_id).name,
|
||||||
|
o_id: link.link_object_source_value,
|
||||||
|
)
|
||||||
|
touch_reference_by_params(
|
||||||
|
object: Link::Object.lookup(id: link.link_object_target_id).name,
|
||||||
|
o_id: link.link_object_target_value,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
# from the other site
|
# from the other site
|
||||||
if data.key?(:link_type)
|
if data.key?(:link_type)
|
||||||
linktype = link_type_get( name: @map[ data[:link_type] ] )
|
linktype = link_type_get(name: @map[ data[:link_type] ])
|
||||||
data[:link_type_id] = linktype.id
|
data[:link_type_id] = linktype.id
|
||||||
end
|
end
|
||||||
links = Link.where(
|
links = Link.where(
|
||||||
|
@ -144,25 +164,33 @@ class Link < ApplicationModel
|
||||||
link_object_source_id: data[:link_object_target_id],
|
link_object_source_id: data[:link_object_target_id],
|
||||||
link_object_source_value: data[:link_object_target_value]
|
link_object_source_value: data[:link_object_target_value]
|
||||||
)
|
)
|
||||||
links.each(&:destroy)
|
|
||||||
|
# touch references
|
||||||
|
links.each {|link|
|
||||||
|
link.destroy
|
||||||
|
touch_reference_by_params(
|
||||||
|
object: Link::Object.lookup(id: link.link_object_source_id).name,
|
||||||
|
o_id: link.link_object_source_value,
|
||||||
|
)
|
||||||
|
touch_reference_by_params(
|
||||||
|
object: Link::Object.lookup(id: link.link_object_target_id).name,
|
||||||
|
o_id: link.link_object_target_value,
|
||||||
|
)
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.link_type_get(data)
|
def self.link_type_get(data)
|
||||||
linktype = Link::Type.find_by( name: data[:name] )
|
linktype = Link::Type.find_by(name: data[:name])
|
||||||
if !linktype
|
if !linktype
|
||||||
linktype = Link::Type.create(
|
linktype = Link::Type.create(name: data[:name])
|
||||||
name: data[:name]
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
linktype
|
linktype
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.link_object_get(data)
|
def self.link_object_get(data)
|
||||||
linkobject = Link::Object.find_by( name: data[:name] )
|
linkobject = Link::Object.find_by(name: data[:name])
|
||||||
if !linkobject
|
if !linkobject
|
||||||
linkobject = Link::Object.create(
|
linkobject = Link::Object.create(name: data[:name])
|
||||||
name: data[:name]
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
linkobject
|
linkobject
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,7 +7,20 @@ class Tag < ApplicationModel
|
||||||
# rubocop:disable Style/ClassVars
|
# rubocop:disable Style/ClassVars
|
||||||
@@cache_item = {}
|
@@cache_item = {}
|
||||||
@@cache_object = {}
|
@@cache_object = {}
|
||||||
# rubocop:enable Style/ClassVars
|
# rubocop:enable Style/ClassVars
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
add tags for certain object
|
||||||
|
|
||||||
|
Tag.tag_add(
|
||||||
|
object: 'Ticket',
|
||||||
|
o_id: ticket.id,
|
||||||
|
item: 'some tag',
|
||||||
|
created_by_id: current_user.id,
|
||||||
|
)
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
def self.tag_add(data)
|
def self.tag_add(data)
|
||||||
|
|
||||||
|
@ -30,9 +43,25 @@ class Tag < ApplicationModel
|
||||||
o_id: data[:o_id],
|
o_id: data[:o_id],
|
||||||
created_by_id: data[:created_by_id],
|
created_by_id: data[:created_by_id],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# touch reference
|
||||||
|
touch_reference_by_params(data)
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
remove tags of certain object
|
||||||
|
|
||||||
|
Tag.tag_add(
|
||||||
|
object: 'Ticket',
|
||||||
|
o_id: ticket.id,
|
||||||
|
item: 'some tag',
|
||||||
|
created_by_id: current_user.id,
|
||||||
|
)
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
def self.tag_remove(data)
|
def self.tag_remove(data)
|
||||||
|
|
||||||
# lookups
|
# lookups
|
||||||
|
@ -50,9 +79,29 @@ class Tag < ApplicationModel
|
||||||
o_id: data[:o_id],
|
o_id: data[:o_id],
|
||||||
)
|
)
|
||||||
result.each(&:destroy)
|
result.each(&:destroy)
|
||||||
|
|
||||||
|
# touch reference
|
||||||
|
touch_reference_by_params(data)
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
tag list for certain object
|
||||||
|
|
||||||
|
tags = Tag.tag_list(
|
||||||
|
object: 'Ticket',
|
||||||
|
o_id: ticket.id,
|
||||||
|
item: 'some tag',
|
||||||
|
created_by_id: current_user.id,
|
||||||
|
)
|
||||||
|
|
||||||
|
returns
|
||||||
|
|
||||||
|
['tag 1', 'tag2', ...]
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
def self.tag_list(data)
|
def self.tag_list(data)
|
||||||
tag_object_id_requested = tag_object_lookup(data[:object])
|
tag_object_id_requested = tag_object_lookup(data[:object])
|
||||||
tag_search = Tag.where(
|
tag_search = Tag.where(
|
||||||
|
|
|
@ -6,16 +6,16 @@ module Ticket::Assets
|
||||||
get all assets / related models for this ticket
|
get all assets / related models for this ticket
|
||||||
|
|
||||||
ticket = Ticket.find(123)
|
ticket = Ticket.find(123)
|
||||||
result = ticket.assets( assets_if_exists )
|
result = ticket.assets(assets_if_exists)
|
||||||
|
|
||||||
returns
|
returns
|
||||||
|
|
||||||
result = {
|
result = {
|
||||||
:users => {
|
users: {
|
||||||
123 => user_model_123,
|
123: user_model_123,
|
||||||
1234 => user_model_1234,
|
1234: user_model_1234,
|
||||||
}
|
},
|
||||||
:tickets => [ ticket_model1 ]
|
tickets: [ ticket_model1 ]
|
||||||
}
|
}
|
||||||
|
|
||||||
=end
|
=end
|
||||||
|
|
Loading…
Reference in a new issue