decidim-core 0.4.3 → 0.4.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/stylesheets/decidim/modules/_card-grid.scss +2 -2
  3. data/app/assets/stylesheets/decidim/modules/_filters.scss +3 -3
  4. data/app/assets/stylesheets/decidim/modules/_main-container.scss +1 -5
  5. data/app/assets/stylesheets/decidim/modules/_process-nav.scss +1 -2
  6. data/app/constraints/decidim/current_participatory_process.rb +1 -1
  7. data/app/controllers/concerns/decidim/needs_authorization.rb +2 -3
  8. data/app/controllers/concerns/decidim/needs_participatory_process.rb +1 -1
  9. data/app/controllers/concerns/decidim/{feature_settings.rb → settings.rb} +1 -1
  10. data/app/controllers/decidim/features/base_controller.rb +1 -2
  11. data/app/controllers/decidim/pages_controller.rb +1 -1
  12. data/app/helpers/decidim/feature_path_helper.rb +1 -1
  13. data/{lib → app/models}/decidim/abilities/admin_ability.rb +1 -0
  14. data/app/models/decidim/abilities/base_ability.rb +34 -0
  15. data/{lib → app/models}/decidim/abilities/participatory_process_admin_ability.rb +4 -0
  16. data/{lib → app/models}/decidim/abilities/participatory_process_collaborator_ability.rb +4 -0
  17. data/{lib → app/models}/decidim/abilities/participatory_process_moderator_ability.rb +0 -0
  18. data/app/models/decidim/feature.rb +3 -78
  19. data/app/models/decidim/organization.rb +0 -2
  20. data/app/models/decidim/participatory_process.rb +2 -16
  21. data/app/models/decidim/participatory_process_group.rb +1 -2
  22. data/app/models/decidim/participatory_process_user_role.rb +9 -0
  23. data/app/models/decidim/user.rb +0 -7
  24. data/app/presenters/decidim/home_stats_presenter.rb +1 -1
  25. data/app/presenters/decidim/resource_locator_presenter.rb +57 -15
  26. data/app/queries/decidim/highlighted_participatory_processes.rb +1 -2
  27. data/app/queries/decidim/organization_participatory_process_groups.rb +14 -0
  28. data/app/queries/decidim/organization_participatory_processes.rb +2 -6
  29. data/app/queries/decidim/organization_prioritized_participatory_processes.rb +3 -3
  30. data/app/queries/decidim/organization_published_participatory_processes.rb +17 -0
  31. data/app/queries/decidim/participatory_processes_with_user_role.rb +1 -1
  32. data/app/queries/decidim/prioritized_participatory_processes.rb +1 -1
  33. data/app/queries/decidim/published_participatory_processes.rb +10 -0
  34. data/app/views/layouts/decidim/_process_header.html.erb +2 -2
  35. data/config/locales/ca.yml +19 -0
  36. data/config/locales/es.yml +19 -0
  37. data/config/locales/fr.yml +2 -2
  38. data/db/migrate/20170608142521_add_organization_to_user_groups.rb +16 -3
  39. data/db/seeds.rb +17 -12
  40. data/lib/decidim/abilities.rb +0 -4
  41. data/lib/decidim/abilities/participatory_process_role_ability.rb +4 -1
  42. data/lib/decidim/core.rb +20 -20
  43. data/lib/decidim/core/api/decidim_type.rb +1 -1
  44. data/lib/decidim/core/api/process_step_type.rb +2 -2
  45. data/lib/decidim/core/api/process_type.rb +1 -1
  46. data/lib/decidim/core/api/session_type.rb +1 -1
  47. data/lib/decidim/core/api/translated_field_type.rb +3 -3
  48. data/lib/decidim/core/test.rb +1 -0
  49. data/lib/decidim/core/test/factories.rb +21 -2
  50. data/lib/decidim/core/test/shared_examples/publicable.rb +27 -0
  51. data/lib/decidim/core/version.rb +1 -1
  52. data/lib/decidim/feature_manifest.rb +6 -6
  53. data/lib/decidim/form_builder.rb +1 -1
  54. data/lib/decidim/has_category.rb +1 -1
  55. data/lib/decidim/has_settings.rb +66 -0
  56. data/lib/decidim/manifest_registry.rb +45 -0
  57. data/lib/decidim/publicable.rb +49 -0
  58. data/lib/decidim/query_extensions.rb +1 -1
  59. data/lib/decidim/reportable.rb +3 -3
  60. data/lib/decidim/{features/settings_manifest.rb → settings_manifest.rb} +5 -5
  61. metadata +26 -33
  62. data/app/models/decidim/ability.rb +0 -32
