diff --git a/app/assets/javascripts/app/controllers/_application_controller_form.js.coffee b/app/assets/javascripts/app/controllers/_application_controller_form.js.coffee index f05dbe36b..3e4078eb2 100644 --- a/app/assets/javascripts/app/controllers/_application_controller_form.js.coffee +++ b/app/assets/javascripts/app/controllers/_application_controller_form.js.coffee @@ -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('
') + + # 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() diff --git a/app/assets/javascripts/app/controllers/agent_ticket_create.js.coffee b/app/assets/javascripts/app/controllers/agent_ticket_create.js.coffee index d4fd34e2c..7c3818822 100644 --- a/app/assets/javascripts/app/controllers/agent_ticket_create.js.coffee +++ b/app/assets/javascripts/app/controllers/agent_ticket_create.js.coffee @@ -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) diff --git a/app/assets/javascripts/app/controllers/agent_ticket_zoom.js.coffee b/app/assets/javascripts/app/controllers/agent_ticket_zoom.js.coffee index 3df6397cf..ce8d20886 100644 --- a/app/assets/javascripts/app/controllers/agent_ticket_zoom.js.coffee +++ b/app/assets/javascripts/app/controllers/agent_ticket_zoom.js.coffee @@ -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 diff --git a/app/assets/javascripts/app/controllers/customer_ticket_new.js.coffee b/app/assets/javascripts/app/controllers/customer_ticket_new.js.coffee index 9f8f95164..9dc1149aa 100644 --- a/app/assets/javascripts/app/controllers/customer_ticket_new.js.coffee +++ b/app/assets/javascripts/app/controllers/customer_ticket_new.js.coffee @@ -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) diff --git a/app/assets/javascripts/app/lib/base/fileuploader.js b/app/assets/javascripts/app/lib/base/fileuploader.js index 6da5d90b3..42786f462 100644 --- a/app/assets/javascripts/app/lib/base/fileuploader.js +++ b/app/assets/javascripts/app/lib/base/fileuploader.js @@ -485,8 +485,8 @@ qq.FileUploader = function(o){ listElement: null, template: '
' + - '
Drop to attach files
' + - '
Attach files
' + + '
Drop to attach files
' + + '
' + '' + '
', diff --git a/app/assets/javascripts/app/models/ticket_article.js.coffee b/app/assets/javascripts/app/models/ticket_article.js.coffee index 8725c56c6..63e80c292 100644 --- a/app/assets/javascripts/app/models/ticket_article.js.coffee +++ b/app/assets/javascripts/app/models/ticket_article.js.coffee @@ -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 = [ diff --git a/app/assets/javascripts/app/views/agent_ticket_zoom.jst.eco b/app/assets/javascripts/app/views/agent_ticket_zoom.jst.eco index 79fc14a8c..da50ffd47 100644 --- a/app/assets/javascripts/app/views/agent_ticket_zoom.jst.eco +++ b/app/assets/javascripts/app/views/agent_ticket_zoom.jst.eco @@ -81,8 +81,6 @@
-
-  
diff --git a/app/assets/stylesheets/zzz.css b/app/assets/stylesheets/zzz.css index bb0cc0740..ec67e65c2 100644 --- a/app/assets/stylesheets/zzz.css +++ b/app/assets/stylesheets/zzz.css @@ -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; +} diff --git a/app/controllers/ticket_articles_controller.rb b/app/controllers/ticket_articles_controller.rb index 605d81bad..f17596350 100644 --- a/app/controllers/ticket_articles_controller.rb +++ b/app/controllers/ticket_articles_controller.rb @@ -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 diff --git a/app/controllers/tickets_controller.rb b/app/controllers/tickets_controller.rb index 103123d39..33083ca29 100644 --- a/app/controllers/tickets_controller.rb +++ b/app/controllers/tickets_controller.rb @@ -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 diff --git a/app/models/store.rb b/app/models/store.rb index a9cfca5ba..a7a75108f 100644 --- a/app/models/store.rb +++ b/app/models/store.rb @@ -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 diff --git a/db/migrate/20120101000030_create_storage.rb b/db/migrate/20120101000030_create_storage.rb index e458df436..e59a9a8bc 100644 --- a/db/migrate/20120101000030_create_storage.rb +++ b/db/migrate/20120101000030_create_storage.rb @@ -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 diff --git a/db/seeds.rb b/db/seeds.rb index 50596aeaa..4bc5f78cf 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -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 )