decidim-participatory_processes 0.30.2 → 0.31.0.rc1

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 (127) hide show
  1. checksums.yaml +4 -4
  2. data/app/cells/decidim/participatory_process_groups/content_blocks/main_data/content.erb +1 -1
  3. data/app/cells/decidim/participatory_process_groups/content_blocks/main_data_cell.rb +1 -15
  4. data/app/cells/decidim/participatory_processes/content_blocks/democratic_quality_stats/show.erb +74 -0
  5. data/app/cells/decidim/participatory_processes/content_blocks/democratic_quality_stats_cell.rb +29 -0
  6. data/app/cells/decidim/participatory_processes/content_blocks/democratic_quality_stats_settings_form/citizen_influence.erb +32 -0
  7. data/app/cells/decidim/participatory_processes/content_blocks/democratic_quality_stats_settings_form/inclusiveness.erb +69 -0
  8. data/app/cells/decidim/participatory_processes/content_blocks/democratic_quality_stats_settings_form/informativeness.erb +29 -0
  9. data/app/cells/decidim/participatory_processes/content_blocks/democratic_quality_stats_settings_form/show.erb +10 -0
  10. data/app/cells/decidim/participatory_processes/content_blocks/democratic_quality_stats_settings_form_cell.rb +81 -0
  11. data/app/cells/decidim/participatory_processes/content_blocks/highlighted_processes_settings_form/show.erb +3 -1
  12. data/app/cells/decidim/participatory_processes/content_blocks/main_data_cell.rb +10 -2
  13. data/app/cells/decidim/participatory_processes/indicator/show.erb +11 -0
  14. data/app/cells/decidim/participatory_processes/indicator_cell.rb +25 -0
  15. data/app/cells/decidim/participatory_processes/process_dropdown_metadata/metadata.erb +0 -7
  16. data/app/cells/decidim/participatory_processes/process_filters_cell.rb +2 -0
  17. data/app/cells/decidim/participatory_processes/process_step/show.erb +1 -1
  18. data/app/commands/decidim/participatory_processes/admin/create_participatory_process.rb +1 -1
  19. data/app/commands/decidim/participatory_processes/admin/create_participatory_process_group.rb +1 -1
  20. data/app/commands/decidim/participatory_processes/admin/{copy_participatory_process.rb → duplicate_participatory_process.rb} +25 -26
  21. data/app/commands/decidim/participatory_processes/admin/import_participatory_process.rb +1 -1
  22. data/app/commands/decidim/participatory_processes/admin/update_participatory_process.rb +16 -4
  23. data/app/commands/decidim/participatory_processes/admin/update_participatory_process_group.rb +1 -1
  24. data/app/controllers/decidim/participatory_processes/admin/{participatory_process_copies_controller.rb → participatory_process_duplicates_controller.rb} +7 -7
  25. data/app/controllers/decidim/participatory_processes/admin/participatory_process_group_landing_page_controller.rb +4 -0
  26. data/app/controllers/decidim/participatory_processes/admin/participatory_process_groups_controller.rb +3 -3
  27. data/app/controllers/decidim/participatory_processes/admin/participatory_process_imports_controller.rb +1 -1
  28. data/app/controllers/decidim/participatory_processes/admin/participatory_process_landing_page_controller.rb +4 -0
  29. data/app/controllers/decidim/participatory_processes/admin/participatory_process_steps_controller.rb +2 -2
  30. data/app/controllers/decidim/participatory_processes/admin/participatory_processes_controller.rb +3 -3
  31. data/app/controllers/decidim/participatory_processes/participatory_processes_controller.rb +0 -9
  32. data/app/forms/decidim/participatory_processes/admin/{participatory_process_copy_form.rb → participatory_process_duplicate_form.rb} +5 -5
  33. data/app/forms/decidim/participatory_processes/admin/participatory_process_form.rb +2 -1
  34. data/app/forms/decidim/participatory_processes/admin/participatory_process_group_form.rb +0 -1
  35. data/app/helpers/decidim/participatory_processes/application_helper.rb +14 -0
  36. data/app/models/decidim/participatory_process.rb +4 -4
  37. data/app/models/decidim/participatory_process_group.rb +9 -0
  38. data/app/permissions/decidim/participatory_processes/permissions.rb +4 -4
  39. data/app/presenters/decidim/participatory_processes/admin_log/participatory_process_group_presenter.rb +0 -1
  40. data/app/presenters/decidim/participatory_processes/admin_log/participatory_process_presenter.rb +0 -1
  41. data/app/presenters/decidim/participatory_processes/participatory_process_democratic_quality_stats_presenter.rb +312 -0
  42. data/app/presenters/decidim/participatory_processes/participatory_process_group_stats_presenter.rb +1 -11
  43. data/app/presenters/decidim/participatory_processes/participatory_process_presenter.rb +35 -1
  44. data/app/presenters/decidim/participatory_processes/participatory_process_stats_presenter.rb +1 -3
  45. data/app/queries/decidim/participatory_processes/participatory_processes_stats_followers_count.rb +31 -0
  46. data/app/queries/decidim/participatory_processes/participatory_processes_stats_participants_count.rb +27 -0
  47. data/app/serializers/decidim/participatory_processes/participatory_process_importer.rb +0 -1
  48. data/app/views/decidim/participatory_processes/admin/{participatory_process_copies → participatory_process_duplicates}/_form.html.erb +5 -5
  49. data/app/views/decidim/participatory_processes/admin/participatory_process_duplicates/new.html.erb +19 -0
  50. data/app/views/decidim/participatory_processes/admin/participatory_process_groups/_form.html.erb +3 -7
  51. data/app/views/decidim/participatory_processes/admin/participatory_process_groups/index.html.erb +31 -15
  52. data/app/views/decidim/participatory_processes/admin/participatory_process_steps/_form.html.erb +1 -1
  53. data/app/views/decidim/participatory_processes/admin/participatory_process_steps/index.html.erb +39 -21
  54. data/app/views/decidim/participatory_processes/admin/participatory_process_user_roles/index.html.erb +42 -24
  55. data/app/views/decidim/participatory_processes/admin/participatory_processes/_form.html.erb +10 -14
  56. data/app/views/decidim/participatory_processes/admin/participatory_processes/_process_row.html.erb +125 -53
  57. data/app/views/decidim/participatory_processes/admin/participatory_processes/edit.html.erb +0 -8
  58. data/app/views/decidim/participatory_processes/admin/participatory_processes/index.html.erb +2 -2
  59. data/app/views/decidim/participatory_processes/admin/participatory_processes/manage_trash.html.erb +2 -1
  60. data/app/views/layouts/decidim/admin/_manage_processes.html.erb +1 -1
  61. data/app/views/layouts/decidim/admin/participatory_process_group.html.erb +1 -1
  62. data/config/assets.rb +2 -2
  63. data/config/locales/ar.yml +0 -13
  64. data/config/locales/bg.yml +0 -24
  65. data/config/locales/bs-BA.yml +0 -4
  66. data/config/locales/ca-IT.yml +319 -25
  67. data/config/locales/ca.yml +319 -25
  68. data/config/locales/cs.yml +93 -26
  69. data/config/locales/de.yml +123 -25
  70. data/config/locales/el.yml +0 -21
  71. data/config/locales/en.yml +303 -24
  72. data/config/locales/es-MX.yml +319 -25
  73. data/config/locales/es-PY.yml +319 -25
  74. data/config/locales/es.yml +319 -25
  75. data/config/locales/eu.yml +304 -25
  76. data/config/locales/fi-plain.yml +303 -24
  77. data/config/locales/fi.yml +303 -24
  78. data/config/locales/fr-CA.yml +86 -24
  79. data/config/locales/fr.yml +86 -24
  80. data/config/locales/ga-IE.yml +0 -7
  81. data/config/locales/gl.yml +0 -19
  82. data/config/locales/hu.yml +0 -21
  83. data/config/locales/id-ID.yml +0 -13
  84. data/config/locales/is-IS.yml +0 -11
  85. data/config/locales/it.yml +0 -20
  86. data/config/locales/ja.yml +123 -25
  87. data/config/locales/lb.yml +0 -20
  88. data/config/locales/lt.yml +0 -21
  89. data/config/locales/lv.yml +0 -14
  90. data/config/locales/nl.yml +0 -20
  91. data/config/locales/no.yml +0 -21
  92. data/config/locales/pl.yml +16 -24
  93. data/config/locales/pt-BR.yml +0 -23
  94. data/config/locales/pt.yml +0 -20
  95. data/config/locales/ro-RO.yml +2 -21
  96. data/config/locales/ru.yml +0 -11
  97. data/config/locales/sk.yml +0 -14
  98. data/config/locales/sr-CS.yml +0 -4
  99. data/config/locales/sv.yml +86 -24
  100. data/config/locales/tr-TR.yml +0 -20
  101. data/config/locales/uk.yml +0 -11
  102. data/config/locales/zh-CN.yml +0 -17
  103. data/config/locales/zh-TW.yml +0 -21
  104. data/db/migrate/20250403110052_add_democratic_quality_static_page.rb +34 -0
  105. data/db/migrate/20250605114136_remove_hashtag_from_participatory_processes.rb +7 -0
  106. data/db/migrate/20250605114415_remove_hashtag_from_participatory_processes_groups.rb +7 -0
  107. data/decidim-participatory_processes.gemspec +3 -0
  108. data/lib/decidim/api/participatory_process_group_type.rb +9 -0
  109. data/lib/decidim/api/participatory_process_input_filter.rb +0 -1
  110. data/lib/decidim/api/participatory_process_step_type.rb +2 -0
  111. data/lib/decidim/api/participatory_process_type.rb +17 -11
  112. data/lib/decidim/participatory_processes/admin_engine.rb +1 -1
  113. data/lib/decidim/participatory_processes/content_blocks/registry_manager.rb +25 -5
  114. data/lib/decidim/participatory_processes/engine.rb +22 -25
  115. data/lib/decidim/participatory_processes/participatory_space.rb +1 -4
  116. data/lib/decidim/participatory_processes/seeds.rb +3 -5
  117. data/lib/decidim/participatory_processes/test/factories.rb +2 -3
  118. data/lib/decidim/participatory_processes/version.rb +1 -1
  119. metadata +72 -22
  120. data/app/cells/decidim/participatory_processes/content_blocks/metrics_cell.rb +0 -25
  121. data/app/presenters/decidim/participatory_processes/participatory_process_metric_charts_presenter.rb +0 -21
  122. data/app/queries/decidim/participatory_processes/metrics/participatory_process_followers_metric_measure.rb +0 -31
  123. data/app/queries/decidim/participatory_processes/metrics/participatory_processes_metric_manage.rb +0 -27
  124. data/app/queries/decidim/participatory_processes/stats_followers_count.rb +0 -60
  125. data/app/queries/decidim/participatory_processes/stats_participants_count.rb +0 -136
  126. data/app/views/decidim/participatory_processes/admin/participatory_process_copies/new.html.erb +0 -19
  127. data/app/views/decidim/participatory_processes/participatory_processes/all_metrics.html.erb +0 -25
