dorsale 3.5.2 → 3.6.0

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.
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