decidim-core 0.3.2 → 0.4.0

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 (70) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/stylesheets/decidim/extras/_add_comments.scss +9 -0
  3. data/app/assets/stylesheets/decidim/extras/_label-required.scss +3 -0
  4. data/app/assets/stylesheets/decidim/extras/_reference.scss +3 -0
  5. data/app/assets/stylesheets/decidim/extras/_social_icons_mini.scss +10 -0
  6. data/app/commands/decidim/invite_user.rb +1 -1
  7. data/app/commands/decidim/update_account.rb +2 -6
  8. data/app/constraints/decidim/current_feature.rb +11 -18
  9. data/app/constraints/decidim/current_participatory_process.rb +35 -0
  10. data/app/controllers/concerns/decidim/devise_controllers.rb +1 -0
  11. data/app/controllers/concerns/decidim/locale_switcher.rb +2 -2
  12. data/app/controllers/concerns/decidim/needs_authorization.rb +1 -2
  13. data/app/controllers/concerns/decidim/needs_organization.rb +1 -2
  14. data/app/controllers/concerns/decidim/needs_participatory_process.rb +19 -10
  15. data/app/controllers/decidim/account_controller.rb +13 -9
  16. data/app/controllers/decidim/application_controller.rb +3 -8
  17. data/app/controllers/decidim/devise/registrations_controller.rb +0 -1
  18. data/app/controllers/decidim/devise/sessions_controller.rb +0 -1
  19. data/app/controllers/decidim/errors_controller.rb +15 -0
  20. data/app/controllers/decidim/features/base_controller.rb +1 -0
  21. data/app/controllers/decidim/participatory_process_groups_controller.rb +6 -2
  22. data/app/controllers/decidim/participatory_process_steps_controller.rb +1 -0
  23. data/app/controllers/decidim/participatory_processes_controller.rb +3 -3
  24. data/app/helpers/decidim/application_helper.rb +3 -0
  25. data/app/helpers/decidim/feature_path_helper.rb +35 -0
  26. data/app/helpers/decidim/feature_reference_helper.rb +4 -2
  27. data/app/helpers/decidim/icon_helper.rb +20 -0
  28. data/app/helpers/decidim/menu_helper.rb +1 -1
  29. data/app/helpers/decidim/participatory_process_helper.rb +0 -14
  30. data/app/models/decidim/feature.rb +9 -1
  31. data/app/models/decidim/static_page.rb +1 -0
  32. data/app/models/decidim/user.rb +2 -0
  33. data/app/queries/decidim/highlighted_participatory_processes.rb +1 -1
  34. data/app/views/decidim/account/show.html.erb +1 -3
  35. data/app/views/decidim/devise/shared/_omniauth_buttons.html.erb +1 -1
  36. data/app/views/decidim/devise/shared/_omniauth_buttons_mini.html.erb +20 -0
  37. data/app/views/{pages/500.html.erb → decidim/errors/internal_server_error.html.erb} +0 -0
  38. data/app/views/{pages/404.html.erb → decidim/errors/not_found.html.erb} +1 -1
  39. data/app/views/decidim/shared/_login_modal.html.erb +4 -0
  40. data/app/views/decidim/shared/_share_modal.html.erb +1 -1
  41. data/app/views/layouts/decidim/_process_header.html.erb +2 -2
  42. data/config/i18n-tasks.yml +2 -0
  43. data/config/initializers/invisible_captcha.rb +2 -2
  44. data/config/locales/ca.yml +14 -8
  45. data/config/locales/en.yml +13 -7
  46. data/config/locales/es.yml +13 -7
  47. data/config/locales/eu.yml +0 -7
  48. data/config/locales/fi.yml +0 -7
  49. data/config/locales/fr.yml +4 -11
  50. data/config/locales/it.yml +0 -7
  51. data/config/locales/nl.yml +0 -7
  52. data/config/routes.rb +2 -8
  53. data/db/migrate/20160817115213_devise_create_decidim_users.rb +6 -6
  54. data/db/migrate/20160920140207_devise_invitable_add_to_decidim_users.rb +9 -9
  55. data/db/seeds.rb +2 -2
  56. data/lib/decidim/core.rb +25 -1
  57. data/lib/decidim/core/engine.rb +0 -1
  58. data/lib/decidim/core/test.rb +1 -0
  59. data/lib/decidim/core/test/factories.rb +11 -6
  60. data/lib/decidim/core/test/shared_examples/comments_examples.rb +69 -66
  61. data/lib/decidim/core/test/shared_examples/errors.rb +21 -0
  62. data/lib/decidim/core/test/shared_examples/has_reference.rb +18 -2
  63. data/lib/decidim/core/test/shared_examples/manage_moderations_examples.rb +2 -2
  64. data/lib/decidim/core/version.rb +1 -1
  65. data/lib/decidim/devise_failure_app.rb +1 -1
  66. data/lib/decidim/form_builder.rb +89 -5
  67. data/lib/decidim/has_reference.rb +3 -15
  68. data/lib/decidim/notifiable.rb +22 -0
  69. data/lib/devise/models/decidim_validatable.rb +4 -4
  70. metadata +41 -16