@@ -0,0 +1,312 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module ParticipatoryProcesses
5
+ # Presenter class for calculating and displaying democratic quality statistics
6
+ # for a participatory process. It handles both automatic metrics and manual
7
+ # auto-evaluation metrics.
8
+ class ParticipatoryProcessDemocraticQualityStatsPresenter
9
+ attr_reader :content_block, :participatory_process
10
+
11
+ def initialize(content_block, participatory_process)
12
+ @content_block = content_block
13
+ @participatory_process = participatory_process
14
+ end
15
+
16
+ def stats
17
+ @stats ||= {
18
+ global_score: calculate_global_score, precision: 2,
19
+ # Automatic metrics based on platform data
20
+ automatic: {
21
+ influence: calculate_automatic_influence,
22
+ hybridization: calculate_automatic_hybridization,
23
+ transparency: calculate_automatic_transparency,
24
+ traceability: calculate_automatic_traceability
25
+ },
26
+ # Auto-evaluation metrics based on survey responses
27
+ auto_evaluation: {
28
+ inclusiveness: calculate_auto_evaluation_inclusiveness,
29
+ citizen_influence: calculate_auto_evaluation_citizen_influence,
30
+ informativeness: calculate_auto_evaluation_informativeness
31
+ }
32
+ }
33
+ end
34
+
35
+ # @return [Boolean]
36
+ def finished_survey?
37
+ settings.functional_diversity_invited != -1 &&
38
+ settings.languages_communicated != -1 &&
39
+ settings.mobility_meeting_access != -1 &&
40
+ settings.participation_scheduling_times != -1 &&
41
+ settings.digital_support_offered != -1 &&
42
+ settings.citizen_influence_level != -1 &&
43
+ settings.citizen_decisional_intervention != -1 &&
44
+ settings.published_information_clarity != -1 &&
45
+ settings.information_provided != -1
46
+ end
47
+
48
+ private
49
+
50
+ # Global score
51
+
52
+ # @return [Float]
53
+ def calculate_global_score
54
+ automatic_metrics = (
55
+ calculate_automatic_influence +
56
+ calculate_automatic_hybridization +
57
+ calculate_automatic_transparency +
58
+ calculate_automatic_traceability
59
+ ) / 4.0
60
+
61
+ if finished_survey?
62
+ auto_evaluation_metrics = (
63
+ calculate_auto_evaluation_inclusiveness +
64
+ calculate_auto_evaluation_citizen_influence +
65
+ calculate_auto_evaluation_informativeness
66
+ ) / 4.0
67
+
68
+ (automatic_metrics + auto_evaluation_metrics) / 2.0
69
+ else
70
+ automatic_metrics
71
+ end
72
+ end
73
+
74
+ # Automatic metrics
75
+
76
+ # Influence
77
+
78
+ # @return [Float]
79
+ def calculate_automatic_influence
80
+ (approved_proposals_score +
81
+ approved_citizen_proposals_relative_score +
82
+ approved_citizen_proposals_absolute_score +
83
+ citizen_linked_results_score) / 4.0
84
+ end
85
+
86
+ # @return [Float]
87
+ def approved_proposals_score
88
+ percentage_to_scale(all_proposals.accepted.count, all_proposals.count)
89
+ end
90
+
91
+ # @return [Float]
92
+ def approved_citizen_proposals_relative_score
93
+ approved_citizen_proposals_count = all_proposals.accepted.with_participants_origin.count
94
+ total_citizen_proposals_count = all_proposals.with_participants_origin.count
95
+
96
+ percentage_to_scale(approved_citizen_proposals_count, total_citizen_proposals_count)
97
+ end
98
+
99
+ # @return [Float]
100
+ def approved_citizen_proposals_absolute_score
101
+ approved_citizen_proposals_count = all_proposals.accepted.with_participants_origin.count
102
+
103
+ percentage_to_scale(approved_citizen_proposals_count, all_proposals.accepted.count)
104
+ end
105
+
106
+ # @return [Float]
107
+ def citizen_linked_results_score
108
+ citizen_results = all_proposals
109
+ .with_participants_origin
110
+ .joins(:resource_links_from)
111
+ .where(
112
+ decidim_resource_links: {
113
+ name: "linked_results",
114
+ to_type: "Decidim::Accountability::Result"
115
+ }
116
+ )
117
+
118
+ percentage_to_scale(citizen_results.count, all_accountability_results.count)
119
+ end
120
+
121
+ # Hybridization
122
+
123
+ # @return [Float]
124
+ def calculate_automatic_hybridization
125
+ (meetings_component_score +
126
+ meetings_online_score +
127
+ meetings_in_person_score +
128
+ meetings_hybrid_score +
129
+ meetings_with_proposals_score) / 5.0
130
+ end
131
+
132
+ # @return [Float]
133
+ def meetings_component_score
134
+ components.where(manifest_name: "meetings").any? ? 5.0 : 0.0
135
+ end
136
+
137
+ # @return [Float]
138
+ def meetings_online_score
139
+ all_meetings.online.any? ? 5.0 : 0.0
140
+ end
141
+
142
+ # @return [Float]
143
+ def meetings_in_person_score
144
+ all_meetings.in_person.any? ? 5.0 : 0.0
145
+ end
146
+
147
+ # @return [Float]
148
+ def meetings_hybrid_score
149
+ all_meetings.hybrid.any? ? 5.0 : 0.0
150
+ end
151
+
152
+ # @return [Float]
153
+ def meetings_with_proposals_score
154
+ if all_meetings.joins(:resource_links_to)
155
+ .where(
156
+ decidim_resource_links: {
157
+ name: "proposals_from_meeting",
158
+ to_type: "Decidim::Meetings::Meeting"
159
+ }
160
+ )
161
+ .any?
162
+ 5.0
163
+ else
164
+ 0.0
165
+ end
166
+ end
167
+
168
+ # Transparency
169
+
170
+ # @return [Float]
171
+ def calculate_automatic_transparency
172
+ [
173
+ answered_proposals_score,
174
+ completed_results_score
175
+ ].sum / 2.0
176
+ end
177
+
178
+ # @return [Float]
179
+ def answered_proposals_score
180
+ percentage_to_scale(all_proposals.answered.count, all_proposals.count)
181
+ end
182
+
183
+ # @return [Float]
184
+ def completed_results_score
185
+ results = all_accountability_results.where(progress: 100)
186
+ percentage_to_scale(results.count, all_accountability_results.count)
187
+ end
188
+
189
+ # Traceability
190
+
191
+ # @return [Float]
192
+ def calculate_automatic_traceability
193
+ [
194
+ proposals_with_history_score,
195
+ linked_results_score,
196
+ quality_meetings_score,
197
+ proposals_linked_to_budgets_score
198
+ ].sum / 4.0
199
+ end
200
+
201
+ # @return [Float]
202
+ def proposals_with_history_score
203
+ linked_proposals_ids = (
204
+ all_proposals.joins(:resource_links_from).pluck(:id) +
205
+ all_proposals.joins(:resource_links_to).pluck(:id)
206
+ ).uniq
207
+
208
+ percentage_to_scale(linked_proposals_ids.count, all_proposals.count)
209
+ end
210
+
211
+ # @return [Float]
212
+ def linked_results_score
213
+ results = all_proposals
214
+ .joins(:resource_links_from)
215
+ .where(
216
+ decidim_resource_links: {
217
+ name: "linked_results",
218
+ to_type: "Decidim::Accountability::Result"
219
+ }
220
+ )
221
+ percentage_to_scale(results.count, all_proposals.count)
222
+ end
223
+
224
+ # @return [Float]
225
+ def quality_meetings_score
226
+ meetings = all_meetings
227
+ .where.not(type_of_meeting: Decidim::Meetings::Meeting::TYPE_OF_MEETING[:online])
228
+ .where.not(end_time: nil)
229
+
230
+ percentage_to_scale(meetings.count, all_meetings.count)
231
+ end
232
+
233
+ # @return [Float]
234
+ def proposals_linked_to_budgets_score
235
+ proposals = all_proposals
236
+ .joins(:resource_links_to)
237
+ .where(decidim_resource_links: { name: "included_proposals", from_type: "Decidim::Budgets::Project" })
238
+
239
+ percentage_to_scale(proposals.count, all_proposals.count)
240
+ end
241
+
242
+ # Auto-evaluation metrics
243
+
244
+ # @return [Float]
245
+ def calculate_auto_evaluation_inclusiveness
246
+ [
247
+ settings.functional_diversity_invited,
248
+ settings.languages_communicated,
249
+ settings.mobility_meeting_access,
250
+ settings.participation_scheduling_times,
251
+ settings.digital_support_offered
252
+ ].sum / 5.0
253
+ end
254
+
255
+ # @return [Float]
256
+ def calculate_auto_evaluation_citizen_influence
257
+ (settings.citizen_influence_level + settings.citizen_decisional_intervention) / 2.0
258
+ end
259
+
260
+ # @return [Float]
261
+ def calculate_auto_evaluation_informativeness
262
+ (settings.published_information_clarity + settings.information_provided) / 2.0
263
+ end
264
+
265
+ # @return [Float]
266
+ def percentage_to_scale(value, total)
267
+ return 1.0 if total.zero?
268
+
269
+ percentage = (value.to_f / total) * 100
270
+ case percentage
271
+ when 0..20 then 1.0
272
+ when 20.1..40 then 2.0
273
+ when 40.1..60 then 3.0
274
+ when 60.1..80 then 4.0
275
+ else 5.0
276
+ end
277
+ end
278
+
279
+ def settings
280
+ content_block.settings
281
+ end
282
+
283
+ def all_proposals
284
+ Decidim::Proposals::Proposal.where(component: proposals_components)
285
+ end
286
+
287
+ def all_meetings
288
+ Decidim::Meetings::Meeting.where(component: meetings_components)
289
+ end
290
+
291
+ def all_accountability_results
292
+ Decidim::Accountability::Result.where(component: accountability_components)
293
+ end
294
+
295
+ def proposals_components
296
+ @proposals_components ||= components.where(manifest_name: "proposals")
297
+ end
298
+
299
+ def meetings_components
300
+ @meetings_components ||= components.where(manifest_name: "meetings")
301
+ end
302
+
303
+ def accountability_components
304
+ @accountability_components ||= components.where(manifest_name: "accountability")
305
+ end
306
+
307
+ def components
308
+ @components ||= participatory_process.components
309
+ end
310
+ end
311
+ end
312
+ end
@@ -8,17 +8,7 @@ module Decidim
8
8
 
