decidim-participatory_processes 0.20.1 → 0.21.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/decidim/participatory_processes/admin/participatory_processes.js.es6 +6 -0
  3. data/app/cells/decidim/participatory_processes/statistic/show.erb +9 -0
  4. data/app/cells/decidim/participatory_processes/statistic_cell.rb +20 -0
  5. data/app/cells/decidim/participatory_processes/statistics/show.erb +17 -0
  6. data/app/cells/decidim/participatory_processes/statistics_cell.rb +18 -0
  7. data/app/commands/decidim/participatory_processes/admin/create_participatory_process.rb +13 -3
  8. data/app/commands/decidim/participatory_processes/admin/update_participatory_process.rb +16 -5
  9. data/app/controllers/concerns/decidim/participatory_processes/admin/filterable.rb +27 -0
  10. data/app/controllers/decidim/participatory_processes/admin/participatory_processes_controller.rb +6 -16
  11. data/app/controllers/decidim/participatory_processes/participatory_processes_controller.rb +17 -3
  12. data/app/forms/decidim/participatory_processes/admin/participatory_process_form.rb +13 -0
  13. data/app/functions/decidim/participatory_processes/participatory_process_finder.rb +10 -0
  14. data/app/functions/decidim/participatory_processes/participatory_process_list.rb +11 -0
  15. data/app/helpers/decidim/participatory_processes/admin/participatory_process_helper.rb +23 -0
  16. data/app/models/decidim/participatory_process.rb +12 -1
  17. data/app/models/decidim/participatory_process_user_role.rb +32 -0
  18. data/app/permissions/decidim/participatory_processes/permissions.rb +9 -0
  19. data/app/presenters/decidim/participatory_processes/participatory_process_stats_presenter.rb +32 -22
  20. data/app/queries/decidim/participatory_processes/stats_followers_count.rb +46 -0
  21. data/app/queries/decidim/participatory_processes/stats_participants_count.rb +98 -0
  22. data/app/serializers/decidim/participatory_processes/participatory_process_importer.rb +2 -0
  23. data/app/serializers/decidim/participatory_processes/participatory_process_serializer.rb +1 -0
  24. data/app/types/decidim/participatory_processes/participatory_process_group_type.rb +20 -0
  25. data/app/types/decidim/participatory_processes/participatory_process_input_filter.rb +13 -0
  26. data/app/types/decidim/participatory_processes/participatory_process_input_sort.rb +15 -0
  27. data/app/types/decidim/participatory_processes/participatory_process_step_type.rb +7 -4
  28. data/app/types/decidim/participatory_processes/participatory_process_type.rb +8 -4
  29. data/app/views/decidim/participatory_processes/admin/participatory_processes/_form.html.erb +31 -0
  30. data/app/views/decidim/participatory_processes/admin/participatory_processes/index.html.erb +18 -15
  31. data/app/views/decidim/participatory_processes/participatory_processes/_metrics.html.erb +1 -1
  32. data/app/views/decidim/participatory_processes/participatory_processes/{statistics.html.erb → all_metrics.html.erb} +0 -0
  33. data/app/views/decidim/participatory_processes/participatory_processes/show.html.erb +15 -1
  34. data/app/views/layouts/decidim/_process_navigation.html.erb +1 -1
  35. data/app/views/layouts/decidim/admin/participatory_process.html.erb +2 -2
  36. data/config/locales/ar.yml +9 -4
  37. data/config/locales/ca.yml +15 -5
  38. data/config/locales/cs.yml +15 -5
  39. data/config/locales/de.yml +6 -4
  40. data/config/locales/el.yml +1 -0
  41. data/config/locales/en.yml +15 -5
  42. data/config/locales/es-MX.yml +14 -4
  43. data/config/locales/es-PY.yml +14 -4
  44. data/config/locales/es.yml +15 -5
  45. data/config/locales/eu.yml +6 -4
  46. data/config/locales/fi-plain.yml +14 -4
  47. data/config/locales/fi.yml +14 -4
  48. data/config/locales/fr.yml +6 -4
  49. data/config/locales/gl.yml +6 -4
  50. data/config/locales/hu.yml +14 -4
  51. data/config/locales/id-ID.yml +6 -4
  52. data/config/locales/is-IS.yml +4 -0
  53. data/config/locales/it.yml +6 -4
  54. data/config/locales/nl.yml +6 -4
  55. data/config/locales/no.yml +11 -4
  56. data/config/locales/pl.yml +6 -4
  57. data/config/locales/pt-BR.yml +6 -4
  58. data/config/locales/pt.yml +6 -4
  59. data/config/locales/ru.yml +5 -3
  60. data/config/locales/sv.yml +6 -4
  61. data/config/locales/tr-TR.yml +6 -4
  62. data/config/locales/uk.yml +5 -3
  63. data/db/migrate/20200114142253_add_scope_type_to_participatory_processes.rb +7 -0
  64. data/db/migrate/20200204154917_add_show_metrics_to_participatory_processes.rb +7 -0
  65. data/lib/decidim/participatory_processes/engine.rb +21 -4
  66. data/lib/decidim/participatory_processes/participatory_space.rb +6 -0
  67. data/lib/decidim/participatory_processes/query_extensions.rb +40 -0
  68. data/lib/decidim/participatory_processes/test/factories.rb +20 -0
  69. data/lib/decidim/participatory_processes/version.rb +1 -1
  70. metadata +27 -11
  71. data/app/views/decidim/participatory_processes/participatory_process_widgets/show.html.erb +0 -17
  72. data/app/views/decidim/participatory_processes/participatory_processes/_statistics.html.erb +0 -10
