decidim-time_tracker 0.3

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 (134) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE-AGPLv3.txt +661 -0
  3. data/README.md +174 -0
  4. data/Rakefile +40 -0
  5. data/app/assets/config/admin/decidim_time_tracker_manifest.css +2 -0
  6. data/app/assets/config/admin/decidim_time_tracker_manifest.js +1 -0
  7. data/app/assets/config/decidim_time_tracker_manifest.css +3 -0
  8. data/app/assets/config/decidim_time_tracker_manifest.js +1 -0
  9. data/app/assets/images/decidim/time_tracker/icon.svg +1 -0
  10. data/app/assets/javascripts/decidim/time_tracker/activity_ui.js.es6 +112 -0
  11. data/app/assets/javascripts/decidim/time_tracker/admin/assignations.js.es6 +35 -0
  12. data/app/assets/javascripts/decidim/time_tracker/reports/reports.js.es6 +19 -0
  13. data/app/assets/javascripts/decidim/time_tracker/time_tracker.js.es6 +82 -0
  14. data/app/assets/javascripts/decidim/time_tracker/timer_api.js.es6 +55 -0
  15. data/app/assets/stylesheets/decidim/time_tracker/_variables.scss +1 -0
  16. data/app/assets/stylesheets/decidim/time_tracker/admin/time_tracker.scss +59 -0
  17. data/app/assets/stylesheets/decidim/time_tracker/time_tracker.scss +118 -0
  18. data/app/cells/decidim/time_tracker/milestone/show.erb +42 -0
  19. data/app/cells/decidim/time_tracker/milestone_cell.rb +54 -0
  20. data/app/commands/decidim/time_tracker/admin/create_activity.rb +39 -0
  21. data/app/commands/decidim/time_tracker/admin/create_assignation.rb +75 -0
  22. data/app/commands/decidim/time_tracker/admin/create_task.rb +33 -0
  23. data/app/commands/decidim/time_tracker/admin/create_time_tracker.rb +76 -0
  24. data/app/commands/decidim/time_tracker/admin/destroy_activity.rb +43 -0
  25. data/app/commands/decidim/time_tracker/admin/destroy_assignation.rb +43 -0
  26. data/app/commands/decidim/time_tracker/admin/destroy_task.rb +43 -0
  27. data/app/commands/decidim/time_tracker/admin/export_time_tracker.rb +150 -0
  28. data/app/commands/decidim/time_tracker/admin/update_activity.rb +49 -0
  29. data/app/commands/decidim/time_tracker/admin/update_assignation.rb +42 -0
  30. data/app/commands/decidim/time_tracker/admin/update_task.rb +44 -0
  31. data/app/commands/decidim/time_tracker/create_milestone.rb +57 -0
  32. data/app/commands/decidim/time_tracker/create_request_assignation.rb +39 -0
  33. data/app/commands/decidim/time_tracker/start_time_event.rb +104 -0
  34. data/app/commands/decidim/time_tracker/stop_last_time_event.rb +45 -0
  35. data/app/controllers/concerns/decidim/time_tracker/admin/filterable_assignations.rb +50 -0
  36. data/app/controllers/decidim/time_tracker/activity_questionnaire_controller.rb +76 -0
  37. data/app/controllers/decidim/time_tracker/admin/activities_controller.rb +82 -0
  38. data/app/controllers/decidim/time_tracker/admin/activity_questionnaire_controller.rb +52 -0
  39. data/app/controllers/decidim/time_tracker/admin/application_controller.rb +22 -0
  40. data/app/controllers/decidim/time_tracker/admin/assignations_controller.rb +84 -0
  41. data/app/controllers/decidim/time_tracker/admin/assignee_questionnaire_controller.rb +58 -0
  42. data/app/controllers/decidim/time_tracker/admin/stats_controller.rb +24 -0
  43. data/app/controllers/decidim/time_tracker/admin/tasks_controller.rb +112 -0
  44. data/app/controllers/decidim/time_tracker/admin/time_tracker_exports_controller.rb +25 -0
  45. data/app/controllers/decidim/time_tracker/application_controller.rb +24 -0
  46. data/app/controllers/decidim/time_tracker/assignations_controller.rb +38 -0
  47. data/app/controllers/decidim/time_tracker/assignee_questionnaire_controller.rb +80 -0
  48. data/app/controllers/decidim/time_tracker/milestones_controller.rb +62 -0
  49. data/app/controllers/decidim/time_tracker/reports/user_controller.rb +38 -0
  50. data/app/controllers/decidim/time_tracker/time_events_controller.rb +68 -0
  51. data/app/controllers/decidim/time_tracker/time_tracker_controller.rb +43 -0
  52. data/app/forms/decidim/time_tracker/admin/activity_form.rb +27 -0
  53. data/app/forms/decidim/time_tracker/admin/assignation_form.rb +29 -0
  54. data/app/forms/decidim/time_tracker/admin/task_form.rb +22 -0
  55. data/app/forms/decidim/time_tracker/milestone_form.rb +32 -0
  56. data/app/forms/decidim/time_tracker/time_event_form.rb +47 -0
  57. data/app/helpers/decidim/time_tracker/admin/application_helper.rb +33 -0
  58. data/app/helpers/decidim/time_tracker/application_helper.rb +95 -0
  59. data/app/jobs/decidim/time_tracker/stop_counter_job.rb +29 -0
  60. data/app/models/decidim/time_tracker/activity.rb +135 -0
  61. data/app/models/decidim/time_tracker/application_record.rb +10 -0
  62. data/app/models/decidim/time_tracker/assignation.rb +68 -0
  63. data/app/models/decidim/time_tracker/assignee.rb +29 -0
  64. data/app/models/decidim/time_tracker/assignee_data.rb +19 -0
  65. data/app/models/decidim/time_tracker/milestone.rb +27 -0
  66. data/app/models/decidim/time_tracker/task.rb +44 -0
  67. data/app/models/decidim/time_tracker/time_event.rb +62 -0
  68. data/app/models/decidim/time_tracker/time_tracker.rb +46 -0
  69. data/app/models/decidim/time_tracker/tos_acceptance.rb +16 -0
  70. data/app/permissions/decidim/time_tracker/admin/permissions.rb +69 -0
  71. data/app/permissions/decidim/time_tracker/permissions.rb +69 -0
  72. data/app/presenters/decidim/time_tracker/admin_log/activity_presenter.rb +44 -0
  73. data/app/presenters/decidim/time_tracker/admin_log/assignation_presenter.rb +48 -0
  74. data/app/presenters/decidim/time_tracker/admin_log/task_presenter.rb +46 -0
  75. data/app/presenters/decidim/time_tracker/admin_log/value_types/activity_presenter.rb +28 -0
  76. data/app/presenters/decidim/time_tracker/admin_log/value_types/time_tracker_presenter.rb +28 -0
  77. data/app/views/decidim/time_tracker/admin/_breadcrumbs.html.erb +56 -0
  78. data/app/views/decidim/time_tracker/admin/activities/_form.html.erb +41 -0
  79. data/app/views/decidim/time_tracker/admin/activities/_index.html.erb +73 -0
  80. data/app/views/decidim/time_tracker/admin/activities/edit.html.erb +5 -0
  81. data/app/views/decidim/time_tracker/admin/activities/new.html.erb +5 -0
  82. data/app/views/decidim/time_tracker/admin/assignations/_form.html.erb +30 -0
  83. data/app/views/decidim/time_tracker/admin/assignations/index.html.erb +67 -0
  84. data/app/views/decidim/time_tracker/admin/assignations/new.html.erb +9 -0
  85. data/app/views/decidim/time_tracker/admin/questionnaires/_index.html.erb +27 -0
  86. data/app/views/decidim/time_tracker/admin/questionnaires/_questionnaire.html.erb +21 -0
  87. data/app/views/decidim/time_tracker/admin/stats/index.html.erb +50 -0
  88. data/app/views/decidim/time_tracker/admin/tasks/_assignations.html.erb +60 -0
  89. data/app/views/decidim/time_tracker/admin/tasks/_form.html.erb +7 -0
  90. data/app/views/decidim/time_tracker/admin/tasks/_index.html.erb +61 -0
  91. data/app/views/decidim/time_tracker/admin/tasks/edit.html.erb +16 -0
  92. data/app/views/decidim/time_tracker/admin/tasks/index.html.erb +5 -0
  93. data/app/views/decidim/time_tracker/admin/tasks/new.html.erb +12 -0
  94. data/app/views/decidim/time_tracker/milestones/index.html.erb +60 -0
  95. data/app/views/decidim/time_tracker/reports/user/index.html.erb +41 -0
  96. data/app/views/decidim/time_tracker/time_tracker/_activity.html.erb +43 -0
  97. data/app/views/decidim/time_tracker/time_tracker/_answer_questionnaire.html.erb +7 -0
  98. data/app/views/decidim/time_tracker/time_tracker/_assignee_data.html.erb +9 -0
  99. data/app/views/decidim/time_tracker/time_tracker/_callout_status.html.erb +3 -0
  100. data/app/views/decidim/time_tracker/time_tracker/_idle_activity.html.erb +27 -0
  101. data/app/views/decidim/time_tracker/time_tracker/_milestone_form.html.erb +35 -0
  102. data/app/views/decidim/time_tracker/time_tracker/_request_activity.html.erb +22 -0
  103. data/app/views/decidim/time_tracker/time_tracker/_sign_in.html.erb +5 -0
  104. data/app/views/decidim/time_tracker/time_tracker/index.html.erb +59 -0
  105. data/config/activity_questionnaire.yml +26 -0
  106. data/config/assignee_questionnaire.yml +37 -0
  107. data/config/i18n-tasks.yml +10 -0
  108. data/config/locales/ca.yml +394 -0
  109. data/config/locales/cs.yml +394 -0
  110. data/config/locales/en.yml +419 -0
  111. data/config/locales/es.yml +394 -0
  112. data/db/migrate/20200302115642_create_decidim_time_tracker_time_trackers.rb +10 -0
  113. data/db/migrate/20200302115654_create_decidim_time_tracker_tasks.rb +11 -0
  114. data/db/migrate/20200302115658_create_decidim_time_tracker_assignees.rb +12 -0
  115. data/db/migrate/20200302115700_create_decidim_time_tracker_activities.rb +19 -0
  116. data/db/migrate/20200302115708_create_decidim_time_tracker_milestones.rb +13 -0
  117. data/db/migrate/20200302115831_create_decidim_time_tracker_assignations.rb +16 -0
  118. data/db/migrate/20200302115840_create_decidim_time_tracker_time_events.rb +15 -0
  119. data/db/migrate/20201118153327_create_decidim_time_tracker_assignee_data.rb +10 -0
  120. data/db/migrate/20201223115130_create_decidim_time_tracker_tos_acceptances.rb +18 -0
  121. data/lib/decidim/time_tracker.rb +45 -0
  122. data/lib/decidim/time_tracker/admin.rb +10 -0
  123. data/lib/decidim/time_tracker/admin_engine.rb +51 -0
  124. data/lib/decidim/time_tracker/component.rb +248 -0
  125. data/lib/decidim/time_tracker/engine.rb +59 -0
  126. data/lib/decidim/time_tracker/reports.rb +10 -0
  127. data/lib/decidim/time_tracker/reports_engine.rb +34 -0
  128. data/lib/decidim/time_tracker/test/admin_log_presenter_examples.rb +34 -0
  129. data/lib/decidim/time_tracker/test/factories.rb +110 -0
  130. data/lib/decidim/time_tracker/test/time_tracker_context.rb +18 -0
  131. data/lib/decidim/time_tracker/time_tracker_activity_questionnaire_answers_serializer.rb +74 -0
  132. data/lib/decidim/time_tracker/version.rb +9 -0
  133. data/vendor/assets/javascripts/jsrender.min.js +4 -0
  134. metadata +276 -0
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module TimeTracker
5
+ # The data store for a Task in the Decidim::TimeTracker component.
6
+ class Task < ApplicationRecord
7
+ include Decidim::Traceable
8
+ include Decidim::Loggable
9
+
10
+ self.table_name = :decidim_time_tracker_tasks
11
+
12
+ belongs_to :time_tracker,
13
+ class_name: "Decidim::TimeTracker::TimeTracker"
14
+
15
+ has_many :activities,
16
+ class_name: "Decidim::TimeTracker::Activity",
17
+ dependent: :destroy
18
+
19
+ delegate :questionnaire, to: :time_tracker
20
+ delegate :component, to: :time_tracker
21
+
22
+ def starts_at
23
+ activities.order(start_date: :asc).first&.start_date
24
+ end
25
+
26
+ def ends_at
27
+ activities.order(end_date: :desc).first&.end_date
28
+ end
29
+
30
+ def assignations_count(filter: :accepted)
31
+ assignations = Assignation.where(activity: activities).send(filter)
32
+ assignations.count
33
+ end
34
+
35
+ def user_is_assignation?(user, filter: :accepted)
36
+ Assignation.where(user: user, activity: activities).send(filter).any?
37
+ end
38
+
39
+ def self.log_presenter_class_for(_log)
40
+ Decidim::TimeTracker::AdminLog::TaskPresenter
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module TimeTracker
5
+ # The data store for a time entry in the Decidim::TimeTracker component.
6
+ class TimeEvent < ApplicationRecord
7
+ self.table_name = :decidim_time_tracker_time_events
8
+
9
+ belongs_to :assignation,
10
+ class_name: "Decidim::TimeTracker::Assignation"
11
+
12
+ belongs_to :activity,
13
+ class_name: "Decidim::TimeTracker::Activity"
14
+
15
+ belongs_to :user,
16
+ foreign_key: "decidim_user_id",
17
+ class_name: "Decidim::User"
18
+
19
+ # note that with the default order reversed
20
+ # the "last" element needs to be found with .first
21
+ default_scope { order(start: :desc) }
22
+ scope :started_between, ->(start_date, end_date) { where("start >= ? AND start <= ?", start_date.to_i, end_date.to_i) }
23
+
24
+ # rubocop:disable Rails/FindBy
25
+ def self.last_for(user)
26
+ if user.is_a?(Assignation)
27
+ where(assignation: user).first
28
+ else
29
+ where(user: user).first
30
+ end
31
+ end
32
+ # rubocop:enable Rails/FindBy
33
+
34
+ # number of seconds since the counting started
35
+ # zero if activity is stopped
36
+ def seconds_elapsed
37
+ return 0 if stopped?
38
+ return 0 if start.blank?
39
+
40
+ @seconds_elapsed ||= Time.current.to_i - start.to_i
41
+ end
42
+
43
+ def stopped?
44
+ stop.to_i >= start
45
+ end
46
+
47
+ def start_time
48
+ Time.zone.at start
49
+ end
50
+
51
+ def stop_time
52
+ Time.zone.at stop
53
+ end
54
+
55
+ def stop!
56
+ self.stop = Time.current.to_i
57
+ self.total_seconds = stop - start
58
+ save!
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module TimeTracker
5
+ class TimeTracker < ApplicationRecord
6
+ include Decidim::HasComponent
7
+ include Decidim::Forms::HasQuestionnaire
8
+ include Decidim::Traceable
9
+ include Decidim::Loggable
10
+
11
+ self.table_name = :decidim_time_trackers
12
+
13
+ component_manifest_name "time_tracker"
14
+
15
+ has_many :tasks,
16
+ class_name: "Decidim::TimeTracker::Task",
17
+ dependent: :destroy
18
+
19
+ has_many :activities,
20
+ class_name: "Decidim::TimeTracker::Activity",
21
+ through: :tasks
22
+
23
+ has_many :assignations,
24
+ class_name: "Decidim::TimeTracker::Assignation",
25
+ through: :activities
26
+
27
+ has_one :assignee_data,
28
+ class_name: "Decidim::TimeTracker::AssigneeData"
29
+
30
+ has_one :assignee_questionnaire,
31
+ source: :questionnaire,
32
+ through: :assignee_data,
33
+ class_name: "Decidim::Forms::Questionnaire"
34
+
35
+ def has_questions?
36
+ questionnaire.questions.any?
37
+ end
38
+
39
+ def has_assignee_questions?
40
+ assignee_data.questionnaire.questions.any?
41
+ end
42
+
43
+ alias activity_questionnaire questionnaire
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module TimeTracker
5
+ # The data store for terms of service acceptance in the Decidim::TimeTracker component.
6
+ class TosAcceptance < ApplicationRecord
7
+ self.table_name = :decidim_time_tracker_tos_acceptances
8
+
9
+ belongs_to :assignee,
10
+ class_name: "Decidim::TimeTracker::Assignee"
11
+
12
+ belongs_to :time_tracker,
13
+ class_name: "Decidim::TimeTracker::TimeTracker"
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module TimeTracker
5
+ module Admin
6
+ class Permissions < Decidim::DefaultPermissions
7
+ def permissions
8
+ return permission_action if permission_action.scope != :admin
9
+
10
+ allowed_task_action?
11
+ allowed_questionnaire_action?
12
+ allowed_activity_action?
13
+ allowed_assignation_action?
14
+
15
+ permission_action
16
+ end
17
+
18
+ def allowed_task_action?
19
+ return unless permission_action.subject.in? [:task, :tasks]
20
+
21
+ case permission_action.action
22
+ when :index, :create, :update, :destroy
23
+ permission_action.allow!
24
+ end
25
+ end
26
+
27
+ def allowed_questionnaire_action?
28
+ return unless permission_action.subject.in? [:questionnaire, :questionnaire_answers]
29
+
30
+ if permission_action.subject == :questionnaire
31
+ case permission_action.action
32
+ when :export_answers, :update, :preview
33
+ permission_action.allow!
34
+ end
35
+ elsif permission_action.subject == :questionnaire_answers
36
+ case permission_action.action
37
+ when :show, :index, :export_response
38
+ permission_action.allow!
39
+ end
40
+ end
41
+ end
42
+
43
+ def allowed_activity_action?
44
+ return unless permission_action.subject.in? [:activity, :activities]
45
+
46
+ case permission_action.action
47
+ when :index, :create, :update, :destroy
48
+ permission_action.allow!
49
+ end
50
+ end
51
+
52
+ def allowed_assignation_action?
53
+ return unless permission_action.subject.in? [:assignation, :assignations]
54
+
55
+ case permission_action.action
56
+ when :update
57
+ permission_action.allow! if assignation.can_change_status?
58
+ when :index, :create, :destroy
59
+ permission_action.allow!
60
+ end
61
+ end
62
+
63
+ def assignation
64
+ @assignation ||= context.fetch(:assignation, nil)
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module TimeTracker
5
+ class Permissions < Decidim::DefaultPermissions
6
+ def permissions
7
+ # for the moment, we let public views for milestones
8
+ allow! if permission_action.subject == :milestone && permission_action.action == :show
9
+
10
+ return permission_action unless user
11
+
12
+ return Decidim::TimeTracker::Admin::Permissions.new(user, permission_action, context).permissions if permission_action.scope == :admin
13
+
14
+ case permission_action.subject
15
+ when :questionnaire
16
+ allow_answer?
17
+ when :assignation
18
+ allow_assignation?
19
+ when :milestone
20
+ allow_milestone?
21
+ else
22
+ allow!
23
+ end
24
+
25
+ permission_action
26
+ end
27
+
28
+ def allow_answer?
29
+ return unless permission_action.action == :answer
30
+
31
+ allow! if current_component&.published?
32
+ end
33
+
34
+ def allow_assignation?
35
+ return allow! unless activity
36
+
37
+ if permission_action.action == :create
38
+ return if activity.has_assignation? user
39
+
40
+ return unless activity.status.in? [:open, :not_started]
41
+
42
+ allow!
43
+ end
44
+ end
45
+
46
+ def allow_milestone?
47
+ return unless activity
48
+
49
+ if permission_action.action == :create
50
+ return unless activity.assignation_accepted? user
51
+
52
+ return if activity.status.in? [:inactive]
53
+
54
+ allow!
55
+ end
56
+ end
57
+
58
+ private
59
+
60
+ def activity
61
+ @activity ||= context.fetch(:activity, nil)
62
+ end
63
+
64
+ def current_component
65
+ @current_component ||= context.fetch(:current_component, nil)
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module TimeTracker
5
+ module AdminLog
6
+ # This class holds the logic to present a `Decidim::TimeTracker::Activity`
7
+ # for the `AdminLog` log.
8
+ #
9
+ # Usage should be automatic and you shouldn't need to call this class
10
+ # directly, but here's an example:
11
+ #
12
+ # action_log = Decidim::ActionLog.last
13
+ # view_helpers # => this comes from the views
14
+ # ActivityPresenter.new(action_log, view_helpers).present
15
+ class ActivityPresenter < Decidim::Log::BasePresenter
16
+ private
17
+
18
+ def diff_fields_mapping
19
+ {
20
+ description: :i18n,
21
+ active: :boolean
22
+ }
23
+ end
24
+
25
+ def i18n_labels_scope
26
+ "activemodel.attributes.time_tracker.activity"
27
+ end
28
+
29
+ def action_string
30
+ case action
31
+ when "create", "delete", "update"
32
+ "decidim.time_tracker.admin_log.activity.#{action}"
33
+ else
34
+ super
35
+ end
36
+ end
37
+
38
+ def has_diff?
39
+ action == "delete" || super
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module TimeTracker
5
+ module AdminLog
6
+ # This class holds the logic to present a `Decidim::TimeTracker::Assignation`
7
+ # for the `AdminLog` log.
8
+ #
9
+ # Usage should be automatic and you shouldn't need to call this class
10
+ # directly, but here's an example:
11
+ #
12
+ # action_log = Decidim::ActionLog.last
13
+ # view_helpers # => this comes from the views
14
+ # AssignationPresenter.new(action_log, view_helpers).present
15
+ class AssignationPresenter < Decidim::Log::BasePresenter
16
+ private
17
+
18
+ def diff_fields_mapping
19
+ {
20
+ status: :string,
21
+ decidim_user_id: :user,
22
+ activity_id: "Decidim::TimeTracker::AdminLog::ValueTypes::ActivityPresenter",
23
+ invited_at: :date,
24
+ invited_by_user: :user,
25
+ requested_at: :date
26
+ }
27
+ end
28
+
29
+ def i18n_labels_scope
30
+ "activemodel.attributes.time_tracker.assignation"
31
+ end
32
+
33
+ def action_string
34
+ case action
35
+ when "create", "delete", "update"
36
+ "decidim.time_tracker.admin_log.assignation.#{action}"
37
+ else
38
+ super
39
+ end
40
+ end
41
+
42
+ def has_diff?
43
+ action == "delete" || super
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module TimeTracker
5
+ module AdminLog
6
+ # This class holds the logic to present a `Decidim::TimeTracker::Task`
7
+ # for the `AdminLog` log.
8
+ #
9
+ # Usage should be automatic and you shouldn't need to call this class
10
+ # directly, but here's an example:
11
+ #
12
+ # action_log = Decidim::ActionLog.last
13
+ # view_helpers # => this comes from the views
14
+ # TaskPresenter.new(action_log, view_helpers).present
15
+ class TaskPresenter < Decidim::Log::BasePresenter
16
+ private
17
+
18
+ def diff_fields_mapping
19
+ {
20
+ name: :i18n,
21
+ time_tracker_id: "Decidim::TimeTracker::AdminLog::ValueTypes::TimeTrackerPresenter",
22
+ active: :boolean,
23
+ updated_at: :date
24
+ }
25
+ end
26
+
27
+ def i18n_labels_scope
28
+ "activemodel.attributes.time_tracker.task"
29
+ end
30
+
31
+ def action_string
32
+ case action
33
+ when "create", "delete", "update"
34
+ "decidim.time_tracker.admin_log.task.#{action}"
35
+ else
36
+ super
37
+ end
38
+ end
39
+
40
+ def has_diff?
41
+ action == "delete" || super
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end