9
9
  private
10
10
 
11
- def participatory_space = __getobj__.fetch(:participatory_process_group)
12
-
13
- def participatory_space_sym = :participatory_process_group
14
-
15
- def participatory_processes
16
- @participatory_processes ||= participatory_space.participatory_processes
17
- end
18
-
19
- def published_components
20
- @published_components ||= Component.where(participatory_space: participatory_processes).published
21
- end
11
+ def scope_entity = __getobj__.fetch(:participatory_process_group)
22
12
  end
23
13
  end
24
14
  end
@@ -2,7 +2,11 @@
2
2
 
3
3
  module Decidim
4
4
  module ParticipatoryProcesses
5
- class ParticipatoryProcessPresenter < SimpleDelegator
5
+ class ParticipatoryProcessPresenter < ResourcePresenter
6
+ include Decidim::ResourceHelper
7
+ include ActionView::Helpers::UrlHelper
8
+ include Decidim::SanitizeHelper
9
+
6
10
  def hero_image_url
7
11
  process.attached_uploader(:hero_image).url
8
12
  end
@@ -13,6 +17,36 @@ module Decidim
13
17
  Decidim::AreaPresenter.new(process.area).translated_name_with_type
14
18
  end
15
19
 
20
+ def title(html_escape: false, all_locales: false)
21
+ return unless process
22
+
23
+ super(process.title, html_escape, all_locales)
24
+ end
25
+
26
+ def description(links: false, strip_tags: false, all_locales: false)
27
+ return unless process
28
+
29
+ content_handle_locale(process.description, all_locales, links, strip_tags)
30
+ end
31
+
32
+ def editor_description(all_locales: false)
33
+ return unless process
34
+
35
+ editor_locales(process.description, all_locales)
36
+ end
37
+
38
+ def short_description(links: false, strip_tags: false, all_locales: false)
39
+ return unless process
40
+
41
+ content_handle_locale(process.short_description, all_locales, links, strip_tags)
42
+ end
43
+
44
+ def editor_short_description(all_locales: false)
45
+ return unless process
46
+
47
+ editor_locales(process.short_description, all_locales)
48
+ end
49
+
16
50
  def process
