Added working file upload.

This commit is contained in:
Martin Edenhofer 2014-10-07 08:05:10 +02:00
parent e7fb98380a
commit cbe1f78e42
10 changed files with 130 additions and 96 deletions

View file

@ -717,7 +717,7 @@ class App.ControllerForm extends App.Controller
renderAttachment = (file) => renderAttachment = (file) =>
item.find('.attachments').append( App.view('generic/attachment_item')( item.find('.attachments').append( App.view('generic/attachment_item')(
fileName: file.filename fileName: file.filename
fileSize: @humanFileSize(file.size) fileSize: @humanFileSize( file.size )
store_id: file.store_id store_id: file.store_id
)) ))
item.on( item.on(
@ -748,8 +748,9 @@ class App.ControllerForm extends App.Controller
@attachmentsHolder = item.find('.attachments') @attachmentsHolder = item.find('.attachments')
html5Upload.initialize( html5Upload.initialize(
uploadUrl: App.Config.get('api_path') + '/ticket_attachment_upload', uploadUrl: App.Config.get('api_path') + '/ticket_attachment_upload',
dropContainer: item.find( ".attachmentPlaceholder" ).get(0), dropContainer: item.get(0),
inputField: item.find( "input" ).get(0), dropContainer1: item.find('.dropArea').get(0),
inputField: item.find( 'input' ).get(0),
key: 'File', key: 'File',
data: { form_id: @form_id }, data: { form_id: @form_id },
maxSimultaneousUploads: 2, maxSimultaneousUploads: 2,
@ -774,9 +775,9 @@ class App.ControllerForm extends App.Controller
# Called during upload progress, first parameter # Called during upload progress, first parameter
# is decimal value from 0 to 100. # is decimal value from 0 to 100.
onProgress: (progress, fileSize, uploadedBytes) => onProgress: (progress, fileSize, uploadedBytes) =>
@progressBar.width(progress + "%") @progressBar.width(parseInt(progress) + "%")
@progressText.text(progress) @progressText.text(parseInt(progress))
console.log('uploadProgress ', progress) console.log('uploadProgress ', parseInt(progress))
) )
) )
@ -805,7 +806,7 @@ class App.ControllerForm extends App.Controller
if @el.find('#' + fileUploaderId )[0] if @el.find('#' + fileUploaderId )[0]
@el.find('#' + fileUploaderId ).fineUploader( @el.find('#' + fileUploaderId ).fineUploader(
request: request:
endpoint: App.Config.get('api_path') + '/ticket_attachment_new' endpoint: App.Config.get('api_path') + '/ticket_attachment_upload'
params: params:
form_id: @form_id form_id: @form_id
text: text:

View file

@ -15,7 +15,6 @@ class App.TicketCreate extends App.Controller
return if !@authenticate() return if !@authenticate()
# set title # set title
@form_id = App.ControllerForm.formId()
@form_meta = undefined @form_meta = undefined
# define default type # define default type
@ -177,12 +176,6 @@ class App.TicketCreate extends App.Controller
render: (template = {}) -> render: (template = {}) ->
@html App.view('agent_ticket_create')(
head: 'New Ticket'
agent: @isRole('Agent')
admin: @isRole('Admin')
)
# get params # get params
params = {} params = {}
if template && !_.isEmpty( template.options ) if template && !_.isEmpty( template.options )
@ -190,6 +183,18 @@ class App.TicketCreate extends App.Controller
else if App.TaskManager.get(@task_key) && !_.isEmpty( App.TaskManager.get(@task_key).state ) else if App.TaskManager.get(@task_key) && !_.isEmpty( App.TaskManager.get(@task_key).state )
params = App.TaskManager.get(@task_key).state params = App.TaskManager.get(@task_key).state
if params['form_id']
@form_id = params['form_id']
else
@form_id = App.ControllerForm.formId()
@html App.view('agent_ticket_create')(
head: 'New Ticket'
agent: @isRole('Agent')
admin: @isRole('Admin')
form_id: @form_id
)
formChanges = (params, attribute, attributes, classname, form, ui) => formChanges = (params, attribute, attributes, classname, form, ui) =>
if @form_meta.dependencies && @form_meta.dependencies[attribute.name] if @form_meta.dependencies && @form_meta.dependencies[attribute.name]
dependency = @form_meta.dependencies[attribute.name][ parseInt(params[attribute.name]) ] dependency = @form_meta.dependencies[attribute.name][ parseInt(params[attribute.name]) ]

View file

@ -160,11 +160,15 @@ class App.TicketZoom extends App.Controller
el: @el.find('.ticket-meta') el: @el.find('.ticket-meta')
) )
@form_id = App.ControllerForm.formId()
new Edit( new Edit(
ticket: @ticket ticket: @ticket
el: @el.find('.ticket-edit') el: @el.find('.ticket-edit')
#el: @el.find('.edit') #el: @el.find('.edit')
form_meta: @form_meta form_meta: @form_meta
form_id: @form_id
defaults: @taskGet('article') defaults: @taskGet('article')
ui: @ ui: @
) )
@ -586,6 +590,7 @@ class App.TicketZoom extends App.Controller
# submit changes # submit changes
ticket.save( ticket.save(
done: (r) => done: (r) =>
@renderDone = false
# reset form after save # reset form after save
@taskReset() @taskReset()
@ -709,10 +714,10 @@ class Edit extends App.Controller
'submit .recipient-list form': 'add_recipient' 'submit .recipient-list form': 'add_recipient'
'focus .js-textarea': 'open_textarea' 'focus .js-textarea': 'open_textarea'
'input .js-textarea': 'detect_empty_textarea' 'input .js-textarea': 'detect_empty_textarea'
'dragenter': 'onDragenter' #'dragenter': 'onDragenter'
'dragleave': 'onDragleave' #'dragleave': 'onDragleave'
'drop': 'onFileDrop' #'drop': 'onFileDrop'
'change input[type=file]': 'onFilePick' #'change input[type=file]': 'onFilePick'
constructor: -> constructor: ->
super super
@ -798,7 +803,40 @@ class Edit extends App.Controller
maxlength: 2500 maxlength: 2500
}) })
@form_id = App.ControllerForm.formId() html5Upload.initialize(
uploadUrl: App.Config.get('api_path') + '/ticket_attachment_upload',
dropContainer: @$('.article-attachment').get(0),
#dropContainer1: @$('.dropArea').get(0),
inputField: @$('.article-attachment input').get(0),
key: 'File',
data: { form_id: @form_id },
maxSimultaneousUploads: 2,
onFileAdded: (file) =>
@attachmentPlaceholder.addClass('hide')
@attachmentUpload.removeClass('hide')
file.on(
# Called after received response from the server
onCompleted: (response) =>
response = JSON.parse(response)
@attachments.push response.data
@attachmentPlaceholder.removeClass('hide')
@attachmentUpload.addClass('hide')
@renderAttachment(response.data)
console.log('upload complete', response.data )
# Called during upload progress, first parameter
# is decimal value from 0 to 100.
onProgress: (progress, fileSize, uploadedBytes) =>
@progressBar.width(parseInt(progress) + "%")
@progressText.text(parseInt(progress))
console.log('uploadProgress ', parseInt(progress))
)
)
# show text module UI # show text module UI
if !@isRole('Customer') if !@isRole('Customer')
@ -1014,75 +1052,37 @@ class Edit extends App.Controller
@open_textarea() if @dragEventCounter is 0 @open_textarea() if @dragEventCounter is 0
@dragEventCounter++ @dragEventCounter++
@ticketEdit.addClass('is-dropTarget') @ticketEdit.parent().addClass('is-dropTarget')
onDragleave: (event) => onDragleave: (event) =>
@dragEventCounter-- @dragEventCounter--
@ticketEdit.removeClass('is-dropTarget') if @dragEventCounter is 0 @ticketEdit.parent().removeClass('is-dropTarget') if @dragEventCounter is 0
onFileDrop: (event) =>
event.preventDefault()
event.stopPropagation()
files = event.originalEvent.dataTransfer.files
@ticketEdit.removeClass('is-dropTarget')
@queueUpload(files)
onFilePick: (event) =>
@open_textarea()
@queueUpload(event.target.files)
queueUpload: (files) ->
@uploadQueue ?= []
# add files
for file in files
@uploadQueue.push(file)
@workOfUploadQueue()
workOfUploadQueue: =>
if !@uploadQueue.length
return
file = @uploadQueue.shift()
# console.log "working of", file, "from", @uploadQueue
@fakeUpload file.name, file.size, @workOfUploadQueue
humanFileSize: (size) =>
i = Math.floor( Math.log(size) / Math.log(1024) )
return ( size / Math.pow(1024, i) ).toFixed(2) * 1 + ' ' + ['B', 'kB', 'MB', 'GB', 'TB'][i]
updateUploadProgress: (progress) =>
@progressBar.width(progress + "%")
@progressText.text(progress)
if progress is 100
@attachmentPlaceholder.removeClass('hide')
@attachmentUpload.addClass('hide')
fakeUpload: (fileName, fileSize, callback) ->
@attachmentPlaceholder.addClass('hide')
@attachmentUpload.removeClass('hide')
progress = 0;
duration = fileSize / 1024
for i in [0..100]
setTimeout @updateUploadProgress, i*duration/100 , i
setTimeout (=>
callback()
@renderAttachment(fileName, fileSize)
), duration
renderAttachment: (fileName, fileSize) =>
@attachments.push([fileName, fileSize])
@attachmentsHolder.append App.view('ticket_zoom/attachment')
fileName: fileName
fileSize: @humanFileSize(fileSize)
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')
App.Ajax.request(
type: 'DELETE'
url: App.Config.get('api_path') + '/ticket_attachment_upload'
data: JSON.stringify( { store_id: store_id } ),
processData: false
success: (data, status, xhr) =>
)
$(e.currentTarget).closest('.attachment').empty()
)
reset: (e) => reset: (e) =>
e.preventDefault() e.preventDefault()

View file

@ -11,6 +11,7 @@
function UploadManager(options) { function UploadManager(options) {
var self = this; var self = this;
self.dropContainer = options.dropContainer; self.dropContainer = options.dropContainer;
self.dropContainer1 = options.dropContainer1;
self.inputField = options.inputField; self.inputField = options.inputField;
self.uploadsQueue = []; self.uploadsQueue = [];
self.activeUploads = 0; self.activeUploads = 0;
@ -67,20 +68,51 @@
console.log('Initializing upload manager'); console.log('Initializing upload manager');
var manager = this, var manager = this,
dropContainer = manager.dropContainer, dropContainer = manager.dropContainer,
dropContainer1 = manager.dropContainer1,
inputField = manager.inputField, inputField = manager.inputField,
inCounter = 0,
cancelEvent = function (e) { cancelEvent = function (e) {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
console.log('in', inCounter)
if ( !$(dropContainer).closest('.richtext').hasClass('is-dropTarget') ) {
inCounter++
}
if ( inCounter === 1 ) {
$(dropContainer).closest('.richtext').addClass('is-dropTarget')
}
};
leaveEvent = function (e) {
e.preventDefault();
e.stopPropagation();
console.log('out', inCounter)
if ( $(dropContainer).closest('.richtext').hasClass('is-dropTarget') ) {
inCounter--
}
if ( inCounter === 0 ) {
$(dropContainer).closest('.richtext').removeClass('is-dropTarget')
}
}; };
if (dropContainer) { if (dropContainer) {
manager.on(dropContainer, 'dragleave', leaveEvent);
manager.on(dropContainer, 'dragover', cancelEvent); manager.on(dropContainer, 'dragover', cancelEvent);
manager.on(dropContainer, 'dragenter', cancelEvent); manager.on(dropContainer, 'dragenter', cancelEvent);
manager.on(dropContainer, 'drop', function (e) { manager.on(dropContainer, 'drop', function (e) {
cancelEvent(e); leaveEvent(e);
manager.processFiles(e.dataTransfer.files); manager.processFiles(e.dataTransfer.files);
}); });
} }
if (dropContainer1) {
manager.on(dropContainer1, 'dragleave', leaveEvent);
manager.on(dropContainer1, 'dragover', cancelEvent);
manager.on(dropContainer1, 'dragenter', cancelEvent);
manager.on(dropContainer1, 'drop', function (e) {
leaveEvent(e);
manager.processFiles(e.dataTransfer.files);
});
}
if (inputField) { if (inputField) {
manager.on(inputField, 'change', function () { manager.on(inputField, 'change', function () {

View file

@ -26,6 +26,7 @@
<form role="form" class="ticket-create"> <form role="form" class="ticket-create">
<input type="hidden" name="formSenderType"/> <input type="hidden" name="formSenderType"/>
<input type="hidden" name="form_id" value="<%= @form_id %>"/>
<div class="ticket-form-top"></div> <div class="ticket-form-top"></div>
<div class="article-form-top"></div> <div class="article-form-top"></div>

View file

@ -1,6 +1,6 @@
<div class="attachment horizontal"> <div class="attachment horizontal">
<div class="attachment-name u-highlight"><%- @fileName %></div> <div class="attachment-name u-highlight"><%= @fileName %></div>
<div class="attachment-size"><%- @fileSize %></div> <div class="attachment-size"><%= @fileSize %></div>
<div class="attachment-delete js-delete align-right u-clickable" data-id="<%= @store_id %>"> <div class="attachment-delete js-delete align-right u-clickable" data-id="<%= @store_id %>">
<div class="delete icon"></div><%- @T('Delete File') %> <div class="delete icon"></div><%- @T('Delete File') %>
</div> </div>

View file

@ -1,3 +1,3 @@
<div class="richtext"> <div class="richtext form-control">
<div contenteditable="true" id="<%= @attribute.id %>" data-name="<%= @attribute.name %>" class="form-control <%= @attribute.class %>"><%= @attribute.value %></div> <div contenteditable="true" id="<%= @attribute.id %>" data-name="<%= @attribute.name %>" class="<%= @attribute.class %>"><%= @attribute.value %></div>
</div> </div>

View file

@ -1,7 +0,0 @@
<div class="attachment horizontal">
<div class="attachment-name u-highlight"><%- @fileName %></div>
<div class="attachment-size"><%- @fileSize %></div>
<div class="attachment-delete js-delete align-right u-clickable">
<div class="delete icon"></div><%- @T('Delete File') %>
</div>
</div>

View file

@ -1,6 +1,7 @@
<form class="article-add <% if @article.internal: %>is-internal<% else: %>is-public<% end %>"> <form class="article-add <% if @article.internal: %>is-internal<% else: %>is-public<% end %>">
<input type="hidden" name="type" value="<%= @article.type %>"> <input type="hidden" name="type" value="<%= @article.type %>">
<input type="hidden" name="internal" value="<%= @article.internal %>"> <input type="hidden" name="internal" value="<%= @article.internal %>">
<input type="hidden" name="form_id" value="<%= @article.form_id %>">
<div class="bubble-grid horizontal"> <div class="bubble-grid horizontal">
<div class="vertical center edit-controls"> <div class="vertical center edit-controls">
<%- App.User.fullLocal( @S('id') ).avatar(false, 'right', 'zIndex-5') %> <%- App.User.fullLocal( @S('id') ).avatar(false, 'right', 'zIndex-5') %>

View file

@ -444,6 +444,7 @@ label {
.form-group .controls .richtext { .form-group .controls .richtext {
position: relative; position: relative;
height: auto;
} }
.form-group .help-message { .form-group .help-message {
@ -2676,7 +2677,7 @@ footer {
display: none; display: none;
} }
.ticket-edit.is-dropTarget .dropArea { .is-dropTarget .dropArea {
display: block; display: block;
} }