@@ -44,6 +44,7 @@ module Decidim
44
44
 
45
45
  moderator_action?
46
46
  collaborator_action?
47
+ valuator_action?
47
48
  process_admin_action?
48
49
 
49
50
  permission_action
@@ -205,6 +206,14 @@ module Decidim
205
206
  allow! if permission_action.action == :preview
206
207
  end
207
208
 
209
+ # Valuators can only read the components of a process.
210
+ def valuator_action?
211
+ return unless can_manage_process?(role: :valuator)
212
+
213
+ allow! if permission_action.action == :read && permission_action.subject == :component
214
+ allow! if permission_action.action == :export && permission_action.subject == :component_data
215
+ end
216
+
208
217
  # Process admins can eprform everything *inside* that process. They cannot
209
218
  # create a process or perform actions on process groups or other
210
219
  # processes.
@@ -7,41 +7,51 @@ module Decidim
7
7
  attribute :participatory_process, Decidim::ParticipatoryProcess
8
8
  include Decidim::IconHelper
9
9
 
10
- # Public: Render a collection of primary stats.
11
- def highlighted
12
- highlighted_stats = component_stats(priority: StatsRegistry::HIGH_PRIORITY)
10
+ # Public: returns a collection of stats (Hash) for the Process Home.
11
+ def collection
12
+ highlighted_stats = process_participants_stats
13
+ highlighted_stats = highlighted_stats.concat(process_followers_stats(priority: StatsRegistry::HIGH_PRIORITY))
14
+ highlighted_stats = highlighted_stats.concat(component_stats(priority: StatsRegistry::HIGH_PRIORITY))
13
15
  highlighted_stats = highlighted_stats.concat(component_stats(priority: StatsRegistry::MEDIUM_PRIORITY))
14
16
  highlighted_stats = highlighted_stats.reject(&:empty?)
15
- highlighted_stats = highlighted_stats.reject { |_manifest, _name, data| data.zero? }
16
- grouped_highlighted_stats = highlighted_stats.group_by { |stats| stats.first.name }
17
-
18
- safe_join(
19
- grouped_highlighted_stats.map do |_manifest_name, stats|
20
- content_tag :div, class: "process_stats-item" do
21
- safe_join(
22
- stats.each_with_index.map do |stat, index|
23
- render_stats_data(stat[0], stat[1], stat[2], index)
24
- end
25
- )
17
+ highlighted_stats = highlighted_stats.reject { |_stat_manifest, _stat_title, stat_number| stat_number.zero? }
18
+ grouped_highlighted_stats = highlighted_stats.group_by(&:first)
19
+
20
+ statistics = []
21
+ grouped_highlighted_stats.each do |_manifest_name, stats|
22
+ stats.each_with_index.each do |stat, _index|
23
+ stat.each_with_index.map do |_item, subindex|
24
+ next unless (subindex % 3).zero?
25
+ next if stat[subindex + 2].zero?
26
+
27
+ statistics << { stat_title: stat[subindex + 1], stat_number: stat[subindex + 2] }
26
28
  end
27
29
  end
28
- )
30
+ end
31
+ statistics
29
32
  end
