zendesk_rails 0.0.1 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +16 -14
- data/app/assets/stylesheets/zendesk_rails/application.css +9 -9
- data/app/controllers/zendesk_rails/tickets_controller.rb +55 -18
- data/app/models/zendesk_rails/comment.rb +19 -0
- data/app/models/zendesk_rails/resource.rb +60 -0
- data/app/models/zendesk_rails/ticket.rb +56 -0
- data/app/views/layouts/zendesk_rails/tickets.html.erb +2 -2
- data/app/views/zendesk_rails/tickets/_comment_form.html.erb +8 -0
- data/app/views/zendesk_rails/tickets/_form.html.erb +25 -0
- data/app/views/zendesk_rails/tickets/index.html.erb +33 -25
- data/app/views/zendesk_rails/tickets/new.html.erb +1 -26
- data/app/views/zendesk_rails/tickets/show.html.erb +6 -13
- data/config/locales/zendesk_rails.yml +4 -0
- data/lib/zendesk_rails/configuration.rb +21 -27
- data/lib/zendesk_rails/engine.rb +0 -7
- data/lib/zendesk_rails/testing.rb +5 -2
- data/lib/zendesk_rails/version.rb +1 -1
- data/lib/zendesk_rails.rb +7 -5
- metadata +25 -23
- data/app/models/zendesk_rails/comment_handler.rb +0 -40
- data/app/models/zendesk_rails/ticket_handler.rb +0 -74
- data/lib/zendesk_rails/controller_helpers.rb +0 -41
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f5fb96a52344222e9e1a3adb8b563ae2241a14eb
|
4
|
+
data.tar.gz: 155198622fa584c50f53ed0d8bf68401cc05614d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 893f78bd0719115cc8a2a66e02f4058b1e2284e45be1654a1f96aba6d9d9fe4bac75860dba708bc3293427394350993737d9fa0ff22b49a0628b42c755e5f0f1
|
7
|
+
data.tar.gz: f9d185c480227309bc0c854b16d4fa0b20874fb29f8bfcc5de5ac66fc2e7575cc1c590b920028645bb213414dab9a844b3394d476def2ee983fbdf5ab96d2403
|
data/README.md
CHANGED
@@ -111,23 +111,25 @@ When `config.test_mode` is true, a fake API will be used. All created tickets wi
|
|
111
111
|
|
112
112
|
### Overriding Controller Behavior
|
113
113
|
|
114
|
-
Zendesk Rails offers hooks that allow you to control what happens after a ticket is created/invalid.
|
114
|
+
Zendesk Rails offers hooks that allow you to control what happens after a ticket is created/updated/invalid. To do that, create `app/controllers/zendesk_rails/tickets_controller.rb`.
|
115
115
|
|
116
116
|
```ruby
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
end
|
125
|
-
end
|
117
|
+
module ZendeskRails
|
118
|
+
class TicketsController < ApplicationController
|
119
|
+
private
|
120
|
+
|
121
|
+
def after_created_ticket ticket # When a ticket is created
|
122
|
+
redirect_to ticket_path(ticket.id), flash: { notice: 'Congrats!' }
|
123
|
+
end
|
126
124
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
125
|
+
def after_invalid_ticket ticket # When a ticket is invalid
|
126
|
+
render 'new'
|
127
|
+
end
|
128
|
+
|
129
|
+
def after_updated_ticket ticket # When a comment is added
|
130
|
+
redirect_to ticket_path(ticket.id), flash: { notice: 'Cool comment, bro.' }
|
131
|
+
end
|
132
|
+
end
|
131
133
|
end
|
132
134
|
```
|
133
135
|
|
@@ -3,27 +3,27 @@
|
|
3
3
|
*= require_self
|
4
4
|
*/
|
5
5
|
|
6
|
-
|
7
|
-
|
6
|
+
.zendesk-no-tickets {
|
7
|
+
margin-top: 30px;
|
8
8
|
}
|
9
9
|
|
10
|
-
.comment {
|
10
|
+
.zendesk-comment {
|
11
11
|
font-size: 17.5px;
|
12
12
|
}
|
13
13
|
|
14
|
-
.comment-body p:last-child,
|
15
|
-
.comment-body ul:last-child,
|
16
|
-
.comment-body ol:last-child {
|
14
|
+
.zendesk-comment-body p:last-child,
|
15
|
+
.zendesk-comment-body ul:last-child,
|
16
|
+
.zendesk-comment-body ol:last-child {
|
17
17
|
margin-bottom: 0;
|
18
18
|
}
|
19
19
|
|
20
|
-
.comment-details {
|
20
|
+
.zendesk-comment-details {
|
21
21
|
display: block;
|
22
22
|
font-size: 80%;
|
23
23
|
line-height: 1.42857143;
|
24
24
|
color: #777;
|
25
25
|
}
|
26
26
|
|
27
|
-
.comment-details:before {
|
27
|
+
.zendesk-comment-details:before {
|
28
28
|
content: '\2014 \00A0';
|
29
|
-
}
|
29
|
+
}
|
@@ -1,43 +1,50 @@
|
|
1
1
|
module ZendeskRails
|
2
2
|
class TicketsController < ApplicationController
|
3
|
+
delegate :config, to: :ZendeskRails, prefix: :zendesk
|
4
|
+
delegate :layout, to: :zendesk_config, prefix: :zendesk
|
5
|
+
|
3
6
|
layout :zendesk_layout
|
4
7
|
|
8
|
+
helper_method :zendesk_config,
|
9
|
+
:zendesk_current_user,
|
10
|
+
:zendesk_user_signed_in?,
|
11
|
+
:zendesk_user_attribute
|
12
|
+
|
13
|
+
rescue_from Resource::NotFoundException do |ex|
|
14
|
+
redirect_to tickets_path, flash: { alert: t('zendesk.tickets.not_found') }
|
15
|
+
end
|
16
|
+
|
5
17
|
def index
|
6
|
-
|
7
|
-
|
8
|
-
})
|
18
|
+
email = zendesk_user_attribute(:email)
|
19
|
+
@tickets = Ticket.belonging_to(email)
|
9
20
|
end
|
10
21
|
|
11
22
|
def show
|
12
|
-
@ticket =
|
13
|
-
@
|
23
|
+
@ticket = Ticket.find_request(params[:id])
|
24
|
+
@comment = Comment.new(@ticket)
|
25
|
+
@comments = @ticket.comments(zendesk_config.comment_list_options)
|
14
26
|
end
|
15
27
|
|
16
28
|
def new
|
17
|
-
@handler =
|
29
|
+
@handler = Ticket.new
|
18
30
|
end
|
19
31
|
|
20
32
|
def create
|
21
|
-
@handler =
|
33
|
+
@handler = Ticket.new(ticket_params)
|
22
34
|
|
23
35
|
if @ticket = @handler.create
|
24
|
-
|
25
|
-
redirect_to after_zendesk_ticket_created_path_for(@ticket), flash: {
|
26
|
-
success: t("zendesk.tickets.create.#{flash_key}.message")
|
27
|
-
}
|
36
|
+
after_created_ticket(@ticket)
|
28
37
|
else
|
29
|
-
|
38
|
+
after_invalid_ticket(@ticket)
|
30
39
|
end
|
31
40
|
end
|
32
41
|
|
33
42
|
def update
|
34
|
-
@ticket =
|
35
|
-
@
|
43
|
+
@ticket = Ticket.find_ticket(params[:id])
|
44
|
+
@comment = Comment.new(@ticket, comment_params)
|
36
45
|
|
37
|
-
if @
|
38
|
-
|
39
|
-
success: t('zendesk.comments.added')
|
40
|
-
}
|
46
|
+
if @comment.save
|
47
|
+
after_updated_ticket(@ticket)
|
41
48
|
else
|
42
49
|
render 'show'
|
43
50
|
end
|
@@ -55,5 +62,35 @@ module ZendeskRails
|
|
55
62
|
email: (params[:ticket][:email].presence || zendesk_user_attribute(:email))
|
56
63
|
})
|
57
64
|
end
|
65
|
+
|
66
|
+
def zendesk_current_user
|
67
|
+
send "current_#{zendesk_config.devise_scope}"
|
68
|
+
end
|
69
|
+
|
70
|
+
def zendesk_user_signed_in?
|
71
|
+
send "#{zendesk_config.devise_scope}_signed_in?"
|
72
|
+
end
|
73
|
+
|
74
|
+
# Gets the value of a user's name/emails based on
|
75
|
+
# configurable attribute names
|
76
|
+
def zendesk_user_attribute(attribute)
|
77
|
+
attr_name = zendesk_config.user_attributes[attribute]
|
78
|
+
zendesk_current_user.try(attr_name)
|
79
|
+
end
|
80
|
+
|
81
|
+
def after_created_ticket ticket
|
82
|
+
key = zendesk_user_signed_in? ? :authenticated : :unauthenticated
|
83
|
+
message = t "zendesk.tickets.create.#{key}.message"
|
84
|
+
redirect_to ticket_path(ticket.id), flash: { notice: message }
|
85
|
+
end
|
86
|
+
|
87
|
+
def after_updated_ticket ticket
|
88
|
+
message = t 'zendesk.comments.added'
|
89
|
+
redirect_to ticket_path(ticket.id), flash: { notice: message }
|
90
|
+
end
|
91
|
+
|
92
|
+
def after_invalid_ticket ticket
|
93
|
+
render 'new'
|
94
|
+
end
|
58
95
|
end
|
59
96
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module ZendeskRails
|
2
|
+
class Comment < Resource
|
3
|
+
attr_reader :ticket
|
4
|
+
has_fields :comment
|
5
|
+
delegate :requester_id, to: :ticket
|
6
|
+
validates_presence_of :comment, :requester_id
|
7
|
+
|
8
|
+
def initialize(ticket, attributes = {})
|
9
|
+
@ticket = ticket
|
10
|
+
super(attributes)
|
11
|
+
end
|
12
|
+
|
13
|
+
def save
|
14
|
+
return false unless valid?
|
15
|
+
ticket.comment = { body: comment, author_id: requester_id }
|
16
|
+
ticket.save
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'active_model'
|
2
|
+
|
3
|
+
module ZendeskRails
|
4
|
+
class Resource
|
5
|
+
include ActiveModel::Validations
|
6
|
+
include ActiveModel::Conversion
|
7
|
+
extend ActiveModel::Naming
|
8
|
+
|
9
|
+
class NotFoundException < StandardError
|
10
|
+
attr_reader :id, :resource
|
11
|
+
|
12
|
+
def initialize(id, resource)
|
13
|
+
@id, @resource = id, resource
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_s
|
17
|
+
"#{resource} ##{id} not found."
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class << self
|
22
|
+
delegate :client, :config, to: :ZendeskRails
|
23
|
+
attr_reader :known_fields
|
24
|
+
|
25
|
+
def has_fields(*names)
|
26
|
+
@known_fields ||= []
|
27
|
+
@known_fields |= names.map(&:to_s)
|
28
|
+
end
|
29
|
+
|
30
|
+
def resource_not_found!(id)
|
31
|
+
fail NotFoundException.new(id, self)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
delegate :known_fields, :client, :config, to: :class
|
35
|
+
|
36
|
+
attr_accessor :attributes
|
37
|
+
|
38
|
+
def initialize(attributes = {})
|
39
|
+
@attributes = attributes.with_indifferent_access
|
40
|
+
end
|
41
|
+
|
42
|
+
def persisted?
|
43
|
+
false
|
44
|
+
end
|
45
|
+
|
46
|
+
def respond_to_missing?(meth, *)
|
47
|
+
known_fields.include?(meth.to_s) || super
|
48
|
+
end
|
49
|
+
|
50
|
+
def method_missing(meth, *args, &block)
|
51
|
+
if attributes.key?(meth)
|
52
|
+
attributes[meth]
|
53
|
+
elsif known_fields.include?(meth.to_s)
|
54
|
+
nil
|
55
|
+
else
|
56
|
+
super
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module ZendeskRails
|
2
|
+
# ActiveModel wrapper for submitting tickets to Zendesk
|
3
|
+
class Ticket < Resource
|
4
|
+
attr_reader :ticket
|
5
|
+
has_fields :name, :email, :subject, :body, :requester
|
6
|
+
validates :subject, :body, :requester, presence: true
|
7
|
+
validate :requester_email_presence, :requester_name_presence
|
8
|
+
|
9
|
+
# Returns ticket from Zendesk's API, not a ZendeskRails::Ticket
|
10
|
+
def create
|
11
|
+
return unless valid?
|
12
|
+
@ticket = client.tickets.create({
|
13
|
+
subject: subject,
|
14
|
+
comment: { value: body },
|
15
|
+
requester: requester
|
16
|
+
}.merge(config.ticket_create_params))
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
[:name, :email].each do |key|
|
22
|
+
define_method "requester_#{key}_presence" do
|
23
|
+
if requester && requester[key].blank?
|
24
|
+
errors.add key, "can't be blank"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class << self
|
30
|
+
def search(conditions = {})
|
31
|
+
conditions[:query] = to_query(conditions[:query])
|
32
|
+
conditions.merge!(config.ticket_list_options)
|
33
|
+
client.search conditions
|
34
|
+
end
|
35
|
+
|
36
|
+
def belonging_to(email)
|
37
|
+
search query: { requester: email }
|
38
|
+
end
|
39
|
+
|
40
|
+
def find_request(id)
|
41
|
+
client.requests.find(id: id) || resource_not_found!(id)
|
42
|
+
end
|
43
|
+
|
44
|
+
def find_ticket(id)
|
45
|
+
client.tickets.find(id: id) || resource_not_found!(id)
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def to_query(query)
|
51
|
+
return query unless query.respond_to?(:keys)
|
52
|
+
query.to_a.map { |a| a.join(':') }.join('+')
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -8,7 +8,7 @@
|
|
8
8
|
<%= csrf_meta_tags %>
|
9
9
|
</head>
|
10
10
|
<body>
|
11
|
-
<div class="navbar navbar-inverse
|
11
|
+
<div class="navbar navbar-inverse" role="navigation">
|
12
12
|
<div class="container">
|
13
13
|
<div class="navbar-header">
|
14
14
|
<%= link_to zendesk_config.app_name, main_app.root_path, class: 'navbar-brand' %>
|
@@ -18,7 +18,7 @@
|
|
18
18
|
|
19
19
|
<div class="container" role="main">
|
20
20
|
<% flash.each do |type, message| %>
|
21
|
-
<div class="alert alert-<%= type %> fade in">
|
21
|
+
<div class="alert alert-<%= { notice: 'success', alert: 'danger'}[type] %> fade in">
|
22
22
|
<button class="close" data-dismiss="alert">×</button>
|
23
23
|
<%= message %>
|
24
24
|
</div>
|
@@ -0,0 +1,8 @@
|
|
1
|
+
<%= form_for(comment, as: :ticket, method: :put, url: ticket_path(@ticket.id)) do |f| %>
|
2
|
+
|
3
|
+
<%= form_group_with_errors f.object, :comment do %>
|
4
|
+
<%= f.text_area :comment, rows: 5, class: "form-control", placeholder: t('zendesk.comments.new.placeholder') %>
|
5
|
+
<% end %>
|
6
|
+
|
7
|
+
<p><%= submit_tag t('zendesk.comments.new.submit'), class: "btn btn-large btn-primary" %></p>
|
8
|
+
<% end %>
|
@@ -0,0 +1,25 @@
|
|
1
|
+
<%= form_for(handler, as: :ticket, url: tickets_path) do |f| %>
|
2
|
+
<% unless zendesk_user_signed_in? %>
|
3
|
+
<%= form_group_with_errors f.object, :name do %>
|
4
|
+
<%= f.label :name, t('zendesk.tickets.new.name.label') %>
|
5
|
+
<%= f.text_field :name, class: "form-control", placeholder: t('zendesk.tickets.new.name.placeholder') %>
|
6
|
+
<% end %>
|
7
|
+
|
8
|
+
<%= form_group_with_errors f.object, :email do %>
|
9
|
+
<%= f.label :email, t('zendesk.tickets.new.email.label') %>
|
10
|
+
<%= f.text_field :email, class: "form-control", placeholder: t('zendesk.tickets.new.email.placeholder') %>
|
11
|
+
<% end %>
|
12
|
+
<% end %>
|
13
|
+
|
14
|
+
<%= form_group_with_errors f.object, :subject do %>
|
15
|
+
<%= f.label :subject, t('zendesk.tickets.new.subject.label') %>
|
16
|
+
<%= f.text_field :subject, class: "form-control", placeholder: t('zendesk.tickets.new.subject.placeholder') %>
|
17
|
+
<% end %>
|
18
|
+
|
19
|
+
<%= form_group_with_errors f.object, :body do %>
|
20
|
+
<%= f.label :body, t('zendesk.tickets.new.body.label') %>
|
21
|
+
<%= f.text_area :body, rows: 10, class: "form-control", placeholder: t('zendesk.tickets.new.body.placeholder') %>
|
22
|
+
<% end %>
|
23
|
+
|
24
|
+
<p><%= f.submit t('zendesk.tickets.new.submit'), class: "btn btn-large btn-primary" %></p>
|
25
|
+
<% end %>
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<div class="jumbotron">
|
2
2
|
<h1><%= t 'zendesk.tickets.jumbotron.callout' %></h1>
|
3
|
-
<p><%= t
|
3
|
+
<p><%= raw t('zendesk.tickets.jumbotron.body') %></p>
|
4
4
|
<p>
|
5
5
|
<%= link_to t('zendesk.tickets.jumbotron.new'), new_ticket_path, class: "btn btn-primary btn-lg" %>
|
6
6
|
</p>
|
@@ -9,29 +9,37 @@
|
|
9
9
|
<div class="row">
|
10
10
|
<div class="col-md-12">
|
11
11
|
<h1><%= t 'zendesk.tickets.list.heading' %></h1>
|
12
|
-
|
13
|
-
<
|
14
|
-
<
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
<
|
21
|
-
|
22
|
-
<
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
12
|
+
<% if @tickets.empty? %>
|
13
|
+
<div class="zendesk-no-tickets well">
|
14
|
+
<h4 class="text-muted text-center">
|
15
|
+
<%= t 'zendesk.tickets.none' %>
|
16
|
+
</h4>
|
17
|
+
</div>
|
18
|
+
<% else %>
|
19
|
+
<div class="table-responsive">
|
20
|
+
<table class="table table-hover table-striped">
|
21
|
+
<thead>
|
22
|
+
<th><%= t 'zendesk.tickets.list.columns.id' %></th>
|
23
|
+
<th><%= t 'zendesk.tickets.list.columns.subject' %></th>
|
24
|
+
<th><%= t 'zendesk.tickets.list.columns.status' %></th>
|
25
|
+
<th><%= t 'zendesk.tickets.list.columns.last_updated' %></th>
|
26
|
+
</thead>
|
27
|
+
<tbody>
|
28
|
+
<% @tickets.each do |ticket| %>
|
29
|
+
<tr>
|
30
|
+
<td><%= link_to ticket.id, zendesk_rails.ticket_path(ticket.id) %></td>
|
31
|
+
<td><%= truncate ticket.subject, length: 300 %></td>
|
32
|
+
<td>
|
33
|
+
<span class="label label-<%= status_label_class(ticket.status) %>">
|
34
|
+
<%= ticket.status.try(:titleize) || 'New' %>
|
35
|
+
</span>
|
36
|
+
</td>
|
37
|
+
<td><%= format_time(ticket.updated_at || ticket.created_at) %></td>
|
38
|
+
</tr>
|
39
|
+
<% end %>
|
40
|
+
</tbody>
|
41
|
+
</table>
|
42
|
+
</div>
|
43
|
+
<% end %>
|
36
44
|
</div>
|
37
45
|
</div>
|
@@ -4,32 +4,7 @@
|
|
4
4
|
|
5
5
|
<div class="row">
|
6
6
|
<div class="col-md-8">
|
7
|
-
<%=
|
8
|
-
<% unless zendesk_user_signed_in? %>
|
9
|
-
<%= form_group_with_errors f.object, :name do %>
|
10
|
-
<%= f.label :name, t('zendesk.tickets.new.name.label') %>
|
11
|
-
<%= f.text_field :name, class: "form-control", placeholder: t('zendesk.tickets.new.name.placeholder') %>
|
12
|
-
<% end %>
|
13
|
-
|
14
|
-
<%= form_group_with_errors f.object, :email do %>
|
15
|
-
<%= f.label :email, t('zendesk.tickets.new.email.label') %>
|
16
|
-
<%= f.text_field :email, class: "form-control", placeholder: t('zendesk.tickets.new.email.placeholder') %>
|
17
|
-
<% end %>
|
18
|
-
<% end %>
|
19
|
-
|
20
|
-
<%= form_group_with_errors f.object, :subject do %>
|
21
|
-
<%= f.label :subject, t('zendesk.tickets.new.subject.label') %>
|
22
|
-
<%= f.text_field :subject, class: "form-control", placeholder: t('zendesk.tickets.new.subject.placeholder') %>
|
23
|
-
<% end %>
|
24
|
-
|
25
|
-
<%= form_group_with_errors f.object, :body do %>
|
26
|
-
<%= f.label :body, t('zendesk.tickets.new.body.label') %>
|
27
|
-
<%= f.text_area :body, rows: 10, class: "form-control", placeholder: t('zendesk.tickets.new.body.placeholder') %>
|
28
|
-
<% end %>
|
29
|
-
|
30
|
-
<p><%= f.submit t('zendesk.tickets.new.submit'), class: "btn btn-large btn-primary" %></p>
|
31
|
-
|
32
|
-
<% end %>
|
7
|
+
<%= render 'form', handler: @handler %>
|
33
8
|
</div>
|
34
9
|
|
35
10
|
<div class="col-md-4">
|
@@ -8,22 +8,15 @@
|
|
8
8
|
<div class="row">
|
9
9
|
<div class="col-md-12">
|
10
10
|
<div class="well">
|
11
|
-
<%=
|
12
|
-
|
13
|
-
<%= form_group_with_errors f.object, :comment do %>
|
14
|
-
<%= f.text_area :comment, rows: 5, class: "form-control", placeholder: t('zendesk.comments.new.placeholder') %>
|
15
|
-
<% end %>
|
16
|
-
|
17
|
-
<p><%= submit_tag t('zendesk.comments.new.submit'), class: "btn btn-large btn-primary" %></p>
|
18
|
-
<% end %>
|
11
|
+
<%= render 'comment_form', comment: @comment %>
|
19
12
|
</div>
|
20
13
|
</div>
|
21
14
|
</div>
|
22
15
|
|
23
16
|
<div class="row">
|
24
17
|
<div class="col-md-12">
|
25
|
-
<% @
|
26
|
-
<div class="well comment">
|
18
|
+
<% @ticket.comments.each do |comment| %>
|
19
|
+
<div class="well zendesk-comment">
|
27
20
|
<div class="row">
|
28
21
|
<% if photo = comment.author.photo %>
|
29
22
|
<div class="col-xs-2 col-md-1">
|
@@ -31,8 +24,8 @@
|
|
31
24
|
</div>
|
32
25
|
<% end %>
|
33
26
|
<div class="<%= photo ? 'col-xs-10 col-md-11' : 'col-md-12' %>">
|
34
|
-
<div class="comment-body"><%= raw comment.html_body %></div>
|
35
|
-
<small class="comment-details">
|
27
|
+
<div class="zendesk-comment-body"><%= raw comment.html_body %></div>
|
28
|
+
<small class="zendesk-comment-details">
|
36
29
|
<%= t 'zendesk.comments.details', time: format_time(comment.created_at), user: comment.author.name %>
|
37
30
|
</small>
|
38
31
|
</div>
|
@@ -40,4 +33,4 @@
|
|
40
33
|
</div>
|
41
34
|
<% end %>
|
42
35
|
</div>
|
43
|
-
</div>
|
36
|
+
</div>
|
@@ -2,6 +2,10 @@ en:
|
|
2
2
|
zendesk:
|
3
3
|
app_name: Help
|
4
4
|
tickets:
|
5
|
+
none: |
|
6
|
+
You haven't submitted any tickets, yet. Once you submit a ticket,
|
7
|
+
it will appear here so you can come back to it later.
|
8
|
+
not_found: We were unable to locate the requested ticket.
|
5
9
|
status:
|
6
10
|
new: warning
|
7
11
|
open: danger
|
@@ -1,19 +1,5 @@
|
|
1
1
|
module ZendeskRails
|
2
2
|
class Configuration
|
3
|
-
CLIENT_OPTIONS = [
|
4
|
-
:username,
|
5
|
-
:password,
|
6
|
-
:token,
|
7
|
-
:url,
|
8
|
-
:retry,
|
9
|
-
:logger,
|
10
|
-
:client_options,
|
11
|
-
:adapter,
|
12
|
-
:allow_http,
|
13
|
-
:access_token,
|
14
|
-
:url_based_access_token
|
15
|
-
]
|
16
|
-
|
17
3
|
DEFAULT_SORTING = {
|
18
4
|
sort_by: :created_at,
|
19
5
|
sort_order: :desc
|
@@ -24,7 +10,6 @@ module ZendeskRails
|
|
24
10
|
email: :email
|
25
11
|
}
|
26
12
|
|
27
|
-
attr_accessor *CLIENT_OPTIONS
|
28
13
|
attr_accessor :layout
|
29
14
|
attr_writer :devise_scope
|
30
15
|
attr_writer :app_name
|
@@ -35,6 +20,13 @@ module ZendeskRails
|
|
35
20
|
attr_writer :comment_list_options
|
36
21
|
attr_writer :ticket_create_params
|
37
22
|
|
23
|
+
def initialize(&block)
|
24
|
+
@zendesk_api_client = ZendeskAPI::Client.new do |config|
|
25
|
+
@zendesk_api_config = config
|
26
|
+
yield self
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
38
30
|
def devise_scope
|
39
31
|
@current_user_method || :user
|
40
32
|
end
|
@@ -67,24 +59,26 @@ module ZendeskRails
|
|
67
59
|
(@comment_list_options || {}).reverse_merge(DEFAULT_SORTING)
|
68
60
|
end
|
69
61
|
|
70
|
-
def
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
62
|
+
def client
|
63
|
+
@client ||= begin
|
64
|
+
if test_mode?
|
65
|
+
require 'zendesk_rails/testing'
|
66
|
+
ZendeskRails::Testing::Client.new
|
67
|
+
else
|
68
|
+
@zendesk_api_client
|
76
69
|
end
|
77
70
|
end
|
78
71
|
end
|
79
72
|
|
80
|
-
|
73
|
+
def respond_to_missing?(meth, *)
|
74
|
+
@zendesk_api_config.respond_to?(meth) || super
|
75
|
+
end
|
81
76
|
|
82
|
-
def
|
83
|
-
if
|
84
|
-
|
85
|
-
ZendeskRails::Testing::Client
|
77
|
+
def method_missing(meth, *args, &block)
|
78
|
+
if @zendesk_api_config.respond_to?(meth)
|
79
|
+
@zendesk_api_config.send(meth, *args, &block)
|
86
80
|
else
|
87
|
-
|
81
|
+
super
|
88
82
|
end
|
89
83
|
end
|
90
84
|
end
|
data/lib/zendesk_rails/engine.rb
CHANGED
@@ -1,15 +1,8 @@
|
|
1
1
|
require 'zendesk_api'
|
2
2
|
require 'zendesk_rails/configuration'
|
3
|
-
require 'zendesk_rails/controller_helpers'
|
4
3
|
|
5
4
|
module ZendeskRails
|
6
5
|
class Engine < ::Rails::Engine
|
7
6
|
isolate_namespace ZendeskRails
|
8
|
-
|
9
|
-
initializer "zendesk_rails.helpers" do
|
10
|
-
ActiveSupport.on_load(:action_controller) do
|
11
|
-
include ZendeskRails::ControllerHelpers
|
12
|
-
end
|
13
|
-
end
|
14
7
|
end
|
15
8
|
end
|
@@ -2,7 +2,7 @@ module ZendeskRails
|
|
2
2
|
module Testing
|
3
3
|
class Resource
|
4
4
|
def initialize(attributes)
|
5
|
-
@attributes = attributes.
|
5
|
+
@attributes = attributes.with_indifferent_access
|
6
6
|
end
|
7
7
|
|
8
8
|
def method_missing(method, *args, &block)
|
@@ -17,8 +17,11 @@ module ZendeskRails
|
|
17
17
|
def all
|
18
18
|
(@all ||= []).sort { |a, b| b.created_at <=> a.created_at }
|
19
19
|
end
|
20
|
-
|
21
20
|
delegate *Array.instance_methods(false), to: :all
|
21
|
+
|
22
|
+
def clear!
|
23
|
+
@all = []
|
24
|
+
end
|
22
25
|
end
|
23
26
|
end
|
24
27
|
|
data/lib/zendesk_rails.rb
CHANGED
@@ -1,11 +1,13 @@
|
|
1
1
|
require 'zendesk_rails/engine'
|
2
2
|
|
3
3
|
module ZendeskRails
|
4
|
-
|
4
|
+
class << self
|
5
|
+
attr_reader :config
|
6
|
+
delegate :client, to: :config
|
5
7
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
8
|
+
def configure(&block)
|
9
|
+
@config = Configuration.new(&block)
|
10
|
+
@config.client
|
11
|
+
end
|
10
12
|
end
|
11
13
|
end
|
metadata
CHANGED
@@ -1,125 +1,125 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zendesk_rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ray Zane
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-06-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - '>='
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '4.0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - '>='
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '4.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: zendesk_api
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - '>='
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - '>='
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: jquery-rails
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - '>='
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - '>='
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: combustion
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ~>
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: 0.5.2
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - ~>
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: 0.5.2
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rspec-rails
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- -
|
73
|
+
- - '>='
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '0'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- -
|
80
|
+
- - '>='
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: simplecov
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- -
|
87
|
+
- - '>='
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: '0'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- -
|
94
|
+
- - '>='
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: capybara
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- -
|
101
|
+
- - '>='
|
102
102
|
- !ruby/object:Gem::Version
|
103
103
|
version: '0'
|
104
104
|
type: :development
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
|
-
- -
|
108
|
+
- - '>='
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
112
|
name: poltergeist
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
|
-
- -
|
115
|
+
- - '>='
|
116
116
|
- !ruby/object:Gem::Version
|
117
117
|
version: '0'
|
118
118
|
type: :development
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
|
-
- -
|
122
|
+
- - '>='
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '0'
|
125
125
|
description: A Rails engine to add help desk ticketing using the Zendesk API.
|
@@ -136,9 +136,12 @@ files:
|
|
136
136
|
- app/assets/stylesheets/zendesk_rails/application.css
|
137
137
|
- app/controllers/zendesk_rails/tickets_controller.rb
|
138
138
|
- app/helpers/zendesk_rails/tickets_helper.rb
|
139
|
-
- app/models/zendesk_rails/
|
140
|
-
- app/models/zendesk_rails/
|
139
|
+
- app/models/zendesk_rails/comment.rb
|
140
|
+
- app/models/zendesk_rails/resource.rb
|
141
|
+
- app/models/zendesk_rails/ticket.rb
|
141
142
|
- app/views/layouts/zendesk_rails/tickets.html.erb
|
143
|
+
- app/views/zendesk_rails/tickets/_comment_form.html.erb
|
144
|
+
- app/views/zendesk_rails/tickets/_form.html.erb
|
142
145
|
- app/views/zendesk_rails/tickets/index.html.erb
|
143
146
|
- app/views/zendesk_rails/tickets/new.html.erb
|
144
147
|
- app/views/zendesk_rails/tickets/show.html.erb
|
@@ -147,7 +150,6 @@ files:
|
|
147
150
|
- lib/tasks/zendesk_rails_tasks.rake
|
148
151
|
- lib/zendesk_rails.rb
|
149
152
|
- lib/zendesk_rails/configuration.rb
|
150
|
-
- lib/zendesk_rails/controller_helpers.rb
|
151
153
|
- lib/zendesk_rails/engine.rb
|
152
154
|
- lib/zendesk_rails/testing.rb
|
153
155
|
- lib/zendesk_rails/version.rb
|
@@ -161,12 +163,12 @@ require_paths:
|
|
161
163
|
- lib
|
162
164
|
required_ruby_version: !ruby/object:Gem::Requirement
|
163
165
|
requirements:
|
164
|
-
- -
|
166
|
+
- - '>='
|
165
167
|
- !ruby/object:Gem::Version
|
166
168
|
version: '0'
|
167
169
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
168
170
|
requirements:
|
169
|
-
- -
|
171
|
+
- - '>='
|
170
172
|
- !ruby/object:Gem::Version
|
171
173
|
version: '0'
|
172
174
|
requirements: []
|
@@ -1,40 +0,0 @@
|
|
1
|
-
module ZendeskRails
|
2
|
-
class CommentHandler
|
3
|
-
include ActiveModel::Validations
|
4
|
-
include ActiveModel::Conversion
|
5
|
-
extend ActiveModel::Naming
|
6
|
-
|
7
|
-
attr_reader :ticket
|
8
|
-
attr_accessor :comment, :requester_id
|
9
|
-
|
10
|
-
validates_presence_of :comment, :requester_id
|
11
|
-
|
12
|
-
def initialize(ticket, attributes = {})
|
13
|
-
@ticket = ticket
|
14
|
-
@requester_id = ticket.requester_id
|
15
|
-
|
16
|
-
attributes.each do |key, value|
|
17
|
-
send("#{key}=", value)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def save
|
22
|
-
return false unless valid?
|
23
|
-
|
24
|
-
ticket.comment = {
|
25
|
-
body: comment,
|
26
|
-
author_id: ticket.requester_id
|
27
|
-
}
|
28
|
-
|
29
|
-
ticket.save
|
30
|
-
end
|
31
|
-
|
32
|
-
def comments
|
33
|
-
@comments ||= ticket.comments(ZendeskRails.config.comment_list_options)
|
34
|
-
end
|
35
|
-
|
36
|
-
def persisted?
|
37
|
-
false
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
@@ -1,74 +0,0 @@
|
|
1
|
-
require 'active_model'
|
2
|
-
|
3
|
-
module ZendeskRails
|
4
|
-
class TicketHandler
|
5
|
-
include ActiveModel::Validations
|
6
|
-
include ActiveModel::Conversion
|
7
|
-
extend ActiveModel::Naming
|
8
|
-
|
9
|
-
attr_reader :ticket
|
10
|
-
attr_accessor :name, :email, :subject, :body, :requester, :comment
|
11
|
-
|
12
|
-
validates :subject, :body, :requester, presence: true
|
13
|
-
validate :requester_email_presence, :requester_name_presence
|
14
|
-
|
15
|
-
def initialize(attributes = {})
|
16
|
-
attributes.each do |key, value|
|
17
|
-
send("#{key}=", value)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def create
|
22
|
-
@ticket = self.class.client.tickets.create(create_params) if valid?
|
23
|
-
end
|
24
|
-
|
25
|
-
def create_params
|
26
|
-
{
|
27
|
-
subject: subject,
|
28
|
-
comment: { value: body },
|
29
|
-
requester: requester
|
30
|
-
}.merge(ZendeskRails.config.ticket_create_params)
|
31
|
-
end
|
32
|
-
|
33
|
-
def persisted?
|
34
|
-
false
|
35
|
-
end
|
36
|
-
|
37
|
-
def requester_email_presence
|
38
|
-
if requester && requester[:email].blank?
|
39
|
-
errors.add(:email, "can't be blank")
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def requester_name_presence
|
44
|
-
if requester && requester[:name].blank?
|
45
|
-
errors.add(:name, "can't be blank")
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
class << self
|
50
|
-
delegate :client, to: ZendeskRails
|
51
|
-
|
52
|
-
def search(conditions = {})
|
53
|
-
conditions[:query] = to_query(conditions[:query])
|
54
|
-
conditions.merge!(ZendeskRails.config.ticket_list_options)
|
55
|
-
client.search(conditions)
|
56
|
-
end
|
57
|
-
|
58
|
-
def find_request(id)
|
59
|
-
client.requests.find(id: id)
|
60
|
-
end
|
61
|
-
|
62
|
-
def find_ticket(id)
|
63
|
-
client.tickets.find(id: id)
|
64
|
-
end
|
65
|
-
|
66
|
-
private
|
67
|
-
|
68
|
-
def to_query(query)
|
69
|
-
return query unless query.respond_to?(:keys)
|
70
|
-
query.to_a.map { |a| a.join(':') }.join('+')
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
@@ -1,41 +0,0 @@
|
|
1
|
-
module ZendeskRails
|
2
|
-
module ControllerHelpers
|
3
|
-
extend ActiveSupport::Concern
|
4
|
-
|
5
|
-
included do
|
6
|
-
delegate :config, to: :ZendeskRails, prefix: :zendesk
|
7
|
-
delegate :layout, to: :zendesk_config, prefix: :zendesk
|
8
|
-
|
9
|
-
helper_method :zendesk_config,
|
10
|
-
:zendesk_current_user,
|
11
|
-
:zendesk_user_signed_in?,
|
12
|
-
:zendesk_user_attribute
|
13
|
-
end
|
14
|
-
|
15
|
-
def zendesk_current_user
|
16
|
-
send "current_#{zendesk_config.devise_scope}"
|
17
|
-
end
|
18
|
-
|
19
|
-
def zendesk_user_signed_in?
|
20
|
-
send "#{zendesk_config.devise_scope}_signed_in?"
|
21
|
-
end
|
22
|
-
|
23
|
-
# Gets the value of a user's name/emails based on
|
24
|
-
# configurable attribute names
|
25
|
-
def zendesk_user_attribute(attribute)
|
26
|
-
attr_name = zendesk_config.user_attributes[attribute]
|
27
|
-
zendesk_current_user.try(attr_name)
|
28
|
-
end
|
29
|
-
|
30
|
-
# The user will be redirected to this URL when a
|
31
|
-
# ticket is successfully created
|
32
|
-
def after_zendesk_ticket_created_path_for(ticket)
|
33
|
-
ticket_path(ticket.id)
|
34
|
-
end
|
35
|
-
|
36
|
-
# Render will be called with these arguments when a ticket is invalid
|
37
|
-
def after_zendesk_ticket_invalid_template
|
38
|
-
'new'
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|