summaryrefslogtreecommitdiff
path: root/help
diff options
context:
space:
mode:
authorjessib <jessib@leap.se>2013-07-09 11:53:58 -0700
committerjessib <jessib@leap.se>2013-07-09 11:53:58 -0700
commit09b7f01cac6df1ae11f4129b20b781b78a3706ac (patch)
tree3921eaa5edd03d80e6b402c5c2f88dda6338ab3a /help
parent9979b50848ce27730f880159512933e50d5ae0e4 (diff)
parent3113f8b814417a896ad5340fda88927733f8ab22 (diff)
Merge branch 'master' into feature/authentication_generic_error
Conflicts: app/views/layouts/_messages.html.haml app/views/layouts/application.html.haml users/app/assets/javascripts/users.js.coffee
Diffstat (limited to 'help')
-rw-r--r--help/README.md1
-rw-r--r--help/Readme.md0
-rw-r--r--help/app/assets/javascripts/tickets.js8
-rw-r--r--help/app/controllers/tickets_controller.rb146
-rw-r--r--help/app/helpers/auto_tickets_path_helper.rb51
-rw-r--r--help/app/helpers/tickets_helper.rb57
-rw-r--r--help/app/models/ticket.rb106
-rw-r--r--help/app/models/ticket_selection.rb41
-rw-r--r--help/app/views/tickets/_admin-nav.html.haml5
-rw-r--r--help/app/views/tickets/_comment.html.haml34
-rw-r--r--help/app/views/tickets/_edit_form.html.haml48
-rw-r--r--help/app/views/tickets/_new_comment.html.haml4
-rw-r--r--help/app/views/tickets/_new_comment_form.html.haml13
-rw-r--r--help/app/views/tickets/_order-nav.html.haml5
-rw-r--r--help/app/views/tickets/_status-nav.html.haml7
-rw-r--r--help/app/views/tickets/_table-nav.html.haml5
-rw-r--r--help/app/views/tickets/_tabs.html.haml23
-rw-r--r--help/app/views/tickets/_ticket.html.haml21
-rw-r--r--help/app/views/tickets/_ticket_data.html.haml35
-rw-r--r--help/app/views/tickets/index.html.haml30
-rw-r--r--help/app/views/tickets/new.html.haml38
-rw-r--r--help/app/views/tickets/show.html.haml28
-rw-r--r--help/config/locales/en.yml22
-rw-r--r--help/config/routes.rb7
-rw-r--r--help/leap_web_help.gemspec2
-rw-r--r--help/test/functional/tickets_controller_test.rb13
26 files changed, 443 insertions, 307 deletions
diff --git a/help/README.md b/help/README.md
new file mode 100644
index 0000000..c9573e6
--- /dev/null
+++ b/help/README.md
@@ -0,0 +1 @@
+Implements a simple, clean, and easy to use help ticketing system. \ No newline at end of file
diff --git a/help/Readme.md b/help/Readme.md
deleted file mode 100644
index e69de29..0000000
--- a/help/Readme.md
+++ /dev/null
diff --git a/help/app/assets/javascripts/tickets.js b/help/app/assets/javascripts/tickets.js
index 5376a6e..bf7965c 100644
--- a/help/app/assets/javascripts/tickets.js
+++ b/help/app/assets/javascripts/tickets.js
@@ -1,4 +1,4 @@
-$(document).ready(function () {
- $.fn.editable.defaults.mode = 'inline';
- $('#title').editable();
-}); \ No newline at end of file
+//$(document).ready(function () {
+// $.fn.editable.defaults.mode = 'inline';
+// $('#title').editable();
+//}); \ No newline at end of file
diff --git a/help/app/controllers/tickets_controller.rb b/help/app/controllers/tickets_controller.rb
index 6562048..094612c 100644
--- a/help/app/controllers/tickets_controller.rb
+++ b/help/app/controllers/tickets_controller.rb
@@ -1,12 +1,13 @@
class TicketsController < ApplicationController
+ include AutoTicketsPathHelper
respond_to :html, :json
#has_scope :open, :type => boolean
- before_filter :set_strings
-
before_filter :authorize, :only => [:index]
before_filter :fetch_ticket, :only => [:show, :update, :destroy] # don't now have an edit method
+ before_filter :fetch_user
+ before_filter :set_title
def new
@ticket = Ticket.new
@@ -20,95 +21,134 @@ class TicketsController < ApplicationController
@ticket.created_by = current_user.id if logged_in?
@ticket.email = current_user.email_address if logged_in? and current_user.email_address
- flash[:notice] = 'Ticket was successfully created.' if @ticket.save
+ if @ticket.save
+ flash[:notice] = t(:thing_was_successfully_created, :thing => t(:ticket))
+ end
# cannot set this until ticket has been saved, as @ticket.id will not be set
- flash[:notice] += " " + t(:access_ticket_text, :full_url => ticket_url(@ticket.id)) if !logged_in? and flash[:notice]
- respond_with(@ticket)
-
- end
-
-=begin
- def edit
- @ticket.comments.build
- # build ticket comments?
+ if !logged_in? and flash[:notice]
+ flash[:notice] += " " + t(:access_ticket_text, :full_url => ticket_url(@ticket.id))
+ end
+ respond_with(@ticket, :location => auto_ticket_path(@ticket))
end
-=end
def show
@comment = TicketComment.new
if !@ticket
- redirect_to tickets_path, :alert => "No such ticket"
+ redirect_to auto_tickets_path, :alert => t(:no_such_thing, :thing => t(:ticket))
return
end
end
def update
+ if params[:commit] == 'close'
+ @ticket.is_open = false
+ @ticket.save
+ redirect_to_tickets
+ elsif params[:commit] == 'open'
+ @ticket.is_open = true
+ @ticket.save
+ redirect_to auto_ticket_path(@ticket)
+ else
+ @ticket.attributes = cleanup_ticket_params(params[:ticket])
- if params[:post] #currently changes to title or is_open status
- @ticket.attributes = params[:post]
- # TODO: do we want to keep the history of title changes? one possibility was adding a comment that said something like 'user changed the title from a to b'
+ if params[:commit] == 'reply_and_close'
+ @ticket.close
+ end
- else
- params[:ticket][:comments_attributes] = nil if params[:ticket][:comments_attributes].values.first[:body].blank? #unset comments hash if no new comment was typed
- @ticket.attributes = params[:ticket] #this will call comments_attributes=
- @ticket.close if params[:commit] == @reply_close_str #this overrides is_open selection
- # what if there is an update and no new comment? Confirm that there is a new comment to update posted_by:
- @ticket.comments.last.posted_by = (current_user ? current_user.id : nil) if @ticket.comments_changed? #protecting posted_by isn't working, so this should protect it.
- end
- if @ticket.changed? and @ticket.save
- flash[:notice] = 'Ticket was successfully updated.'
- if @ticket.is_open || !logged_in?
- respond_with @ticket
- else #for closed tickets with authenticated users, redirect to index.
- redirect_to tickets_path
+ if @ticket.comments_changed?
+ @ticket.comments.last.posted_by = (current_user ? current_user.id : nil)
end
- else
- #redirect_to [:show, @ticket] #
- flash[:alert] = 'Ticket has not been changed'
- redirect_to @ticket
- #respond_with(@ticket) # why does this go to edit?? redirect???
- end
+ if @ticket.changed?
+ if @ticket.save
+ flash[:notice] = t(:changes_saved)
+ redirect_to_tickets
+ else
+ respond_with @ticket
+ end
+ else
+ redirect_to auto_ticket_path(@ticket)
+ end
+ end
end
def index
- @all_tickets = Ticket.for_user(current_user, params, admin?) #for tests, useful to have as separate variable
- @tickets = @all_tickets.page(params[:page]).per(10)
+ @all_tickets = Ticket.search(search_options(params))
+ @tickets = @all_tickets.page(params[:page]).per(APP_CONFIG[:pagination_size])
end
def destroy
# should we allow non-admins to delete their own tickets? i don't think necessary.
@ticket.destroy if admin?
- redirect_to tickets_path
+ redirect_to auto_tickets_path
+ end
+
+ protected
+
+ def set_title
+ @title = t(:tickets)
end
private
- def ticket_access?
- @ticket and (admin? or !@ticket.created_by or (current_user and current_user.id == @ticket.created_by))
+ #
+ # redirects to ticket index, if appropriate.
+ # otherwise, just redirects to @ticket
+ #
+ def redirect_to_tickets
+ if logged_in?
+ if params[:commit] == t(:reply_and_close)
+ redirect_to auto_tickets_path
+ else
+ redirect_to auto_ticket_path(@ticket)
+ end
+ else
+ # if we are not logged in, there is no index to view
+ redirect_to auto_ticket_path(@ticket)
+ end
end
- def set_strings
- @post_reply_str = 'Post reply' #t :post_reply
- @reply_close_str = 'Reply and close' #t :reply_and_close
+ #
+ # unset comments hash if no new comment was typed
+ #
+ def cleanup_ticket_params(ticket)
+ if ticket && ticket[:comments_attributes]
+ if ticket[:comments_attributes].values.first[:body].blank?
+ ticket[:comments_attributes] = nil
+ end
+ end
+ return ticket
+ end
+
+ def ticket_access?
+ @ticket and (admin? or !@ticket.created_by or (current_user and current_user.id == @ticket.created_by))
end
def fetch_ticket
@ticket = Ticket.find(params[:id])
if !@ticket and admin?
- redirect_to tickets_path, :alert => t(:no_such_thing, :thing => 'ticket')
+ redirect_to auto_tickets_path, :alert => t(:no_such_thing, :thing => 'ticket')
return
end
access_denied unless ticket_access?
end
- # not using now, as we are using comment_attributes= from the Ticket model
-=begin
- def add_comment
- comment = TicketComment.new(params[:comment])
- comment.posted_by = User.current.id if User.current #could be nil
- comment.posted_at = Time.now # TODO: it seems strange to have this here, and not in model
- @ticket.comments << comment
+
+ def fetch_user
+ if params[:user_id]
+ @user = User.find_by_param(params[:user_id])
+ end
+ end
+
+ #
+ # clean up params for ticket search
+ #
+ def search_options(params)
+ params.merge(
+ :admin_status => params[:user_id] ? 'mine' : 'all',
+ :user_id => @user ? @user.id : current_user.id,
+ :is_admin => admin?
+ )
end
-=end
+
end
diff --git a/help/app/helpers/auto_tickets_path_helper.rb b/help/app/helpers/auto_tickets_path_helper.rb
new file mode 100644
index 0000000..bb71260
--- /dev/null
+++ b/help/app/helpers/auto_tickets_path_helper.rb
@@ -0,0 +1,51 @@
+#
+# These "auto" forms of the normal ticket path route helpers allow us to do two things automatically:
+#
+# (1) include the user in the path if appropriate.
+# (2) retain the sort params, if appropriate.
+#
+# Tickets views with a user_id are limited to that user. For admins, they don't need a user_id for any ticket action.
+#
+# This is available both to the views and the tickets_controller.
+#
+module AutoTicketsPathHelper
+
+ protected
+
+ def auto_tickets_path(options={})
+ options = ticket_view_options.merge options
+ if @user
+ user_tickets_path(@user, options)
+ else
+ tickets_path(options)
+ end
+ end
+
+ def auto_ticket_path(ticket, options={})
+ options = ticket_view_options.merge options
+ if @user
+ user_ticket_path(@user, ticket, options)
+ else
+ ticket_path(ticket, options)
+ end
+ end
+
+ def auto_new_ticket_path(options={})
+ options = ticket_view_options.merge options
+ if @user
+ new_user_ticket_path(@user, options)
+ else
+ new_ticket_path(options)
+ end
+ end
+
+ private
+
+ def ticket_view_options
+ hsh = {}
+ hsh[:open_status] = params[:open_status] if params[:open_status] && !params[:open_status].empty?
+ hsh[:sort_order] = params[:sort_order] if params[:sort_order] && !params[:sort_order].empty?
+ hsh
+ end
+
+end \ No newline at end of file
diff --git a/help/app/helpers/tickets_helper.rb b/help/app/helpers/tickets_helper.rb
index bd2c069..7af50d6 100644
--- a/help/app/helpers/tickets_helper.rb
+++ b/help/app/helpers/tickets_helper.rb
@@ -1,27 +1,54 @@
module TicketsHelper
+ #
+ # FORM HELPERS
+ #
- def status
- params[:open_status] || 'open'
+ #
+ # hidden fields that should be added to ever ticket form.
+ # these are use for proper redirection after successful actions.
+ #
+ def hidden_ticket_fields
+ haml_concat hidden_field_tag('open_status', params[:open_status])
+ haml_concat hidden_field_tag('sort_order', params[:sort_order])
+ haml_concat hidden_field_tag('user_id', params[:user_id])
+ ""
end
- def admin
- # do we not want this set for non-admins? the param will be viewable in the url
- params[:admin_status] || 'all'
+ #
+ # PARAM HELPERS
+ #
+
+ def search_status
+ if action?(:index)
+ params[:open_status] || 'open'
+ else
+ nil
+ end
end
- def order
+ def search_order
params[:sort_order] || 'updated_at_desc'
end
+ #
+ # LINK HELPERS
+ #
+
def link_to_status(new_status)
- label = new_status + ' issues'
- link_to label, :open_status => new_status, :admin_status => admin, :sort_order => order
+ if new_status == "open"
+ label = t(:open_tickets)
+ elsif new_status == "closed"
+ label = t(:closed_tickets)
+ elsif new_status == "all"
+ label = t(:all_tickets)
+ end
+ link_to label, auto_tickets_path(:open_status => new_status, :sort_order => search_order)
end
def link_to_order(order_field)
- if order.start_with?(order_field)
+ if search_order.start_with?(order_field)
# link for currently-filtered field. Link to other direction of this field.
- if order.end_with? 'asc'
+ if search_order.end_with? 'asc'
direction = 'desc'
icon_direction = 'up'
else
@@ -35,8 +62,14 @@ module TicketsHelper
direction = 'desc'
end
- link_to :sort_order => order_field + '_at_' + direction, :open_status => status, :admin_status => admin do
- arrow + order_field + ' at'
+ if order_field == 'updated'
+ label = t(:updated)
+ elsif order_field == 'created'
+ label = t(:created)
+ end
+
+ link_to auto_tickets_path(:sort_order => order_field + '_at_' + direction, :open_status => search_status) do
+ arrow + label
end
end
diff --git a/help/app/models/ticket.rb b/help/app/models/ticket.rb
index 738487a..8066d0d 100644
--- a/help/app/models/ticket.rb
+++ b/help/app/models/ticket.rb
@@ -1,49 +1,30 @@
+#
+# TODO: thought i should reverse keys for descending, but that didn't work.
+# look into whether that should be tweaked, and whether it works okay with
+# pagination (seems to now...)
+#
+# TODO: better validation of email
+#
+# TODO: don't hardcode strings 'unknown user' and 'unauthenticated user'
+#
class Ticket < CouchRest::Model::Base
- #include ActiveModel::Validations
-
use_database "tickets"
- #require 'securerandom'
-=begin
- title
- created_at
- updated_at
- email_address
- user
- user_verified?
- admins (list of admins who have commented on the ticket)
- code (secret url)
-=end
-
- #belongs_to :user #from leap_web_users. doesn't necessarily belong to a user though
- property :created_by, String, :protected => true #Integer #nil unless user was authenticated for ticket creation, #THIS should not be changed after being set
- property :regarding_user, String#Integer # form cannot be submitted if they type in a username w/out corresponding ID. this field can be nil. for authenticated ticket creation by non-admins, should this just automatically be set to be same as created_by? or maybe we don't use this field unless created_by is nil?
- #also, both created_by and regarding_user could be nil---say user forgets username, or has general question
- property :title, String
- property :email, String #verify
-
- #property :user_verified, TrueClass, :default => false #will be true exactly when user is set
- #admins
- #property :code, String, :protected => true # only should be set if created_by is nil #instead we will just use couchdb ID
- property :is_open, TrueClass, :default => true
- property :comments, [TicketComment]
+
+ property :created_by, String, :protected => true # nil for anonymous tickets, should never be changed
+ property :regarding_user, String # may be nil or valid username
+ property :title, String
+ property :email, String
+ property :is_open, TrueClass, :default => true
+ property :comments, [TicketComment]
timestamps!
- #before_validation :set_created_by, :set_code, :set_email, :on => :create
before_validation :set_email, :set_regarding_user, :on => :create
-
- #named_scope :open, :conditions => {:is_open => true} #??
-
design do
- #TODO--clean this all up
- #view :by_is_open
- #view :by_created_by
-
view :by_updated_at
view :by_created_at
- #view :by_is_open_and_created_by
view :by_is_open_and_created_at
view :by_is_open_and_updated_at
@@ -52,63 +33,31 @@ class Ticket < CouchRest::Model::Base
end
validates :title, :presence => true
- #validates :comments, :presence => true #do we want it like this?
-
-
- # html5 has built-in validation which isn't ideal, as it says 'please enter an email address' for invalid email addresses, which implies an email address is required, and it is not.
validates :email, :allow_blank => true, :format => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/
- #TODO:
- #def set_created_by
- # self.created_by = User.current if User.current
- #end
-
- def self.for_user(user, options = {}, is_admin = false)
-
- # TODO: thought i should reverse keys for descending, but that didn't work. look into whether that should be tweaked, and whether it works okay with pagination (seems to now...)
-
- options[:user_id] = user.id
- options[:is_admin] = is_admin
-
+ def self.search(options = {})
@selection = TicketSelection.new(options)
@selection.tickets
end
- #def self.tickets_by_commenter(user_id)#, options = {})
- # Ticket.includes_post_by_and_updated_at.startkey([user_id, 0]).endkey([user_id, Time.now])
- #end
-
def is_creator_validated?
!!created_by
end
-=begin
- def set_code #let's not use this---can use same show url
- # ruby 1.9 provides url-safe option---this is not necessarily url-safe
- self.code = SecureRandom.hex(8) if !is_creator_validated?
- end
-=end
-
-
def set_email
self.email = nil if self.email == ""
- # in controller set to be current users email if that exists
end
def set_regarding_user
self.regarding_user = nil if self.regarding_user == ""
end
- #not saving with close and reopen, as we will save in update when they are called.
- #TODO: not sure if we should bother with these:
def close
self.is_open = false
- #save
end
def reopen
self.is_open = true
- #save
end
def commenters
@@ -118,20 +67,21 @@ class Ticket < CouchRest::Model::Base
if user = User.find(comment.posted_by)
commenters << user.login if user and !commenters.include?(user.login)
else
- commenters << 'unknown user' if !commenters.include?('unknown user') #todo don't hardcode string 'unknown user'
+ commenters << 'unknown user' if !commenters.include?('unknown user')
end
else
- commenters << 'unauthenticated user' if !commenters.include?('unauthenticated user') #todo don't hardcode string 'unauthenticated user'
+ commenters << 'unauthenticated user' if !commenters.include?('unauthenticated user')
end
end
commenters.join(', ')
end
+ #
+ # update comments. User should be set by controller.
+ #
def comments_attributes=(attributes)
- if attributes # could be empty as we will empty if nothing was typed in
- comment = TicketComment.new(attributes.values.first) #TicketComment.new(attributes)
- #comment.posted_by = User.current.id if User.current #we want to avoid User.current, and current_user won't work here. instead will set in tickets_controller
- # what about: comment.posted_by = self.updated_by (will need to add ticket.updated_by)
+ if attributes
+ comment = TicketComment.new(attributes.values.first)
comment.posted_at = Time.now
comments << comment
end
@@ -144,11 +94,5 @@ class Ticket < CouchRest::Model::Base
def regarding_user_actual_user
User.find_by_login(self.regarding_user)
end
-=begin
- def validate
- if email_address and not email_address.strip =~ RFC822::EmailAddress
- errors.add 'email', 'contains an invalid address'
- end
- end
-=end
+
end
diff --git a/help/app/models/ticket_selection.rb b/help/app/models/ticket_selection.rb
index bebe5fc..74d5b78 100644
--- a/help/app/models/ticket_selection.rb
+++ b/help/app/models/ticket_selection.rb
@@ -1,10 +1,20 @@
class TicketSelection
+ #
+ # supported options:
+ #
+ # user_id: id of the user (uuid string)
+ # open_status: open | closed | all
+ # sort_order: updated_at_desc | updated_at_asc | created_at_desc | created_at_asc
+ # admin_status: mine | all
+ # is_admin: true | false
+ #
def initialize(options = {})
- @options = options
- @options[:open_status] ||= 'open'
- @options[:sort_order] ||= 'updated_at_desc'
-
+ @user_id = options[:user_id].gsub /[^a-z0-9]/, ''
+ @open_status = allow options[:open_status], 'open', 'closed', 'all'
+ @sort_order = allow options[:sort_order], 'updated_at_desc', 'updated_at_asc', 'created_at_desc', 'created_at_asc'
+ @admin_status = allow options[:admin_status], 'mine', 'all'
+ @is_admin = allow options[:is_admin], false, true
end
def tickets
@@ -13,25 +23,32 @@ class TicketSelection
protected
+ def allow(source, *allowed)
+ if allowed.include?(source)
+ source
+ else
+ allowed.first
+ end
+ end
def finder_method
method = 'by_'
method += 'includes_post_by_and_' if only_mine?
- method += 'is_open_and_' if @options[:open_status] != 'all'
- method += @options[:sort_order].sub(/_(de|a)sc$/, '')
+ method += 'is_open_and_' if @open_status != 'all'
+ method += @sort_order.sub(/_(de|a)sc$/, '')
end
def startkey
startkeys = []
- startkeys << @options[:user_id] if only_mine?
- startkeys << (@options[:open_status] == 'open') if @options[:open_status] != 'all'
+ startkeys << @user_id if only_mine?
+ startkeys << (@open_status == 'open') if @open_status != 'all'
startkeys << 0
- startkeys = startkeys.join if startkeys.length == 1 #want string not array if just one thing in array
+ startkeys = startkeys.join if startkeys.length == 1 # want string not array if just one thing in array
startkeys
end
def endkey
- endtime = Time.now + 2.days #TODO. this obviously isn't ideal
+ endtime = Time.now + 2.days # TODO. this obviously isn't ideal
if self.startkey.is_a?(Array)
endkeys = self.startkey
endkeys.pop
@@ -43,12 +60,12 @@ class TicketSelection
def order
# we have defined the ascending method to return the view itself:
- (@options[:sort_order].end_with? 'desc') ? 'descending' : 'ascending'
+ (@sort_order.end_with? 'desc') ? 'descending' : 'ascending'
end
def only_mine?
- !@options[:is_admin] or (@options[:admin_status] == 'mine')
+ !@is_admin || @admin_status == 'mine'
end
end
diff --git a/help/app/views/tickets/_admin-nav.html.haml b/help/app/views/tickets/_admin-nav.html.haml
deleted file mode 100644
index 0e45c40..0000000
--- a/help/app/views/tickets/_admin-nav.html.haml
+++ /dev/null
@@ -1,5 +0,0 @@
-%ul.nav.nav-pills.nav-stacked
- %li{:class => ("active" if admin == 'mine')}
- = link_to 'tickets i admin', {:admin_status => 'mine', :open_status => status, :sort_order => order}
- %li{:class => ("active" if admin == 'all')}
- = link_to 'all tickets', {:admin_status => 'all', :open_status => status, :sort_order => order}
diff --git a/help/app/views/tickets/_comment.html.haml b/help/app/views/tickets/_comment.html.haml
index 501ceec..4252eee 100644
--- a/help/app/views/tickets/_comment.html.haml
+++ b/help/app/views/tickets/_comment.html.haml
@@ -1,20 +1,20 @@
-- # style is super ugly but just for now
- if admin? or !comment.private # only show comment if user is admin or comment is not private
%tr
- %td
- - if comment.posted_by_user
- %b
- = 'Posted by' + (comment.posted_by_user.is_admin? ? ' admin' : '') + ':'
- = comment.posted_by_user.login
- - else
- %b
- Unauthenticated post
+ %td.user
+ %div
+ %strong
+ - if comment.posted_by_user
+ = comment.posted_by_user.login
+ - else
+ = t(:anonymous)
+ %div= comment.posted_at.to_s(:short)
+ - if comment.posted_by_user && comment.posted_by_user.is_admin?
+ %div
+ %span.label.label-inverse
+ = t(:admin)
- if comment.private
- (Private comment)
- .pull-right
- %b
- Posted at:
- = comment.posted_at.to_s(:short)
- %br
- = comment.body
-
+ %div
+ %span.label.label-important
+ = t(:private)
+ %td.comment
+ = comment.body \ No newline at end of file
diff --git a/help/app/views/tickets/_edit_form.html.haml b/help/app/views/tickets/_edit_form.html.haml
new file mode 100644
index 0000000..5252c2e
--- /dev/null
+++ b/help/app/views/tickets/_edit_form.html.haml
@@ -0,0 +1,48 @@
+:ruby
+ # created by user link
+ if @ticket.created_by_user
+ created_by = link_to(@ticket.created_by_user.login, user_overview_path(@ticket.created_by_user))
+ else
+ created_by = t(:anonymous)
+ end
+
+ # regarding user link
+ if admin?
+ if @ticket.regarding_user_actual_user
+ regarding_user_link = link_to @ticket.regarding_user_actual_user.login, user_overview_path(@ticket.regarding_user_actual_user)
+ else
+ regarding_user_link = "(#{t(:unknown)})"
+ end
+ else
+ regarding_user_link = ''
+ end
+
+= form_for @ticket do |f|
+ = hidden_ticket_fields
+ %p.first
+ - if @ticket.is_open?
+ %span.label.label-info= t(:open)
+ - else
+ %span.label.label-success= t(:closed)
+ %span.label.label-clear= t(:created_by_on, :user => created_by, :time => @ticket.created_at.to_s(:short)).html_safe
+ %div= t(:subject)
+ = f.text_field :title, :class => 'large full-width'
+ .row-fluid
+ .span4
+ %div= t(:status)
+ = f.select :is_open, [[t(:open), "true"], [t(:closed), "false"]]
+ .span4
+ %div= t(:email)
+ = f.text_field :email
+ .span4
+ %div
+ = t(:regarding_account)
+ = regarding_user_link
+ = f.text_field :regarding_user
+ = f.button t(:save), :name => 'commit', :class => 'btn', :type => 'submit', :value => 'save'
+ - if @ticket.is_open?
+ = f.button t(:close), :name => 'commit', :class => 'btn', :type => 'submit', :value => 'close'
+ - else
+ = f.button t(:open), :name => 'commit', :class => 'btn', :type => 'submit', :value => 'open'
+ - if admin?
+ = link_to t(:destroy), auto_ticket_path(@ticket), :confirm => t(:are_you_sure), :method => :delete, :class => 'btn'
diff --git a/help/app/views/tickets/_new_comment.html.haml b/help/app/views/tickets/_new_comment.html.haml
deleted file mode 100644
index 96388ea..0000000
--- a/help/app/views/tickets/_new_comment.html.haml
+++ /dev/null
@@ -1,4 +0,0 @@
-= f.simple_fields_for :comments, @comment do |c|
- = c.input :body, :label => 'Comment', :as => :text, :input_html => {:class => "span9", :rows=>4}
- - if admin?
- = c.input :private, :as => :boolean, :label => false, :inline_label => true
diff --git a/help/app/views/tickets/_new_comment_form.html.haml b/help/app/views/tickets/_new_comment_form.html.haml
new file mode 100644
index 0000000..8418e01
--- /dev/null
+++ b/help/app/views/tickets/_new_comment_form.html.haml
@@ -0,0 +1,13 @@
+-#
+-# for posting a new comment to an existing ticket.
+-#
+= simple_form_for @ticket, :html => {:class => 'slim'} do |f|
+ = hidden_ticket_fields
+ = f.simple_fields_for :comments, @comment, :wrapper => :none, :html => {:class => 'slim'} do |c|
+ = c.input :body, :label => false, :as => :text, :input_html => {:class => "full-width", :rows=> 5}
+ - if admin?
+ = c.input :private, :as => :boolean, :label => false, :inline_label => true
+ = f.button :button, t(:post_reply), :name => 'commit', :class => 'btn-primary', :type => 'submit', :value => 'post_reply'
+ - if logged_in? && @ticket.is_open
+ = f.button :button, t(:reply_and_close), :name => 'commit', :class => 'btn', :type => 'submit', :value => 'reply_and_close'
+ = link_to t(:cancel), auto_tickets_path, :class => :btn
diff --git a/help/app/views/tickets/_order-nav.html.haml b/help/app/views/tickets/_order-nav.html.haml
deleted file mode 100644
index 9e8bcee..0000000
--- a/help/app/views/tickets/_order-nav.html.haml
+++ /dev/null
@@ -1,5 +0,0 @@
-%ul.nav.nav-pills.pull-right
- %li{:class=> ("active" if order.start_with? 'created_at' )}
- = link_to_order('created')
- %li{:class=> ("active" if order.start_with? 'updated_at' )}
- = link_to_order('updated')
diff --git a/help/app/views/tickets/_status-nav.html.haml b/help/app/views/tickets/_status-nav.html.haml
deleted file mode 100644
index 69f4248..0000000
--- a/help/app/views/tickets/_status-nav.html.haml
+++ /dev/null
@@ -1,7 +0,0 @@
-%ul.nav.nav-tabs
- %li{:class => ("active" if status == 'open')}
- = link_to_status 'open'
- %li{:class => ("active" if status == 'closed')}
- = link_to_status 'closed'
- %li{:class => ("active" if status == 'all')}
- = link_to_status 'all'
diff --git a/help/app/views/tickets/_table-nav.html.haml b/help/app/views/tickets/_table-nav.html.haml
deleted file mode 100644
index 635b59b..0000000
--- a/help/app/views/tickets/_table-nav.html.haml
+++ /dev/null
@@ -1,5 +0,0 @@
-.row
- .span6
- = render 'tickets/status-nav'
- .span4
- = render 'tickets/order-nav'
diff --git a/help/app/views/tickets/_tabs.html.haml b/help/app/views/tickets/_tabs.html.haml
new file mode 100644
index 0000000..b7b5d3a
--- /dev/null
+++ b/help/app/views/tickets/_tabs.html.haml
@@ -0,0 +1,23 @@
+-#
+-# SORT ORDER TABS
+-#
+- unless action?(:new)
+ %ul.nav.nav-pills.pull-right.slim
+ %li{:class=> ("active" if search_order.start_with? 'created_at')}
+ = link_to_order('created')
+ %li{:class=> ("active" if search_order.start_with? 'updated_at')}
+ = link_to_order('updated')
+
+-#
+-# STATUS FILTER TABS
+-#
+%ul.nav.nav-tabs
+ - if logged_in?
+ %li{:class => ("active" if search_status == 'open')}
+ = link_to_status 'open'
+ %li{:class => ("active" if search_status == 'closed')}
+ = link_to_status 'closed'
+ %li{:class => ("active" if search_status == 'all')}
+ = link_to_status 'all'
+ %li{:class => ("active" if action?(:new))}
+ = link_to icon(:plus, :black) + t(:new_ticket), auto_new_ticket_path
diff --git a/help/app/views/tickets/_ticket.html.haml b/help/app/views/tickets/_ticket.html.haml
index 7b37652..a064c4e 100644
--- a/help/app/views/tickets/_ticket.html.haml
+++ b/help/app/views/tickets/_ticket.html.haml
@@ -1,17 +1,6 @@
-- updated_at_text = 'updated: ' + ticket.updated_at.to_s(:long)
+- url = auto_ticket_path(ticket)
%tr
- %td
- %b
- = link_to ticket.title, ticket
- - if params[:controller] == 'tickets'
- %br
- %small
- created:
- = ticket.created_at.to_s(:long)
- = updated_at_text
- %small.pull-right
- comments by:
- = ticket.commenters
- - else
- %small
- = updated_at_text \ No newline at end of file
+ %td= link_to ticket.title, url
+ %td= link_to ticket.created_at.to_s(:short), url
+ %td= link_to ticket.updated_at.to_s(:short), url
+ %td= ticket.commenters
diff --git a/help/app/views/tickets/_ticket_data.html.haml b/help/app/views/tickets/_ticket_data.html.haml
deleted file mode 100644
index 6a1a896..0000000
--- a/help/app/views/tickets/_ticket_data.html.haml
+++ /dev/null
@@ -1,35 +0,0 @@
-.spam12
- %b
- Created by:
- - if @ticket.created_by_user
- = link_to @ticket.created_by_user.login, user_path(@ticket.created_by_user)
- - else
- Unauthenticated ticket creator
- - if @ticket.regarding_user
- %b
- Regarding user:
- - if admin?
- - if @ticket.regarding_user_actual_user
- = link_to @ticket.regarding_user_actual_user.login, user_path(@ticket.regarding_user_actual_user)
- - else
- = @ticket.regarding_user + ' (no such user)'
- - else # a non-admin is viewing the ticket, so they shouldn't see confirmation of whether the regarding_user exists or not.
- = @ticket.regarding_user
- - if @ticket.email
- %b
- email:
- = @ticket.email
- %b
- Created at:
- = @ticket.created_at.to_s(:short)
- %b
- Updated at:
- = @ticket.updated_at.to_s(:short)
- %b
- = "Status:"
- - if @ticket.is_open
- = 'open'
- = button_to 'Close', {:post => {:is_open => false}}, :method => :put, :class => 'btn btn-small'
- - else
- = 'closed'
- = button_to 'Open', {:post => {:is_open => true}}, :method => :put, :class => 'btn btn-small'
diff --git a/help/app/views/tickets/index.html.haml b/help/app/views/tickets/index.html.haml
index 23a503d..c02a326 100644
--- a/help/app/views/tickets/index.html.haml
+++ b/help/app/views/tickets/index.html.haml
@@ -1,17 +1,19 @@
-%h1 tickets index
+- @show_navigation = !params[:user_id].nil?
-Create a
-= link_to "new ticket", new_ticket_path
+= render 'tickets/tabs'
-= #%div{"data-pjax-container" => ""} # not sure how to get this working right
-.row
- .span2
- - if admin?
- = render 'tickets/admin-nav'
- .span10
- = render 'tickets/table-nav'
- %table.table-striped.table-bordered.table-hover{:style => "width:100%;"}
- %tbody
- = render @tickets.all
- = paginate @tickets
+%table.table.table-striped.table-bordered
+ %thead
+ %tr
+ %th= t(:subject)
+ %th= t(:created)
+ %th= t(:updated)
+ %th= t(:voices)
+ %tbody
+ - if @tickets.any?
+ = render @tickets.all
+ - else
+ %tr
+ %td{:colspan=>4}= t(:none)
+= paginate @tickets
diff --git a/help/app/views/tickets/new.html.haml b/help/app/views/tickets/new.html.haml
index 1aa689b..c0a343d 100644
--- a/help/app/views/tickets/new.html.haml
+++ b/help/app/views/tickets/new.html.haml
@@ -1,10 +1,30 @@
-.span12
- %h2=t :new_ticket
- = simple_form_for @ticket, :validate => true, :html => {:class => 'form-horizontal'} do |f|
- = f.input :title
- = f.input :email if !current_user #hmm--might authenticated users want to submit an alternate email?
+- @show_navigation = !params[:user_id].nil?
+
+= render 'tickets/tabs'
+
+- if admin? && @user
+ - email = @user.email_address
+ - regarding = @user.login
+- elsif logged_in?
+ - email = current_user.email_address
+ - regarding = current_user.login
+
+= simple_form_for @ticket, :validate => true, :html => {:class => 'form-horizontal'} do |f|
+ = hidden_ticket_fields
+ = f.input :title, :label => t(:subject)
+ - if logged_in?
+ = f.input :email, input_html: {value: email}
+ = f.input :regarding_user, input_html: {value: regarding}
+ - else
+ = f.input :email
= f.input :regarding_user
- = render :partial => 'new_comment', :locals => {:f => f}
- .form-actions
- = f.button :submit, :class => 'btn-primary'
- = link_to t(:cancel), tickets_path, :class => :btn
+ = f.simple_fields_for :comments, @comment do |c|
+ = c.input :body, :label => t(:description), :as => :text, :input_html => {:class => "full-width", :rows=> 5}
+ - if admin?
+ = c.input :private, :as => :boolean, :label => false, :inline_label => true
+ .form-actions
+ = f.button :submit, :class => 'btn-primary', :value => t(:create_thing, :thing => t(:ticket))
+ - if logged_in?
+ = link_to t(:cancel), auto_tickets_path, :class => :btn
+ - else
+ = link_to t(:cancel), root_path, :class => 'btn' \ No newline at end of file
diff --git a/help/app/views/tickets/show.html.haml b/help/app/views/tickets/show.html.haml
index a69048b..bfdb773 100644
--- a/help/app/views/tickets/show.html.haml
+++ b/help/app/views/tickets/show.html.haml
@@ -1,18 +1,12 @@
-.spam12
- %h2
- %a#title.editable.editable-click{"data-name" => "title", "data-resource" => "post", "data-type" => "text", "data-url" => ticket_path(@ticket.id), "data-pk" => @ticket.id, :href => "#"}
- = @ticket.title
- = render 'tickets/ticket_data'
- %table.table-striped.table-bordered.table-hover{:style => "width:100%;"}
- %tbody
- = render(:partial => "comment", :collection => @ticket.comments)
- = #render @ticket.comments should work if view is in /app/views/comments/_comment
+- @show_navigation = !params[:user_id].nil?
- = simple_form_for @ticket, :html => {:class => 'form-horizontal'} do |f| # don't need validations so long as this is so simple
- = render :partial => 'new_comment', :locals => {:f => f}
- .span10.offset3
- = f.button :submit, @post_reply_str, :class => 'btn-primary'
- - if @ticket.is_open
- = f.button :submit, @reply_close_str
- = link_to t(:Destroy), ticket_path, :confirm => 'are you sure?', :method => :delete, :class => 'btn btn-danger' if admin?
- = link_to t(:cancel), tickets_path, :class => :btn
+.ticket
+ = render 'tickets/edit_form'
+ %table.table.table-striped.table-bordered
+ %tbody
+ = render :partial => 'tickets/comment', :collection => @ticket.comments
+ %tr
+ %td.user
+ = logged_in? ? current_user.login : t(:anonymous)
+ %td.comment
+ = render 'tickets/new_comment_form' \ No newline at end of file
diff --git a/help/config/locales/en.yml b/help/config/locales/en.yml
index 4ea662a..342adea 100644
--- a/help/config/locales/en.yml
+++ b/help/config/locales/en.yml
@@ -1,2 +1,22 @@
en:
- access_ticket_text: "You can later access this ticket at the url %{full_url}. You might want to bookmark this page to find it again. Anybody with this URL will be able to access this ticket, so if you are on a shared computer you might want to remove it from the browser history"
+ access_ticket_text: >
+ You can later access this ticket at the URL %{full_url}. You might want to bookmark this page to find it again.
+ Anybody with this URL will be able to access this ticket, so if you are on a shared computer you might want to
+ remove it from the browser history.
+ support_tickets: "Support Tickets"
+ all_tickets: "All Tickets"
+ my_tickets: "My Tickets"
+ open_tickets: "Open Tickets"
+ closed_tickets: "Closed Tickets"
+ new_ticket: "New Ticket"
+ tickets: "Tickets"
+ subject: "Subject"
+ destroy: "Destroy"
+ open: "Open"
+ closed: "Closed"
+ close: "Close"
+ post_reply: "Post Reply"
+ reply_and_close: "Reply and Close"
+ description: "Description"
+ ticket: "Ticket"
+ regarding_account: "Regarding Account" \ No newline at end of file
diff --git a/help/config/routes.rb b/help/config/routes.rb
index 86a9201..8f3241c 100644
--- a/help/config/routes.rb
+++ b/help/config/routes.rb
@@ -1,5 +1,6 @@
Rails.application.routes.draw do
-
- resources :tickets, :only => [:new, :create, :index, :show, :update, :destroy]
- #resources :ticket, :only => [:show]
+ resources :tickets, :except => :edit
+ resources :users do
+ resources :tickets, :except => :edit
+ end
end
diff --git a/help/leap_web_help.gemspec b/help/leap_web_help.gemspec
index 09827dc..4914694 100644
--- a/help/leap_web_help.gemspec
+++ b/help/leap_web_help.gemspec
@@ -12,7 +12,7 @@ Gem::Specification.new do |s|
s.summary = "Help Desk for LeapWeb"
s.description = "Managing Tickets for a Leap provider"
- s.files = Dir["{app,config,db,lib}/**/*"] + ["Rakefile", "Readme.md"]
+ s.files = Dir["{app,config,db,lib}/**/*"] + ["Rakefile", "README.md"]
s.test_files = Dir["test/**/*"]
s.add_dependency "leap_web_core", LeapWeb::VERSION
diff --git a/help/test/functional/tickets_controller_test.rb b/help/test/functional/tickets_controller_test.rb
index f8627d8..6479ba4 100644
--- a/help/test/functional/tickets_controller_test.rb
+++ b/help/test/functional/tickets_controller_test.rb
@@ -181,23 +181,24 @@ class TicketsControllerTest < ActionController::TestCase
test "admin_status mine vs all" do
testticket = FactoryGirl.create :ticket
+ user = find_record :user
login :is_admin? => true, :email => nil
- get :index, {:admin_status => "all", :open_status => "open"}
+ get :index, {:open_status => "open"}
assert assigns(:all_tickets).include?(testticket)
- get :index, {:admin_status => "mine", :open_status => "open"}
+ get :index, {:user_id => user.id, :open_status => "open"}
assert !assigns(:all_tickets).include?(testticket)
testticket.destroy
end
test "commenting on a ticket adds to tickets that are mine" do
testticket = FactoryGirl.create :ticket
- login :is_admin? => true, :email => nil
-
- get :index, {:admin_status => "mine", :open_status => "open"}
+ user = find_record :admin_user
+ login user
+ get :index, {:user_id => user.id, :open_status => "open"}
assert_difference('assigns[:all_tickets].count') do
put :update, :id => testticket.id, :ticket => {:comments_attributes => {"0" => {"body" =>"NEWER comment"}}}
- get :index, {:admin_status => "mine", :open_status => "open"}
+ get :index, {:user_id => user.id, :open_status => "open"}
end
assert assigns(:all_tickets).include?(assigns(:ticket))