Browse Source

Added support for signature and different sender addresses.

Martin Edenhofer 12 years ago
parent
commit
7d23efda79

+ 2 - 2
Gemfile

@@ -1,6 +1,6 @@
 source 'http://rubygems.org'
 
-gem 'rails', '3.2.3'
+gem 'rails', '3.2.8'
 
 # Bundle edge Rails instead:
 #gem 'rails',     :git => 'git://github.com/rails/rails.git'
@@ -47,7 +47,7 @@ gem 'simple-rss'
 # gem 'therubyracer'
 
 # e. g. for mysql you need to load mysql
-# gem 'mysql2'
+gem 'mysql2'
 
 # Use unicorn as the web server
 # gem 'unicorn'

+ 4 - 12
app/assets/javascripts/app/controllers/_application_controller_form.js.coffee

@@ -382,19 +382,11 @@ class App.ControllerForm extends App.Controller
 
       # if active or if active doesn't exist
       if item.active || !( 'active' of item )
-        name = '???'
-        if item.name
-          name = item.name
-        else if item.firstname
-          name = item.firstname
-          if item.lastname
-            if name
-             name = name + ' '
-          name = name + item.lastname
-
-        name_new = name
+        name_new = '?'
+        if item.displayName
+          name_new = item.displayName()
         if attribute.translate
-          name_new = Ti(name)
+          name_new = Ti(name_new)
         attribute.options.push {
           name:  name_new,
           value: item.id,

+ 214 - 22
app/assets/javascripts/app/controllers/_channel/email.js.coffee

@@ -21,12 +21,14 @@ class App.ChannelEmail extends App.ControllerTabs
         controller: App.ChannelEmailOutbound,
       },
       {
-        name:   'Sigantures',
-        target: 'c-signature',
+        name:       'Sigantures',
+        target:     'c-signature',
+        controller: App.ChannelEmailSignature,
       },
       {
-        name:   'Adresses',
-        target: 'c-address',
+        name:       'Adresses',
+        target:     'c-address',
+        controller: App.ChannelEmailAddress,
       },
       {
         name:   'Filter',
@@ -42,6 +44,183 @@ class App.ChannelEmail extends App.ControllerTabs
 
     @render()
 
+class App.ChannelEmailAddress extends App.Controller
+  events:
+    'click [data-type=new]':  'new'
+    'click [data-type=edit]': 'edit'
+
+  constructor: ->
+    super
+
+    App.EmailAddress.bind 'refresh change', @render
+    App.EmailAddress.fetch()
+
+  render: =>
+    data = App.EmailAddress.all()
+
+    html = $('<div></div>')
+
+    table = @table(
+      model:    App.EmailAddress,
+      objects:  data,
+    )
+
+    html.append( table )
+    html.append( '<a data-type="new" class="btn">' + T('New') + '</a>' )
+    @html html
+
+  new: (e) =>
+    e.preventDefault()
+    new App.ChannelEmailAddressEdit()
+
+  edit: (e) =>
+    e.preventDefault()
+    item = $(e.target).item( App.EmailAddress )
+    new App.ChannelEmailAddressEdit( object: item )
+
+class App.ChannelEmailAddressEdit extends App.ControllerModal
+  constructor: ->
+    super
+    @render(@object)
+
+  render: (data = {}) ->
+    if @object
+      @html App.view('generic/admin/edit')(
+        head: 'Email-Address'
+      )
+      @form = new App.ControllerForm(
+        el:        @el.find('#object_edit'),
+        model:     App.EmailAddress,
+        params:    @object,
+        autofocus: true,
+      )
+    else
+      @html App.view('generic/admin/new')(
+        head: 'Email-Address'
+      )
+      @form = new App.ControllerForm(
+        el:        @el.find('#object_new'),
+        model:     App.EmailAddress,
+        autofocus: true,
+      )
+    @modalShow()
+
+  submit: (e) =>
+    e.preventDefault()
+
+    # get params
+    params = @formParam(e.target)
+
+    object = @object || new App.EmailAddress
+    object.load(params)
+
+    # validate form
+    errors = @form.validate( params )
+
+    # show errors in form
+    if errors
+      @log 'error new', errors
+      @formValidate( form: e.target, errors: errors )
+      return false
+
+    # save object
+    object.save(
+      success: =>
+        @modalHide()
+      error: =>
+        @log 'errors'
+        @modalHide()
+    )
+
+class App.ChannelEmailSignature extends App.Controller
+  events:
+    'click [data-type=new]':  'new'
+    'click [data-type=edit]': 'edit'
+
+  constructor: ->
+    super
+
+    App.Signature.bind 'refresh change', @render
+    App.Signature.fetch()
+
+  render: =>
+    data = App.Signature.all()
+
+    html = $('<div></div>')
+
+    table = @table(
+      model:    App.Signature,
+      objects:  data,
+    )
+
+    html.append( table )
+    html.append( '<a data-type="new" class="btn">' + T('New') + '</a>' )
+    @html html
+
+  new: (e) =>
+    e.preventDefault()
+    new App.ChannelEmailSignatureEdit()
+
+  edit: (e) =>
+    e.preventDefault()
+    item = $(e.target).item( App.Signature )
+    @log '123', item, $(e.target)
+    new App.ChannelEmailSignatureEdit( object: item )
+
+class App.ChannelEmailSignatureEdit extends App.ControllerModal
+  constructor: ->
+    super
+    @render(@object)
+
+  render: (data = {}) ->
+    if @object
+      @html App.view('generic/admin/edit')(
+        head: 'Signature'
+      )
+      @form = new App.ControllerForm(
+        el:        @el.find('#object_edit'),
+        model:     App.Signature,
+        params:    @object,
+        autofocus: true,
+      )
+    else
+      @html App.view('generic/admin/new')(
+        head: 'Signature'
+      )
+      @form = new App.ControllerForm(
+        el:        @el.find('#object_new'),
+        model:     App.Signature,
+        autofocus: true,
+      )
+    @modalShow()
+
+  submit: (e) =>
+    e.preventDefault()
+
+    # get params
+    params = @formParam(e.target)
+
+    object = @object || new App.Signature
+    object.load(params)
+
+    # validate form
+    errors = @form.validate( params )
+
+    # show errors in form
+    if errors
+      @log 'error new', errors
+      @formValidate( form: e.target, errors: errors )
+      return false
+
+    # save object
+    object.save(
+      success: =>
+        @modalHide()
+      error: =>
+        @log 'errors'
+        @modalHide()
+    )
+
 class App.ChannelEmailInbound extends App.Controller
   events:
     'click [data-type=new]':  'new'
@@ -65,13 +244,14 @@ class App.ChannelEmailInbound extends App.Controller
         data.push channel
 
     table = @table(
+      header:   ['Host', 'User', 'Adapter', 'Active'],
       overview: ['host', 'user', 'adapter', 'active'],
       model:    App.Channel,
       objects:  data,
     )
 
     html.append( table )
-    html.append( '<a data-type="new" class="btn">new account</a>' )
+    html.append( '<a data-type="new" class="btn">' + T('New') + '</a>' )
     @html html
 
   new: (e) =>
@@ -100,14 +280,24 @@ class App.ChannelEmailInboundEdit extends App.ControllerModal
       { name: 'group_id', display: 'Group',    tag: 'select',   multiple: false, null: false, filter: @edit_form, nulloption: false, relation: 'Group', class: 'span4', default: data['group_id']  },
       { name: 'active',   display: 'Active',   tag: 'select',   multiple: false, null: false, options: { true: 'yes', false: 'no' } , class: 'span4', default: data['active'] },
     ]
