radesk 0.3.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/radesk/radesk.js.coffee +4 -0
  3. data/app/assets/stylesheets/radesk/radesk.css.scss +41 -19
  4. data/app/controllers/radesk/admin/activities_controller.rb +11 -0
  5. data/app/controllers/radesk/admin/admin_controller.rb +9 -0
  6. data/app/controllers/radesk/admin/categories_controller.rb +2 -3
  7. data/app/controllers/radesk/admin/users_controller.rb +18 -0
  8. data/app/controllers/radesk/answers_controller.rb +9 -11
  9. data/app/controllers/radesk/application_controller.rb +5 -1
  10. data/app/controllers/radesk/tickets_controller.rb +23 -13
  11. data/app/controllers/radesk/uploads_controller.rb +18 -0
  12. data/app/helpers/radesk/activities_helper.rb +11 -0
  13. data/app/helpers/radesk/application_helper.rb +9 -0
  14. data/app/mailers/radesk/user_mailer.rb +5 -4
  15. data/app/models/radesk/activity.rb +6 -0
  16. data/app/models/radesk/answer.rb +7 -3
  17. data/app/models/radesk/concerns/access.rb +9 -0
  18. data/app/models/radesk/ticket.rb +8 -5
  19. data/app/models/radesk/upload.rb +9 -0
  20. data/app/views/layouts/radesk/application.html.haml +6 -5
  21. data/app/views/radesk/admin/activities/_answer.html.haml +1 -0
  22. data/app/views/radesk/admin/activities/_ticket.html.haml +1 -0
  23. data/app/views/radesk/admin/activities/index.html.haml +16 -0
  24. data/app/views/radesk/admin/categories/_form.html.haml +3 -1
  25. data/app/views/radesk/admin/categories/edit.html.haml +1 -2
  26. data/app/views/radesk/admin/categories/index.html.haml +11 -9
  27. data/app/views/radesk/admin/categories/new.html.haml +1 -2
  28. data/app/views/radesk/admin/users/show.html.haml +3 -0
  29. data/app/views/radesk/answers/_form.html.haml +24 -0
  30. data/app/views/radesk/answers/_list.html.haml +29 -13
  31. data/app/views/radesk/answers/_upload_fields.html.haml +2 -0
  32. data/app/views/radesk/answers/edit.html.haml +1 -6
  33. data/app/views/radesk/tickets/_form.html.haml +5 -4
  34. data/app/views/radesk/tickets/_list.html.haml +23 -0
  35. data/app/views/radesk/tickets/index.html.haml +13 -24
  36. data/app/views/radesk/tickets/new.html.haml +1 -2
  37. data/app/views/radesk/tickets/show.html.haml +4 -35
  38. data/app/views/radesk/uploads/destroy.js.erb +1 -0
  39. data/config/locales/en.yml +51 -0
  40. data/config/locales/zh-CN.yml +37 -0
  41. data/config/routes.rb +9 -0
  42. data/db/migrate/20150112111134_remove_message_from_radesk_tickets.rb +5 -0
  43. data/db/migrate/20150112182604_create_radesk_uploads.rb +11 -0
  44. data/db/migrate/20150114194722_create_radesk_activities.rb +11 -0
  45. data/lib/generators/radesk/dummy/templates/Rakefile +6 -0
  46. data/lib/generators/radesk/dummy/templates/app/assets/javascripts/application.js +13 -0
  47. data/lib/generators/radesk/dummy/templates/app/assets/stylesheets/application.css +15 -0
  48. data/lib/generators/radesk/dummy/templates/app/controllers/application_controller.rb +5 -0
  49. data/lib/generators/radesk/dummy/templates/app/helpers/application_helper.rb +2 -0
  50. data/lib/generators/radesk/dummy/templates/app/models/user.rb +10 -0
  51. data/lib/generators/radesk/dummy/templates/app/views/layouts/application.html.erb +14 -0
  52. data/lib/generators/radesk/dummy/templates/bin/bundle +3 -0
  53. data/lib/generators/radesk/dummy/templates/bin/rails +4 -0
  54. data/lib/generators/radesk/dummy/templates/bin/rake +4 -0
  55. data/lib/generators/radesk/dummy/templates/bin/setup +29 -0
  56. data/lib/generators/radesk/dummy/templates/config.ru +4 -0
  57. data/lib/generators/radesk/dummy/templates/config/application.rb +31 -0
  58. data/lib/generators/radesk/dummy/templates/config/boot.rb +5 -0
  59. data/lib/generators/radesk/dummy/templates/config/database.yml +25 -0
  60. data/lib/generators/radesk/dummy/templates/config/environment.rb +5 -0
  61. data/lib/generators/radesk/dummy/templates/config/environments/development.rb +44 -0
  62. data/lib/generators/radesk/dummy/templates/config/environments/production.rb +79 -0
  63. data/lib/generators/radesk/dummy/templates/config/environments/test.rb +42 -0
  64. data/lib/generators/radesk/dummy/templates/config/initializers/assets.rb +11 -0
  65. data/lib/generators/radesk/dummy/templates/config/initializers/backtrace_silencers.rb +7 -0
  66. data/lib/generators/radesk/dummy/templates/config/initializers/cookies_serializer.rb +3 -0
  67. data/lib/generators/radesk/dummy/templates/config/initializers/devise.rb +259 -0
  68. data/lib/generators/radesk/dummy/templates/config/initializers/filter_parameter_logging.rb +4 -0
  69. data/lib/generators/radesk/dummy/templates/config/initializers/inflections.rb +16 -0
  70. data/lib/generators/radesk/dummy/templates/config/initializers/mime_types.rb +4 -0
  71. data/lib/generators/radesk/dummy/templates/config/initializers/session_store.rb +3 -0
  72. data/lib/generators/radesk/dummy/templates/config/initializers/wrap_parameters.rb +14 -0
  73. data/lib/generators/radesk/dummy/templates/config/locales/devise.en.yml +60 -0
  74. data/lib/generators/radesk/dummy/templates/config/locales/en.yml +23 -0
  75. data/lib/generators/radesk/dummy/templates/config/routes.rb +3 -0
  76. data/lib/generators/radesk/dummy/templates/config/secrets.yml +22 -0
  77. data/lib/generators/radesk/dummy/templates/db/migrate/20150108203658_devise_create_users.rb +42 -0
  78. data/lib/generators/radesk/dummy/templates/public/404.html +67 -0
  79. data/lib/generators/radesk/dummy/templates/public/422.html +67 -0
  80. data/lib/generators/radesk/dummy/templates/public/500.html +66 -0
  81. data/lib/generators/radesk/dummy/templates/public/favicon.ico +0 -0
  82. data/lib/generators/radesk/dummy_generator.rb +13 -0
  83. data/lib/generators/radesk/install/templates/initializer.rb +2 -0
  84. data/lib/radesk.rb +8 -0
  85. data/lib/radesk/version.rb +1 -1
  86. metadata +176 -46
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cc951107bd076dc1fa44b4c559672d1d8f368fff
4
- data.tar.gz: 8dbf8b5bd494980eed407be55f7f836d66989136
3
+ metadata.gz: b2ed092bc42cc7e458336c1c4e0a11904dd13474
4
+ data.tar.gz: aa72ca554c26ad3e28e5c2f9eb1ee33959e2c6c4
5
5
  SHA512:
6
- metadata.gz: 1f5572478e61d09ba31065e1fc8a7356784076d13f763c6a0d20fa5ed6c16eacbbb40522114e3d21bcd96512976a472ed148d8f3f1383e70fd56de29cdd27879
7
- data.tar.gz: 21a91363a3e735fddce8cbc3fc50d0dea6d87fd94693f492c0ff3eeeaf65ca2eaf593acb0c9df3c0afc26f8e0489927f3dbedec7542f3a6af84160bf1570896d
6
+ metadata.gz: 74b0cd8822399fde34cb6f7dbbe22867fd35fb1391ff42d73b78a942387d628a816db73f4fa044283604b3acb57b0e7c0d2672e3634674ff555d212376ce8e33
7
+ data.tar.gz: c53a78034253365ac4c094d052abd55e6a028c4084e5d7512fbffa63c817bdedbebd3ca138e96d7ee0c34f5c6cb70d0e9475a63522e73aa7965b0a0ad3796515
@@ -0,0 +1,4 @@
1
+ $ ->
2
+ $(".add_fields").click (event) ->
3
+ $(this).before($(this).data('fields'))
4
+ event.preventDefault()
@@ -11,7 +11,7 @@ $light_color: #f6f6f6;
11
11
  }
12
12
  }
13
13
  a {
14
- color: $dark_color;
14
+ color: $dark_color;
15
15
  text-decoration: none;
16
16
  &:hover {
17
17
  color: $main_color;
@@ -28,8 +28,6 @@ $light_color: #f6f6f6;
28
28
  margin: 0 auto;
29
29
  }
30
30
 
31
-
32
-
33
31
  .notice {
34
32
  background: $main_color;
35
33
  color: #fff;
@@ -125,34 +123,29 @@ $light_color: #f6f6f6;
125
123
 
126
124
  .ticket {
127
125
  margin-bottom: 40px;
128
- .message {
129
- font-size: 14px;
130
- line-height: 20px;
131
- }
132
- .info {
133
- margin-bottom: 20px;
134
- color: darken($light_color, 20%);
135
- span {
136
- margin-left: 10px;
137
- }
138
- }
139
126
  }
140
127
 
141
128
  .answers {
142
129
  margin-bottom: 40px;
143
130
  .answer {
144
- padding: 20px 0;
145
- border-top: 1px solid darken($light_color, 5%);
146
- &.private {
147
- background: $light_color;
148
- padding: 20px;
131
+ margin-bottom: 20px;
132
+ padding-bottom: 20px;
133
+ border-bottom: 1px solid $light_color;
134
+ &:last-child {
135
+ border: none;
149
136
  }
150
137
  .info {
151
138
  margin-bottom: 10px;
152
139
  color: darken($light_color, 20%);
140
+ .private {
141
+ color: $main_color;
142
+ }
153
143
  span {
154
144
  margin-left: 10px;
155
145
  }
146
+ a {
147
+ color: darken($light_color, 20%);
148
+ }
156
149
  }
157
150
  .message {
158
151
  font-size: 14px;
@@ -161,6 +154,19 @@ $light_color: #f6f6f6;
161
154
  }
162
155
  }
163
156
 
157
+ .uploads {
158
+ padding-top: 20px;
159
+ .file {
160
+ margin-bottom: 3px;
161
+ .fa {
162
+ margin-right: 3px;
163
+ }
164
+ a {
165
+ color: darken($light_color, 20%);
166
+ }
167
+ }
168
+ }
169
+
164
170
  .btn {
165
171
  display: inline-block;
166
172
  padding: 8px 13px;
@@ -212,6 +218,22 @@ $light_color: #f6f6f6;
212
218
  margin-right: 5px;
213
219
  }
214
220
  }
221
+ .beside {
222
+ display: inline-block;
223
+ margin-left: 10px;
224
+ }
225
+ }
226
+ }
227
+
228
+ .add-something {
229
+ padding-top: 100px;
230
+ .title {
231
+ font-size: 20px;
232
+ margin-bottom: 5px;
233
+ }
234
+ .description {
235
+ color: darken($light_color, 20%);
236
+ margin-bottom: 20px;
215
237
  }
216
238
  }
217
239
  }
@@ -0,0 +1,11 @@
1
+ require_dependency "radesk/application_controller"
2
+
3
+ module Radesk
4
+ module Admin
5
+ class ActivitiesController < AdminController
6
+ def index
7
+ @activities = Radesk::Activity.all.order('id DESC').page(params[:page]).per(20)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ require_dependency "radesk/application_controller"
2
+
3
+ module Radesk
4
+ module Admin
5
+ class AdminController < ApplicationController
6
+ before_action :radesk_authorize_admin!
7
+ end
8
+ end
9
+ end
@@ -2,10 +2,9 @@ require_dependency "radesk/application_controller"
2
2
 
3
3
  module Radesk
4
4
  module Admin
5
- class CategoriesController < ApplicationController
5
+ class CategoriesController < AdminController
6
6
  before_action :set_category, only: [:show, :destroy, :edit, :update]
7
- before_action :radesk_authorize_admin!
8
-
7
+
9
8
  def index
10
9
  @categories = Category.all
11
10
  end
@@ -0,0 +1,18 @@
1
+ require_dependency "radesk/application_controller"
2
+
3
+ module Radesk
4
+ module Admin
5
+ class UsersController < AdminController
6
+ before_action :set_user, only: [:show]
7
+
8
+ def show
9
+ @tickets = Radesk::Ticket.where(:user_id => @user).page(params[:page]).per(20)
10
+ end
11
+
12
+ private
13
+ def set_user
14
+ @user = Radesk.user_class_name.constantize.find(params[:id])
15
+ end
16
+ end
17
+ end
18
+ end
@@ -2,19 +2,20 @@ require_dependency "radesk/application_controller"
2
2
 