30
33
 
31
34
  private
32
35
 
36
+ def process_participants_stats
37
+ Decidim.stats.only([:participants_count]).with_context(participatory_process)
38
+ .map { |stat_title, stat_number| [participatory_process.manifest.name, stat_title, stat_number] }
39
+ end
40
+
33
41
  def component_stats(conditions)
34
42
  Decidim.component_manifests.map do |component_manifest|
35
- component_manifest.stats.filter(conditions).with_context(published_components).map { |name, data| [component_manifest, name, data] }.flatten
43
+ component_manifest.stats.except([:proposals_accepted])
44
+ .filter(conditions)
45
+ .with_context(published_components)
46
+ .map { |stat_title, stat_number| [component_manifest.name, stat_title, stat_number] }.flatten
36
47
  end
37
48
  end
38
49
 
39
- def render_stats_data(component_manifest, name, data, index)
40
- safe_join([
41
- index.zero? ? manifest_icon(component_manifest) : " /&nbsp".html_safe,
42
- content_tag(:span, "#{number_with_delimiter(data)} " + I18n.t(name, scope: "decidim.participatory_processes.statistics"),
43
- class: "#{name} process_stats-text")
44
- ])
50
+ def process_followers_stats(conditions)
51
+ Decidim.stats.only([:followers_count])
52
+ .filter(conditions)
53
+ .with_context(participatory_process)
54
+ .map { |stat_title, stat_number| [participatory_process.manifest.name, stat_title, stat_number] }
45
55
  end
46
56
 
47
57
  def published_components
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module ParticipatoryProcesses
5
+ # This class counts all Followers of a participatory processes
6
+ class StatsFollowersCount < Rectify::Query
7
+ def self.for(participatory_space)
8
+ return 0 unless participatory_space.is_a? Decidim::ParticipatoryProcess
9
+
10
+ new(participatory_space).query
11
+ end
12
+
13
+ def initialize(participatory_space)
14
+ @participatory_space = participatory_space
15
+ end
16
+
17
+ def query
18
+ space_query + components_query
19
+ end
20
+
21
+ private
22
+
23
+ attr_reader :participatory_space
24
+
25
+ def components_query
26
+ Decidim.component_manifests.sum do |component|
27
+ component.stats
28
+ .filter(tag: :followers)
29
+ .with_context(participatory_space.components.published)
30
+ .map { |_name, value| value }
31
+ .sum
32
+ end
33
+ end
34
+
35
+ def space_query
36
+ Decidim.participatory_space_manifests.sum do |space|
37
+ space.stats
38
+ .filter(tag: :followers)
39
+ .with_context(participatory_space)
40
+ .map { |_name, value| value }
41
+ .sum
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,98 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module ParticipatoryProcesses
5
+ # This class counts unique Participants on a participatory processes
6
+ class StatsParticipantsCount < Rectify::Query
7
+ def self.for(participatory_space)
8
+ return 0 unless participatory_space.is_a? Decidim::ParticipatoryProcess
9
+
10
+ new(participatory_space).query
11
+ end
12
+
13
+ def initialize(participatory_space)
14
+ @participatory_space = participatory_space
15
+ end
16
+
17
+ def query
18
+ [
19
+ comments_query,
20
+ debates_query,
21
+ endorsements_query,
22
+ project_supports_query,
23
+ proposals_query,
24
+ proposal_supports_query,
25
+ survey_answer_query
26
+ ].flatten.uniq.count
27
+ end
28
+
29
+ private
30
+
31
+ attr_reader :participatory_space
32
+
33
+ def comments_query
34
+ Decidim::Comments::Comment
35
+ .where(decidim_root_commentable_id: participatory_space.id)
36
+ .pluck(:decidim_author_id)
37
+ .uniq
38
+ end
39
+
40
+ def debates_query
41
+ Decidim::Debates::Debate
42
+ .where(
43
+ component: space_components,
44
+ decidim_author_type: Decidim::UserBaseEntity.name
45
+ )
46
+ .not_hidden
47
+ .pluck(:decidim_author_id)
48
+ .uniq
49
+ end
50
+
51
+ def endorsements_query
52
+ Decidim::Proposals::ProposalEndorsement
53
+ .where(proposal: proposals_components)
54
+ .pluck(:decidim_author_id)
55
+ .uniq
56
+ end
57
+
58
+ def proposals_query
59
+ Decidim::Coauthorship
60
+ .where(
61
+ coauthorable: proposals_components,
62
+ decidim_author_type: Decidim::UserBaseEntity.name
63
+ )
64
+ .pluck(:decidim_author_id)
65
+ .uniq
66
+ end
67
+
68
+ def proposal_supports_query
69
+ Decidim::Proposals::ProposalVote
70
+ .where(
71
+ proposal: proposals_components
72
+ )
73
+ .final
74
+ .pluck(:decidim_author_id)
75
+ .uniq
76
+ end
77
+
78
+ def project_supports_query
79
+ Decidim::Budgets::Order
80
+ .where(component: space_components)
81
+ .pluck(:decidim_user_id)
82
+ .uniq
83
+ end
84
+
85
+ def survey_answer_query
86
+ Decidim::Forms::Answer.newsletter_participant_ids(space_components)
87
+ end
88
+
89
+ def space_components
90
+ @space_components ||= participatory_space.components
91
+ end
92
+
93
+ def proposals_components
94
+ @proposals_components ||= Decidim::Proposals::FilteredProposals.for(space_components).published.not_hidden
95
+ end
96
+ end
97
+ end
98
+ end
@@ -39,7 +39,9 @@ module Decidim
39
39
  meta_scope: attributes["meta_scope"],