@@ -2,47 +2,89 @@
2
2
 
3
3
  module Decidim
4
4
  # A presenter to get the url or path from a resource.
5
- class ResourceLocatorPresenter < Rectify::Presenter
5
+ class ResourceLocatorPresenter
6
6
  def initialize(resource)
7
7
  @resource = resource
8
8
  end
9
9
 
10
- # Builds the path to a resource. Useful when linking to a resource from
10
+ # Builds the path to the resource. Useful when linking to a resource from
11
11
  # another engine.
12
12
  #
13
13
  # options - An optional hash of options to pass to the Rails router
14
14
  #
15
15
  # Returns a String.
16
16
  def path(options = {})
17
- _route(@resource, "path", options)
17
+ member_route("path", options)
18
18
  end
19
19
 
20
- # Builds the url to a resource. Useful when linking to a resource from
20
+ # Builds the url to the resource. Useful when linking to a resource from
21
21
  # another engine.
22
22
  #
23
23
  # options - An optional hash of options to pass to the Rails router
24
24
  #
25
25
  # Returns a String.
26
26
  def url(options = {})
27
- _route(@resource, "url", options.merge(host: @resource.organization.host))
27
+ member_route("url", options.merge(host: @resource.organization.host))
28
+ end
29
+
30
+ # Builds the index path to the associated collection of resources.
31
+ #
32
+ # options - An optional hash of options to pass to the Rails router
33
+ #
34
+ # Returns a String.
35
+ def index(options = {})
36
+ collection_route("path", options)
28
37
  end
29
38
 
30
39
  private
31
40
 
32
- # Private: Build the route to a given resource.
41
+ # Private: Build the route to the resource.
33
42
  #
34
43
  # Returns a String.
