Implemented issue #195 - Take over attachment on ticket split.

This commit is contained in:
Martin Edenhofer 2017-12-05 15:49:59 +01:00
parent de55dbeb33
commit 75ac4252f3
7 changed files with 128 additions and 104 deletions

View file

@ -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) =>
@attachments = _.filter(
@attachments,
(item) ->
return if item.id isnt file.store_id
item
)
store_id = $(e.currentTarget).data('id')
renderFile = (file) =>
item.find('.attachments').append(App.view('generic/attachment_item')(file))
@attachments.push file
# 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),
processData: false
)
if params && params.attachments
for file in params.attachments
renderFile(file)
# 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()
# remove items
item.find('.attachments').on('click', '.js-delete', (e) =>
id = $(e.currentTarget).data('id')
@attachments = _.filter(
@attachments,
(item) ->
return if item.id.toString() is id.toString()
item
)
@attachments = []
# delete attachment from storage
App.Ajax.request(
type: 'DELETE'
url: "#{App.Config.get('api_path')}/ticket_attachment_upload"
data: JSON.stringify(id: id),
processData: false
)
# remove attachment from dom
element = $(e.currentTarget).closest('.attachments')
$(e.currentTarget).closest('.attachment').remove()
if element.find('.attachment').length == 0
element.empty()
)
@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

View file

@ -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'
}

View file

@ -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' )

View file

@ -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) =>
@attachments = _.filter(
@attachments,
(item) ->
return if item.id isnt file.store_id
item
)
store_id = $(e.currentTarget).data('id')
@attachmentsHolder.append(App.view('generic/attachment_item')(file))
# 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)
processData: false
)
bindAttachmentDelete: =>
@attachmentsHolder.on('click', '.js-delete', (e) =>
id = $(e.currentTarget).data('id')
@attachments = _.filter(
@attachments,
(item) ->
return if item.id.toString() is id.toString()
item
)
# 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()
# delete attachment from storage
App.Ajax.request(
type: 'DELETE'
url: App.Config.get('api_path') + '/ticket_attachment_upload'
data: JSON.stringify(id: id)
processData: false
)
# remove attachment from dom
element = $(e.currentTarget).closest('.attachments')
$(e.currentTarget).closest('.attachment').remove()
if element.find('.attachment').length == 0
element.empty()
)

View file

@ -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>

View file

@ -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,
}

View file

@ -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