17
51
  __getobj__
18
52
  end
@@ -8,9 +8,7 @@ module Decidim
8
8
 
9
9
  private
10
10
 
11
- def participatory_space = __getobj__.fetch(:participatory_process)
12
-
13
- def participatory_space_sym = :participatory_processes
11
+ def scope_entity = __getobj__.fetch(:participatory_process)
14
12
  end
15
13
  end
16
14
  end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module ParticipatoryProcesses
5
+ # This class counts all Followers of a participatory process or
6
+ # participatory processes belonging to a participatory process group
7
+ class ParticipatoryProcessesStatsFollowersCount < Decidim::StatsFollowersCount
8
+ def self.for(participatory_space)
9
+ return 0 unless participatory_space.is_a?(Decidim::ParticipatoryProcess) ||
10
+ (participatory_space.is_a?(Decidim::ParticipatoryProcessGroup) &&
11
+ participatory_space.participatory_processes.exists?)
12
+
13
+ new(participatory_space).query
14
+ end
15
+
16
+ private
17
+
18
+ def participatory_space_items
19
+ @participatory_space_items ||= if participatory_space.is_a?(Decidim::ParticipatoryProcess)
20
+ participatory_space
21
+ else
22
+ participatory_space.participatory_processes
23
+ end
24
+ end
25
+
26
+ def space_components
27
+ Decidim::Component.where(participatory_space: participatory_space_items).published
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module ParticipatoryProcesses
5
+ # This class counts unique Participants on a participatory process or
6
+ # participatory processes belonging to a participatory process group
7
+ class ParticipatoryProcessesStatsParticipantsCount < Decidim::StatsParticipantsCount
8
+ def self.for(participatory_space)
9
+ return 0 unless participatory_space.is_a?(Decidim::ParticipatoryProcess) ||
10
+ (participatory_space.is_a?(Decidim::ParticipatoryProcessGroup) &&
11
+ participatory_space.participatory_processes.exists?)
12
+
13
+ new(participatory_space).query
14
+ end
15
+
16
+ private
17
+
18
+ def space_components
19
+ @space_components ||= if participatory_space.is_a?(Decidim::ParticipatoryProcess)
20
+ participatory_space.components
21
+ else
22
+ Decidim::Component.where(participatory_space: participatory_space.participatory_processes)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -28,7 +28,6 @@ module Decidim
28
28
  title:,
