dorsale 3.5.2 → 3.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5 -0
  3. data/Rakefile +12 -13
  4. data/app/assets/javascripts/dorsale/common/comments.coffee +7 -7
  5. data/app/assets/stylesheets/dorsale/common/comments.sass +1 -1
  6. data/app/assets/stylesheets/dorsale/engines/customer_vault.sass +22 -0
  7. data/app/assets/stylesheets/dorsale/engines/flyboy.sass +16 -0
  8. data/app/controllers/dorsale/comments_controller.rb +8 -1
  9. data/app/controllers/dorsale/customer_vault/people_controller.rb +12 -7
  10. data/app/controllers/dorsale/flyboy/tasks_controller.rb +6 -4
  11. data/app/helpers/dorsale/comments_helper.rb +7 -4
  12. data/app/helpers/dorsale/flyboy/application_helper.rb +49 -4
  13. data/app/helpers/dorsale/users_helper.rb +4 -0
  14. data/app/models/dorsale/comment.rb +1 -1
  15. data/app/models/dorsale/customer_vault/corporation.rb +2 -2
  16. data/app/models/dorsale/customer_vault/event.rb +28 -0
  17. data/app/models/dorsale/customer_vault/individual.rb +2 -2
  18. data/app/models/dorsale/customer_vault/person.rb +13 -0
  19. data/app/models/dorsale/flyboy/task.rb +45 -35
  20. data/app/policies/dorsale/customer_vault/event_policy_helper.rb +4 -0
  21. data/app/policies/dorsale/customer_vault/link_policy_helper.rb +1 -0
  22. data/app/policies/dorsale/flyboy/task_policy_helper.rb +1 -1
  23. data/app/policies/dorsale/policy_checker.rb +1 -0
  24. data/app/services/dorsale/flyboy/task/snoozer.rb +49 -0
  25. data/app/views/dorsale/comments/_comment.html.slim +3 -3
  26. data/app/views/dorsale/comments/_comments.html.slim +1 -1
  27. data/app/views/dorsale/comments/_form.html.slim +5 -2
  28. data/app/views/dorsale/comments/_list.html.slim +1 -1
  29. data/app/views/dorsale/customer_vault/events/_event.html.slim +24 -0
  30. data/app/views/dorsale/customer_vault/events/_list.html.slim +6 -0
  31. data/app/views/dorsale/customer_vault/people/activity.slim +3 -4
  32. data/app/views/dorsale/customer_vault/people/show.html.slim +2 -1
  33. data/app/views/dorsale/flyboy/tasks/_context.html.slim +1 -1
  34. data/app/views/dorsale/flyboy/tasks/_form.html.slim +10 -6
  35. data/app/views/dorsale/flyboy/tasks/_reminder_fields.html.slim +36 -0
  36. data/app/views/dorsale/flyboy/tasks/_term_fields.html.slim +20 -0
  37. data/config/locales/customer_vault.en.yml +10 -0
  38. data/config/locales/customer_vault.fr.yml +10 -0
  39. data/config/locales/flyboy.en.yml +21 -0
  40. data/config/locales/flyboy.fr.yml +21 -0
  41. data/db/migrate/20170413082819_dorsale_flyboy_tasks_new_reminder.rb +9 -0
  42. data/db/migrate/20170418070730_create_dorsale_customer_vault_events.rb +31 -0
  43. data/features/customer_vault_corporations.feature +1 -1
  44. data/features/flyboy_tasks.feature +34 -0
  45. data/features/step_definitions/common_steps.rb +25 -0
  46. data/features/step_definitions/customer_vault_corporations_steps.rb +7 -6
  47. data/features/step_definitions/flyboy_tasks_steps.rb +26 -18
  48. data/lib/dorsale/version.rb +1 -1
  49. data/spec/controllers/dorsale/comments_controller_spec.rb +15 -1
  50. data/spec/controllers/dorsale/customer_vault/people_controller_spec.rb +45 -7
  51. data/spec/controllers/dorsale/flyboy/tasks_controller_spec.rb +39 -44
  52. data/spec/factories/customer_vault_event.rb +7 -0
  53. data/spec/factories/dorsale_comments.rb +6 -0
  54. data/spec/factories/flyboy_tasks.rb +0 -2
  55. data/spec/helpers/dorsale/flyboy/application_helper_spec.rb +4 -4
  56. data/spec/models/dorsale/comment_spec.rb +12 -3
  57. data/spec/models/dorsale/customer_vault/corporation_spec.rb +1 -0
  58. data/spec/models/dorsale/customer_vault/event_spec.rb +23 -0
  59. data/spec/models/dorsale/customer_vault/individual_spec.rb +1 -0
  60. data/spec/models/dorsale/customer_vault/person_spec.rb +7 -7
  61. data/spec/models/dorsale/flyboy/task_spec.rb +69 -85
  62. data/spec/services/dorsale/flyboy/task/snoozer_spec.rb +117 -0
  63. metadata +18 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 91e5341eb8cfffe13a70e3a8ee82da977139c0a2