40
40
  start_date: attributes["start_date"],
41
41
  end_date: attributes["end_date"],
42
+ announcement: attributes["announcement"],
42
43
  private_space: attributes["private_space"],
44
+ scopes_enabled: attributes["scopes_enabled"],
43
45
  participatory_process_group: import_process_group(attributes["participatory_process_group"])
44
46
  )
45
47
  @imported_process.remote_hero_image_url = attributes["remote_hero_image_url"] if remote_file_exists?(attributes["remote_hero_image_url"])
@@ -52,6 +52,7 @@ module Decidim
52
52
  private_space: participatory_process.private_space,
53
53
  promoted: participatory_process.promoted,
54
54
  scopes_enabled: participatory_process.scopes_enabled,
55
+ show_metrics: participatory_process.show_metrics,
55
56
  show_statistics: participatory_process.show_statistics,
56
57
  participatory_process_steps: serialize_participatory_process_steps,
57
58
  participatory_process_categories: serialize_categories,
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module ParticipatoryProcesses
5
+ # This type represents a ParticipatoryProcess.
6
+ ParticipatoryProcessGroupType = GraphQL::ObjectType.define do
7
+ name "ParticipatoryProcessGroup"
8
+ description "A participatory process group"
9
+
10
+ field :id, !types.ID, "ID of this participatory process group"
11
+ field :name, Decidim::Core::TranslatedFieldType, "The name of this participatory process group"
12
+ field :description, Decidim::Core::TranslatedFieldType, "The description of this participatory process group", property: :description
13
+ field :participatoryProcesses, !types[ParticipatoryProcessType] do
14
+ description "Lists all the participatory processes belonging to this group"
15
+ property :participatory_processes
16
+ end
17
+ field :heroImage, types.String, "The hero image for this participatory process group", property: :hero_image
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module ParticipatoryProcesses
5
+ class ParticipatoryProcessInputFilter < Decidim::Core::BaseInputFilter
6
+ include Decidim::Core::HasPublishableInputFilter
7
+ include Decidim::Core::HasHastaggableInputFilter
8
+
9
+ graphql_name "ParticipatoryProcessFilter"
10
+ description "A type used for filtering participatory processes"
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module ParticipatoryProcesses
5
+ class ParticipatoryProcessInputSort < Decidim::Core::BaseInputSort
6
+ include Decidim::Core::HasPublishableInputSort
7
+
8
+ graphql_name "ParticipatoryProcessSort"
9
+ description "A type used for sorting participatory processess"
10
+
11
+ argument :id, String, "Sort by ID, valid values are ASC or DESC", required: false
12
+ argument :start_date, String, "Sort by participatory process starting date, valid values are ASC or DESC", required: false
13
+ end
14
+ end
15
+ end
@@ -16,10 +16,13 @@ module Decidim
16
16
  end
17
17
 
18
18
  field :title, !Decidim::Core::TranslatedFieldType, "The title of this step"