3
3
  module Radesk
4
4
  class AnswersController < ApplicationController
5
- before_action :set_answer, only: [:edit, :update, :destroy]
6
- before_action :check_access, only: [:edit, :update, :destroy]
5
+ include Radesk::ActivitiesHelper
6
+
7
7
  before_action :radesk_authorize!
8
+ before_action :set_answer, only: [:edit, :update, :destroy]
9
+ before_filter -> { radesk_check_access(@answer) }, only: [:edit, :update, :destroy]
8
10
 
9
11
  def create
10
12
  @answer = Answer.new(answer_params)
11
- @answer.user_id = send(Radesk.current_user_method_name).id
13
+ @answer.user_id = radesk_current_user.id
12
14
  @answer.ticket_id = params[:ticket_id]
13
15
 
14
16
  if @answer.save
15
- if @answer.user.id != @answer.ticket.user.id && !@answer.user.radesk_admin?
16
- UserMailer.new_answer(@answer.ticket.id).deliver
17
- end
17
+ UserMailer.new_answer(@answer).deliver_now
18
+ add_activity(@answer, 'create')
18
19
  redirect_to @answer.ticket, notice: 'Answer was successfully created.'
19
20
  else
20
21
  redirect_to :back, notice: @answer.errors.full_messages.first
@@ -26,6 +27,7 @@ module Radesk
26
27
 
27
28
  def update
28
29
  if @answer.update(answer_params)
30
+ add_activity(@answer, 'update')
29
31
  redirect_to @answer.ticket, notice: 'Answer was successfully updated.'
30
32
  else
31
33
  render :edit
@@ -42,12 +44,8 @@ module Radesk
42
44
  @answer = Answer.find(params[:id])
43
45
  end
44
46
 
45
- def check_access
46
- redirect_to :back unless @answer.has_access?(radesk_current_user)
47
- end
48
-
49
47
  def answer_params
50
- params.require(:answer).permit(:message, :private)
48
+ params.require(:answer).permit(:message, :private, :uploads_attributes => [:id, :file])
51
49
  end
52
50
  end
53
51
  end
@@ -6,11 +6,15 @@ module Radesk
6
6
  helper_method :radesk_current_user
7
7
 
8
8
  def radesk_authorize!
9
- redirect_to '/' if !(radesk_current_user)
9
+ redirect_to Radesk.sign_in_path if !(radesk_current_user)
10
10
  end
11
11
 
12
12
  def radesk_authorize_admin!
13
13
  redirect_to root_path if !(radesk_current_user.radesk_admin?)
14
14
  end
15
+
16
+ def radesk_check_access(object)
17
+ redirect_to root_path unless object.has_access?(radesk_current_user)
18
+ end
15
19
  end
16
20
  end
@@ -2,13 +2,20 @@ require_dependency "radesk/application_controller"
2
2
 
3
3
  module Radesk
4
4
  class TicketsController < ApplicationController
5
- before_action :set_ticket, only: [:show, :edit, :update, :destroy, :open, :close]
6
- before_action :check_access, only: [:show, :edit, :update, :destroy]
5
+ include Radesk::ActivitiesHelper
6
+
7
7
  before_action :radesk_authorize!