@@ -3,6 +3,8 @@
3
3
  module Decidim
4
4
  # Main module to add application-wide helpers.
5
5
  module ApplicationHelper
6
+ include Decidim::OmniauthHelper
7
+
6
8
  # Truncates a given text respecting its HTML tags.
7
9
  #
8
10
  # text - The String text to be truncated.
@@ -17,6 +19,7 @@ module Decidim
17
19
  options[:tail] = options.delete(:separator) || options[:tail] || "..."
18
20
  options[:count_tags] ||= false
19
21
  options[:count_tail] ||= false
22
+ options[:tail_before_final_tag] ||= true
20
23
 
21
24
  Truncato.truncate(text, options)
22
25
  end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ # A helper to get the root path for a feature.
5
+ module FeaturePathHelper
6
+ # Returns the defined root path for a given feature.
7
+ #
8
+ # feature - the Feature we want to find the root path for.
9
+ #
10
+ # Returns a url.
11
+ def feature_path(feature)
12
+ feature_root_path_for(feature.manifest.engine, feature)
13
+ end
14
+
15
+ # Returns the defined admin root path for a given feature.
16
+ #
17
+ # feature - the Feature we want to find the root path for.
18
+ #
19
+ # Returns a url.
20
+ def manage_feature_path(feature)
21
+ feature_root_path_for(feature.manifest.admin_engine, feature)
22
+ end
23
+
24
+ private
25
+
26
+ def feature_root_path_for(engine, feature)
27
+ url_params = {
28
+ feature_id: feature.id,
29
+ participatory_process_id: feature.participatory_process.id
30
+ }
31
+
32
+ engine.routes.url_helpers.root_path(url_params)
33
+ end
34
+ end
35
+ end
@@ -6,12 +6,14 @@ module Decidim
6
6
  # Displays the localized reference for the given feature.
7
7
  #
8
8
  # feature - the Feature that has the reference to display.
9
+ # options - An optional hash of options
10
+ # * class: A string of extra css classes
9
11
  #
10
12
  # Returns a String.
11
- def feature_reference(feature)
13
+ def feature_reference(feature, options = {})
12
14
  return unless feature.reference
13
15
  @reference = feature.reference
14
- "<div class='reference'>#{localized_reference}</div>".html_safe
16
+ "<div class='reference #{options[:class]}'>#{localized_reference}</div>".html_safe
15
17
  end
16
18
 
17
19
  private
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ # Helpers related to icons
5
+ module IconHelper
6
+ # Public: Returns an icon given an instance of a Feature. It defaults to
7
+ # a question mark when no icon is found.
8
+ #
9
+ # feature - The feature to generate the icon for.
10
+ #
11
+ # Returns an HTML tag with the icon.
12
+ def feature_icon(feature)
13
+ if feature.manifest.icon
14
+ external_icon feature.manifest.icon
15
+ else
16
+ icon "question-mark"
17
+ end
18
+ end
19
+ end
20
+ end
@@ -5,7 +5,7 @@ module Decidim
5
5
  module MenuHelper
6
6
  # Public: Returns the main menu presenter object
7
7
  def main_menu
