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.
- checksums.yaml +7 -0
- data/LICENSE-AGPLv3.txt +661 -0
- data/README.md +174 -0
- data/Rakefile +40 -0
- data/app/assets/config/admin/decidim_time_tracker_manifest.css +2 -0
- data/app/assets/config/admin/decidim_time_tracker_manifest.js +1 -0
- data/app/assets/config/decidim_time_tracker_manifest.css +3 -0
- data/app/assets/config/decidim_time_tracker_manifest.js +1 -0
- data/app/assets/images/decidim/time_tracker/icon.svg +1 -0
- data/app/assets/javascripts/decidim/time_tracker/activity_ui.js.es6 +112 -0
- data/app/assets/javascripts/decidim/time_tracker/admin/assignations.js.es6 +35 -0
- data/app/assets/javascripts/decidim/time_tracker/reports/reports.js.es6 +19 -0
- data/app/assets/javascripts/decidim/time_tracker/time_tracker.js.es6 +82 -0
- data/app/assets/javascripts/decidim/time_tracker/timer_api.js.es6 +55 -0
- data/app/assets/stylesheets/decidim/time_tracker/_variables.scss +1 -0
- data/app/assets/stylesheets/decidim/time_tracker/admin/time_tracker.scss +59 -0
- data/app/assets/stylesheets/decidim/time_tracker/time_tracker.scss +118 -0
- data/app/cells/decidim/time_tracker/milestone/show.erb +42 -0
- data/app/cells/decidim/time_tracker/milestone_cell.rb +54 -0
- data/app/commands/decidim/time_tracker/admin/create_activity.rb +39 -0
- data/app/commands/decidim/time_tracker/admin/create_assignation.rb +75 -0
- data/app/commands/decidim/time_tracker/admin/create_task.rb +33 -0
- data/app/commands/decidim/time_tracker/admin/create_time_tracker.rb +76 -0
- data/app/commands/decidim/time_tracker/admin/destroy_activity.rb +43 -0
- data/app/commands/decidim/time_tracker/admin/destroy_assignation.rb +43 -0
- data/app/commands/decidim/time_tracker/admin/destroy_task.rb +43 -0
- data/app/commands/decidim/time_tracker/admin/export_time_tracker.rb +150 -0
- data/app/commands/decidim/time_tracker/admin/update_activity.rb +49 -0
- data/app/commands/decidim/time_tracker/admin/update_assignation.rb +42 -0
- data/app/commands/decidim/time_tracker/admin/update_task.rb +44 -0
- data/app/commands/decidim/time_tracker/create_milestone.rb +57 -0
- data/app/commands/decidim/time_tracker/create_request_assignation.rb +39 -0
- data/app/commands/decidim/time_tracker/start_time_event.rb +104 -0
- data/app/commands/decidim/time_tracker/stop_last_time_event.rb +45 -0
- data/app/controllers/concerns/decidim/time_tracker/admin/filterable_assignations.rb +50 -0
- data/app/controllers/decidim/time_tracker/activity_questionnaire_controller.rb +76 -0
- data/app/controllers/decidim/time_tracker/admin/activities_controller.rb +82 -0
- data/app/controllers/decidim/time_tracker/admin/activity_questionnaire_controller.rb +52 -0
- data/app/controllers/decidim/time_tracker/admin/application_controller.rb +22 -0
- data/app/controllers/decidim/time_tracker/admin/assignations_controller.rb +84 -0
- data/app/controllers/decidim/time_tracker/admin/assignee_questionnaire_controller.rb +58 -0
- data/app/controllers/decidim/time_tracker/admin/stats_controller.rb +24 -0
- data/app/controllers/decidim/time_tracker/admin/tasks_controller.rb +112 -0
- data/app/controllers/decidim/time_tracker/admin/time_tracker_exports_controller.rb +25 -0
- data/app/controllers/decidim/time_tracker/application_controller.rb +24 -0
- data/app/controllers/decidim/time_tracker/assignations_controller.rb +38 -0
- data/app/controllers/decidim/time_tracker/assignee_questionnaire_controller.rb +80 -0
- data/app/controllers/decidim/time_tracker/milestones_controller.rb +62 -0
- data/app/controllers/decidim/time_tracker/reports/user_controller.rb +38 -0
- data/app/controllers/decidim/time_tracker/time_events_controller.rb +68 -0
- data/app/controllers/decidim/time_tracker/time_tracker_controller.rb +43 -0
- data/app/forms/decidim/time_tracker/admin/activity_form.rb +27 -0
- data/app/forms/decidim/time_tracker/admin/assignation_form.rb +29 -0
- data/app/forms/decidim/time_tracker/admin/task_form.rb +22 -0
- data/app/forms/decidim/time_tracker/milestone_form.rb +32 -0
- data/app/forms/decidim/time_tracker/time_event_form.rb +47 -0
- data/app/helpers/decidim/time_tracker/admin/application_helper.rb +33 -0
- data/app/helpers/decidim/time_tracker/application_helper.rb +95 -0
- data/app/jobs/decidim/time_tracker/stop_counter_job.rb +29 -0
- data/app/models/decidim/time_tracker/activity.rb +135 -0
- data/app/models/decidim/time_tracker/application_record.rb +10 -0
- data/app/models/decidim/time_tracker/assignation.rb +68 -0
- data/app/models/decidim/time_tracker/assignee.rb +29 -0
- data/app/models/decidim/time_tracker/assignee_data.rb +19 -0
- data/app/models/decidim/time_tracker/milestone.rb +27 -0
- data/app/models/decidim/time_tracker/task.rb +44 -0
- data/app/models/decidim/time_tracker/time_event.rb +62 -0
- data/app/models/decidim/time_tracker/time_tracker.rb +46 -0
- data/app/models/decidim/time_tracker/tos_acceptance.rb +16 -0
- data/app/permissions/decidim/time_tracker/admin/permissions.rb +69 -0
- data/app/permissions/decidim/time_tracker/permissions.rb +69 -0
- data/app/presenters/decidim/time_tracker/admin_log/activity_presenter.rb +44 -0
- data/app/presenters/decidim/time_tracker/admin_log/assignation_presenter.rb +48 -0
- data/app/presenters/decidim/time_tracker/admin_log/task_presenter.rb +46 -0
- data/app/presenters/decidim/time_tracker/admin_log/value_types/activity_presenter.rb +28 -0
- data/app/presenters/decidim/time_tracker/admin_log/value_types/time_tracker_presenter.rb +28 -0
- data/app/views/decidim/time_tracker/admin/_breadcrumbs.html.erb +56 -0
- data/app/views/decidim/time_tracker/admin/activities/_form.html.erb +41 -0
- data/app/views/decidim/time_tracker/admin/activities/_index.html.erb +73 -0
- data/app/views/decidim/time_tracker/admin/activities/edit.html.erb +5 -0
- data/app/views/decidim/time_tracker/admin/activities/new.html.erb +5 -0
- data/app/views/decidim/time_tracker/admin/assignations/_form.html.erb +30 -0
- data/app/views/decidim/time_tracker/admin/assignations/index.html.erb +67 -0
- data/app/views/decidim/time_tracker/admin/assignations/new.html.erb +9 -0
- data/app/views/decidim/time_tracker/admin/questionnaires/_index.html.erb +27 -0
- data/app/views/decidim/time_tracker/admin/questionnaires/_questionnaire.html.erb +21 -0
- data/app/views/decidim/time_tracker/admin/stats/index.html.erb +50 -0
- data/app/views/decidim/time_tracker/admin/tasks/_assignations.html.erb +60 -0
- data/app/views/decidim/time_tracker/admin/tasks/_form.html.erb +7 -0
- data/app/views/decidim/time_tracker/admin/tasks/_index.html.erb +61 -0
- data/app/views/decidim/time_tracker/admin/tasks/edit.html.erb +16 -0
- data/app/views/decidim/time_tracker/admin/tasks/index.html.erb +5 -0
- data/app/views/decidim/time_tracker/admin/tasks/new.html.erb +12 -0
- data/app/views/decidim/time_tracker/milestones/index.html.erb +60 -0
- data/app/views/decidim/time_tracker/reports/user/index.html.erb +41 -0
- data/app/views/decidim/time_tracker/time_tracker/_activity.html.erb +43 -0
- data/app/views/decidim/time_tracker/time_tracker/_answer_questionnaire.html.erb +7 -0
- data/app/views/decidim/time_tracker/time_tracker/_assignee_data.html.erb +9 -0
- data/app/views/decidim/time_tracker/time_tracker/_callout_status.html.erb +3 -0
- data/app/views/decidim/time_tracker/time_tracker/_idle_activity.html.erb +27 -0
- data/app/views/decidim/time_tracker/time_tracker/_milestone_form.html.erb +35 -0
- data/app/views/decidim/time_tracker/time_tracker/_request_activity.html.erb +22 -0
- data/app/views/decidim/time_tracker/time_tracker/_sign_in.html.erb +5 -0
- data/app/views/decidim/time_tracker/time_tracker/index.html.erb +59 -0
- data/config/activity_questionnaire.yml +26 -0
- data/config/assignee_questionnaire.yml +37 -0
- data/config/i18n-tasks.yml +10 -0
- data/config/locales/ca.yml +394 -0
- data/config/locales/cs.yml +394 -0
- data/config/locales/en.yml +419 -0
- data/config/locales/es.yml +394 -0
- data/db/migrate/20200302115642_create_decidim_time_tracker_time_trackers.rb +10 -0
- data/db/migrate/20200302115654_create_decidim_time_tracker_tasks.rb +11 -0
- data/db/migrate/20200302115658_create_decidim_time_tracker_assignees.rb +12 -0
- data/db/migrate/20200302115700_create_decidim_time_tracker_activities.rb +19 -0
- data/db/migrate/20200302115708_create_decidim_time_tracker_milestones.rb +13 -0
- data/db/migrate/20200302115831_create_decidim_time_tracker_assignations.rb +16 -0
- data/db/migrate/20200302115840_create_decidim_time_tracker_time_events.rb +15 -0
- data/db/migrate/20201118153327_create_decidim_time_tracker_assignee_data.rb +10 -0
- data/db/migrate/20201223115130_create_decidim_time_tracker_tos_acceptances.rb +18 -0
- data/lib/decidim/time_tracker.rb +45 -0
- data/lib/decidim/time_tracker/admin.rb +10 -0
- data/lib/decidim/time_tracker/admin_engine.rb +51 -0
- data/lib/decidim/time_tracker/component.rb +248 -0
- data/lib/decidim/time_tracker/engine.rb +59 -0
- data/lib/decidim/time_tracker/reports.rb +10 -0
- data/lib/decidim/time_tracker/reports_engine.rb +34 -0
- data/lib/decidim/time_tracker/test/admin_log_presenter_examples.rb +34 -0
- data/lib/decidim/time_tracker/test/factories.rb +110 -0
- data/lib/decidim/time_tracker/test/time_tracker_context.rb +18 -0
- data/lib/decidim/time_tracker/time_tracker_activity_questionnaire_answers_serializer.rb +74 -0
- data/lib/decidim/time_tracker/version.rb +9 -0
- data/vendor/assets/javascripts/jsrender.min.js +4 -0
- 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
|