4
- data.tar.gz: 1f9010dd33f9a3e4ed88e3fea11ce31dd530c36d
3
+ metadata.gz: aecc5956667a15cbe2f9141ba8b3f4fb10166639
4
+ data.tar.gz: 73a2f249fc10462d3ee1e1a74825f8d66833c85e
5
5
  SHA512:
6
- metadata.gz: 7ab4ad3cfed29a2ca2a86fde75db9ddf1a1d2bf038bc64e8b790c5afa3896f59c7f9f6e044eee91aa92513e1cf47c3642cbcd784a0e1a9c38d8e0ec31d7936d6
7
- data.tar.gz: 8b4980ddc931a658e670d68a7834ef3bf76fd0510a1936e9c5fb292fcc93e8deafd18ca197a993d474b4d61cde6aa0c76c83b45f28063dad89a04d4792876926
6
+ metadata.gz: bb9dcf6ade68da4dd3fc4248c84d57f890e32e64923892197e3a0f39f5141ea65ccc06992e01d13217787989f1db51a22d722c3d7a529e029aff8a3aa040b914
7
+ data.tar.gz: 6ff17588e48f01f0d36fb51d4f762b682ead1d92d7c70ab57967ee3b050c58613e30d253ecc48f58be7dbe63aefef5353e69dcfd81131ac34749900dfeacac87
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.6.0
4
+
5
+ - Task term and reminder improvements
6
+ - Add CustomerVault events
7
+
3
8
  ## 3.5.2
4
9
 
5
10
  - Comments improvements
data/Rakefile CHANGED
@@ -10,7 +10,7 @@ RDoc::Task.new(:rdoc) do |rdoc|
10
10
  rdoc.rdoc_dir = 'rdoc'
11
11
  rdoc.title = 'Dorsale'
12
12
  rdoc.options << '--line-numbers'
13
- rdoc.rdoc_files.include('README.rdoc')
13
+ rdoc.rdoc_files.include('README.md')
14
14
  rdoc.rdoc_files.include('lib/**/*.rb')
15
15
  end
16
16
 
@@ -18,21 +18,20 @@ APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
18
18
  load 'rails/tasks/engine.rake'
19
19
 
20
20
 
21
+ load 'rails/tasks/statistics.rake'
21
22
 
22
- Bundler::GemHelper.install_tasks
23
23
 
24
- Dir[File.join(File.dirname(__FILE__), 'tasks/**/*.rake')].each {|f| load f }
25
24
 
25
+ require 'bundler/gem_tasks'
26
26
 
27
- if Rails.env.test?
28
- require 'rspec/core'
29
- require 'rspec/core/rake_task'
27
+ require 'rake/testtask'
28
+
29
+ Rake::TestTask.new(:test) do |t|
30
+ t.libs << 'lib'
31
+ t.libs << 'test'
32
+ t.pattern = 'test/**/*_test.rb'
33
+ t.verbose = false
34
+ end
30
35
 
31
- desc "Run all specs in spec directory (excluding plugin specs)"
32
- RSpec::Core::RakeTask.new(:spec => 'app:db:test:prepare')
33
36
 