8
+ before_action :set_ticket, only: [:show, :edit, :update, :destroy, :open, :close]
9
+ before_action :set_tickets, only: [:index, :category]
10
+ before_filter -> { radesk_check_access(@ticket) }, only: [:show, :edit, :update, :destroy, :open, :close]
8
11
 
9
12
  def index
10
- @tickets = Ticket.includes(Radesk.user_class_name.downcase.to_sym).all.page(params[:page]).per(20)
11
- @tickets = @tickets.where(:user_id => radesk_current_user.id) unless radesk_current_user.try(:radesk_admin?)
13
+ end
14
+
15
+ def category
16
+ @category = Radesk::Category.find(params[:id])
17
+ @tickets = @tickets.where(:category_id => @category)
18
+ render :index
12
19
  end
13
20
 
14
21
  def show
@@ -20,13 +27,16 @@ module Radesk
20
27
 
21
28
  def new
22
29
  @ticket = Ticket.new
30
+ @ticket.answers.build
23
31
  end
24
32
 
25
33
  def create
26
34
  @ticket = Ticket.new(ticket_params)
27
35
  @ticket.user_id = send(Radesk.current_user_method_name).id
36
+ @ticket.answers.first.user = radesk_current_user
28
37
 
29
38
  if @ticket.save
39
+ add_activity(@ticket, 'create')
30
40
  redirect_to @ticket, notice: 'Ticket was successfully created.'
31
41
  else
32
42
  render :new
@@ -38,6 +48,7 @@ module Radesk
38
48
 
39
49
  def update
40
50
  if @ticket.update(ticket_params)
51
+ add_activity(@ticket, 'update')
41
52
  redirect_to @ticket, notice: 'Ticket was successfully updated.'
42
53
  else
43
54
  render :edit
@@ -45,21 +56,19 @@ module Radesk
45
56
  end
46
57
 
47
58
  def destroy
48
- if radesk_current_user.try(:radesk_admin?)
49
- @ticket.destroy
50
- redirect_to tickets_url, notice: 'Ticket was successfully destroyed.'
51
- else
52
- redirect_to :back
53
- end
59
+ @ticket.destroy
60
+ redirect_to tickets_url, notice: 'Ticket was successfully destroyed.'
54
61
  end
55
62
 
56
63
  def open
57
64
  @ticket.update(:closed => false)
65
+ add_activity(@ticket, 'open')
58
66
  render 'update_status'
59
67
  end
60
68
 
61
69
  def close
62
70
  @ticket.update(:closed => true)
71
+ add_activity(@ticket, 'close')
63
72
  render 'update_status'
64
73
  end
65
74
 
@@ -68,12 +77,13 @@ module Radesk
68
77
  @ticket = Ticket.find(params[:id])
69
78
  end
70
79
 
71
- def check_access
72
- redirect_to :back unless @ticket.has_access?(radesk_current_user)
80
+ def set_tickets
81
+ @tickets = Ticket.includes(Radesk.user_class_name.downcase.to_sym).all.page(params[:page]).per(20)
82
+ @tickets = @tickets.where(:user_id => radesk_current_user.id) unless radesk_current_user.try(:radesk_admin?)
73
83
  end
74
84
 
75
85
  def ticket_params
76
- params.require(:ticket).permit(:title, :message, :closed, :category_id)
86
+ params.require(:ticket).permit(:title, :message, :closed, :category_id, :answers_attributes => [:id, :message])
77
87
  end
78
88
  end
79
89
  end