29
29
  slug:,
30
30
  subtitle: attributes["subtitle"],
31
- hashtag: attributes["hashtag"],
32
31
  description: attributes["description"],
33
32
  short_description: attributes["short_description"],
34
33
  promoted: attributes["promoted"],
@@ -4,26 +4,26 @@
4
4
  <div class="row column">
5
5
  <%= form.translated :text_field, :title, autofocus: true, aria: { label: :title } %>
6
6
  </div>
7
- <div class="row column">
7
+ <div class="row column" data-controller="slug">
8
8
  <%= form.text_field :slug, help_text: t(".slug_help_html", url: decidim_form_slug_url(:processes, form.object.slug)) %>
9
9
  </div>
10
10
  <div class="row column">
11
11
  <div class="card">
12
12
  <div class="card-divider">
13
- <legend><%= t("participatory_process_copies.new.select", scope: "decidim.admin") %></legend>
13
+ <legend><%= t("participatory_process_duplicates.new.select", scope: "decidim.admin") %></legend>
14
14
  </div>
15
15
  <div class="card-section">
16
16
  <div class="row">
17
17
  <div class="columns">
18
- <%= form.check_box :copy_steps %>
18
+ <%= form.check_box :duplicate_steps %>
19
19
  </div>
20
20
 
21
21
  <div class="columns">