34
- task :default => :spec
35
- else
36
- require File.expand_path('../spec/dummy/config/application', __FILE__)
37
- Rails.application.load_tasks
38
- end
37
+ task default: :test
@@ -7,17 +7,17 @@ window.dorsaleComments =
7
7
  dorsaleComments.setupShowMoreLinks()
8
8
 
9
9
  setupCreateForm: ->
10
- $("#dorsale-comments").on "ajax:success", "form[id*=new]", (e, data) ->
10
+ $(document).on "ajax:success", "form#new-dorsale-comment", (e, data) ->
11
11
  if data.length
12
- $(this).find("textarea").val("")
13
- $("#dorsale-comments-list").prepend(data)
12
+ $(this).find("#comment_title, #comment_text").val("")
13
+ $(".dorsale-comments-list").prepend(data)
14
14
 
15
15
  setupEditForm: ->
16
- $("#dorsale-comments-list").on "ajax:success", "form[id*=edit]", (e, data) ->
16
+ $(document).on "ajax:success", "form#edit-dorsale-comment", (e, data) ->
17
17
  $(this).replaceWith(data)
18
18
 
19
19
  setupEditButtons: ->
20
- $("#dorsale-comments-list").on "click", "[href$=edit]", ->
20
+ $(document).on "click", "a.edit-dorsale-comment", ->
21
21
  container = $(this).parents(".comment")
22
22
  url = this.href
23
23
 
@@ -30,12 +30,12 @@ window.dorsaleComments =
30
30
  return false
31
31
 
32
32
  setupDeleteButtons: ->
33
- $("#dorsale-comments-list").on "ajax:success", "[data-method=delete]", ->
33
+ $(document).on "ajax:success", ".delete-dorsale-comment", ->
34
34
  $(this).parents(".comment").fadeOut ->
35
35
  $(this).remove()
36
36
 
37
37
  setupShowMoreLinks: ->
38
- $("#dorsale-comments").on "click", ".comment-show_more", ->
38
+ $(document).on "click", ".comment-show_more", ->
39
39
  $(this).parents(".comment-text-truncated").remove()
40
40
  return false
41
41
 
@@ -1,4 +1,4 @@
1
- #dorsale-comments-list
1
+ .dorsale-comments-list
2
2
  margin: 1em 0
3
3
 
4
4
  .comment
@@ -27,3 +27,25 @@
27
27
  right: 0
28
28
  width: 33.33%
29
29
  margin: 0
30
+
31
+ .event
32
+ @extend .well
33
+ box-shadow: none
34
+ padding: 0.5em
35
+ margin: 0.75em 0
36
+
37
+ .avatar
38
+ float: left
39
+ margin-right: 15px
40
+ height: 50px
41
+ width: 50px
42
+
43
+ .event-infos
44
+ font-size: 80%
45
+ @extend .text-muted
46
+
47
+ .event-person
48
+ font-weight: bold
49
+
50
+ p.event-text
51
+ margin: 1rem 0 0 65px
@@ -59,6 +59,22 @@
59
59
  th.task-term,
60
60
  text-align: right
61
61
 
62
+ .task_reminder_fields,
63
+ .task_term_fields,
64
+ display: flex
65
+
66
+ > div
67
+ margin-right: 15px
68
+
69
+ label
70
+ line-height: 2.5em
71
+
72
+ input, select
73
+ width: auto
74
+
75
+ input[id$=duration]
76
+ width: 5em
77
+
62
78
  @media print
63
79
  #new_task_comment_tr
64
80
  display: none
@@ -13,6 +13,7 @@ class Dorsale::CommentsController < ::Dorsale::ApplicationController
13
13
  authorize @comment, :create?
14
14
 
15
15
  if @comment.save
16
+ notify_attachable!(:create)
16
17
  render_comment
17
18
  else
18
19
  render_nothing
@@ -27,6 +28,7 @@ class Dorsale::CommentsController < ::Dorsale::ApplicationController
27
28
  authorize @comment, :update?
28
29
 