35
- def _route(resource, route_type, options)
36
- manifest = resource.class.resource_manifest
37
- engine = manifest.feature_manifest.engine
38
-
39
- url_params = {
40
- id: resource.id,
41
- feature_id: resource.feature.id,
42
- participatory_process_id: resource.feature.participatory_process.id
44
+ def member_route(route_type, options)
45
+ route_proxy.send("#{member_route_name}_#{route_type}", member_params.merge(options))
46
+ end
47
+
48
+ # Private: Build the route to the associated collection of resources.
49
+ #
50
+ # Returns a String.
51
+ def collection_route(route_type, options)
52
+ route_proxy.send("#{collection_route_name}_#{route_type}", collection_params.merge(options))
53
+ end
54
+
55
+ def manifest
56
+ @resource.class.resource_manifest
57
+ end
58
+
59
+ def feature
60
+ @resource.feature
61
+ end
62
+
63
+ def engine
64
+ manifest.feature_manifest.engine
65
+ end
66
+
67
+ def member_params
68
+ collection_params.merge(id: @resource.id)
69
+ end
70
+
71
+ def collection_params
72
+ {
73
+ feature_id: feature.id,
74
+ participatory_process_id: feature.participatory_process.id
43
75
  }
76
+ end
77
+
78
+ def member_route_name
79
+ manifest.route_name
80
+ end
81
+
82
+ def collection_route_name
83
+ member_route_name.pluralize
84
+ end
44
85
 
45
- engine.routes.url_helpers.send("#{manifest.route_name}_#{route_type}", url_params.merge(options))
86
+ def route_proxy
87
+ @route_proxy ||= engine.routes.url_helpers
46
88
  end
47
89
  end
48
90
  end
@@ -1,8 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Decidim
4
- # This query adds some scopes so the processes are ready to be showed in a
5
- # public view.
4
+ # This query selects some prioritized processes.
6
5
  class HighlightedParticipatoryProcesses < Rectify::Query
7
6
  def query
8
7
  PrioritizedParticipatoryProcesses.new.query.limit(8)
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ # This query class filters participatory process groups given an organization.
5
+ class OrganizationParticipatoryProcessGroups < Rectify::Query
6
+ def initialize(organization)
7
+ @organization = organization
8
+ end
9
+
10
+ def query
11
+ ParticipatoryProcessGroup.where(organization: @organization)
12
+ end
13
+ end
14
+ end
@@ -1,18 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Decidim
4
- # This query class returns the visible Participatory Processes given an
5
- # Organization.
4
+ # This query class filters all processes given an organization.
6
5
  class OrganizationParticipatoryProcesses < Rectify::Query
7
6
  def initialize(organization)
8
7
  @organization = organization
9
8
  end
10
9
 
11
10
  def query
12
- raise MandatoryOrganization unless @organization
13
- ParticipatoryProcess.where(organization: @organization).published
11
+ ParticipatoryProcess.where(organization: @organization)
14
12
  end
15
-
16
- class MandatoryOrganization < StandardError; end
17
13
  end
18
14
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Decidim
4
- # This query class returns the public Participatory Processes given an
5
- # Organization in a meaningful order.
4
+ # This query class filters public processes given an organization in a
5
+ # meaningful prioritized order.
6
6
  class OrganizationPrioritizedParticipatoryProcesses < Rectify::Query
7
7
  def initialize(organization)
8
8
  @organization = organization
@@ -10,7 +10,7 @@ module Decidim
10
10
 
11
11
  def query
12
12
  Rectify::Query.merge(
13
- OrganizationParticipatoryProcesses.new(@organization),
13
+ OrganizationPublishedParticipatoryProcesses.new(@organization),
14
14
  PrioritizedParticipatoryProcesses.new
15
15
  ).query
16
16
  end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ # This query class filters published processes given an organization.
5
+ class OrganizationPublishedParticipatoryProcesses < Rectify::Query
6
+ def initialize(organization)
7
+ @organization = organization
8
+ end
9
+
10
+ def query
11
+ Rectify::Query.merge(
12
+ OrganizationParticipatoryProcesses.new(@organization),
13
+ PublishedParticipatoryProcesses.new
14
+ ).query
15
+ end
16
+ end
17
+ end
@@ -28,7 +28,7 @@ module Decidim
28
28
  # Returns an ActiveRecord::Relation.
29
29
  def query
30
30
  # Admin users have all role privileges for all organization processes
31
- return user.organization.participatory_processes if user.admin?
31
+ return OrganizationParticipatoryProcesses.new(user.organization).query if user.admin?
32
32
 
33
33
  ParticipatoryProcess.where(id: process_ids)
34
34
  end
@@ -5,7 +5,7 @@ module Decidim
5
5
  # first, and closest to finalization date second.
6
6
  class PrioritizedParticipatoryProcesses < Rectify::Query
7
7
  def query
8
- Decidim::ParticipatoryProcess.order("promoted DESC").includes(:active_step).order("decidim_participatory_process_steps.end_date ASC")
8
+ Decidim::ParticipatoryProcess.order(promoted: :desc).includes(:active_step).order("decidim_participatory_process_steps.end_date ASC")
9
9
  end
10
10
  end
11
11
  end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ # This query filters published processes only.
5
+ class PublishedParticipatoryProcesses < Rectify::Query
6
+ def query
7
+ ParticipatoryProcess.published
8
+ end
9
+ end
10
+ end
@@ -48,8 +48,8 @@
48
48
 
49
49
  <% current_participatory_process.features.each do |feature| %>
50
50
  <% if feature.published? || feature == self.try(:current_feature) %>
51
- <li class="<%= "is-active" if is_active_link?(feature_path(feature), :inclusive) %>">
52
- <%= active_link_to feature_path(feature), class: "process-nav__link", active: :inclusive, class_active: "is-active" do %>
51
+ <li class="<%= "is-active" if is_active_link?(main_feature_path(feature), :inclusive) %>">
52
+ <%= active_link_to main_feature_path(feature), class: "process-nav__link", active: :inclusive, class_active: "is-active" do %>
53
53
  <%= feature_icon(feature) %>
54
54
 
55
55
  <%= translated_attribute(feature.name) %>
@@ -205,6 +205,20 @@ ca:
205
205
  participatory_structure: Estructura participativa
206
206
  scope: Àmbit
207
207
  target: A qui va dirigit?
208
+ statistics:
209
+ answers_count: Respostes
210
+ comments_count: Comentaris
211
+ headline: Activitat
212
+ meetings_count: Trobades
213
+ orders_count: Vots
214
+ pages_count: Pàgines
215
+ processes_count: Processos
216
+ projects_count: Projectes
217
+ proposals_count: Propostes
218
+ results_count: Resultats
219
+ surveys_count: Enquestes
220
+ users_count: Participants
221
+ votes_count: Suports
208
222
  reported_mailer:
209
223
  hide:
210
224
  hello: Hola %{name},
@@ -382,12 +396,17 @@ ca:
382
396
  active_step: Fase activa
383
397
  see_all_processes: Veure tots els processos
384
398
  statistics:
399
+ answers_count: Respostes
385
400
  comments_count: Comentaris
386
401
  headline: Estat actual de %{organization}
387
402
  meetings_count: Trobades
403
+ orders_count: Vots
404
+ pages_count: Pàgines
388
405
  processes_count: Processos
406
+ projects_count: Projectes
389
407
  proposals_count: Propostes
390
408
  results_count: Resultats
409
+ surveys_count: Enquestes
391
410
  users_count: Participants
392
411
  votes_count: Suports
393
412
  sub_hero:
@@ -205,6 +205,20 @@ es:
205
205
  participatory_structure: Estructura participativa
206
206
  scope: Ámbito
207
207
  target: '¿A quién va dirigido?'
208
+ statistics:
209
+ answers_count: Respuestas
210
+ comments_count: Comentarios
211
+ headline: Actividad
212
+ meetings_count: Encuentros
213
+ orders_count: Votos
214
+ pages_count: Páginas
215
+ processes_count: Procesos
216
+ projects_count: Proyectos
217
+ proposals_count: Propuestas
218
+ results_count: Resultados
219
+ surveys_count: Encuestas
220
+ users_count: Participantes
221
+ votes_count: Soportes
208
222
  reported_mailer:
209
223
  hide:
210
224
  hello: Hola %{name},
@@ -382,12 +396,17 @@ es:
382
396
  active_step: Fase activa
383
397
  see_all_processes: Ver todos los procesos
384
398
  statistics:
399
+ answers_count: Respuestas
385
400
  comments_count: Comentarios
386
401
  headline: Estado actual de %{organization}
387
402
  meetings_count: Encuentros
403
+ orders_count: Votos
404
+ pages_count: Páginas
388
405
  processes_count: Procesos
406
+ projects_count: Proyectos
389
407
  proposals_count: Propuestas
390
408
  results_count: Resultados
409
+ surveys_count: Encuestas
391
410
  users_count: Participantes
392
411
  votes_count: Votos
393
412
  sub_hero:
@@ -86,7 +86,7 @@ fr:
86
86
  registrations:
87
87
  new:
88
88
  already_have_an_account?: Vous avez déjà un compte?
89
- newsletter_notifications: Recevoir des lettres d'informations sur l'activité de la plateforme
89
+ newsletter_notifications: Recevoir des lettres d'informations sur l'activité de la plateforme
90
90
  sign_in: S'identifier
91
91
  sign_up: S'inscrire
92
92
  sign_up_as:
@@ -380,4 +380,4 @@ fr:
380
380
  last: Dernière &raquo;
381
381
  next: Suivant &rsaquo;
382
382
  previous: "&lsaquo; Précédent"
383
- truncate: "&hellip;"
383
+ truncate: "&hellip;"
@@ -1,12 +1,25 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class AddOrganizationToUserGroups < ActiveRecord::Migration[5.0]
4
+ class UserGroup < ApplicationRecord
5
+ self.table_name = :decidim_user_groups
6
+ end
7
+
4
8
  def change
5
9
  add_column :decidim_user_groups, :decidim_organization_id, :integer
6
10
 
7
- Decidim::UserGroup.includes(:users).find_each do |user_group|
8
- user_group.organization = user_group.users.first.organization
9
- user_group.save!(validate: false)
11
+ UserGroup.find_each do |user_group|
12
+ execute <<~SQL.squish
13
+ UPDATE decidim_user_groups
14
+ SET decidim_organization_id = (
15
+ SELECT MIN(u.decidim_organization_id)
16
+ FROM decidim_users u
17
+ INNER JOIN decidim_user_group_memberships m
18
+ ON u.id = m.decidim_user_id
19
+ WHERE m.decidim_user_group_id = #{user_group.id}
20
+ )
21
+ WHERE id = #{user_group.id}
22
+ SQL
10
23
  end
11
24
 
12
25
  change_column :decidim_user_groups, :decidim_organization_id, :integer, null: false
data/db/seeds.rb CHANGED
@@ -17,7 +17,7 @@ if !Rails.env.production? || ENV["SEED"]
17
17
  end,
18
18
  homepage_image: File.new(File.join(__dir__, "seeds", "homepage_image.jpg")),
19
19
  default_locale: I18n.default_locale,
20
- available_locales: Decidim.available_locales,
20
+ available_locales: [:en, :ca, :es],
21
21
  reference_prefix: Faker::Name.suffix
22
22
  )
