Added general support of attachments.
This commit is contained in:
parent
4e1d519575
commit
5ca42745ab
13 changed files with 129 additions and 86 deletions
|
@ -284,6 +284,20 @@ class App.ControllerForm extends App.Controller
|
|||
# textarea
|
||||
else if attribute.tag is 'textarea'
|
||||
item = $( App.view('generic/textarea')( attribute: attribute ) )
|
||||
if attribute.upload
|
||||
fileUploaderId = 'file-uploader-' + new Date().getTime() + '-' + Math.floor( Math.random() * 99999 )
|
||||
item.after('<div class="' + attribute.class + '" id="' + fileUploaderId + '"></div>')
|
||||
|
||||
# add file uploader
|
||||
u = =>
|
||||
uploader = new qq.FileUploader(
|
||||
element: document.getElementById(fileUploaderId)
|
||||
action: '/api/ticket_attachment_new'
|
||||
debug: false
|
||||
params:
|
||||
form_id: @form_id
|
||||
)
|
||||
@delay( u, 200 )
|
||||
|
||||
# tag
|
||||
else if attribute.tag is 'tag'
|
||||
|
@ -643,6 +657,9 @@ class App.ControllerForm extends App.Controller
|
|||
App.Log.log 'ControllerForm', 'notice', 'formParam', form, param
|
||||
return param
|
||||
|
||||
@formId: ->
|
||||
formId = new Date().getTime() + Math.floor( Math.random() * 99999 )
|
||||
formId.toString().substr formId.toString().length-9, 9
|
||||
|
||||
@disable: (form) ->
|
||||
App.Log.log 'ControllerForm', 'notice', 'disable...', $(form.target).parent()
|
||||
|
|
|
@ -15,6 +15,7 @@ class Index extends App.Controller
|
|||
|
||||
# set title
|
||||
@title 'New Ticket'
|
||||
@form_id = App.ControllerForm.formId()
|
||||
@fetch(params)
|
||||
@navupdate '#ticket_create'
|
||||
|
||||
|
@ -105,20 +106,20 @@ class Index extends App.Controller
|
|||
{ name: 'owner_id', display: 'Owner', tag: 'select', multiple: false, null: true, filter: @edit_form, nulloption: true, relation: 'User', default: defaults['owner_id'], class: 'span7', },
|
||||
{ name: 'tags', display: 'Tags', tag: 'tag', type: 'text', null: true, default: defaults['tags'], class: 'span7', },
|
||||
{ name: 'subject', display: 'Subject', tag: 'input', type: 'text', limit: 200, null: false, default: defaults['subject'], class: 'span7', },
|
||||
{ name: 'body', display: 'Text', tag: 'textarea', rows: 6, null: false, default: defaults['body'], class: 'span7', },
|
||||
{ name: 'body', display: 'Text', tag: 'textarea', rows: 8, null: false, default: defaults['body'], class: 'span7', upload: true },
|
||||
{ name: 'ticket_state_id', display: 'State', tag: 'select', multiple: false, null: false, filter: @edit_form, relation: 'TicketState', default: defaults['ticket_state_id'], translate: true, class: 'medium' },
|
||||
{ name: 'ticket_priority_id', display: 'Priority', tag: 'select', multiple: false, null: false, filter: @edit_form, relation: 'TicketPriority', default: defaults['ticket_priority_id'], translate: true, class: 'medium' },
|
||||
]
|
||||
@html App.view('agent_ticket_create')( head: 'New Ticket' )
|
||||
|
||||
new App.ControllerForm(
|
||||
el: @el.find('#form_create'),
|
||||
model: {
|
||||
configure_attributes: configure_attributes,
|
||||
className: 'create',
|
||||
},
|
||||
autofocus: true,
|
||||
form_data: @edit_form,
|
||||
el: @el.find('#form_create')
|
||||
form_id: @form_id
|
||||
model:
|
||||
configure_attributes: configure_attributes
|
||||
className: 'create'
|
||||
autofocus: true
|
||||
form_data: @edit_form
|
||||
)
|
||||
|
||||
# add elastic to textarea
|
||||
|
@ -176,15 +177,14 @@ class Index extends App.Controller
|
|||
|
||||
# create article
|
||||
params['article'] = {
|
||||
from: params.customer_id_autocompletion,
|
||||
to: (group && group.name) || '',
|
||||
subject: params.subject,
|
||||
body: params.body,
|
||||
ticket_article_type_id: type.id,
|
||||
ticket_article_sender_id: sender.id,
|
||||
created_by_id: params.customer_id,
|
||||
from: params.customer_id_autocompletion
|
||||
to: (group && group.name) || ''
|
||||
subject: params.subject
|
||||
body: params.body
|
||||
ticket_article_type_id: type.id
|
||||
ticket_article_sender_id: sender.id
|
||||
form_id: @form_id
|
||||
}
|
||||
# console.log('params', params)
|
||||
|
||||
object.load(params)
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ class Index extends App.Controller
|
|||
|
||||
@navupdate '#'
|
||||
|
||||
@form_id = App.ControllerForm.formId()
|
||||
@edit_form = undefined
|
||||
@ticket_id = params.ticket_id
|
||||
@article_id = params.article_id
|
||||
|
@ -105,7 +106,7 @@ class Index extends App.Controller
|
|||
{ name: 'cc', display: 'Cc', tag: 'input', type: 'text', limit: 100, null: true, class: 'span7', item_class: 'hide' },
|
||||
{ name: 'subject', display: 'Subject', tag: 'input', type: 'text', limit: 100, null: true, class: 'span7', item_class: 'hide' },
|
||||
{ name: 'in_reply_to', display: 'In Reply to', tag: 'input', type: 'text', limit: 100, null: true, class: 'span7', item_class: 'hide' },
|
||||
{ name: 'body', display: 'Text', tag: 'textarea', rows: 5, limit: 100, null: true, class: 'span7', item_class: '' },
|
||||
{ name: 'body', display: 'Text', tag: 'textarea', rows: 6, limit: 100, null: true, class: 'span7', item_class: '', upload: true },
|
||||
{ name: 'internal', display: 'Visability', tag: 'select', default: false, null: true, options: { true: 'internal', false: 'public' }, class: 'medium', item_class: '' },
|
||||
]
|
||||
if @isRole('Customer')
|
||||
|
@ -114,7 +115,7 @@ class Index extends App.Controller
|
|||
{ name: 'cc', display: 'Cc', tag: 'input', type: 'text', limit: 100, null: true, class: 'span7', item_class: 'hide' },
|
||||
{ name: 'subject', display: 'Subject', tag: 'input', type: 'text', limit: 100, null: true, class: 'span7', item_class: 'hide' },
|
||||
{ name: 'in_reply_to', display: 'In Reply to', tag: 'input', type: 'text', limit: 100, null: true, class: 'span7', item_class: 'hide' },
|
||||
{ name: 'body', display: 'Text', tag: 'textarea', rows: 5, limit: 100, null: true, class: 'span7', item_class: '' },
|
||||
{ name: 'body', display: 'Text', tag: 'textarea', rows: 6, limit: 100, null: true, class: 'span7', item_class: '', upload: true },
|
||||
]
|
||||
|
||||
@html App.view('agent_ticket_zoom')(
|
||||
|
@ -125,6 +126,7 @@ class Index extends App.Controller
|
|||
|
||||
new App.ControllerForm(
|
||||
el: @el.find('#form-ticket-update')
|
||||
form_id: @form_id
|
||||
model:
|
||||
configure_attributes: @configure_attributes_ticket
|
||||
className: 'create'
|
||||
|
@ -134,6 +136,7 @@ class Index extends App.Controller
|
|||
|
||||
new App.ControllerForm(
|
||||
el: @el.find('#form-article-update')
|
||||
form_id: @form_id
|
||||
model:
|
||||
configure_attributes: @configure_attributes_article
|
||||
form_data: @edit_form
|
||||
|
@ -158,18 +161,6 @@ class Index extends App.Controller
|
|||
@scrollTo( 0, offset )
|
||||
@delay( scrollTo, 100 )
|
||||
|
||||
@delay(@u, 200)
|
||||
|
||||
u: =>
|
||||
uploader = new qq.FileUploader(
|
||||
element: document.getElementById('file-uploader')
|
||||
action: '/api/ticket_attachment_new'
|
||||
params:
|
||||
form: 'TicketZoom'
|
||||
form_id: @ticket.id
|
||||
debug: false
|
||||
)
|
||||
|
||||
ticket_action_row: =>
|
||||
|
||||
# start customer info controller
|
||||
|
@ -410,8 +401,10 @@ class Index extends App.Controller
|
|||
# create article
|
||||
if params['body']
|
||||
article = new App.TicketArticle
|
||||
params.from = @Session.get( 'firstname' ) + ' ' + @Session.get( 'lastname' )
|
||||
params.from = @Session.get( 'firstname' ) + ' ' + @Session.get( 'lastname' )
|
||||
params.ticket_id = @ticket.id
|
||||
params.form_id = @form_id
|
||||
|
||||
if !params['internal']
|
||||
params['internal'] = false
|
||||
|
||||
|
|
|
@ -11,9 +11,10 @@ class Index extends App.Controller
|
|||
|
||||
# check authentication
|
||||
return if !@authenticate()
|
||||
|
||||
|
||||
# set title
|
||||
@title 'New Ticket'
|
||||
@form_id = App.ControllerForm.formId()
|
||||
@fetch(params)
|
||||
@navupdate '#customer_ticket_new'
|
||||
|
||||
|
@ -98,20 +99,20 @@ class Index extends App.Controller
|
|||
{ name: 'group_id', display: 'Group', tag: 'select', multiple: false, null: false, filter: groupFilter, nulloption: true, relation: 'Group', default: defaults['group_id'], class: 'span7', },
|
||||
# { name: 'owner_id', display: 'Owner', tag: 'select', multiple: false, null: true, filter: @edit_form, nulloption: true, relation: 'User', default: defaults['owner_id'], class: 'span7', },
|
||||
{ name: 'subject', display: 'Subject', tag: 'input', type: 'text', limit: 100, null: false, default: defaults['subject'], class: 'span7', },
|
||||
{ name: 'body', display: 'Text', tag: 'textarea', rows: 10, null: false, default: defaults['body'], class: 'span7', },
|
||||
{ name: 'body', display: 'Text', tag: 'textarea', rows: 10, null: false, default: defaults['body'], class: 'span7', upload: true },
|
||||
# { name: 'ticket_state_id', display: 'State', tag: 'select', multiple: false, null: false, filter: @edit_form, relation: 'TicketState', default: defaults['ticket_state_id'], translate: true, class: 'medium' },
|
||||
# { name: 'ticket_priority_id', display: 'Priority', tag: 'select', multiple: false, null: false, filter: @edit_form, relation: 'TicketPriority', default: defaults['ticket_priority_id'], translate: true, class: 'medium' },
|
||||
]
|
||||
@html App.view('agent_ticket_create')( head: 'New Ticket' )
|
||||
|
||||
new App.ControllerForm(
|
||||
el: @el.find('#form_create'),
|
||||
model: {
|
||||
configure_attributes: configure_attributes,
|
||||
className: 'create',
|
||||
},
|
||||
autofocus: true,
|
||||
form_data: @edit_form,
|
||||
el: @el.find('#form_create')
|
||||
form_id: @form_id
|
||||
model:
|
||||
configure_attributes: configure_attributes
|
||||
className: 'create'
|
||||
autofocus: true
|
||||
form_data: @edit_form
|
||||
)
|
||||
|
||||
# add elastic to textarea
|
||||
|
@ -157,13 +158,13 @@ class Index extends App.Controller
|
|||
|
||||
# create article
|
||||
params['article'] = {
|
||||
from: "#{ @Session.get('firstname') } #{ @Session.get('lastname') }",
|
||||
to: (group && group.name) || '',
|
||||
subject: params.subject,
|
||||
body: params.body,
|
||||
ticket_article_type_id: type.id,
|
||||
ticket_article_sender_id: sender.id,
|
||||
created_by_id: @Session.get('id'),
|
||||
from: "#{ @Session.get('firstname') } #{ @Session.get('lastname') }"
|
||||
to: (group && group.name) || ''
|
||||
subject: params.subject
|
||||
body: params.body
|
||||
ticket_article_type_id: type.id
|
||||
ticket_article_sender_id: sender.id
|
||||
form_id: @form_id
|
||||
}
|
||||
# console.log('params', params)
|
||||
|
||||
|
|
|
@ -485,8 +485,8 @@ qq.FileUploader = function(o){
|
|||
listElement: null,
|
||||
|
||||
template: '<div class="qq-uploader">' +
|
||||
'<div class="qq-upload-drop-area btn"><i class="icon-attachment"></i> Drop to attach files</div>' +
|
||||
'<div class="qq-upload-button btn"><i class="icon-attachment"></i> Attach files</div>' +
|
||||
'<div class="qq-upload-icon qq-upload-drop-area btn keepright"><i class="icon-attachment"></i> Drop to attach files</div>' +
|
||||
'<div class="qq-upload-icon qq-upload-button btn keepright"><i class="icon-attachment"></i></div>' +
|
||||
'<ul class="qq-upload-list"></ul>' +
|
||||
'</div>',
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
class App.TicketArticle extends App.Model
|
||||
@configure 'TicketArticle', 'from', 'to', 'cc', 'subject', 'body', 'ticket_id', 'ticket_article_type_id', 'ticket_article_sender_id', 'internal', 'in_reply_to'
|
||||
@configure 'TicketArticle', 'from', 'to', 'cc', 'subject', 'body', 'ticket_id', 'ticket_article_type_id', 'ticket_article_sender_id', 'internal', 'in_reply_to', 'form_id'
|
||||
@extend Spine.Model.Ajax
|
||||
@url: '/api/ticket_articles'
|
||||
@configure_attributes = [
|
||||
|
|
|
@ -81,8 +81,6 @@
|
|||
<form class="form-stacked keepleft">
|
||||
<div id="form-ticket-update"></div>
|
||||
<div id="form-article-update"></div>
|
||||
<div class="keepleft" id="file-uploader"></div>
|
||||
|
||||
<button type="submit" class="btn btn-primary submit"><%- @T( 'Submit' ) %></button>
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
@ -7,6 +7,27 @@ label, input, button, select, textarea {
|
|||
font-size: 13px;
|
||||
}
|
||||
|
||||
select,
|
||||
textarea,
|
||||
input[type="text"],
|
||||
input[type="password"],
|
||||
input[type="datetime"],
|
||||
input[type="datetime-local"],
|
||||
input[type="date"],
|
||||
input[type="month"],
|
||||
input[type="time"],
|
||||
input[type="week"],
|
||||
input[type="number"],
|
||||
input[type="email"],
|
||||
input[type="url"],
|
||||
input[type="search"],
|
||||
input[type="tel"],
|
||||
input[type="color"],
|
||||
.uneditable-input {
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
|
||||
|
||||
.spinner {
|
||||
float: left;
|
||||
background:url("/assets/spinner.gif") no-repeat;
|
||||
|
@ -351,3 +372,12 @@ footer {
|
|||
text-shadow: 0 1px 0 #fff;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.qq-upload-list {
|
||||
margin: 5px 10px 0px;
|
||||
padding: 0;
|
||||
list-style: disc;
|
||||
}
|
||||
.qq-upload-icon {
|
||||
margin: 0px 20px;
|
||||
}
|
||||
|
|
|
@ -17,22 +17,26 @@ class TicketArticlesController < ApplicationController
|
|||
|
||||
# POST /articles
|
||||
def create
|
||||
@article = Ticket::Article.new(params[:ticket_article])
|
||||
form_id = params[:ticket_article][:form_id]
|
||||
params[:ticket_article].delete(:form_id)
|
||||
@article = Ticket::Article.new( params[:ticket_article] )
|
||||
@article.created_by_id = current_user.id
|
||||
@article.updated_by_id = current_user.id
|
||||
|
||||
# find attachments in upload cache
|
||||
@article['attachments'] = Store.list(
|
||||
:object => 'UploadCache::TicketZoom::' + current_user.id.to_s,
|
||||
:o_id => @article.ticket_id
|
||||
)
|
||||
if form_id
|
||||
@article['attachments'] = Store.list(
|
||||
:object => 'UploadCache',
|
||||
:o_id => form_id,
|
||||
)
|
||||
end
|
||||
|
||||
if @article.save
|
||||
|
||||
# remove attachments from upload cache
|
||||
Store.remove(
|
||||
:object => 'UploadCache::TicketZoom::' + current_user.id.to_s,
|
||||
:o_id => @article.ticket_id
|
||||
:object => 'UploadCache',
|
||||
:o_id => form_id,
|
||||
)
|
||||
|
||||
render :json => @article, :status => :created
|
||||
|
@ -61,12 +65,8 @@ class TicketArticlesController < ApplicationController
|
|||
head :ok
|
||||
end
|
||||
|
||||
|
||||
|
||||
# POST /ticket_attachment/new
|
||||
def attachment_new
|
||||
# puts '-------'
|
||||
# puts params.inspect
|
||||
|
||||
# store file
|
||||
# content_type = request.content_type
|
||||
|
@ -83,7 +83,7 @@ class TicketArticlesController < ApplicationController
|
|||
'Content-Type' => content_type
|
||||
}
|
||||
Store.add(
|
||||
:object => 'UploadCache::' + params[:form] + '::' + current_user.id.to_s,
|
||||
:object => 'UploadCache',
|
||||
:o_id => params[:form_id],
|
||||
:data => request.body.read,
|
||||
:filename => params[:qqfile],
|
||||
|
@ -95,7 +95,7 @@ class TicketArticlesController < ApplicationController
|
|||
:success => true,
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
# GET /ticket_attachment/1
|
||||
def attachment
|
||||
|
||||
|
|
|
@ -51,26 +51,32 @@ class TicketsController < ApplicationController
|
|||
|
||||
# create article if given
|
||||
if params[:article]
|
||||
@article = Ticket::Article.new(params[:article])
|
||||
form_id = params[:article][:form_id]
|
||||
params[:article].delete(:form_id)
|
||||
@article = Ticket::Article.new( params[:article] )
|
||||
@article.created_by_id = params[:article][:created_by_id] || current_user.id
|
||||
@article.updated_by_id = params[:article][:updated_by_id] || current_user.id
|
||||
@article.ticket_id = @ticket.id
|
||||
|
||||
# find attachments in upload cache
|
||||
@article['attachments'] = Store.list(
|
||||
:object => 'UploadCache::TicketZoom::' + current_user.id.to_s,
|
||||
:o_id => @article.ticket_id
|
||||
)
|
||||
if form_id
|
||||
@article['attachments'] = Store.list(
|
||||
:object => 'UploadCache',
|
||||
:o_id => form_id,
|
||||
)
|
||||
end
|
||||
if !@article.save
|
||||
render :json => @article.errors, :status => :unprocessable_entity
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
# remove attachments from upload cache
|
||||
Store.remove(
|
||||
:object => 'UploadCache::TicketZoom::' + current_user.id.to_s,
|
||||
:o_id => @article.ticket_id
|
||||
)
|
||||
if params[:form_id]
|
||||
Store.remove(
|
||||
:object => 'UploadCache',
|
||||
:o_id => form_id,
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
render :json => @ticket, :status => :created
|
||||
|
|
|
@ -17,19 +17,19 @@ class Store < ActiveRecord::Base
|
|||
)
|
||||
end
|
||||
data['store_object_id'] = store_object.id
|
||||
|
||||
|
||||
# check if record already exists
|
||||
# store = Store.where( :store_object_id => store_object.id, :o_id => data['o_id'], ).first
|
||||
# if store != nil
|
||||
# return store
|
||||
# end
|
||||
|
||||
|
||||
# check real store
|
||||
md5 = Digest::MD5.hexdigest( data['data'] )
|
||||
data['size'] = data['data'].to_s.to_blob.bytesize
|
||||
|
||||
file = Store::File.where( :md5 => md5 ).first
|
||||
|
||||
|
||||
# store attachment
|
||||
if file == nil
|
||||
file = Store::File.create(
|
||||
|
@ -37,7 +37,7 @@ class Store < ActiveRecord::Base
|
|||
:md5 => md5
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
data['store_file_id'] = file.id
|
||||
data['created_by_id'] = 1
|
||||
|
||||
|
@ -50,11 +50,10 @@ class Store < ActiveRecord::Base
|
|||
|
||||
return store
|
||||
end
|
||||
|
||||
|
||||
def self.list(data)
|
||||
# search
|
||||
stores = Store.where( :store_object_id => Store::Object.where( :name => data[:object] ) ).
|
||||
where( :o_id => data[:o_id] ).
|
||||
stores = Store.where( :store_object_id => Store::Object.where( :name => data[:object] ), :o_id => data[:o_id].to_i ).
|
||||
order('created_at ASC, id ASC')
|
||||
return stores
|
||||
end
|
||||
|
@ -67,10 +66,9 @@ class Store < ActiveRecord::Base
|
|||
stores.each do |store|
|
||||
store.destroy
|
||||
end
|
||||
return 1
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
class Object < ActiveRecord::Base
|
||||
validates :name, :presence => true
|
||||
end
|
||||
|
|
|
@ -3,7 +3,7 @@ class CreateStorage < ActiveRecord::Migration
|
|||
create_table :stores do |t|
|
||||
t.references :store_object, :null => false
|
||||
t.references :store_file, :null => false
|
||||
t.column :o_id, :integer, :null => false
|
||||
t.column :o_id, :integer, :limit => 8, :null => false
|
||||
t.column :preferences, :string, :limit => 2500, :null => true
|
||||
t.column :size, :string, :limit => 50, :null => true
|
||||
t.column :filename, :string, :limit => 250, :null => false
|
||||
|
|
|
@ -1812,7 +1812,7 @@ Translation.create( :locale => 'de', :source => "The way to communicate with us
|
|||
Translation.create( :locale => 'de', :source => "or", :target => "oder", :updated_by_id => 1, :created_by_id => 1 )
|
||||
Translation.create( :locale => 'de', :source => "yes", :target => "ja", :updated_by_id => 1, :created_by_id => 1 )
|
||||
Translation.create( :locale => 'de', :source => "no", :target => "nein", :updated_by_id => 1, :created_by_id => 1 )
|
||||
Translation.create( :locale => 'de', :source => "Attachment", :target => "Anhang", :updated_by_id => 1, :created_by_id => 1 )
|
||||
Translation.create( :locale => 'de', :source => "Attachment", :target => "Anhang", :updated_by_id => 1, :created_by_id => 1 )
|
||||
|
||||
|
||||
#Translation.create( :locale => 'de', :source => "", :target => "", :updated_by_id => 1, :created_by_id => 1 )
|
||||
|
|
Loading…
Reference in a new issue