8
- @main_menu ||= MenuPresenter.new(
8
+ @main_menu ||= ::Decidim::MenuPresenter.new(
9
9
  :menu,
10
10
  self,
11
11
  element_class: "main-nav__link",
@@ -13,19 +13,5 @@ module Decidim
13
13
  dates = [participatory_process_step.start_date, participatory_process_step.end_date]
14
14
  dates.map { |date| date ? localize(date.to_date, format: :default) : "?" }.join(" - ")
15
15
  end
16
-
17
- # Public: Returns an icon given an instance of a Feature. It defaults to
18
- # a question mark when no icon is found.
19
- #
20
- # feature - The feature to generate the icon for.
21
- #
22
- # Returns an HTML tag with the icon.
23
- def feature_icon(feature)
24
- if feature.manifest.icon
25
- external_icon feature.manifest.icon
26
- else
27
- icon "question-mark"
28
- end
29
- end
30
16
  end
31
17
  end
@@ -61,6 +61,14 @@ module Decidim
61
61
  self[:settings]["global"] = serialize_settings(settings_schema(:global), data)
62
62
  end
63
63
 
64
+ def default_step_settings
65
+ settings_schema(:step).new(self[:settings]["default_step"])
66
+ end
67
+
68
+ def default_step_settings=(data)
69
+ self[:settings]["default_step"] = serialize_settings(settings_schema(:step), data)
70
+ end
71
+
64
72
  def step_settings
65
73
  participatory_process.steps.each_with_object({}) do |step, result|
66
74
  result[step.id.to_s] = settings_schema(:step).new(self[:settings].dig("steps", step.id.to_s))
@@ -75,7 +83,7 @@ module Decidim
75
83
 
76
84
  def active_step_settings
77
85
  active_step = participatory_process.active_step
78
- return nil unless active_step
86
+ return default_step_settings unless active_step
79
87
 
80
88
  step_settings.fetch(active_step.id.to_s)
81
89
  end
@@ -11,6 +11,7 @@ module Decidim
11
11
  belongs_to :organization, foreign_key: "decidim_organization_id", class_name: "Decidim::Organization", inverse_of: :static_pages
12
12
 
13
13
  validates :slug, presence: true, uniqueness: { scope: :organization }
14
+ validates :slug, format: { with: /\A[a-z0-9-]+/ }
14
15
 
15
16
  # These pages will be created by default when registering an organization
16
17
  # and cannot be deleted.
@@ -28,6 +28,8 @@ module Decidim
28
28
  validate :all_roles_are_valid
29
29
  mount_uploader :avatar, Decidim::AvatarUploader
30
30
 
31
+ scope :not_deleted, -> { where(deleted_at: nil) }
32
+
31
33
  # Public: Allows customizing the invitation instruction email content when
32
34
  # inviting a user.
33
35
  #
@@ -5,7 +5,7 @@ module Decidim
5
5
  # public view.
6
6
  class HighlightedParticipatoryProcesses < Rectify::Query
7
7
  def query
8
- Decidim::ParticipatoryProcess.order("promoted DESC").includes(:active_step).order("decidim_participatory_process_steps.end_date ASC").limit(8)
8
+ PrioritizedParticipatoryProcesses.new.query.limit(8)
9
9
  end
10
10
  end
11
11
  end
@@ -1,9 +1,7 @@
1
1
  <div class="row">
2
2
  <%= decidim_form_for(@account, url: account_path, method: :put, class: "user-form") do |f| %>
3
3
  <div class="columns large-4">
4
- <%= image_tag current_user.avatar.big.url, width: "100%" %>
5
- <%= f.file_field :avatar, label: false %>
6
- <%= f.check_box :remove_avatar %>
4
+ <%= f.upload :avatar %>
7
5
  </div>
8
6
 
9
7
  <div class="columns large-8 end">
@@ -12,7 +12,7 @@
12
12
  <%= icon normalize_provider_name(provider) %>
13
13
  </span>
14
14
  <%= t("devise.shared.links.sign_in_with_provider", provider: normalize_provider_name(provider).titleize) %>
15
- <% end %>
15
+ <% end %>
16
16
  </div>
17
17
  <% end %>
18
18
  <% end %>
@@ -0,0 +1,20 @@
1
+ <% if Devise.mappings[:user].omniauthable? && any_social_provider_enabled? %>
2
+ <div class="row">
3
+ <div class="columns medium-8 medium-centered">
4
+ <span class="register__separator">
5
+ <span class="register__separator__text"><%= t('or', scope: "decidim.devise.shared.omniauth_buttons") %></span>
6
+ </span>
7
+ <div class="text-center">
8
+ <%- Decidim::User.omniauth_providers.each do |provider| %>
9
+ <% if social_provider_enabled? provider %>
10
+ <%= link_to decidim.send("user_#{provider}_omniauth_authorize_path"), class: "button button--social button--#{normalize_provider_name(provider)} button--social--mini" do %>
11
+ <span class="button--social__icon">
12
+ <%= icon normalize_provider_name(provider) %>
13
+ </span>
14
+ <% end %>
15
+ <% end %>
16
+ <% end %>
17
+ </div>
18
+ </div>
19
+ </div>
20
+ <% end %>
@@ -8,6 +8,6 @@
8
8
  <%= link_to t(".back_home"), root_path, class: "button" %>
9
9
  </div>
10
10
  </div>
11
+ </div>
11
12
  </div>
12
- </div>
13
13
  </main>
@@ -24,6 +24,10 @@
24
24
  <p class="text-center">
25
25
  <%= link_to t('.sign_up'), decidim.new_user_registration_path, class: "sign-up-link" %>
26
26
  </p>
27
+ <p class="text-center">
28
+ <%= link_to t("devise.shared.links.forgot_your_password"), new_password_path(:user) %>
29
+ </p>
27
30
  </div>
31
+ <%= render "decidim/devise/shared/omniauth_buttons_mini" %>
28
32
  </div>
29
33
  </div>
@@ -29,5 +29,5 @@
29
29
  <span aria-hidden="true">&times;</span>
30
30
  </button>
31
31
  </div>
32
- <h4 class="heading4"><%= "#{content_for(:meta_url)}" %></h4>
32
+ <h4 class="heading4"><%= "#{decidim_meta_url}" %></h4>
33
33
  </div>
@@ -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?(decidim.feature_path(current_participatory_process, feature), :inclusive) %>">
52
- <%= active_link_to decidim.feature_path(current_participatory_process, feature), class: "process-nav__link", active: :inclusive, class_active: "is-active" do %>
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 %>
53
53
  <%= feature_icon(feature) %>
54
54
 
55
55
  <%= translated_attribute(feature.name) %>
@@ -105,6 +105,8 @@ ignore_unused:
105
105
  - decidim.participatory_processes.scopes.global
106
106
  - decidim.participatory_processes.participatory_process_groups.none
107
107
  - pages.home.statistics.*
108
+ - forms.*
109
+
108
110
  # - 'activerecord.attributes.*'
109
111
  # - '{devise,kaminari,will_paginate}.*'
110
112
  # - 'simple_form.{yes,no}'
@@ -2,9 +2,9 @@
2
2
 
3
3
  InvisibleCaptcha.setup do |config|
4
4
  config.honeypots << "another_fake_attribute"
5
- config.visual_honeypots = false
5
+ config.visual_honeypots = false
6
6
  config.timestamp_threshold = 4
7
- config.timestamp_enabled = false
7
+ config.timestamp_enabled = false
8
8
  # Leave these unset if you want to use I18n (see below)
9
9
  # config.sentence_for_humans = 'If you are a human, ignore this field'
10
10
  # config.timestamp_error_message = 'Sorry, that was too quick! Please resubmit.'
@@ -118,6 +118,14 @@ ca:
118
118
  shared:
119
119
  omniauth_buttons:
120
120
  or: O
121
+ errors:
122
+ internal_server_error:
123
+ title: Hi ha hagut un problema amb el nostre servidor
124
+ try_later: Si us plau, torna-ho a intentar més tard.
125
+ not_found:
126
+ back_home: Tornar a l'inici
127
+ content_doesnt_exist: Aquesta adreça és incorrecta o ha estat eliminada.
128
+ title: No s'ha trobat la pàgina que busques
121
129
  export_mailer:
122
130
  export:
123
131
  ready: S'adjunta una versió comprimida de l'exportació.
@@ -145,6 +153,9 @@ ca:
145
153
  proposal: propostes
146
154
  result: Resultats
147
155
  forms:
156
+ current_file: Fitxer actual
157
+ current_image: Imatge actual
158
+ default_image: Imatge predeterminada
148
159
  errors:
149
160
  error: Hi ha un error en aquest camp.
150
161
  menu:
@@ -284,6 +295,8 @@ ca:
284
295
  too_many_marks: Està utilitzant massa símbols d'exclamació o interrogació
285
296
  too_much_caps: Està utilitzant massa majúscules
286
297
  too_short: És massa curt
298
+ forms:
299
+ required: Obligatori
287
300
  invisible_captcha:
288
301
  sentence_for_humans: Si ets un humà, pots ignorar aquest camp
289
302
  timestamp_error_message: Ho sentim, has estat massa ràpid! Torna a enviar-ho.
@@ -345,13 +358,6 @@ ca:
345
358
  locale:
346
359
  name: Català
347
360
  pages:
348
- '404':
349
- back_home: Tornar a l'inici
350
- content_doesnt_exist: Aquesta adreça és incorrecta o ha estat eliminada.
351
- title: No s'ha trobat la pàgina que busques!
352
- '500':
353
- title: Hi ha hagut un problema amb el nostre servidor
354
- try_later: Si us plau, torna-ho a intentar més tard.
355
361
  home:
356
362
  extended:
357
363
  debates: Debats
@@ -364,7 +370,7 @@ ca:
364
370
  proposals_explanation: Espai obert de propostes dels ciutadans sobre quin tipus de ciutat volem viure.
365
371
  footer_sub_hero:
366
372
  footer_sub_hero_body: Construïm una societat més oberta, transparent i col·laborativa.<br />Uneix-te, participa i decideix.
367
- footer_sub_hero_headline: Benvingut a la plataforma participativa %{organization}.
373
+ footer_sub_hero_headline: Bienvenida y bienvenido a la plataforma participativa %{organization}.
368
374
  register: Registra't
369
375
  hero:
370
376
  participate: Participa
@@ -119,6 +119,14 @@ en:
119
119
  shared:
120
120
  omniauth_buttons:
121
121
  or: Or
122
+ errors:
123
+ internal_server_error:
124
+ title: There was a problem with our server
125
+ try_later: Please try again later.
126
+ not_found:
127
+ back_home: Back home
128
+ content_doesnt_exist: This address is incorrect or has been removed.
129
+ title: The page you're looking for can't be found
122
130
  export_mailer:
123
131
  export:
124
132
  ready: Please find attached a zipped version of your export.
@@ -146,6 +154,9 @@ en:
146
154
  proposal: Proposals
147
155
  result: Results
148
156
  forms:
157
+ current_file: Current file
158
+ current_image: Current image
159
+ default_image: Default image
149
160
  errors:
150
161
  error: There's an error in this field.
151
162
  menu:
@@ -285,6 +296,8 @@ en:
285
296
  too_many_marks: Is using too many marks
286
297
  too_much_caps: Is using too much caps
287
298
  too_short: Is too short
299
+ forms:
300
+ required: Required
288
301
  invisible_captcha:
289
302
  sentence_for_humans: If you are human, ignore this field
290
303
  timestamp_error_message: Sorry, that was too quick! Please resubmit.
@@ -346,13 +359,6 @@ en:
346
359
  locale:
347
360
  name: English
348
361
  pages:
349
- '404':
350
- back_home: Back home
351
- content_doesnt_exist: This address is incorrect or has been removed.
352
- title: The page you're looking for can't be found
353
- '500':
354
- title: There was a problem with our server
355
- try_later: Please try again later.
356
362
  home:
357
363
  extended:
358
364
  debates: Debates
@@ -118,6 +118,14 @@ es:
118
118
  shared:
119
119
  omniauth_buttons:
120
120
  or: O
121
+ errors:
122
+ internal_server_error:
123
+ title: Ha habido un problema con nuestro servidor
124
+ try_later: Por favor, vuelve a intentarlo más tarde.
125
+ not_found:
126
+ back_home: Volver al inicio
127
+ content_doesnt_exist: Esta dirección es incorrecta o ha sido eliminada.
128
+ title: No se ha encontrado la página que buscas
121
129
  export_mailer:
122
130
  export:
123
131
  ready: Adjunto encontrará una versión comprimida de su exportación.
@@ -145,6 +153,9 @@ es:
145
153
  proposal: Propuestas
146
154
  result: Resultados
147
155
  forms:
156
+ current_file: Archivo actual
157
+ current_image: Imagen actual
158
+ default_image: Imagen predeterminada
148
159
  errors:
149
160
  error: Hay un error en este campo.
150
161
  menu:
@@ -284,6 +295,8 @@ es:
284
295
  too_many_marks: Está utilizando demasiados símbolos de interrogación o exclamación
285
296
  too_much_caps: Está usando demasiadas mayúsculas
286
297
  too_short: Es demasiado corto
298
+ forms:
299
+ required: Obligatorio
287
300
  invisible_captcha:
288
301
  sentence_for_humans: Si eres humano, ignora este campo
289
302
  timestamp_error_message: Lo siento, has sido demasiado rápido! Por favor, vuelva a enviar.
@@ -345,13 +358,6 @@ es:
345
358
  locale:
346
359
  name: Castellano
347
360
  pages:
348
- '404':
349
- back_home: Volver al inicio
350
- content_doesnt_exist: Esta dirección es incorrecta o ha sido eliminada.
351
- title: '¡No se ha encontrado la página que buscas!'
352
- '500':
353
- title: Ha habido un problema con nuestro servidor
354
- try_later: Por favor, vuelve a intentarlo más tarde.
355
361
  home:
356
362
  extended:
357
363
  debates: Debates
@@ -323,13 +323,6 @@ eu:
323
323
  locale:
324
324
  name: Euskera
325
325
  pages:
326
- '404':
327
- back_home: Itzuli hasierara
328
- content_doesnt_exist: Helbide okerra da edo ezabatu da.
329
- title: Ez dugu aurkitu bilatzen duzun orria!
330
- '500':
331
- title: Arazo bat izan da gure zerbitzariarekin
332
- try_later: Mesedez, berriz saiatu geroago.
333
326
  home:
334
327
  extended:
335
328
  debates: Eztabaidak