29
30
  if @comment.update(comment_params_for_update)
31
+ notify_attachable!(:update)
30
32
  render_comment
31
33
  else
32
34
  render_form
@@ -36,7 +38,8 @@ class Dorsale::CommentsController < ::Dorsale::ApplicationController
36
38
  def destroy
37
39
  authorize @comment, :delete?
38
40
 
39
- @comment.destroy
41
+ @comment.destroy!
42
+ notify_attachable!(:delete)
40
43
 
41
44
  render_nothing
42
45
  end
@@ -109,4 +112,8 @@ class Dorsale::CommentsController < ::Dorsale::ApplicationController
109
112
  def comment_params_for_update
110
113
  comment_params
111
114
  end
115
+
116
+ def notify_attachable!(action)
117
+ @comment.commentable.try(:receive_comment_notification, @comment, action)
118
+ end
112
119
  end
@@ -32,14 +32,9 @@ class Dorsale::CustomerVault::PeopleController < ::Dorsale::CustomerVault::Appli
32
32
  def activity
33
33
  authorize model, :list?
34
34
 
35
- @people ||= scope
35
+ @events ||= policy_scope(::Dorsale::CustomerVault::Event)
36
36
 
37
- @comments ||= policy_scope(::Dorsale::Comment)
38
- .where("commentable_type LIKE ?", "%CustomerVault%")
39
- .order("created_at DESC, id DESC")
40
- .preload(:commentable, :author)
41
-
42
- @comments = @comments.page(params[:page]).per(50)
37
+ @events = @events.page(params[:page]).per(50)
43
38
  end
44
39
 
45
40
  def new
@@ -62,6 +57,7 @@ class Dorsale::CustomerVault::PeopleController < ::Dorsale::CustomerVault::Appli
62
57
  @person ||= scope.new(person_params_for_create)
63
58
 
64
59
  if @person.save
60
+ generate_event!("create")
65
61
  flash[:notice] = t("messages.#{person_type.to_s.pluralize}.create_ok")
66
62
  redirect_to back_url
67
63
  else
@@ -91,6 +87,7 @@ class Dorsale::CustomerVault::PeopleController < ::Dorsale::CustomerVault::Appli
91
87
  authorize @person, :update?
92
88
 
93
89
  if @person.update(person_params_for_update)
90
+ generate_event!("update")
94
91
  flash[:notice] = t("messages.#{person_type.to_s.pluralize}.update_ok")
95
92
  redirect_to back_url
96
93
  else
@@ -207,4 +204,12 @@ class Dorsale::CustomerVault::PeopleController < ::Dorsale::CustomerVault::Appli
207
204
  person_params
208
205
  end
209
206
 
207
+ def generate_event!(action)
208
+ policy_scope(::Dorsale::CustomerVault::Event).create!(
209
+ :author => current_user,
210
+ :person => @person,
211
+ :action => action,
212
+ )
213
+ end
214
+
210
215
  end
@@ -55,6 +55,7 @@ class Dorsale::Flyboy::TasksController < ::Dorsale::Flyboy::ApplicationControlle
55
55
 
56
56
  def new
57
57
  @task ||= scope.new
58
+ @task.owner ||= current_user
58
59
  @task.taskable_guid = params[:taskable_guid]
59
60
 
60
61
  set_owners
@@ -129,9 +130,7 @@ class Dorsale::Flyboy::TasksController < ::Dorsale::Flyboy::ApplicationControlle
129
130
  def snooze
130
131
  authorize @task, :snooze?
131
132
 
132
- @task.snooze
133
-
134
- if @task.save
133
+ if @task.snoozer.snooze
135
134
  flash[:success] = t("messages.tasks.snooze_ok")
136
135
  else
137
136
  flash[:danger] = t("messages.tasks.snooze_error")
@@ -183,7 +182,10 @@ class Dorsale::Flyboy::TasksController < ::Dorsale::Flyboy::ApplicationControlle
183
182
  :description,
184
183
  :progress,
185
184
  :term,
