Browse Source

Added general support of attachments.

Martin Edenhofer 12 years ago
parent
commit
5ca42745ab

+ 17 - 0
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('<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()

+ 16 - 16
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)
 

+ 8 - 15
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
 

+ 17 - 16
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)
 

+ 2 - 2
app/assets/javascripts/app/lib/base/fileuploader.js

@@ -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 - 1
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 = [

+ 0 - 2
app/assets/javascripts/app/views/agent_ticket_zoom.jst.eco

@@ -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>
-          &nbsp;
           <button type="submit" class="btn btn-primary submit"><%- @T( 'Submit' ) %></button>
         </form>
       </div>

+ 30 - 0
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;
+}

+ 13 - 13
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
 

+ 16 - 10
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

Some files were not shown because too many files changed in this diff