decidim-participatory_processes 0.15.2 → 0.16.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +21 -15
- data/app/commands/decidim/participatory_processes/admin/activate_participatory_process_step.rb +1 -1
- data/app/commands/decidim/participatory_processes/admin/update_participatory_process_step.rb +1 -1
- data/app/controllers/decidim/participatory_processes/admin/participatory_processes_controller.rb +0 -9
- data/app/controllers/decidim/participatory_processes/participatory_processes_controller.rb +14 -6
- data/app/events/decidim/participatory_process_step_activated_event.rb +23 -0
- data/app/events/decidim/participatory_process_step_changed_event.rb +23 -0
- data/app/models/decidim/participatory_process.rb +16 -4
- data/app/models/decidim/participatory_process_step.rb +2 -2
- data/app/permissions/decidim/participatory_processes/permissions.rb +7 -12
- data/app/presenters/decidim/participatory_processes/participatory_process_metric_charts_presenter.rb +83 -0
- data/app/queries/decidim/participatory_processes/metrics/participatory_process_followers_metric_measure.rb +31 -0
- data/app/queries/decidim/participatory_processes/visible_participatory_processes.rb +1 -0
- data/app/types/decidim/participatory_processes/participatory_process_type.rb +32 -0
- data/app/views/decidim/participatory_processes/admin/participatory_processes/edit.html.erb +0 -4
- data/app/views/decidim/participatory_processes/participatory_processes/_metrics.html.erb +10 -0
- data/app/views/decidim/participatory_processes/participatory_processes/_statistics.html.erb +1 -1
- data/app/views/decidim/participatory_processes/participatory_processes/index.html.erb +2 -3
- data/app/views/decidim/participatory_processes/participatory_processes/show.html.erb +4 -1
- data/app/views/decidim/participatory_processes/participatory_processes/statistics.html.erb +9 -0
- data/app/views/layouts/decidim/_process_header.html.erb +8 -45
- data/app/views/layouts/decidim/_process_header_steps.html.erb +18 -22
- data/app/views/layouts/decidim/_process_navigation.html.erb +20 -0
- data/app/views/layouts/decidim/participatory_process.html.erb +1 -1
- data/config/locales/ca.yml +9 -5
- data/config/locales/de.yml +9 -5
- data/config/locales/en.yml +9 -5
- data/config/locales/es-PY.yml +9 -5
- data/config/locales/es.yml +9 -5
- data/config/locales/eu.yml +9 -5
- data/config/locales/fi-pl.yml +9 -5
- data/config/locales/fi.yml +9 -5
- data/config/locales/fr.yml +9 -5
- data/config/locales/gl.yml +9 -5
- data/config/locales/hu.yml +9 -5
- data/config/locales/id-ID.yml +9 -5
- data/config/locales/it.yml +9 -5
- data/config/locales/nl.yml +9 -5
- data/config/locales/pl.yml +9 -5
- data/config/locales/pt-BR.yml +9 -5
- data/config/locales/pt.yml +9 -5
- data/config/locales/ru.yml +2 -5
- data/config/locales/sv.yml +9 -5
- data/config/locales/tr-TR.yml +9 -5
- data/config/locales/uk.yml +2 -5
- data/lib/decidim/participatory_processes/admin_engine.rb +1 -1
- data/lib/decidim/participatory_processes/engine.rb +18 -11
- data/lib/decidim/participatory_processes/test/factories.rb +11 -0
- data/lib/decidim/participatory_processes/version.rb +1 -1
- metadata +16 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dcc7482dcc0d05dd5b2736b409fe3c21cac93daa281b3742e3aac4b84af0e8b7
|
4
|
+
data.tar.gz: 25445b48ad99ad7b91ad4dd96107c74435499f80ac0cdb9dada9d0b6cbe54e1c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1a2f754d7e05d3ad0c1daca4681d5e927cf4620661be5e6b57c7cfe695b37d402876a8ab39719fe270365030c107d6dff5057295db977b9e4b0ad940ccfe5a01
|
7
|
+
data.tar.gz: f4770fbfa28e7f8598bef52e10cb6685b8aaeddfc8037f1e28b929f16a039e62a907a4e573af87832254e748a85c2f536dbe0debde4a9803c440fa0086482edc
|
data/README.md
CHANGED
@@ -2,11 +2,18 @@
|
|
2
2
|
|
3
3
|
Participatory processes are the standard Decidim's participatory space.
|
4
4
|
|
5
|
-
A participatory process
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
5
|
+
A participatory process:
|
6
|
+
|
7
|
+
* can define its own steps
|
8
|
+
* can define helper text
|
9
|
+
* can attach different components (such as meetings or proposals) with different configurations to each of them.
|
10
|
+
* can have attachments
|
11
|
+
* can be associated to custom categories
|
12
|
+
* can be promoted
|
13
|
+
* can be a private process, and only users with permissions can see the process
|
14
|
+
* special content can be added to the process or superprocess home
|
15
|
+
* can show statistics on process home.
|
16
|
+
* are fully manageable via an administration UI.
|
10
17
|
|
11
18
|
## Usage
|
12
19
|
|
@@ -14,22 +21,21 @@ This module provides:
|
|
14
21
|
|
15
22
|
* A CRUD engine to manage participatory processes.
|
16
23
|
|
17
|
-
* Public views for participatory process via a high level section in the main
|
18
|
-
menu.
|
24
|
+
* Public views for participatory process via a high level section in the main menu.
|
19
25
|
|
20
26
|
## Installation
|
21
27
|
|
22
|
-
|
28
|
+
This is on the default Decidim installation so you shouldn't change anything to use this participatory space.
|
29
|
+
|
30
|
+
## Screenshots
|
31
|
+
|
32
|
+
![Public View](docs/screenshot01.png)
|
23
33
|
|
24
|
-
|
25
|
-
gem 'decidim-participatory_processes'
|
26
|
-
```
|
34
|
+
![Admin View](docs/screenshot02.png)
|
27
35
|
|
28
|
-
|
36
|
+
## Documentation
|
29
37
|
|
30
|
-
|
31
|
-
bundle
|
32
|
-
```
|
38
|
+
Read more about this Space on [Admin Manual](https://docs.decidim.org/admin-manual/en/processess/).
|
33
39
|
|
34
40
|
## Contributing
|
35
41
|
|
data/app/commands/decidim/participatory_processes/admin/activate_participatory_process_step.rb
CHANGED
@@ -60,7 +60,7 @@ module Decidim
|
|
60
60
|
event: "decidim.events.participatory_process.step_activated",
|
61
61
|
event_class: Decidim::ParticipatoryProcessStepActivatedEvent,
|
62
62
|
resource: step,
|
63
|
-
|
63
|
+
followers: step.participatory_process.followers
|
64
64
|
)
|
65
65
|
end
|
66
66
|
|
data/app/commands/decidim/participatory_processes/admin/update_participatory_process_step.rb
CHANGED
@@ -60,7 +60,7 @@ module Decidim
|
|
60
60
|
event: "decidim.events.participatory_process.step_changed",
|
61
61
|
event_class: Decidim::ParticipatoryProcessStepChangedEvent,
|
62
62
|
resource: step,
|
63
|
-
|
63
|
+
followers: step.participatory_process.followers
|
64
64
|
)
|
65
65
|
end
|
66
66
|
end
|
data/app/controllers/decidim/participatory_processes/admin/participatory_processes_controller.rb
CHANGED
@@ -68,15 +68,6 @@ module Decidim
|
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
71
|
-
def destroy
|
72
|
-
enforce_permission_to :destroy, :process, process: current_participatory_process
|
73
|
-
current_participatory_process.destroy!
|
74
|
-
|
75
|
-
flash[:notice] = I18n.t("participatory_processes.destroy.success", scope: "decidim.admin")
|
76
|
-
|
77
|
-
redirect_to participatory_processes_path
|
78
|
-
end
|
79
|
-
|
80
71
|
def copy
|
81
72
|
enforce_permission_to :create, Decidim::ParticipatoryProcess
|
82
73
|
end
|
@@ -6,7 +6,7 @@ module Decidim
|
|
6
6
|
# public layout.
|
7
7
|
class ParticipatoryProcessesController < Decidim::ParticipatoryProcesses::ApplicationController
|
8
8
|
include ParticipatorySpaceContext
|
9
|
-
participatory_space_layout only: :show
|
9
|
+
participatory_space_layout only: [:show, :statistics]
|
10
10
|
|
11
11
|
helper Decidim::AttachmentsHelper
|
12
12
|
helper Decidim::IconHelper
|
@@ -16,7 +16,7 @@ module Decidim
|
|
16
16
|
|
17
17
|
helper ParticipatoryProcessHelper
|
18
18
|
|
19
|
-
helper_method :collection, :promoted_participatory_processes, :participatory_processes, :stats, :filter
|
19
|
+
helper_method :collection, :promoted_participatory_processes, :participatory_processes, :stats, :metrics, :filter
|
20
20
|
helper_method :process_count_by_filter
|
21
21
|
|
22
22
|
def index
|
@@ -27,7 +27,11 @@ module Decidim
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def show
|
30
|
-
|
30
|
+
enforce_permission_to :read, :process, process: current_participatory_space
|
31
|
+
end
|
32
|
+
|
33
|
+
def statistics
|
34
|
+
enforce_permission_to :read, :process, process: current_participatory_space
|
31
35
|
end
|
32
36
|
|
33
37
|
private
|
@@ -57,11 +61,11 @@ module Decidim
|
|
57
61
|
end
|
58
62
|
|
59
63
|
def participatory_processes
|
60
|
-
@participatory_processes ||= filtered_participatory_processes(filter)
|
64
|
+
@participatory_processes ||= filtered_participatory_processes(filter).query.where(decidim_participatory_process_group_id: nil)
|
61
65
|
end
|
62
66
|
|
63
67
|
def promoted_participatory_processes
|
64
|
-
@promoted_participatory_processes ||= filtered_participatory_processes | PromotedParticipatoryProcesses.new
|
68
|
+
@promoted_participatory_processes ||= filtered_participatory_processes("all") | PromotedParticipatoryProcesses.new
|
65
69
|
end
|
66
70
|
|
67
71
|
def filtered_participatory_process_groups(filter_name = filter)
|
@@ -76,6 +80,10 @@ module Decidim
|
|
76
80
|
@stats ||= ParticipatoryProcessStatsPresenter.new(participatory_process: current_participatory_space)
|
77
81
|
end
|
78
82
|
|
83
|
+
def metrics
|
84
|
+
@metrics ||= ParticipatoryProcessMetricChartsPresenter.new(participatory_process: current_participatory_space)
|
85
|
+
end
|
86
|
+
|
79
87
|
def filter
|
80
88
|
@filter = params[:filter] || default_filter
|
81
89
|
end
|
@@ -91,7 +99,7 @@ module Decidim
|
|
91
99
|
return @process_count_by_filter if @process_count_by_filter
|
92
100
|
|
93
101
|
@process_count_by_filter = %w(active upcoming past).inject({}) do |collection_by_filter, filter_name|
|
94
|
-
processes = filtered_participatory_processes(filter_name)
|
102
|
+
processes = filtered_participatory_processes(filter_name).query.where(decidim_participatory_process_group_id: nil)
|
95
103
|
groups = filtered_participatory_process_groups(filter_name)
|
96
104
|
collection_by_filter.merge(filter_name.to_s => processes.count + groups.count)
|
97
105
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen-string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
class ParticipatoryProcessStepActivatedEvent < Decidim::Events::SimpleEvent
|
5
|
+
include Rails.application.routes.mounted_helpers
|
6
|
+
|
7
|
+
def resource_path
|
8
|
+
@resource_path ||= decidim_participatory_processes.participatory_process_participatory_process_steps_path(participatory_process_slug: participatory_space.slug)
|
9
|
+
end
|
10
|
+
|
11
|
+
def resource_url
|
12
|
+
@resource_url ||= decidim_participatory_processes
|
13
|
+
.participatory_process_participatory_process_steps_url(
|
14
|
+
participatory_process_slug: participatory_space.slug,
|
15
|
+
host: participatory_space.organization.host
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
def participatory_space
|
20
|
+
resource.participatory_process
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen-string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
class ParticipatoryProcessStepChangedEvent < Decidim::Events::SimpleEvent
|
5
|
+
include Rails.application.routes.mounted_helpers
|
6
|
+
|
7
|
+
def resource_path
|
8
|
+
@resource_path ||= decidim_participatory_processes.participatory_process_participatory_process_steps_path(participatory_process_slug: participatory_space.slug)
|
9
|
+
end
|
10
|
+
|
11
|
+
def resource_url
|
12
|
+
@resource_url ||= decidim_participatory_processes
|
13
|
+
.participatory_process_participatory_process_steps_url(
|
14
|
+
participatory_process_slug: participatory_space.slug,
|
15
|
+
host: participatory_space.organization.host
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
def participatory_space
|
20
|
+
resource.participatory_process
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -66,6 +66,22 @@ module Decidim
|
|
66
66
|
where(promoted: true)
|
67
67
|
end
|
68
68
|
|
69
|
+
def self.private_processes
|
70
|
+
where(private_space: true)
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.active_spaces
|
74
|
+
active
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.future_spaces
|
78
|
+
upcoming
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.past_spaces
|
82
|
+
past
|
83
|
+
end
|
84
|
+
|
69
85
|
def self.log_presenter_class_for(_log)
|
70
86
|
Decidim::ParticipatoryProcesses::AdminLog::ParticipatoryProcessPresenter
|
71
87
|
end
|
@@ -83,10 +99,6 @@ module Decidim
|
|
83
99
|
slug
|
84
100
|
end
|
85
101
|
|
86
|
-
def self.private_processes
|
87
|
-
where(private_space: true)
|
88
|
-
end
|
89
|
-
|
90
102
|
def can_participate?(user)
|
91
103
|
return true unless private_space?
|
92
104
|
return true if private_space? && users.include?(user)
|
@@ -21,7 +21,7 @@ module Decidim
|
|
21
21
|
validates :position, numericality: { greater_than_or_equal_to: 0, only_integer: true }, allow_blank: true
|
22
22
|
validates :position, uniqueness: { scope: :decidim_participatory_process_id }
|
23
23
|
|
24
|
-
|
24
|
+
before_validation :set_position, on: :create
|
25
25
|
|
26
26
|
def self.log_presenter_class_for(_log)
|
27
27
|
Decidim::ParticipatoryProcesses::AdminLog::StepPresenter
|
@@ -42,7 +42,7 @@ module Decidim
|
|
42
42
|
return if position.present?
|
43
43
|
return self.position = 0 if participatory_process.steps.select(&:persisted?).empty?
|
44
44
|
|
45
|
-
self.position = participatory_process.steps.
|
45
|
+
self.position = participatory_process.steps.maximum(:position) + 1
|
46
46
|
end
|
47
47
|
end
|
48
48
|
end
|
@@ -35,7 +35,6 @@ module Decidim
|
|
35
35
|
user_can_read_process_list?
|
36
36
|
user_can_read_current_process?
|
37
37
|
user_can_create_process?
|
38
|
-
user_can_destroy_process?
|
39
38
|
|
40
39
|
# org admins and space admins can do everything in the admin section
|
41
40
|
org_admin_action?
|
@@ -102,11 +101,17 @@ module Decidim
|
|
102
101
|
[:process, :participatory_space].include?(permission_action.subject) &&
|
103
102
|
process
|
104
103
|
|
104
|
+
return disallow! if cannot_view_private_space
|
105
105
|
return allow! if user&.admin?
|
106
106
|
return allow! if process.published?
|
107
107
|
toggle_allow(can_manage_process?)
|
108
108
|
end
|
109
109
|
|
110
|
+
def cannot_view_private_space
|
111
|
+
return unless process.private_space
|
112
|
+
!user || !user.admin && !process.users.include?(user)
|
113
|
+
end
|
114
|
+
|
110
115
|
def public_report_content_action?
|
111
116
|
return unless permission_action.action == :create &&
|
112
117
|
permission_action.subject == :moderation
|
@@ -164,14 +169,6 @@ module Decidim
|
|
164
169
|
toggle_allow(user.admin?)
|
165
170
|
end
|
166
171
|
|
167
|
-
# Only organization admins can destroy a process
|
168
|
-
def user_can_destroy_process?
|
169
|
-
return unless permission_action.action == :destroy &&
|
170
|
-
permission_action.subject == :process
|
171
|
-
|
172
|
-
toggle_allow(user.admin?)
|
173
|
-
end
|
174
|
-
|
175
172
|
# Everyone can read the process list
|
176
173
|
def user_can_read_process_list?
|
177
174
|
return unless read_process_list_permission_action?
|
@@ -201,14 +198,12 @@ module Decidim
|
|
201
198
|
|
202
199
|
# Process admins can eprform everything *inside* that process. They cannot
|
203
200
|
# create a process or perform actions on process groups or other
|
204
|
-
# processes.
|
201
|
+
# processes.
|
205
202
|
def process_admin_action?
|
206
203
|
return unless can_manage_process?(role: :admin)
|
207
204
|
return if user.admin?
|
208
205
|
return disallow! if permission_action.action == :create &&
|
209
206
|
permission_action.subject == :process
|
210
|
-
return disallow! if permission_action.action == :destroy &&
|
211
|
-
permission_action.subject == :process
|
212
207
|
|
213
208
|
is_allowed = [
|
214
209
|
:attachment,
|
data/app/presenters/decidim/participatory_processes/participatory_process_metric_charts_presenter.rb
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module ParticipatoryProcesses
|
5
|
+
# A presenter to render metrics in ParticipatoryProcesses statistics page
|
6
|
+
class ParticipatoryProcessMetricChartsPresenter < Decidim::MetricChartsPresenter
|
7
|
+
attribute :participatory_process, Decidim::ParticipatoryProcess
|
8
|
+
|
9
|
+
def params
|
10
|
+
capture do
|
11
|
+
concat(content_tag(:input, nil, type: :hidden, id: :"metrics-space_type", value: participatory_process.class))
|
12
|
+
concat(content_tag(:input, nil, type: :hidden, id: :"metrics-space_id", value: participatory_process.id))
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def highlighted
|
17
|
+
render_highlighted(Decidim.metrics_registry.filtered(highlight: true, scope: "participatory_process"))
|
18
|
+
end
|
19
|
+
|
20
|
+
def not_highlighted
|
21
|
+
render_not_highlighted(Decidim.metrics_registry.filtered(highlight: false, scope: "participatory_process"))
|
22
|
+
end
|
23
|
+
|
24
|
+
def big_stats
|
25
|
+
safe_join(
|
26
|
+
Decidim.metrics_registry.filtered(scope: "participatory_process", block: "big", sort: true).map do |metric_manifest|
|
27
|
+
content_tag :div, class: "row" do
|
28
|
+
render_metrics_descriptive(metric_manifest.metric_name,
|
29
|
+
klass: "column",
|
30
|
+
graph_klass: "small",
|
31
|
+
title: I18n.t("decidim.metrics.#{metric_manifest.metric_name}.title"),
|
32
|
+
description: I18n.t("decidim.metrics.#{metric_manifest.metric_name}.description"),
|
33
|
+
download: true,
|
34
|
+
data: { ratio: "11:4", axis: true })
|
35
|
+
end
|
36
|
+
end
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
40
|
+
def medium_stats
|
41
|
+
safe_join(
|
42
|
+
Decidim.metrics_registry.filtered(scope: "participatory_process", block: "medium", sort: true).in_groups_of(2).map do |metrics_group|
|
43
|
+
content_tag :div, class: "row" do
|
44
|
+
safe_join(
|
45
|
+
metrics_group.map do |metric_manifest|
|
46
|
+
next "" if metric_manifest.blank?
|
47
|
+
render_metrics_descriptive(metric_manifest.metric_name,
|
48
|
+
klass: "column medium-6",
|
49
|
+
graph_klass: "small",
|
50
|
+
title: I18n.t("decidim.metrics.#{metric_manifest.metric_name}.title"),
|
51
|
+
description: I18n.t("decidim.metrics.#{metric_manifest.metric_name}.description"),
|
52
|
+
download: true,
|
53
|
+
data: { ratio: "16:9", axis: true })
|
54
|
+
end
|
55
|
+
)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
)
|
59
|
+
end
|
60
|
+
|
61
|
+
def small_stats
|
62
|
+
safe_join(
|
63
|
+
Decidim.metrics_registry.filtered(scope: "participatory_process", block: "small", sort: true).in_groups_of(3).map do |metrics_group|
|
64
|
+
content_tag :div, class: "row" do
|
65
|
+
safe_join(
|
66
|
+
metrics_group.map do |metric_manifest|
|
67
|
+
next "" if metric_manifest.blank?
|
68
|
+
render_metrics_data(metric_manifest.metric_name,
|
69
|
+
klass: "column medium-4",
|
70
|
+
ratio: "16:9",
|
71
|
+
margin: "margin-top: 30px",
|
72
|
+
graph_klass: "small",
|
73
|
+
download: true,
|
74
|
+
data: { ratio: "16:9" })
|
75
|
+
end
|
76
|
+
)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module ParticipatoryProcesses
|
5
|
+
module Metrics
|
6
|
+
# Searches for unique Users following the next objects
|
7
|
+
# - ParticipatoryProcesses
|
8
|
+
class ParticipatoryProcessFollowersMetricMeasure < Decidim::MetricMeasure
|
9
|
+
def valid?
|
10
|
+
super && @resource.is_a?(Decidim::Participable)
|
11
|
+
end
|
12
|
+
|
13
|
+
def calculate
|
14
|
+
participatory_process = @resource
|
15
|
+
|
16
|
+
process_followers = Decidim::Follow.where(followable: participatory_process).joins(:user)
|
17
|
+
.where("decidim_follows.created_at <= ?", end_time)
|
18
|
+
cumulative_users = process_followers.pluck(:decidim_user_id)
|
19
|
+
|
20
|
+
process_followers = process_followers.where("decidim_follows.created_at >= ?", start_time)
|
21
|
+
quantity_users = process_followers.pluck(:decidim_user_id)
|
22
|
+
|
23
|
+
{
|
24
|
+
cumulative_users: cumulative_users.uniq,
|
25
|
+
quantity_users: quantity_users.uniq
|
26
|
+
}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|