19
-
20
- field :startDate, Decidim::Core::DateType, "This step's start date.", property: :start_date
21
-
22
- field :endDate, Decidim::Core::DateType, "This step's end date.", property: :end_date
19
+ field :description, Decidim::Core::TranslatedFieldType, "The description of this step"
20
+ field :startDate, Decidim::Core::DateType, "This step's start date", property: :start_date
21
+ field :endDate, Decidim::Core::DateType, "This step's end date", property: :end_date
22
+ field :callToActionPath, types.String, "A call to action URL for this step", property: :cta_path
23
+ field :callToActionText, Decidim::Core::TranslatedFieldType, "The call to action text for this step", property: :cta_text
24
+ field :active, types.Boolean, "If this step is the active one"
25
+ field :position, types.Int, "Ordering position among all the steps"
23
26
  end
24
27
  end
25
28
  end
@@ -6,6 +6,7 @@ module Decidim
6
6
  ParticipatoryProcessType = GraphQL::ObjectType.define do
7
7
  interfaces [
8
8
  -> { Decidim::Core::ParticipatorySpaceInterface },
9
+ -> { Decidim::Core::ParticipatorySpaceResourceableInterface },
9
10
  -> { Decidim::Core::ScopableInterface },
10
11
  -> { Decidim::Core::AttachableInterface }
11
12
  ]
@@ -13,6 +14,7 @@ module Decidim
13
14
  name "ParticipatoryProcess"
14
15
  description "A participatory process"
15
16
 
17
+ field :id, !types.ID, "The internal ID for this participatory process"
16
18
  field :slug, !types.String
17
19
  field :hashtag, types.String, "The hashtag for this participatory process"
18
20
  field :createdAt, !Decidim::Core::DateTimeType, "The time this page was created", property: :created_at
@@ -33,6 +35,7 @@ module Decidim
33
35
  field :target, Decidim::Core::TranslatedFieldType, "Who participates in this participatory process."
34
36
  field :participatoryScope, Decidim::Core::TranslatedFieldType, "What is decided on this participatory process.", property: :participatory_scope
35
37
  field :participatoryStructure, Decidim::Core::TranslatedFieldType, "How it is decided on this participatory process.", property: :participatory_structure
38
+ field :showMetrics, types.Boolean, "If this participatory process should show metrics", property: :show_metrics
36
39
  field :showStatistics, types.Boolean, "If this participatory process should show statistics", property: :show_statistics
37
40
  field :scopesEnabled, types.Boolean, "If this participatory process has scopes enabled", property: :scopes_enabled
38
41
 
@@ -40,11 +43,12 @@ module Decidim
40
43
 
41
44
  field :reference, types.String, "Reference prefix for this participatory process"
42
45
  field :steps, !types[ParticipatoryProcessStepType], "All the steps of this process."
46
+ field :categories, !types[Decidim::Core::CategoryType], "Categories for this participatory process"
43
47
 
44
- # These fields may be private:
45
- # decidim_participatory_process_group_id
46
- # decidim_organization_id
47
- # private_space
48
+ field :participatoryProcessGroup, ParticipatoryProcessGroupType do
49
+ description "The participatory process group in which this process belong to"
50
+ property :participatory_process_group
51
+ end
48
52
  end
49
53
  end
50
54
  end
@@ -116,6 +116,18 @@
116
116
 
117
117
  <div class="row column">
118
118
  <%= scopes_picker_field form, :scope_id, root: nil %>
119
+
120
+ <div class="row" id="scope-depth ">
121
+ <%= form.collection_select :scope_type_max_depth_id,
122
+ organization_scope_depths,
123
+ :id,
124
+ :name,
125
+ scope_type_depth_select_options,
126
+ scope_type_depth_select_html_options %>
127
+ <p class="help-text">
128
+ <%== t(".scope_type_max_depth_help") %>
129
+ </p>
130
+ </div>
119
131
  </div>
120
132
 
121
133
  <div class="row column">
@@ -147,6 +159,21 @@
147
159
  </div>
148
160
  </div>
149
161
 
