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
+ module Admin
6
+ # A command with all the business logic when updating an task
7
+ class UpdateTask < Rectify::Command
8
+ # Public: Initializes the command.
9
+ #
10
+ # form - A form object with the params.
11
+ def initialize(task, form, user)
12
+ @task = task
13
+ @form = form
14
+ @user = user
15
+ end
16
+
17
+ # Executes the command. Broadcasts these events:
18
+ #
19
+ # - :ok when everything is valid.
20
+ # - :invalid if the form wasn't valid and we couldn't proceed.
21
+ #
22
+ # Returns nothing.
23
+ def call
24
+ return broadcast(:invalid) if form.invalid?
25
+
26
+ update_task!
27
+ broadcast(:ok)
28
+ end
29
+
30
+ private
31
+
32
+ attr_reader :form
33
+
34
+ def update_task!
35
+ Decidim.traceability.update!(
36
+ @task,
37
+ @user,
38
+ name: form.name
39
+ )
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module TimeTracker
5
+ # A command with all the business logic when a user creates a new milestone.
6
+ class CreateMilestone < Rectify::Command
7
+ include ::Decidim::AttachmentMethods
8
+ # Public: Initializes the command.
9
+ #
10
+ # form - A form object with the params.
11
+ def initialize(form, current_user)
12
+ @form = form
13
+ @current_user = current_user
14
+ end
15
+
16
+ # Executes the command. Broadcasts these events:
17
+ #
18
+ # - :ok when everything is valid, together with the milestone.
19
+ # - :invalid if the form wasn't valid and we couldn't proceed.
20
+ #
21
+ # Returns nothing.
22
+ def call
23
+ return broadcast(:invalid, form.errors) if form.invalid?
24
+
25
+ if attachment_present?
26
+ build_attachment
27
+ return broadcast(:invalid, form.attachment.errors) if attachment_invalid?
28
+ end
29
+
30
+ transaction do
31
+ create_milestone!
32
+ create_attachment if attachment_present?
33
+ end
34
+
35
+ broadcast(:ok, @milestone)
36
+ end
37
+
38
+ private
39
+
40
+ attr_reader :form, :current_user, :milestone, :attachment
41
+
42
+ def create_milestone!
43
+ @milestone = Decidim::TimeTracker::Milestone.create!(
44
+ title: form.title,
45
+ description: form.description,
46
+ user: current_user,
47
+ activity: form.activity
48
+ )
49
+ @attached_to = @milestone
50
+ end
51
+
52
+ def attachment_present?
53
+ @form.attachment && @form.attachment.file.present?
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module TimeTracker
5
+ # A command with all the business logic when requesting to be an assignation
6
+ class CreateRequestAssignation < Rectify::Command
7
+ def initialize(activity, user)
8
+ @activity = activity
9
+ @user = user
10
+ end
11
+
12
+ # Creates the assignation if valid.
13
+ #
14
+ # Broadcasts :ok if successful, :invalid otherwise.
15
+ def call
16
+ begin
17
+ create_request_assignation
18
+ rescue StandardError
19
+ return broadcast(:invalid)
20
+ end
21
+
22
+ broadcast(:ok, activity)
23
+ end
24
+
25
+ private
26
+
27
+ attr_reader :activity
28
+
29
+ def create_request_assignation
30
+ Decidim::TimeTracker::Assignation.create!(
31
+ activity: @activity,
32
+ user: @user,
33
+ status: :pending,
34
+ requested_at: Time.current
35
+ )
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module TimeTracker
5
+ # A command with all the business logic when creating a time event
6
+ class StartTimeEvent < Rectify::Command
7
+ # Public: Initializes the command.
8
+ #
9
+ # form - A form object with the params.
10
+ def initialize(form)
11
+ @form = form
12
+ end
13
+
14
+ # Executes the command. Broadcasts these events:
15
+ #
16
+ # - :ok when everything is valid.
17
+ # - :invalid if the form wasn't valid and we couldn't proceed.
18
+ #
19
+ # Returns nothing.
20
+ def call
21
+ return broadcast(:invalid, form.errors&.first&.second) if form.invalid?
22
+
23
+ return broadcast(:already_active, @time_entry) if already_active?
24
+
25
+ return broadcast(:invalid, form.errors&.first&.second) if activity_invalid?
26
+
27
+ begin
28
+ stop_previous_activity
29
+ create_time_event!
30
+ StopCounterJob.set(wait: form.activity.remaining_seconds_for_today.seconds).perform_later(@time_entry)
31
+ rescue StandardError => e
32
+ return broadcast(:invalid, e.message)
33
+ end
34
+
35
+ broadcast(:ok, @time_entry)
36
+ end
37
+
38
+ attr_reader :form
39
+
40
+ private
41
+
42
+ def activity_invalid?
43
+ unless activity_started?
44
+ form.errors.add(:activity, :not_started)
45
+ return true
46
+ end
47
+
48
+ if activity_finished?
49
+ form.errors.add(:activity, :finished)
50
+ return true
51
+ end
52
+
53
+ unless time_available?
54
+ form.errors.add(:activity, :no_time_available)
55
+ return true
56
+ end
57
+ end
58
+
59
+ def create_time_event!
60
+ @time_entry = Decidim::TimeTracker::TimeEvent.create!(
61
+ user: form.user,
62
+ assignation: form.assignation,
63
+ activity: form.activity,
64
+ start: start_time.to_i
65
+ )
66
+ end
67
+
68
+ def start_time
69
+ form.start.presence || Time.current
70
+ end
71
+
72
+ def stop_previous_activity
73
+ previous = TimeEvent.where.not(activity: form.activity).last_for(form.user)
74
+
75
+ return unless previous
76
+ return if previous.stopped? && previous.stop.to_i < start_time.to_i
77
+
78
+ previous.stop!
79
+ end
80
+
81
+ def already_active?
82
+ @time_entry = TimeEvent.where(activity: form.activity).last_for(form.user)
83
+
84
+ return false unless @time_entry
85
+ return false if @time_entry.stopped?
86
+
87
+ elapsed = (start_time.to_i - @time_entry.start) + form.activity.user_total_seconds_for_date(form.user, start_time)
88
+ elapsed < form.activity.remaining_seconds_for_today
89
+ end
90
+
91
+ def activity_started?
92
+ form.activity.start_date.beginning_of_day <= start_time
93
+ end
94
+
95
+ def activity_finished?
96
+ form.activity.end_date.end_of_day <= start_time
97
+ end
98
+
99
+ def time_available?
100
+ form.activity.user_total_seconds_for_date(form.user, start_time) < form.activity.remaining_seconds_for_today
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module TimeTracker
5
+ # Stops the last event for the user
6
+ class StopLastTimeEvent < Rectify::Command
7
+ # Public: Initializes the command.
8
+ #
9
+ # form - A form object with the params.
10
+ def initialize(current_user)
11
+ @current_user = current_user
12
+ end
13
+
14
+ # Executes the command. Broadcasts these events:
15
+ #
16
+ # - :ok when everything is valid.
17
+ # - :invalid if the form wasn't valid and we couldn't proceed.
18
+ #
19
+ # Returns nothing.
20
+ def call
21
+ return broadcast(:already_stopped, @last_entry) if last_entry.stopped?
22
+
23
+ begin
24
+ stop_time_event!
25
+ rescue StandardError => e
26
+ return broadcast(:invalid, e.message)
27
+ end
28
+
29
+ broadcast(:ok, @last_entry)
30
+ end
31
+
32
+ attr_reader :current_user, :form
33
+
34
+ private
35
+
36
+ def last_entry
37
+ @last_entry ||= Decidim::TimeTracker::TimeEvent.last_for(current_user)
38
+ end
39
+
40
+ def stop_time_event!
41
+ last_entry.stop!
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/concern"
4
+
5
+ module Decidim
6
+ module TimeTracker
7
+ module Admin
8
+ module FilterableAssignations
9
+ extend ActiveSupport::Concern
10
+
11
+ included do
12
+ include Decidim::Admin::Filterable
13
+
14
+ private
15
+
16
+ def base_query
17
+ assignations_collection
18
+ end
19
+
20
+ def search_field_predicate
21
+ :user_name_or_user_nickname_or_user_email_cont
22
+ end
23
+
24
+ def filters
25
+ [:activity_id_eq, :activity_task_id_eq]
26
+ end
27
+
28
+ def filters_with_values
29
+ {
30
+ activity_id_eq: time_tracker.activities.pluck(:id),
31
+ activity_task_id_eq: time_tracker.tasks.pluck(:id)
32
+ }
33
+ end
34
+
35
+ def dynamically_translated_filters
36
+ [:activity_id_eq, :activity_task_id_eq]
37
+ end
38
+
39
+ def translated_activity_id_eq(id)
40
+ translated_attribute(Activity.find_by(id: id).description)
41
+ end
42
+
43
+ def translated_activity_task_id_eq(id)
44
+ translated_attribute(Task.find_by(id: id).name)
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module TimeTracker
5
+ class ActivityQuestionnaireController < Decidim::TimeTracker::ApplicationController
6
+ include Decidim::Forms::Concerns::HasQuestionnaire
7
+
8
+ # only allows answers if not in preview mode
9
+ def preview
10
+ return show if request.method == "GET"
11
+
12
+ flash[":alert"] = I18n.t("questionnaire_in_preview_mode", scope: "decidim.time_tracker.time_tracker")
13
+ redirect_to preview_task_activity_form_path(activity_id: activity.id, id: activity.questionnaire)
14
+ end
15
+
16
+ def questionnaire_for
17
+ time_tracker
18
+ end
19
+
20
+ # only allows answers if not in preview mode
21
+ def allow_answers?
22
+ return false if current_user.blank?
23
+
24
+ return true if params[:action] == "preview" && current_user.admin?
25
+
26
+ activity.allow_answers_for? current_user
27
+ end
28
+
29
+ # Returns the path to answer this questionnaire for normal users
30
+ # If the questionnaire is rendered in a preview route, then just do nothing with the responses
31
+ def update_url
32
+ return preview_task_activity_form_path(activity_id: activity.id, id: activity.questionnaire) if params[:action] == "preview"
33
+
34
+ answer_task_activity_form_path(activity_id: activity.id, id: activity.questionnaire)
35
+ end
36
+
37
+ def form_path
38
+ task_activity_form_path(activity_id: activity.id, id: activity.questionnaire)
39
+ end
40
+
41
+ def after_answer_path
42
+ Decidim::EngineRouter.main_proxy(current_component).root_path
43
+ end
44
+
45
+ # Override so can answer only if is an assignation can view
46
+ # Also admins can preview it (but not answer)
47
+ def visitor_can_answer?
48
+ return false if current_user.blank?
49
+
50
+ return true if params[:action] == "preview" && current_user.admin?
51
+
52
+ activity.assignation_accepted? current_user
53
+ end
54
+
55
+ # Override to allow respond users once per-activity
56
+ def visitor_already_answered?
57
+ return false if current_user.blank?
58
+
59
+ return false if params[:action] == "preview" && current_user.admin?
60
+
61
+ activity.questionnaire.answered_by?(session_token)
62
+ end
63
+
64
+ private
65
+
66
+ # Override to enable response once for each activity
67
+ def session_token
68
+ activity.session_token(current_user)
69
+ end
70
+
71
+ def activity
72
+ @activity ||= Activity.find(params[:activity_id])
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module TimeTracker
5
+ module Admin
6
+ class ActivitiesController < Admin::ApplicationController
7
+ include Decidim::TimeTracker::ApplicationHelper
8
+ helper_method :activities, :current_task, :current_activity, :activities_label
9
+
10
+ def new
11
+ enforce_permission_to :create, :activities
12
+
13
+ @form = form(ActivityForm).instance
14
+ end
15
+
16
+ def edit
17
+ enforce_permission_to :update, :activity, activity: current_activity
18
+ @form = form(ActivityForm).from_model(current_activity, task: current_task, activity: current_activity)
19
+ end
20
+
21
+ def create
22
+ enforce_permission_to :create, :activities
23
+
24
+ @form = form(ActivityForm).from_params(params)
25
+
26
+ CreateActivity.call(@form, current_task) do |_activity|
27
+ on(:ok) do
28
+ flash[:notice] = I18n.t("activities.create.success", scope: "decidim.time_tracker.admin")
29
+ redirect_to EngineRouter.admin_proxy(current_component).edit_task_path(current_task)
30
+ end
31
+
32
+ on(:invalid) do
33
+ flash.now[:alert] = I18n.t("activities.create.error", scope: "decidim.time_tracker.admin")
34
+ render :new
35
+ end
36
+ end
37
+ end
38
+
39
+ def update
40
+ enforce_permission_to :update, :activity, activity: current_activity
41
+ @form = form(ActivityForm).from_params(params, task: current_task, activity: current_activity)
42
+ UpdateActivity.call(current_activity, @form, current_user) do
43
+ on(:ok) do
44
+ flash[:notice] = I18n.t("activities.update.success", scope: "decidim.time_tracker.admin")
45
+ redirect_to EngineRouter.admin_proxy(current_component).edit_task_path(current_task)
46
+ end
47
+
48
+ on(:invalid) do
49
+ flash.now[:alert] = I18n.t("activities.update.error", scope: "decidim.time_tracker.admin")
50
+ render :edit
51
+ end
52
+ end
53
+ end
54
+
55
+ def destroy
56
+ enforce_permission_to :destroy, :activity, activity: current_activity
57
+
58
+ DestroyActivity.call(current_activity, current_user) do
59
+ on(:ok) do
60
+ flash[:notice] = I18n.t("activities.destroy.success", scope: "decidim.time_tracker.admin")
61
+ redirect_to EngineRouter.admin_proxy(current_component).edit_task_path(current_task)
62
+ end
63
+ end
64
+ end
65
+
66
+ private
67
+
68
+ def activities
69
+ @activities = Decidim::TimeTracker::Activity.where(task: current_task.id)
70
+ end
71
+
72
+ def current_task
73
+ @current_task ||= Task.find(params[:task_id])
74
+ end
75
+
76
+ def current_activity
77
+ @current_activity ||= Activity.find_by(id: params[:id])
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end