@@ -0,0 +1,18 @@
1
+ require_dependency "radesk/application_controller"
2
+
3
+ module Radesk
4
+ class UploadsController < ApplicationController
5
+ before_action :radesk_authorize!
6
+ before_action :set_upload, only: [:destroy]
7
+ before_filter -> { radesk_check_access(@upload.answer) }, only: [:destroy]
8
+
9
+ def destroy
10
+ @upload.destroy
11
+ end
12
+
13
+ private
14
+ def set_upload
15
+ @upload = Radesk::Upload.find(params[:id])
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,11 @@
1
+ module Radesk
2
+ module ActivitiesHelper
3
+ def add_activity(trackable, action = params[:action])
4
+ Radesk::Activity.create(:user_id => radesk_current_user, :action => action, :trackable => trackable)
5
+ end
6
+
7
+ def destroy_activities(trackable)
8
+ Radesk::Activity.where(:trackable_id => trackable.id).destroy_all
9
+ end
10
+ end
11
+ end
@@ -1,4 +1,13 @@
1
1
  module Radesk
2
2
  module ApplicationHelper
3
+ def link_to_add_fields(name = nil, f, association, partial, &block)
4
+ new_object = f.object.send(association).klass.new
5
+ fields = f.fields_for association, new_object do |builder|
6
+ render :partial => "radesk/#{partial}", :locals => { :f => builder }
7
+ end
8
+ link_to '#', class: "add_fields", data: { id: new_object.object_id, fields: fields.gsub("\n", "") } do
9
+ name || capture(&block)
10
+ end
11
+ end
3
12
  end
4
13
  end
@@ -2,10 +2,11 @@ module Radesk
2
2
  class UserMailer < ActionMailer::Base
3
3
  default :from => Radesk.email_from
4
4
 
5
- def new_answer(ticket_id)
6
- @ticket = Radesk::Ticket.find(ticket_id)
7
-
8
- mail(:to => @ticket.user.email, :subject => 'New answer')
5
+ def new_answer(answer)
6
+ @ticket = answer.ticket
7
+ if answer.user.id != answer.ticket.user.id && !answer.private?
8
+ mail(:to => @ticket.user.email, :subject => 'New answer')
9
+ end
9
10
  end
10
11
  end
11
12
  end
@@ -0,0 +1,6 @@
1
+ module Radesk
2
+ class Activity < ActiveRecord::Base
3
+ belongs_to :user, :class_name => Radesk.user_class_name.to_s, :foreign_key => :user_id
4
+ belongs_to :trackable, polymorphic: true
5
+ end
6
+ end
@@ -1,14 +1,18 @@
1
1
  module Radesk
2
2
  class Answer < ActiveRecord::Base
3
+ include Radesk::Concerns::Access
4
+ include Radesk::ActivitiesHelper
5
+
3
6
  belongs_to :user, :class_name => Radesk.user_class_name.to_s, :foreign_key => :user_id
4
7
  belongs_to :ticket
8
+ has_many :uploads
9
+
10
+ accepts_nested_attributes_for :uploads
5
11
 
6
12
  validates_presence_of :message
7
13
 
8
14
  scope :without_private, -> { where(:private => false) }
9
15
 
10
- def has_access?(user)
11
- self.user_id == user.id || user.try(:radesk_admin?)
12
- end
16
+ after_destroy { |answer| destroy_activities(answer) }
13
17
  end
14
18
  end
@@ -0,0 +1,9 @@
1
+ module Radesk
2
+ module Concerns
3
+ module Access
4
+ def has_access?(user)
5
+ self.user_id == user.id || user.try(:radesk_admin?)
6
+ end
7
+ end
8
+ end
9
+ end
@@ -1,15 +1,18 @@
1
1
  module Radesk
2
2
  class Ticket < ActiveRecord::Base
3
+ include Radesk::Concerns::Access
4
+ include Radesk::ActivitiesHelper
5
+
3
6
  belongs_to :user, :class_name => Radesk.user_class_name.to_s, :foreign_key => :user_id
4
7
  belongs_to :category
5
- has_many :answers
8
+ has_many :answers, :dependent => :destroy
9
+
10
+ accepts_nested_attributes_for :answers
6
11
 
7
- validates_presence_of :title, :message
12
+ validates_presence_of :title
8
13
 
9
14
  default_scope { order('closed ASC').order('id DESC') }
10
15
 
11
- def has_access?(user)
12
- self.user_id == user.id || user.try(:radesk_admin?)
13
- end
16
+ after_destroy { |ticket| destroy_activities(ticket) }
14
17
  end
15
18
  end