162
+ <div class="card-divider">
163
+ <h2 class="card-title"><%= t(".related_processes") %></h2>
164
+ </div>
165
+
166
+ <div class="card-section">
167
+ <div class="row column">
168
+ <%= form.select(
169
+ :related_process_ids,
170
+ @form.processes.order(title: :asc).map{|process| [translated_attribute(process.title), process.id]},
171
+ { include_blank: true },
172
+ { multiple: true, class: "chosen-select" }
173
+ ) %>
174
+ </div>
175
+ </div>
176
+
150
177
  <div class="card-divider">
151
178
  <h2 class="card-title"><%= t(".other") %></h2>
152
179
  </div>
@@ -155,6 +182,10 @@
155
182
  <div class="row column">
156
183
  <%= form.check_box :show_statistics %>
157
184
  </div>
185
+
186
+ <div class="row column">
187
+ <%= form.check_box :show_metrics %>
188
+ </div>
158
189
  </div>
159
190
  </div>
160
191
 
@@ -1,14 +1,20 @@
1
1
  <%= render partial: "decidim/participatory_processes/admin/shared/secondary_nav" %>
2
2
 
3
- <div class="card" id="processes">
3
+ <div class="card with-overflow" id="processes">
4
4
  <div class="card-divider">
5
5
  <h2 class="card-title">
6
6
  <%= t("participatory_processes", scope: "decidim.admin.titles") %>
7
7
 
8
- <% if @process_group %>
8
+ <% if allowed_to? :create, :process %>
9
+ <%= link_to t("actions.new_process", scope: "decidim.admin"),
10
+ ["new", "participatory_process"],
11
+ class: "button tiny button--title" %>
12
+ <% end %>
13
+
14
+ <% if process_group %>
9
15
  <span>&lt;</span>
10
- <%= link_to translated_attribute(@process_group.name),
11
- edit_participatory_process_group_path(@process_group) %>
16
+ <%= link_to translated_attribute(process_group.name),
17
+ edit_participatory_process_group_path(process_group) %>
12
18
  <% end %>
13
19
 
14
20
  <% if allowed_to? :import, :process %>
@@ -17,28 +23,23 @@
17
23
  class: "button tiny button--title" %>
18
24
  <% end %>
19
25
 
20
- <% if allowed_to? :create, :process %>
21
- <%= link_to t("actions.new_process", scope: "decidim.admin"),
22
- ["new", "participatory_process"],
23
- class: "button tiny button--title" %>
24
- <% end %>
25
-
26
26
  <button data-toggle="process_groups" class="dropdown button tiny button--title">
27
27
  <%= t("actions.filter.process_groups", scope: "decidim.admin") %>
28
28
  </button>
29
29
  <div id="process_groups" class="dropdown-pane" data-position="bottom" data-dropdown data-auto-focus="true">
30
30
  <ul class="list-reset">
31
- <%= link_to url_for(group_id: nil) do %>
32
- <li><%= t("actions.filter.all", scope: "decidim.admin") %></li>
31
+ <%= link_to query_params_with(decidim_participatory_process_group_id_eq: nil) do %>
32
+ <li><%= t("actions.filter.all_processes", scope: "decidim.admin") %></li>
33
33
  <% end %>
34
- <% Decidim::ParticipatoryProcessGroup.all.each do |group| %>
35
- <%= link_to url_for(group_id: group.id) do %>
36
- <li><%= translated_attribute(group.name) %></li>
34
+ <% process_groups_for_select.each do |group_name, group_id| %>
35
+ <%= link_to query_params_with(decidim_participatory_process_group_id_eq: group_id) do %>
36
+ <li><%= group_name %></li>
37
37
  <% end %>
38
38
  <% end %>
39
39
  </ul>
40
40
  </div>
41
41
  </div>
42
+ <%= admin_filter_selector %>
42
43
  <div class="card-section">
43
44
  <div class="table-scroll">
44
45
  <table class="table-list">
@@ -70,6 +71,8 @@
70
71
  <% end %>
71
72
  <% if allowed_to? :update, :process, process: process %>
72
73
  <%= link_to translated_attribute(process.title), edit_participatory_process_path(process) %><br>
74
+ <% elsif allowed_to? :read, :component, process: process %>
75
+ <%= link_to translated_attribute(process.title), components_path(process) %><br>
73
76
  <% elsif allowed_to? :preview, :process, process: process %>
74
77
  <%= link_to translated_attribute(process.title), decidim_participatory_processes.participatory_process_path(process) %><br>
75
78
  <% elsif allowed_to? :read, :moderation, process: process %>