23
23
 
@@ -28,9 +28,8 @@ if !Rails.env.production? || ENV["SEED"]
28
28
  )
29
29
  end
30
30
 
31
- Decidim::User.create!(
31
+ Decidim::User.find_or_initialize_by(email: "admin@example.org").update!(
32
32
  name: Faker::Name.name,
33
- email: "admin@example.org",
34
33
  password: "decidim123456",
35
34
  password_confirmation: "decidim123456",
36
35
  organization: organization,
@@ -42,9 +41,8 @@ if !Rails.env.production? || ENV["SEED"]
42
41
  replies_notifications: true
43
42
  )
44
43
 
45
- Decidim::User.create!(
44
+ Decidim::User.find_or_initialize_by(email: "user@example.org").update!(
46
45
  name: Faker::Name.name,
47
- email: "user@example.org",
48
46
  password: "decidim123456",
49
47
  password_confirmation: "decidim123456",
50
48
  confirmed_at: Time.current,
@@ -115,22 +113,25 @@ if !Rails.env.production? || ENV["SEED"]
115
113
  end
116
114
 
117
115
  Decidim::ParticipatoryProcess.find_each do |process|
118
- Decidim::ParticipatoryProcessStep.create!(
116
+ Decidim::ParticipatoryProcessStep.find_or_initialize_by(
117
+ participatory_process: process,
118
+ active: true
119
+ ).update!(
119
120
  title: Decidim::Faker::Localized.sentence(1, false, 2),
120
121
  description: Decidim::Faker::Localized.wrapped("<p>", "</p>") do
121
122
  Decidim::Faker::Localized.paragraph(3)
122
123
  end,
123
- active: true,
124
124
  start_date: 1.month.ago.at_midnight,
125
- end_date: 2.months.from_now.at_midnight,
126
- participatory_process: process
125
+ end_date: 2.months.from_now.at_midnight
127
126
  )
128
127
 
129
128
  # Create users with specific roles
130
129
  Decidim::ParticipatoryProcessUserRole::ROLES.each do |role|
131
- user = Decidim::User.create!(
130
+ email = "participatory_process_#{process.id}_#{role}@example.org"
131
+
132
+ user = Decidim::User.find_or_initialize_by(email: email)
133
+ user.update!(
132
134
  name: Faker::Name.name,
133
- email: "participatory_process_#{process.id}_#{role}@example.org",
134
135
  password: "decidim123456",
135
136
  password_confirmation: "decidim123456",
136
137
  organization: organization,
@@ -141,7 +142,11 @@ if !Rails.env.production? || ENV["SEED"]
141
142
  replies_notifications: true
142
143
  )
143
144
 
144
- Decidim::ParticipatoryProcessUserRole.create!(user: user, participatory_process: process, role: role)
145
+ Decidim::ParticipatoryProcessUserRole.find_or_create_by!(
146
+ user: user,
147
+ participatory_process: process,
148
+ role: role
149
+ )
145
150
  end
146
151
 
147
152
  Decidim::Attachment.create!(
@@ -2,10 +2,6 @@
2
2
 
3
3
  module Decidim
4
4
  module Abilities
5
- autoload :AdminAbility, "decidim/abilities/admin_ability"
6
5
  autoload :ParticipatoryProcessRoleAbility, "decidim/abilities/participatory_process_role_ability"
7
- autoload :ParticipatoryProcessAdminAbility, "decidim/abilities/participatory_process_admin_ability"
8
- autoload :ParticipatoryProcessCollaboratorAbility, "decidim/abilities/participatory_process_collaborator_ability"
9
- autoload :ParticipatoryProcessModeratorAbility, "decidim/abilities/participatory_process_moderator_ability"
10
6
  end
11
7
  end