22
- <%= form.check_box :copy_components %>
22
+ <%= form.check_box :duplicate_components %>
23
23
  </div>
24
24
 
25
25
  <div class="columns">
26
- <%= form.check_box :copy_landing_page_blocks %>
26
+ <%= form.check_box :duplicate_landing_page_blocks %>
27
27
  </div>
28
28
  </div>
29
29
  </div>
@@ -0,0 +1,19 @@
1
+ <% add_decidim_page_title(t("participatory_process_duplicates.new.title", scope: "decidim.admin")) %>
2
+ <div class="item_show__header">
3
+ <h1 class="item_show__header-title">
4
+ <%= t("participatory_process_duplicates.new.title", scope: "decidim.admin") %>
5
+ </h1>
6
+ </div>
7
+
8
+ <div class="item__edit item__edit-1col">
9
+ <div class="item__edit-form">
10
+ <%= decidim_form_for(@form, url: participatory_process_duplicates_path(current_participatory_process), method: :post, html: { class: "form form-defaults duplicate_participatory_process" }) do |f| %>
11
+ <%= render partial: "form", object: f %>
12
+ <div class="item__edit-sticky">
13
+ <div class="item__edit-sticky-container">
14
+ <%= f.submit t("participatory_process_duplicates.new.duplicate", scope: "decidim.admin"), class: "button button__sm button__secondary" %>
15
+ </div>
16
+ </div>
17
+ <% end %>
18
+ </div>
19
+ </div>
@@ -1,5 +1,5 @@
1
1
  <div class="form__wrapper">