-    @html App.view('generic/admin/new')(
-      head: 'New Channel'
-    )
-    @form = new App.ControllerForm(
-      el: @el.find('#object_new'),
-      model: { configure_attributes: configure_attributes, className: '' },
-      autofocus: true,
-    )
+    if @object
+      @html App.view('generic/admin/edit')(
+        head: 'Channel'
+      )
+      @form = new App.ControllerForm(
+        el: @el.find('#object_edit'),
+        model: { configure_attributes: configure_attributes, className: '' },
+        autofocus: true,
+      )
+    else
+      @html App.view('generic/admin/new')(
+        head: 'Channel'
+      )
+      @form = new App.ControllerForm(
+        el: @el.find('#object_new'),
+        model: { configure_attributes: configure_attributes, className: '' },
+        autofocus: true,
+      )
     @modalShow()
 
   submit: (e) =>
@@ -179,15 +369,17 @@ class App.ChannelEmailOutbound extends App.Controller
             adapter_used = channel.adapter
             channel_used = channel
 
-    if adapter_used is 'Sendmail'
-      configure_attributes = [
-        { name: 'adapter', display: 'Send Mails via', tag: 'select', multiple: false, null: false, options: adapters , class: 'span4', default: adapter_used },
-      ]
-      @form = new App.ControllerForm(
-        el: @el.find('#form-email-adapter'),
-        model: { configure_attributes: configure_attributes, className: '' },
-        autofocus: true,
-      )
+    configure_attributes = [
+      { name: 'adapter', display: 'Send Mails via', tag: 'select', multiple: false, null: false, options: adapters , class: 'span4', default: adapter_used },
+    ]
+    new App.ControllerForm(
+      el: @el.find('#form-email-adapter'),
+      model: { configure_attributes: configure_attributes, className: '' },
+      autofocus: true,
+    )
+
+#    if adapter_used is 'Sendmail'
+#      # some form
 
     if adapter_used is 'SMTP'
       configure_attributes = [

+ 3 - 3
app/assets/javascripts/app/lib/collection.js.coffee

@@ -78,7 +78,7 @@ class _Singleton
 
     if _.isArray( params.data )
       for object in params.data
-        console.log( 'load ARRAY', object)
+#        console.log( 'load ARRAY', object)
         App[params.type].refresh( object, options: { clear: true } )
 
         # remember in store if not already requested from local storage
@@ -88,7 +88,7 @@ class _Singleton
 
 #    if _.isObject( params.data )
     for key, object of params.data
-      console.log( 'load OB', object)
+#      console.log( 'load OB', object)
       App[params.type].refresh( object, options: { clear: true } )
 
       # remember in store if not already requested from local storage
@@ -100,7 +100,7 @@ class _Singleton
     console.log( 'find', type, id )
 #    if App[type].exists( id ) && !callback
     if App[type].exists( id )
-      console.log( 'find exists', type, id )
+#      console.log( 'find exists', type, id )
       data = App[type].find( id )
       if callback
         callback( data )

+ 13 - 0
app/assets/javascripts/app/models/application_model.js.coffee

@@ -1,5 +1,18 @@
 class App.Model extends Spine.Model
 
+  displayName: ->
+    return @name if @name
+    if @realname
+      return "#{@realname} <#{@email}>"
+    if @firstname
+      name = @firstname
+      if @lastname
+        if name
+         name = name + ' '
+      name = name + @lastname
+      return name
+    return '???'
+
   @validate: ( data = {} ) ->
     return if !data['model'].configure_attributes
 

+ 15 - 0
app/assets/javascripts/app/models/email_address.js.coffee

@@ -0,0 +1,15 @@
+class App.EmailAddress extends App.Model
+  @configure 'EmailAddress', 'realname', 'email', 'note', 'active'
+  @extend Spine.Model.Ajax
+  @url: '/api/email_addresses'
+
+  @configure_attributes = [
+    { name: 'realname',             display: 'Realname',          tag: 'input', type: 'text', limit: 250, 'null': false, 'class': 'span4' },
+    { name: 'email',                display: 'Email',             tag: 'input', type: 'text', limit: 250, 'null': false, 'class': 'span4' },
+    { name: 'note',                 display: 'Note',              tag: 'textarea', note: 'Notes are visible to agents only, never to customers.', limit: 250, 'null': true, 'class': 'span4' },
+    { name: 'updated_at',           display: 'Updated',           type: 'time', readonly: 1 },
+    { name: 'active',               display: 'Active',            tag: 'boolean', type: 'boolean', 'default': true, 'null': false, 'class': 'span4' },
+  ]
+  @configure_overview = [
+    'realname', 'email'
+  ]

+ 4 - 2
app/assets/javascripts/app/models/group.js.coffee

@@ -1,13 +1,15 @@
 class App.Group extends App.Model
-  @configure 'Group', 'name', 'assignment_timeout', 'follow_up_possible', 'follow_up_assignment', 'note', 'active'
+  @configure 'Group', 'name', 'assignment_timeout', 'follow_up_possible', 'follow_up_assignment', 'email_address_id', 'signature_id', 'note', 'active'
   @extend Spine.Model.Ajax
   @url: '/api/groups'
 
   @configure_attributes = [
     { name: 'name',                 display: 'Name',              tag: 'input', type: 'text', limit: 100, 'null': false, 'class': 'span4' },
-    { name: 'assignment_timeout',   display: 'Assignment Timout', tag: 'input', note: 'Assignment timout in minutes if assigned agent is not working on it. Ticket will be shown as unassigend.', type: 'text', limit: 100, 'null': false, 'class': 'span4' },
+    { name: 'assignment_timeout',   display: 'Assignment Timout', tag: 'input', note: 'Assignment timout in minutes if assigned agent is not working on it. Ticket will be shown as unassigend.', type: 'text', limit: 100, 'null': true, 'class': 'span4' },
     { name: 'follow_up_possible',   display: 'Follow possible',   tag: 'select', default: 'yes', options: { yes: 'yes', reject: 'reject follow up/do not reopen Ticket', 'new_ticket': 'do not reopen Ticket but create new Ticket' }, 'null': false, note: 'Follow up for closed ticket possible or not.', 'class': 'span4' },
     { name: 'follow_up_assignment', display: 'Assign Follow Ups', tag: 'select', default: 'yes', options: { yes: 'yes', no: 'no' }, 'null': false, note: 'Assign follow up to latest agent again.', 'class': 'span4' },
+    { name: 'email_address_id',     display: 'Email',             tag: 'select', multiple: false, null: true, relation: 'EmailAddress', nulloption: true, class: 'span4' },
+    { name: 'signature_id',         display: 'Signature',         tag: 'select', multiple: false, null: true, relation: 'Signature', nulloption: true, class: 'span4' },
     { name: 'note',                 display: 'Note',              tag: 'textarea', note: 'Notes are visible to agents only, never to customers.', limit: 250, 'null': true, 'class': 'span4' },
     { name: 'updated_at',           display: 'Updated',           type: 'time', readonly: 1 },
     { name: 'active',               display: 'Active',            tag: 'boolean', type: 'boolean', 'default': true, 'null': false, 'class': 'span4' },

+ 1 - 1
app/assets/javascripts/app/views/channel/email_outbound.jst.eco

@@ -1,5 +1,5 @@
 <form class="form-horizontal" id="mail_adapter">
   <div id="form-email-adapter"></div>
   <div id="form-email-adapter-settings"></div>
-  <button data-type="" type="submit" class="btn">submit</botton>
+  <button data-type="" type="submit" class="btn"><%- T('Submit') %></botton>
 </form>

+ 144 - 0
app/controllers/email_addresses_controller.rb

@@ -0,0 +1,144 @@
+class EmailAddressesController < ApplicationController
+  before_filter :authentication_check
+
+=begin
+
+Format:
+JSON
+
+Example:
+{
+  "id":1,
+  "realname":"some realname",
+  "email":"system@example.com",
+  "updated_at":"2012-09-14T17:51:53Z",
+  "created_at":"2012-09-14T17:51:53Z",
+  "updated_by_id":2,
+  "created_by_id":2,
+}
+
+=end
+
+=begin
+
+Resource:
+GET /api/email_address.json
+
+Response:
+[
+  {
+    "id": 1,
+    "realname":"some realname1",
+    ...
+  },
+  {
+    "id": 2,
+    "realname":"some realname2",
+    ...
+  }
+]
+
+Test:
+curl http://localhost/api/email_address.json -v -u #{login}:#{password}
+
+=end
+
+  def index
+    model_index_render(EmailAddress, params)
+  end
+
+=begin
+
+Resource:
+GET /api/email_address/#{id}.json
+
+Response:
+{
+  "id": 1,
+  "name": "name_1",
+  ...
+}
+
+Test:
+curl http://localhost/api/email_address/#{id}.json -v -u #{login}:#{password}
+ 
+=end
+
+  def show
+    model_show_render(EmailAddress, params)
+  end
+
+=begin
+
+Resource:
+POST /api/email_address.json
+
+Payload:
+{
+  "realname":"some realname",
+  "email":"system@example.com",
+  "note": "",
+  "active":true,
+}
+
+Response:
+{
+  "id": 1,
+  "realname":"some realname",
+  "email":"system@example.com",
+  ...
+}
+
+Test:
+curl http://localhost/api/email_address.json -v -u #{login}:#{password} -H "Content-Type: application/json" -X POST -d '{"name": "some_name","active": true, "note": "some note"}'
+
+=end
+
+  def create
+    model_create_render(EmailAddress, params)
+  end
+
+=begin
+
+Resource:
+PUT /api/email_address/{id}.json
+
+Payload:
+{
+  "realname":"some realname",
+  "email":"system@example.com",
+  "note": "",
+  "active":true,
+}
+
+Response:
+{
+  "id": 1,
+  "realname":"some realname",
+  "email":"system@example.com",
+  ...
+}
+
+Test:
+curl http://localhost/api/email_address.json -v -u #{login}:#{password} -H "Content-Type: application/json" -X PUT -d '{"name": "some_name","active": true, "note": "some note"}'
+
+=end
+
+  def update
+    model_update_render(EmailAddress, params)
+  end
+
+=begin
+
+Resource:
+
+Response:
+
+Test:
+ 
+=end
+
+  def destroy
+    model_destory_render(EmailAddress, params)
+  end
+end

+ 7 - 0
app/controllers/sessions/collection_ticket.rb

@@ -1,12 +1,19 @@
 module ExtraCollection
   def add(collections)
 
+    # all ticket stuff
     collections['TicketStateType']     = Ticket::StateType.all
     collections['TicketState']         = Ticket::State.all
     collections['TicketPriority']      = Ticket::Priority.all
     collections['TicketArticleType']   = Ticket::Article::Type.all
     collections['TicketArticleSender'] = Ticket::Article::Sender.all
 
+    # all signatures
+    collections['Signature']           = Signature.all
+
+    # all email addresses
+    collections['EmailAddress']        = EmailAddress.all
+
   end
   module_function :add
 end

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