186
- :reminder,
185
+ :reminder_type,
186
+ :reminder_date,
187
+ :reminder_duration,
188
+ :reminder_unit,
187
189
  :owner_guid,
188
190
  ]
189
191
  end
@@ -1,8 +1,7 @@
1
1
  module Dorsale::CommentsHelper
2
- def comments_for(commentable, comments = nil)
3
- comments = ::Dorsale::Comment.where(commentable: commentable) if comments.nil?
4
- comments = policy_scope(comments).preload(:commentable, :author)
5
- new_comment = policy_scope(comments).new(commentable: commentable, author: current_user)
2
+ def comments_for(commentable)
3
+ comments = policy_scope(::Dorsale::Comment).where(commentable: commentable)
4
+ new_comment = new_comment_for(commentable)
6
5
 
7
6
  render(
8
7
  :partial => "dorsale/comments/comments",
@@ -13,6 +12,10 @@ module Dorsale::CommentsHelper
13
12
  )
14
13
  end
15
14
 
15
+ def new_comment_for(commentable)
16
+ policy_scope(Dorsale::Comment).new(commentable: commentable, author: current_user)
17
+ end
18
+
16
19
  def truncate_comments_in_this_page?
17
20
  controller_name == "people"
18
21
  end
@@ -26,10 +26,11 @@ module Dorsale::Flyboy::ApplicationHelper
26
26
  end
27
27
 
28
28
  def task_color(task)
29
- return "finished" if task.done
30
- return "ontime" if task.reminder > Time.zone.now.to_date
31
- return "onalert" if task.term < Time.zone.now.to_date
32
- return "onwarning"
29
+ return "finished" if task.done
30
+ return "onalert" if task.term < Time.zone.now.to_date
31
+ return "onwarning" if task.reminder_date && task.reminder_date < Time.zone.now.to_date
32
+ return "ontime"
33
+
33
34
  end
34
35
 
35
36
  def flyboy_status_for_filters_select
@@ -44,4 +45,48 @@ module Dorsale::Flyboy::ApplicationHelper
44
45
  policy_scope(User)
45
46
  end
46
47
 
48
+ def flyboy_reminder_types_for_select
49
+ {
50
+ Dorsale::Flyboy::Task.t("reminder_type.none") => "",
51
+ Dorsale::Flyboy::Task.t("reminder_type.duration") => "duration",
52
+ Dorsale::Flyboy::Task.t("reminder_type.custom") => "custom",
53
+ }
54
+ end
55
+
56
+ def flyboy_reminder_type_units_for_select
57
+ {
58
+ Dorsale::Flyboy::Task.t("reminder_unit.days") => "days",
59
+ Dorsale::Flyboy::Task.t("reminder_unit.weeks") => "weeks",
60
+ Dorsale::Flyboy::Task.t("reminder_unit.months") => "months",
61
+ }
62
+ end
63
+
64
+ def task_term_values_for_select
65
+ today = Time.zone.now.to_date
66
+ tomorrow = (Time.zone.now + 1.day).to_date
67
+ this_week = Time.zone.now.to_date.end_of_week
68
+ next_week = (Time.zone.now + 1.week).to_date.end_of_week
69
+
70
+ # Because today or tomorrow can be equal to this week
71
+ if @task.term == today
72
+ is_today = true
73
+ elsif @task.term == tomorrow
74
+ is_tomorrow = true
75
+ elsif @task.term == this_week
76
+ is_this_week = true
77
+ elsif @task.term == next_week
78
+ is_next_week = true
79
+ else
80
+ is_custom = true
81
+ end
82
+
83
+ [
84
+ [Dorsale::Flyboy::Task.t("term_value.today"), today.to_s, {selected: is_today}],
85
+ [Dorsale::Flyboy::Task.t("term_value.tomorrow"), tomorrow.to_s, {selected: is_tomorrow}],
86
+ [Dorsale::Flyboy::Task.t("term_value.this_week"), this_week.to_s, {selected: is_this_week}],
87
+ [Dorsale::Flyboy::Task.t("term_value.next_week"), next_week.to_s, {selected: is_next_week}],
88
+ [Dorsale::Flyboy::Task.t("term_value.custom"), :custom, {selected: is_custom}],
89
+ ]
90
+ end
91
+
47
92
  end