2
- <div class="card" data-component="accordion" id="accordion-title">
2
+ <div class="card" data-controller="accordion" id="accordion-title">
3
3
  <div class="card-divider">
4
4
  <button class="card-divider-button" data-open="true" data-controls="panel-title" type="button">
5
5
  <%= icon "arrow-right-s-line" %>
@@ -30,7 +30,7 @@
30
30
  </div>
31
31
  </div>
32
32
 
33
- <div class="card" data-component="accordion" id="accordion-metadata">
33
+ <div class="card" data-controller="accordion" id="accordion-metadata">
34
34
  <div class="card-divider">
35
35
  <button class="card-divider-button" data-open="true" data-controls="panel-metadata" type="button">
36
36
  <%= icon "arrow-right-s-line" %>
@@ -41,10 +41,6 @@
41
41
  </div>
42
42
 
43
43
  <div id="panel-metadata" class="card-section">
44
- <div class="row column">
45
- <%= form.text_field :hashtag %>
46
- </div>
47
-
48
44
  <div class="row column">
49
45
  <%= form.text_field :group_url %>
50
46
  </div>
@@ -75,7 +71,7 @@
75
71
  </div>
76
72
  </div>
77
73
 
78
- <div class="card" data-component="accordion" id="accordion-visibility">
74
+ <div class="card" data-controller="accordion" id="accordion-visibility">
79
75
  <div class="card-divider">
80
76
  <button class="card-divider-button" data-open="true" data-controls="panel-visibility" type="button">
81
77
  <%= icon "arrow-right-s-line" %>
@@ -15,18 +15,18 @@
15
15
  <%= admin_tabs(:admin_participatory_processes_menu).render %>
16
16
 
