Implemented issue #195 - Take over attachment on ticket split.
This commit is contained in:
parent
de55dbeb33
commit
75ac4252f3
7 changed files with 128 additions and 104 deletions
|
@ -1,8 +1,7 @@
|
|||
# coffeelint: disable=camel_case_classes
|
||||
class App.UiElement.richtext
|
||||
@render: (attribute) ->
|
||||
|
||||
item = $( App.view('generic/richtext')( attribute: attribute ) )
|
||||
@render: (attribute, params) ->
|
||||
item = $( App.view('generic/richtext')(attribute: attribute) )
|
||||
item.find('[contenteditable]').ce(
|
||||
mode: attribute.type
|
||||
maxlength: attribute.maxlength
|
||||
|
@ -15,42 +14,42 @@ class App.UiElement.richtext
|
|||
new App[plugin.controller](params)
|
||||
|
||||
if attribute.upload
|
||||
item.append( $( App.view('generic/attachment')( attribute: attribute ) ) )
|
||||
@attachments = []
|
||||
item.append( $( App.view('generic/attachment')(attribute: attribute) ) )
|
||||
|
||||
renderAttachment = (file) =>
|
||||
item.find('.attachments').append( App.view('generic/attachment_item')(
|
||||
fileName: file.filename
|
||||
fileSize: App.Utils.humanFileSize(file.size)
|
||||
store_id: file.store_id
|
||||
))
|
||||
item.on(
|
||||
'click'
|
||||
"[data-id=#{file.store_id}]", (e) =>
|
||||
renderFile = (file) =>
|
||||
item.find('.attachments').append(App.view('generic/attachment_item')(file))
|
||||
@attachments.push file
|
||||
|
||||
if params && params.attachments
|
||||
for file in params.attachments
|
||||
renderFile(file)
|
||||
|
||||
# remove items
|
||||
item.find('.attachments').on('click', '.js-delete', (e) =>
|
||||
id = $(e.currentTarget).data('id')
|
||||
@attachments = _.filter(
|
||||
@attachments,
|
||||
(item) ->
|
||||
return if item.id isnt file.store_id
|
||||
return if item.id.toString() is id.toString()
|
||||
item
|
||||
)
|
||||
store_id = $(e.currentTarget).data('id')
|
||||
|
||||
# delete attachment from storage
|
||||
App.Ajax.request(
|
||||
type: 'DELETE'
|
||||
url: "#{App.Config.get('api_path')}/ticket_attachment_upload"
|
||||
data: JSON.stringify(store_id: store_id),
|
||||
data: JSON.stringify(id: id),
|
||||
processData: false
|
||||
)
|
||||
|
||||
# remove attachment from dom
|
||||
element = $(e.currentTarget).closest('.attachments')
|
||||
$(e.currentTarget).closest('.attachment').remove()
|
||||
# empty .attachment (remove spaces) to keep css working, thanks @mrflix :-o
|
||||
if element.find('.attachment').length == 0
|
||||
element.empty()
|
||||
)
|
||||
|
||||
@attachments = []
|
||||
@progressBar = item.find('.attachmentUpload-progressBar')
|
||||
@progressText = item.find('.js-percentage')
|
||||
@attachmentPlaceholder = item.find('.attachmentPlaceholder')
|
||||
|
@ -84,7 +83,6 @@ class App.UiElement.richtext
|
|||
# Called after received response from the server
|
||||
onCompleted: (response) =>
|
||||
response = JSON.parse(response)
|
||||
@attachments.push response.data
|
||||
|
||||
@attachmentPlaceholder.removeClass('hide')
|
||||
@attachmentUpload.addClass('hide')
|
||||
|
@ -93,7 +91,7 @@ class App.UiElement.richtext
|
|||
@progressBar.width(parseInt(0) + '%')
|
||||
@progressText.text('')
|
||||
|
||||
renderAttachment(response.data)
|
||||
renderFile(response.data)
|
||||
item.find('input').val('')
|
||||
|
||||
App.Log.debug 'UiElement.richtext', 'upload complete', response.data
|
||||
|
@ -111,4 +109,5 @@ class App.UiElement.richtext
|
|||
)
|
||||
)
|
||||
App.Delay.set(u, 100, undefined, 'form_upload')
|
||||
|
||||
item
|
||||
|
|
|
@ -14,6 +14,8 @@ class App.TicketCreate extends App.Controller
|
|||
# define default type
|
||||
@default_type = 'phone-in'
|
||||
|
||||
@formId = App.ControllerForm.formId()
|
||||
|
||||
# remember split info if exists
|
||||
@split = ''
|
||||
if @ticket_id && @article_id
|
||||
|
@ -158,7 +160,7 @@ class App.TicketCreate extends App.Controller
|
|||
# get data / in case also ticket data for split
|
||||
buildScreen: (params) =>
|
||||
|
||||
if !params.ticket_id && !params.article_id
|
||||
if _.isEmpty(params.ticket_id) && _.isEmpty(params.article_id)
|
||||
if !_.isEmpty(params.customer_id)
|
||||
@render(options: { customer_id: params.customer_id })
|
||||
return
|
||||
|
@ -173,6 +175,7 @@ class App.TicketCreate extends App.Controller
|
|||
data:
|
||||
ticket_id: params.ticket_id
|
||||
article_id: params.article_id
|
||||
form_id: @formId
|
||||
processData: true
|
||||
success: (data, status, xhr) =>
|
||||
|
||||
|
@ -194,6 +197,9 @@ class App.TicketCreate extends App.Controller
|
|||
else
|
||||
t.body = App.Utils.text2html(a.body)
|
||||
|
||||
# add attachments
|
||||
t.attachments = data.attachments
|
||||
|
||||
# render page
|
||||
@render(options: t)
|
||||
)
|
||||
|
@ -206,18 +212,15 @@ class App.TicketCreate extends App.Controller
|
|||
params = template.options
|
||||
else if App.TaskManager.get(@task_key) && !_.isEmpty(App.TaskManager.get(@task_key).state)
|
||||
params = App.TaskManager.get(@task_key).state
|
||||
if !_.isEmpty(params['form_id'])
|
||||
@formId = params['form_id']
|
||||
|
||||
if params['form_id']
|
||||
@form_id = params['form_id']
|
||||
else
|
||||
@form_id = App.ControllerForm.formId()
|
||||
|
||||
@html App.view('agent_ticket_create')(
|
||||
@html(App.view('agent_ticket_create')(
|
||||
head: 'New Ticket'
|
||||
agent: @permissionCheck('ticket.agent')
|
||||
admin: @permissionCheck('admin')
|
||||
form_id: @form_id
|
||||
)
|
||||
form_id: @formId
|
||||
))
|
||||
|
||||
signatureChanges = (params, attribute, attributes, classname, form, ui) =>
|
||||
if attribute && attribute.name is 'group_id'
|
||||
|
@ -272,7 +275,7 @@ class App.TicketCreate extends App.Controller
|
|||
}
|
||||
new App.ControllerForm(
|
||||
el: @$('.ticket-form-top')
|
||||
form_id: @form_id
|
||||
form_id: @formId
|
||||
model: App.Ticket
|
||||
screen: 'create_top'
|
||||
events:
|
||||
|
@ -288,14 +291,14 @@ class App.TicketCreate extends App.Controller
|
|||
|
||||
new App.ControllerForm(
|
||||
el: @$('.article-form-top')
|
||||
form_id: @form_id
|
||||
form_id: @formId
|
||||
model: App.TicketArticle
|
||||
screen: 'create_top'
|
||||
params: params
|
||||
)
|
||||
new App.ControllerForm(
|
||||
el: @$('.ticket-form-middle')
|
||||
form_id: @form_id
|
||||
form_id: @formId
|
||||
model: App.Ticket
|
||||
screen: 'create_middle'
|
||||
events:
|
||||
|
@ -310,7 +313,7 @@ class App.TicketCreate extends App.Controller
|
|||
)
|
||||
new App.ControllerForm(
|
||||
el: @$('.ticket-form-bottom')
|
||||
form_id: @form_id
|
||||
form_id: @formId
|
||||
model: App.Ticket
|
||||
screen: 'create_bottom'
|
||||
events:
|
||||
|
@ -420,7 +423,7 @@ class App.TicketCreate extends App.Controller
|
|||
body: params.body
|
||||
type_id: type.id
|
||||
sender_id: sender.id
|
||||
form_id: @form_id
|
||||
form_id: @formId
|
||||
content_type: 'text/html'
|
||||
}
|
||||
else
|
||||
|
@ -432,7 +435,7 @@ class App.TicketCreate extends App.Controller
|
|||
body: params.body
|
||||
type_id: type.id
|
||||
sender_id: sender.id
|
||||
form_id: @form_id
|
||||
form_id: @formId
|
||||
content_type: 'text/html'
|
||||
}
|
||||
|
||||
|
|
|
@ -349,7 +349,7 @@ class LayoutRefCommunicationReply extends App.ControllerContent
|
|||
|
||||
file = @uploadQueue.shift()
|
||||
# console.log "working of", file, "from", @uploadQueue
|
||||
@fakeUpload file.name, file.size, @workOfUploadQueue
|
||||
@fakeUpload(file.name, file.size, @workOfUploadQueue)
|
||||
|
||||
humanFileSize: (size) ->
|
||||
i = Math.floor( Math.log(size) / Math.log(1024) )
|
||||
|
@ -363,27 +363,27 @@ class LayoutRefCommunicationReply extends App.ControllerContent
|
|||
@attachmentPlaceholder.removeClass('hide')
|
||||
@attachmentUpload.addClass('hide')
|
||||
|
||||
fakeUpload: (fileName, fileSize, callback) ->
|
||||
fakeUpload: (filename, size, callback) ->
|
||||
@attachmentPlaceholder.addClass('hide')
|
||||
@attachmentUpload.removeClass('hide')
|
||||
|
||||
progress = 0
|
||||
duration = fileSize / 1024
|
||||
duration = size / 1024
|
||||
|
||||
for i in [0..100]
|
||||
setTimeout @updateUploadProgress, i*duration/100 , i
|
||||
|
||||
setTimeout (=>
|
||||
callback()
|
||||
@renderAttachment(fileName, fileSize)
|
||||
@renderAttachment(filename, size)
|
||||
), duration
|
||||
|
||||
renderAttachment: (fileName, fileSize) =>
|
||||
@attachments.push([fileName, fileSize])
|
||||
@attachmentsHolder.append App.view('generic/attachment_item')
|
||||
fileName: fileName
|
||||
fileSize: @humanFileSize(fileSize)
|
||||
|
||||
renderAttachment: (filename, size) =>
|
||||
@attachments.push([filename, size])
|
||||
@attachmentsHolder.append(App.view('generic/attachment_item')
|
||||
filename: filename
|
||||
size: @humanFileSize(size)
|
||||
)
|
||||
|
||||
App.Config.set( 'layout_ref/communication_reply/:content', LayoutRefCommunicationReply, 'Routes' )
|
||||
|
||||
|
|
|
@ -245,7 +245,7 @@ class App.TicketZoomArticleNew extends App.Controller
|
|||
controller = new App.ControllerForm(
|
||||
el: @$('.recipients')
|
||||
model:
|
||||
configure_attributes: configure_attributes,
|
||||
configure_attributes: configure_attributes
|
||||
)
|
||||
|
||||
@$('[data-name="body"]').ce({
|
||||
|
@ -255,12 +255,13 @@ class App.TicketZoomArticleNew extends App.Controller
|
|||
})
|
||||
|
||||
html5Upload.initialize(
|
||||
uploadUrl: App.Config.get('api_path') + '/ticket_attachment_upload',
|
||||
dropContainer: @$('.article-add').get(0),
|
||||
cancelContainer: @cancelContainer,
|
||||
inputField: @$('.article-attachment input').get(0),
|
||||
key: 'File',
|
||||
data: { form_id: @form_id },
|
||||
uploadUrl: App.Config.get('api_path') + '/ticket_attachment_upload'
|
||||
dropContainer: @$('.article-add').get(0)
|
||||
cancelContainer: @cancelContainer
|
||||
inputField: @$('.article-attachment input').get(0)
|
||||
key: 'File'
|
||||
data:
|
||||
form_id: @form_id
|
||||
maxSimultaneousUploads: 1,
|
||||
onFileAdded: (file) =>
|
||||
|
||||
|
@ -303,6 +304,8 @@ class App.TicketZoomArticleNew extends App.Controller
|
|||
)
|
||||
)
|
||||
|
||||
@bindAttachmentDelete()
|
||||
|
||||
# show text module UI
|
||||
if !@permissionCheck('ticket.customer')
|
||||
textModule = new App.WidgetTextModule(
|
||||
|
@ -737,33 +740,29 @@ class App.TicketZoomArticleNew extends App.Controller
|
|||
@articleNewEdit.parent().removeClass('is-dropTarget') if @dragEventCounter is 0
|
||||
|
||||
renderAttachment: (file) =>
|
||||
@attachmentsHolder.append App.view('generic/attachment_item')
|
||||
fileName: file.filename
|
||||
fileSize: @humanFileSize( file.size )
|
||||
store_id: file.store_id
|
||||
@attachmentsHolder.on(
|
||||
'click'
|
||||
"[data-id=#{file.store_id}]", (e) =>
|
||||
@attachmentsHolder.append(App.view('generic/attachment_item')(file))
|
||||
|
||||
bindAttachmentDelete: =>
|
||||
@attachmentsHolder.on('click', '.js-delete', (e) =>
|
||||
id = $(e.currentTarget).data('id')
|
||||
@attachments = _.filter(
|
||||
@attachments,
|
||||
(item) ->
|
||||
return if item.id isnt file.store_id
|
||||
return if item.id.toString() is id.toString()
|
||||
item
|
||||
)
|
||||
store_id = $(e.currentTarget).data('id')
|
||||
|
||||
# delete attachment from storage
|
||||
App.Ajax.request(
|
||||
type: 'DELETE'
|
||||
url: App.Config.get('api_path') + '/ticket_attachment_upload'
|
||||
data: JSON.stringify(store_id: store_id)
|
||||
data: JSON.stringify(id: id)
|
||||
processData: false
|
||||
)
|
||||
|
||||
# remove attachment from dom
|
||||
element = $(e.currentTarget).closest('.attachments')
|
||||
$(e.currentTarget).closest('.attachment').remove()
|
||||
# empty .attachment (remove spaces) to keep css working, thanks @mrflix :-o
|
||||
if element.find('.attachment').length == 0
|
||||
element.empty()
|
||||
)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<div class="attachment">
|
||||
<div class="attachment-name"><%= @fileName %></div>
|
||||
<div class="attachment-size"><%= @fileSize %></div>
|
||||
<div class="attachment-delete js-delete" data-id="<%= @store_id %>">
|
||||
<div class="attachment-name"><%= @filename %></div>
|
||||
<div class="attachment-size"><%= @humanFileSize(@size) %></div>
|
||||
<div class="attachment-delete js-delete" data-id="<%= @id %>">
|
||||
<%- @Icon('diagonal-cross') %><%- @T('Delete File') %>
|
||||
</div>
|
||||
</div>
|
|
@ -150,13 +150,16 @@ class TicketArticlesController < ApplicationController
|
|||
|
||||
# DELETE /ticket_attachment_upload
|
||||
def ticket_attachment_upload_delete
|
||||
if params[:store_id]
|
||||
Store.remove_item(params[:store_id])
|
||||
|
||||
if params[:id].present?
|
||||
Store.remove_item(params[:id])
|
||||
render json: {
|
||||
success: true,
|
||||
}
|
||||
return
|
||||
elsif params[:form_id]
|
||||
end
|
||||
|
||||
if params[:form_id].present?
|
||||
Store.remove(
|
||||
object: 'UploadCache',
|
||||
o_id: params[:form_id],
|
||||
|
@ -167,7 +170,7 @@ class TicketArticlesController < ApplicationController
|
|||
return
|
||||
end
|
||||
|
||||
render json: { message: 'No such store_id or form_id!' }, status: :unprocessable_entity
|
||||
render json: { message: 'No such id or form_id!' }, status: :unprocessable_entity
|
||||
end
|
||||
|
||||
# POST /ticket_attachment_upload
|
||||
|
@ -198,7 +201,7 @@ class TicketArticlesController < ApplicationController
|
|||
render json: {
|
||||
success: true,
|
||||
data: {
|
||||
store_id: store.id,
|
||||
id: store.id,
|
||||
filename: file.original_filename,
|
||||
size: store.size,
|
||||
}
|
||||
|
|
|
@ -357,8 +357,28 @@ class TicketsController < ApplicationController
|
|||
article = Ticket::Article.find(params[:article_id])
|
||||
assets = article.assets(assets)
|
||||
|
||||
attachments = []
|
||||
if params[:form_id].present?
|
||||
attachments = Store.list(
|
||||
object: 'UploadCache',
|
||||
o_id: params[:form_id],
|
||||
).to_a
|
||||
article.attachments.each do |attachment|
|
||||
next if attachment.preferences['Content-ID'].present?
|
||||
file = Store.add(
|
||||
object: 'UploadCache',
|
||||
o_id: params[:form_id],
|
||||
data: attachment.content,
|
||||
filename: attachment.filename,
|
||||
preferences: attachment.preferences,
|
||||
)
|
||||
attachments.push file
|
||||
end
|
||||
end
|
||||
|
||||
render json: {
|
||||
assets: assets
|
||||
assets: assets,
|
||||
attachments: attachments,
|
||||
}
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue