Added working file upload.
This commit is contained in:
parent
e7fb98380a
commit
cbe1f78e42
10 changed files with 130 additions and 96 deletions
|
@ -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:
|
||||||
|
|
|
@ -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]) ]
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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 () {
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
|
@ -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>
|
|
|
@ -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') %>
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue