Browse Source

Init version of customer panel.

Martin Edenhofer 12 years ago
parent
commit
4c824992ee

+ 12 - 7
app/assets/javascripts/app/controllers/agent_ticket_view.js.coffee

@@ -20,8 +20,8 @@ class Index extends App.Controller
     @title ''
     @navupdate '#ticket_view/' + @view
 
-    @meta          = {}
-    @bulk          = {}
+    @meta = {}
+    @bulk = {}
 
     # set controller to active
     Config['ActiveController'] = '#ticket_overview_' + @view
@@ -126,19 +126,24 @@ class Index extends App.Controller
     @html html
 
     # create table/overview
+    checkbox = true
+    edit = true
+    if @isRole('Customer')
+      checkbox = false
+      edit = false
     table = ''
     if @view_mode is 'm'
       table = App.view('agent_ticket_view/detail')(
         overview: @overview,
         objects:  @ticket_list_show,
-        checkbox: true
+        checkbox: checkbox,
       )
       table = $(table)
       table.delegate('[name="bulk_all"]', 'click', (e) ->
         if $(e.target).attr('checked')
-          $(e.target).parents().find('[name="bulk"]').attr('checked', true);
+          $(e.target).parents().find('[name="bulk"]').attr('checked', true)
         else
-          $(e.target).parents().find('[name="bulk"]').attr('checked', false);       
+          $(e.target).parents().find('[name="bulk"]').attr('checked', false)
       )
     else
       shown_all_attributes = @ticketTableAttributes( App.Overview.find(@overview.id).view.s.overview )
@@ -146,7 +151,8 @@ class Index extends App.Controller
         overview_extended: shown_all_attributes,
         model:             App.Ticket,
         objects:           @ticket_list_show,
-        checkbox:          true,
+        checkbox:          checkbox,
+        edit:              edit,
       )
 
     # append content table
@@ -209,7 +215,6 @@ class Index extends App.Controller
     # render init page
     html = App.view('agent_ticket_view/bulk')(
       meta:        @overview.meta,
-      checkbox:    true
       form_ticket: form_ticket,
 #      form_article: form_article,
     )

+ 9 - 177
app/assets/javascripts/app/controllers/customer_tickets.js.coffee

@@ -1,10 +1,10 @@
 $ = jQuery.sub()
 
 class Index extends App.Controller
-  events:
-    'submit form':         'submit',
-    'click .submit':       'submit',
-    'click .cancel':       'cancel',
+#  events:
+#    'submit form':         'submit',
+#    'click .submit':       'submit',
+#    'click .cancel':       'cancel',
 
   constructor: (params) ->
     super
@@ -14,186 +14,18 @@ class Index extends App.Controller
 
     # set title
     @title 'My Tickets'
-    @fetch(params)
+#    @fetch(params)
     @navupdate '#customer_tickets'
 
-    @edit_form = undefined
-
-    # lisen if view need to be rerendert
-    Spine.bind 'ticket_create_rerender', (defaults) =>
-      @log 'rerender', defaults
-      @render(defaults)
-
-  # get data / in case also ticket data for split
-  fetch: (params) ->
-
-    # use cache
-    cache = App.Store.get( 'ticket_create_attributes' )
-
-    if cache && !params.ticket_id && !params.article_id
-
-      # get edit form attributes
-      @edit_form = cache.edit_form
-
-      # load user collection
-      @loadCollection( type: 'User', data: cache.users )
-
-      @render()
-    else
-      App.Com.ajax(
-        id:    'ticket_create',
-        type:  'GET',
-        url:   '/ticket_create',
-        data:  {
-          ticket_id: params.ticket_id,
-          article_id: params.article_id,
-        },
-        processData: true,
-        success: (data, status, xhr) =>
-
-          # cache request
-          App.Store.write( 'ticket_create_attributes', data )
-
-          # get edit form attributes
-          @edit_form = data.edit_form
-
-          # load user collection
-          @loadCollection( type: 'User', data: data.users )
-
-          # load ticket collection
-          if data.ticket && data.articles
-            @loadCollection( type: 'Ticket', data: [data.ticket] )
-
-            # load article collections
-            @loadCollection( type: 'TicketArticle', data: data.articles || [] )
-
-            # render page
-            t = App.Ticket.find(params.ticket_id).attributes()
-            a = App.TicketArticle.find(params.article_id)
-            
-            # reset owner
-            t.owner_id = 0
-            t.customer_id_autocompletion = a.from
-            t.subject = a.subject || t.title
-            t.body = a.body
-            @log '11111', t
-          @render( options: t )
-      )
-
-  render: (template = {}) ->
-
-    # set defaults
-    defaults = template['options'] || {}
-    if !( 'ticket_state_id' of defaults )
-      defaults['ticket_state_id'] = App.TicketState.findByAttribute( 'name', 'new' )
-    if !( 'ticket_priority_id' of defaults )
-      defaults['ticket_priority_id'] = App.TicketPriority.findByAttribute( 'name', '2 normal' )
+    @render()
 
-    # remember customers
-    if $('#create_customer_id').val()
-      defaults['customer_id'] = $('#create_customer_id').val()
-      defaults['customer_id_autocompletion'] = $('#create_customer_id_autocompletion').val()
-    else
-#      defaults['customer_id'] = '2'
-#      defaults['customer_id_autocompletion'] = '12312313'
+  render: ->
 
-    # generate form    
-    configure_attributes = [
-#      { name: 'customer_id',        display: 'Customer', tag: 'autocompletion', type: 'text', limit: 100, null: false, relation: 'User', class: 'span7', autocapitalize: false, help: 'Select the customer of the Ticket or create one.', link: '<a href="" class="customer_new">&raquo;</a>', callback: @userInfo },
-      { name: 'group_id',           display: 'Group',    tag: 'select',   multiple: false, null: false, filter: @edit_form, 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: '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')(
+    @html App.view('agent_ticket_view')(
       head: 'My Ticket',
-      form: @formGen( model: { configure_attributes: configure_attributes, className: 'create' } ),
+#      form: @formGen( model: { configure_attributes: configure_attributes, className: 'create' } ),
     )
 
-    # add elastic to textarea
-    @el.find('textarea').elastic()
-
-    # update textarea size
-    @el.find('textarea').trigger('change')
-
-    # start customer info controller
-    if defaults['customer_id']
-      $('#create_customer_id').val( defaults['customer_id'] )
-      $('#create_customer_id_autocompletion').val( defaults['customer_id_autocompletion'] )
-      @userInfo( user_id: defaults['customer_id'] )
-
-  cancel: ->
-    @render()
-    
-  submit: (e) ->
-    e.preventDefault()
-        
-    # get params
-    params = @formParam(e.target)
-
-    # fillup params
-    if !params.title
-      params.title = params.subject
-
-    # create ticket
-    object = new App.Ticket
-    @log 'updateAttributes', params
-    
-    # find sender_id
-    sender = App.TicketArticleSender.findByAttribute( 'name', 'Customer' )
-    type   = App.TicketArticleType.findByAttribute( 'name', 'phone' )
-    if params.group_id
-      group  = App.Group.find(params.group_id)
-
-    # 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,
-    }
-#          console.log('params', params)
-    
-    object.load(params)
-
-    # validate form
-    errors = object.validate()
-    
-    # show errors in form
-    if errors
-      @log 'error new', errors
-      @validateForm( form: e.target, errors: errors )
-      
-    # save ticket, create article
-    else 
-
-      # disable form
-      @formDisable(e)
-      ui = @
-      object.save(
-        success: ->
-
-          # notify UI
-          ui.notify
-            type:    'success',
-            msg:     T('Ticket %s created!', @.number),
-            link:    "#ticket/zoom/#{@.id}"
-            timeout: 12000,
-      
-          # create new create screen
-          ui.render()
-          
-          # scroll to top
-          ui.scrollTo()
 
-        error: ->
-          ui.log 'save failed!'
-          ui.formEnable(e)
-      )
 
 Config.Routes['customer_tickets'] = Index

+ 5 - 0
app/assets/javascripts/app/controllers/dashboard.js.coffee

@@ -8,6 +8,11 @@ class Index extends App.Controller
     # check authentication
     return if !@authenticate()
 
+    # check role
+    if @isRole('Customer')
+      @navigate '#ticket_view/my_tickets'
+      return
+
     # set title
     @title 'Dashboard'
     @navupdate '#/'

+ 1 - 1
app/assets/javascripts/app/controllers/organizations.js.coffee

@@ -58,7 +58,7 @@ Config.NavBar['TicketOverview'] = { prio: 1000, parent: '', name: 'Overviews', t
 #Config.NavBar[''] = { prio: 1600, parent: '', name: 'anybody+agent', target: '#aa', role: ['Anybody', 'Agent'] }
 #Config.NavBar[''] = { prio: 1600, parent: '', name: 'Anybody', target: '#anybody', role: ['Anybody'] }
 Config.NavBar['CustomerTicketNew'] = { prio: 1600, parent: '', name: 'New Ticket', target: '#customer_ticket_new', role: ['Customer'] }
-Config.NavBar['CustomerTickets'] = { prio: 1700, parent: '', name: 'My Tickets', target: '#customer_tickets', role: ['Customer'] }
+Config.NavBar['CustomerTickets'] = { prio: 1700, parent: '', name: 'My Tickets', target: '#ticket_view/my_tickets', role: ['Customer'] }
 
 Config.NavBarRight['TicketNew'] = { prio: 8000, parent: '', name: 'New', target: '#ticket_create', role: ['Agent'] }
 Config.NavBarRight['User'] = {

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

@@ -2,10 +2,13 @@ class App.Group extends App.Model
   @configure 'Group', 'name', 'note', 'active'
   @extend Spine.Model.Ajax
   @configure_attributes = [
-    { name: 'name', display: 'Name', tag: 'input', type: 'text', limit: 100, 'null': false, 'class': 'xlarge' },
-    { name: 'note', display: 'Note', note: 'Notes are visible to agents only, never to customers.', tag: 'textarea', limit: 250, 'null': true, 'class': 'xlarge' },
-    { name: 'updated_at', display: 'Updated', type: 'time', readonly: 1 },
-    { name: 'active', display: 'Active', tag: 'boolean', type: 'boolean', 'default': true, 'null': false, 'class': 'xlarge' },
+    { 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: '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: '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 = [
     'name',

+ 5 - 5
app/assets/javascripts/app/models/organization.js.coffee

@@ -2,11 +2,11 @@ class App.Organization extends App.Model
   @configure 'Organization', 'name', 'shared', 'note', 'active'
   @extend Spine.Model.Ajax
   @configure_attributes = [
-    { name: 'name',       display: 'Name', tag: 'input', type: 'text', limit: 100, 'null': false, 'class': 'xlarge' },
-    { name: 'note',       display: 'Note', note: 'Notes are visible to agents only, never to customers.', tag: 'textarea', limit: 250, 'null': true, 'class': 'xlarge' },
-    { name: 'shared',     display: 'Shared organiztion', note: 'Customers in the organiztion can view each other items.', tag: 'boolean', type: 'boolean', 'default': true, 'null': false, 'class': 'xlarge' },
-    { name: 'updated_at', display: 'Updated', type: 'time', readonly: 1 },
-    { name: 'active',     display: 'Active', tag: 'boolean', type: 'boolean', 'default': true, 'null': false, 'class': 'xlarge' },
+    { name: 'name',       display: 'Name',                tag: 'input',     type: 'text', limit: 100, 'null': false, 'class': 'span4' },
+    { name: 'shared',     display: 'Shared organiztion',  tag: 'boolean',   note: 'Customers in the organiztion can view each other items.', type: 'boolean', 'default': true, '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',   note: 'boolean', 'default': true, 'null': false, 'class': 'span4' },
   ]
   @configure_overview = [
     'name', 'shared',

+ 4 - 4
app/assets/javascripts/app/models/role.js.coffee

@@ -2,10 +2,10 @@ class App.Role extends App.Model
   @configure 'Role', 'name', 'note', 'active'
   @extend Spine.Model.Ajax
   @configure_attributes = [
-    { name: 'name', display: 'Name', tag: 'input', type: 'text', limit: 100, 'null': false, 'class': 'xlarge' },
-    { name: 'note', display: 'Note', note: 'Notes are visible to agents only, never to customers.', tag: 'textarea', limit: 250, 'null': true, 'class': 'xlarge' },
-    { name: 'updated_at', display: 'Updated', type: 'time', readonly: 1 },
-    { name: 'active', display: 'Active', tag: 'boolean', type: 'boolean', 'default': true, 'null': false, 'class': 'xlarge' },
+    { name: 'name',       display: 'Name',    tag: 'input',   type: 'text', limit: 100, '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 = [
     'name',

+ 17 - 17
app/assets/javascripts/app/models/user.js.coffee

@@ -3,23 +3,23 @@ class App.User extends App.Model
   @extend Spine.Model.Ajax
 #  @hasMany 'roles', 'App.Role'
   @configure_attributes = [
-    { name: 'login',            display: 'Login',         tag: 'input',    type: 'text',     limit: 100, null: false, class: 'xlarge', autocapitalize: false, signup: false, quick: false },
-    { name: 'firstname',        display: 'Firstname',     tag: 'input',    type: 'text',     limit: 100, null: false, class: 'xlarge', signup: true, quick: true, info: true, invite_agent: true },
-    { name: 'lastname',         display: 'Lastname',      tag: 'input',    type: 'text',     limit: 100, null: false, class: 'xlarge', signup: true, quick: true, info: true, invite_agent: true },
-    { name: 'email',            display: 'Email',         tag: 'input',    type: 'email',    limit: 100, null: false, class: 'xlarge', signup: true, quick: true, info: true, invite_agent: true },
-    { name: 'web',              display: 'Web',           tag: 'input',    type: 'url',      limit: 100, null: true,  class: 'xlarge', signup: false, quick: true, info: true },
-    { name: 'phone',            display: 'Phone',         tag: 'input',    type: 'phone',    limit: 100, null: true,  class: 'xlarge', signup: false, quick: true, info: true },
-    { name: 'mobile',           display: 'Mobile',        tag: 'input',    type: 'phone',    limit: 100, null: true,  class: 'xlarge', signup: false, quick: true, info: true },
-    { name: 'fax',              display: 'Fax',           tag: 'input',    type: 'phone',    limit: 100, null: true,  class: 'xlarge', signup: false, quick: true, info: true },
-    { name: 'street',           display: 'Street',        tag: 'input',    type: 'text',    limit: 100, null: true,  class: 'xlarge', signup: false, quick: true, info: true },
-    { name: 'zip',              display: 'Zip',           tag: 'input',    type: 'text',    limit: 100, null: true,  class: 'xlarge', signup: false, quick: true, info: true },
-    { name: 'city',             display: 'City',          tag: 'input',    type: 'text',    limit: 100, null: true,  class: 'xlarge', signup: false, quick: true, info: true },
-    { name: 'password',         display: 'Password',      tag: 'input',    type: 'password', limit: 50,  null: true, autocomplete: 'off', class: 'xlarge', signup: true,  quick: false, },
-    { name: 'organization_id',  display: 'Organization',  tag: 'select',   multiple: false, nulloption: true, null: true, relation: 'Organization', class: 'xlarge' },
-    { name: 'note',             display: 'Note',          tag: 'textarea', note: 'Notes are visible to agents only, never to customers.', limit: 250, null: true, class: 'xlarge', quick: true, info: true },
-    { name: 'role_ids',         display: 'Roles',         tag: 'checkbox', multiple: true, null: false, relation: 'Role', class: 'xlarge' },
-    { name: 'group_ids',        display: 'Groups',        tag: 'checkbox', multiple: true, null: true, relation: 'Group', class: 'xlarge', invite_agent: true },
-    { name: 'active',           display: 'Active',        tag: 'boolean',  default: true, null: true, class: 'xlarge' },
+    { name: 'login',            display: 'Login',         tag: 'input',    type: 'text',     limit: 100, null: false, class: 'span4', autocapitalize: false, signup: false, quick: false },
+    { name: 'firstname',        display: 'Firstname',     tag: 'input',    type: 'text',     limit: 100, null: false, class: 'span4', signup: true, quick: true, info: true, invite_agent: true },
+    { name: 'lastname',         display: 'Lastname',      tag: 'input',    type: 'text',     limit: 100, null: false, class: 'span4', signup: true, quick: true, info: true, invite_agent: true },
+    { name: 'email',            display: 'Email',         tag: 'input',    type: 'email',    limit: 100, null: false, class: 'span4', signup: true, quick: true, info: true, invite_agent: true },
+    { name: 'web',              display: 'Web',           tag: 'input',    type: 'url',      limit: 100, null: true,  class: 'span4', signup: false, quick: true, info: true },
+    { name: 'phone',            display: 'Phone',         tag: 'input',    type: 'phone',    limit: 100, null: true,  class: 'span4', signup: false, quick: true, info: true },
+    { name: 'mobile',           display: 'Mobile',        tag: 'input',    type: 'phone',    limit: 100, null: true,  class: 'span4', signup: false, quick: true, info: true },
+    { name: 'fax',              display: 'Fax',           tag: 'input',    type: 'phone',    limit: 100, null: true,  class: 'span4', signup: false, quick: true, info: true },
+    { name: 'street',           display: 'Street',        tag: 'input',    type: 'text',    limit: 100, null: true,  class: 'span4', signup: false, quick: true, info: true },
+    { name: 'zip',              display: 'Zip',           tag: 'input',    type: 'text',    limit: 100, null: true,  class: 'span4', signup: false, quick: true, info: true },
+    { name: 'city',             display: 'City',          tag: 'input',    type: 'text',    limit: 100, null: true,  class: 'span4', signup: false, quick: true, info: true },
+    { name: 'password',         display: 'Password',      tag: 'input',    type: 'password', limit: 50,  null: true, autocomplete: 'off', class: 'span4', signup: true,  quick: false, },
+    { name: 'organization_id',  display: 'Organization',  tag: 'select',   multiple: false, nulloption: true, null: true, relation: 'Organization', class: 'span4' },
+    { name: 'note',             display: 'Note',          tag: 'textarea', note: 'Notes are visible to agents only, never to customers.', limit: 250, null: true, class: 'span4', quick: true, info: true },
+    { name: 'role_ids',         display: 'Roles',         tag: 'checkbox', multiple: true, null: false, relation: 'Role', class: 'span4' },
+    { name: 'group_ids',        display: 'Groups',        tag: 'checkbox', multiple: true, null: true, relation: 'Group', class: 'span4', invite_agent: true },
+    { name: 'active',           display: 'Active',        tag: 'boolean',  default: true, null: true, class: 'span4' },
     { name: 'updated_at',       display: 'Updated',       type: 'time',    readonly: 1 },
   ]
   @configure_overview = [

+ 1 - 1
app/assets/javascripts/app/views/agent_ticket_view.jst.eco

@@ -1,7 +1,7 @@
 <div class="page-header">
   <div class="row">
     <div class="span9">
-      <h1><%- T(@overview.meta.name) %> <small><a href="#" data-type="settings" class="icon-edit"></a></small></h1>
+      <h1><%- T(@overview.meta.name) %> <% if @edit: %><small><a href="#" data-type="settings" class="icon-edit"></a></small><% end %></h1>
     </div>
     <div class="span3">
       <div class="pagination keepright">

+ 11 - 3
app/controllers/application_controller.rb

@@ -129,9 +129,17 @@ class ApplicationController < ActionController::Base
 
   def is_role( role_name )
     return false if !current_user
-    current_user.roles.each { |role|
-      return true if role.name == role_name
-    }
+    return true if current_user.is_role( role_name )
+    return false
+  end
+
+  def ticket_permission(ticket)
+    return true if ticket.permission( :current_user => current_user )
+
+    render(
+      :json => {},
+      :status => :unauthorized
+    )
     return false
   end
 

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