17
17
  <div class="card">
18
- <div class="table-scroll">
18
+ <div class="table-stacked">
19
19
  <table class="table-list">
20
20
  <thead>
21
21
  <tr>
22
22
  <th><%= t("models.participatory_process_group.fields.title", scope: "decidim.admin") %></th>
23
- <th></th>
23
+ <th><%= t("models.participatory_process_group.fields.actions", scope: "decidim.admin") %></th>
24
24
  </tr>
25
25
  </thead>
26
26
  <tbody>
27
27
  <% collection.each do |group| %>
28
28
  <tr>
29
- <td>
29
+ <td data-label="<%= t("models.participatory_process_group.fields.title", scope: "decidim.admin") %>">
30
30
  <% if group.promoted? %>
31
31
  <%= icon_with_tooltip "star-s-fill", t("models.assembly.fields.promoted", scope: "decidim.admin") %>
32
32
  <% end %>
@@ -36,20 +36,36 @@
36
36
  <%= translated_attribute(group.title) %>
37
37
  <% end %>
38
38
  </td>
39
- <td class="table-list__actions">
40
- <% if allowed_to? :update, :process_group, process_group: group %>
41
- <%= icon_link_to "pencil-line", [:edit, group], t("actions.edit", scope: "decidim.admin"), class: "action-icon--edit" %>
42
- <% else %>
43
- <span class="action-space icon"></span>
44
- <% end %>
39
+ <td class="table-list__actions" data-label="<%= t("models.participatory_process_group.fields.actions", scope: "decidim.admin") %>">
40
+ <button type="button" data-controller="dropdown" data-target="actions-process-group-<%= group.id %>" aria-label="<%= t("decidim.admin.actions.actions_label", resource: translated_attribute(group.title)) %>">
41
+ <%= icon "more-fill", class: "text-secondary" %>
42
+ </button>
45
43
 
46
- <%= icon_link_to "eye-line", decidim_participatory_processes.participatory_process_group_path(group), t("actions.preview", scope: "decidim.admin"), class: "action-icon--preview", target: "_blank", data: { "external-link": false } %>
44
+ <div class="inline-block relative">
45
+ <ul id="actions-process-group-<%= group.id %>" class="dropdown dropdown__action" aria-hidden="true">
46
+ <% if allowed_to? :update, :process_group, process_group: group %>
47
+ <li class="dropdown__item">
48
+ <%= link_to [:edit, group], class: "dropdown__button" do %>
49
+ <%= icon "pencil-line" %> <%= t("actions.edit", scope: "decidim.admin") %>
50
+ <% end %>
51
+ </li>
52
+ <% end %>
47
53
 
48
- <% if allowed_to? :destroy, :process_group, process_group: group %>
49
- <%= icon_link_to "delete-bin-line", group, t("actions.destroy", scope: "decidim.admin"), class: "action-icon--remove", method: :delete, data: { confirm: t("actions.confirm_destroy", scope: "decidim.admin") } %>
50
- <% else %>
51
- <span class="action-space icon"></span>
52
- <% end %>
54
+ <li class="dropdown__item">
55
+ <%= link_to decidim_participatory_processes.participatory_process_group_path(group), class: "dropdown__button", target: "_blank", data: { "external-link": false } do %>
56
+ <%= icon "eye-line" %> <%= t("actions.preview", scope: "decidim.admin") %>
57
+ <% end %>
58
+ </li>
59
+
60
+ <% if allowed_to? :destroy, :process_group, process_group: group %>
61
+ <li class="dropdown__item">
62
+ <%= link_to group, method: :delete, data: { confirm: t("actions.confirm_destroy", scope: "decidim.admin") }, class: "dropdown__button dropdown__button--danger" do %>
63
+ <%= icon "delete-bin-line" %> <%= t("actions.destroy", scope: "decidim.admin") %>
64
+ <% end %>
65
+ </li>
66
+ <% end %>
67
+ </ul>
68
+ </div>
53
69
  </td>
54
70
  </tr>
55
71
  <% end %>
@@ -17,7 +17,7 @@
17
17
  <%= form.datetime_field :end_date %>
18
18
  </div>
19
19
 
20
- <div class="row column slug">
20
+ <div class="row column" data-controller="slug">
21
21
  <%= form.text_field :cta_path,
22
22
  help_text: t(".cta_path_help_html", url: decidim_form_slug_url("processes/" + current_participatory_process.slug, form.object.cta_path)) %>
23
23
  </div>