@@ -8,4 +8,8 @@ module Dorsale::UsersHelper
8
8
  :title => user.to_s,
9
9
  )
10
10
  end
11
+
12
+ def default_avatar_url
13
+ "https://www.gravatar.com/avatar/?default=mm&size=200"
14
+ end
11
15
  end
@@ -10,7 +10,7 @@ class Dorsale::Comment < ::Dorsale::ApplicationRecord
10
10
  default_scope -> {
11
11
  all
12
12
  .order(created_at: :desc, id: :desc)
13
- .preload(:author)
13
+ .preload(:author, :commentable)
14
14
  }
15
15
 
16
16
  private
@@ -5,8 +5,8 @@ class Dorsale::CustomerVault::Corporation < Dorsale::CustomerVault::Person
5
5
  validates :corporation_name, presence: true
6
6
  has_many :individuals
7
7
 
8
- def self_and_related_comments
9
- ::Dorsale::Comment.where(commentable: [self] + individuals)
8
+ def self_and_related_events
9
+ ::Dorsale::CustomerVault::Event.where(person: [self] + individuals)
10
10
  end
11
11
 
12
12
  def name
@@ -0,0 +1,28 @@
1
+ class Dorsale::CustomerVault::Event < ::Dorsale::ApplicationRecord
2
+ self.table_name = :dorsale_customer_vault_events
3
+
4
+ ACTIONS = %w(create update comment)
5
+
6
+ belongs_to :author, class_name: User
7
+ belongs_to :person, class_name: Dorsale::CustomerVault::Person
8
+ belongs_to :comment, class_name: Dorsale::Comment
9
+
10
+ validates :author, presence: true
11
+ validates :person, presence: true
12
+ validates :action, presence: true, inclusion: {in: ACTIONS}
13
+ validates :comment, presence: true, if: proc { action == "comment" }
14
+
15
+ default_scope -> {
16
+ all
17
+ .order(created_at: :desc, id: :desc)
18
+ .preload(:author, :person, :comment)
19
+ }
20
+
21
+ def date
22
+ created_at.try(:to_date)
23
+ end
24
+
25
+ def text
26
+ t("text.#{action}")
27
+ end
28
+ end
@@ -6,8 +6,8 @@ class Dorsale::CustomerVault::Individual < Dorsale::CustomerVault::Person
6
6
  validates :last_name, presence: true
7
7
  belongs_to :corporation
8
8
 
9
- def self_and_related_comments
10
- comments
9
+ def self_and_related_events
10
+ events
11
11
  end
12
12
 
13
13
  def name
@@ -23,6 +23,7 @@ class Dorsale::CustomerVault::Person < ::Dorsale::ApplicationRecord
23
23
  has_many :comments, class_name: ::Dorsale::Comment, as: :commentable, dependent: :destroy
24
24
  has_one :address, class_name: ::Dorsale::Address, as: :addressable, inverse_of: :addressable, dependent: :destroy
25
25
  has_many :tasks, class_name: ::Dorsale::Flyboy::Task, as: :taskable, dependent: :destroy
26
+ has_many :events, dependent: :destroy
26
27
  has_many :invoices, class_name: ::Dorsale::BillingMachine::Invoice, as: :customer
27
28
  accepts_nested_attributes_for :address, allow_destroy: true
28
29
 
@@ -66,4 +67,16 @@ class Dorsale::CustomerVault::Person < ::Dorsale::ApplicationRecord
66
67
  links.each(&:destroy!)
67
68
  end
68
69
 
70
+ def receive_comment_notification(comment, action)
71
+ if action == :create
72
+ scope = Pundit.policy_scope!(comment.author, ::Dorsale::CustomerVault::Event)
73
+ scope.create!(
74
+ :author => comment.author,
75
+ :person => self,
76
+ :comment => comment,
77
+ :action => "comment",
78
+ )
79
+ end
80
+ end
81
+
69
82
  end