decidim-core 0.28.3 → 0.28.4

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 (62) hide show
  1. checksums.yaml +4 -4
  2. data/app/cells/decidim/content_blocks/stats_cell.rb +1 -1
  3. data/app/cells/decidim/endorsement_buttons_cell.rb +1 -1
  4. data/app/cells/decidim/nav_links/show.erb +3 -3
  5. data/app/cells/decidim/resource_types_filter/show.erb +11 -12
  6. data/app/commands/decidim/amendable/create_draft.rb +1 -0
  7. data/app/controllers/concerns/decidim/devise_authentication_methods.rb +1 -1
  8. data/app/controllers/concerns/decidim/direct_upload.rb +82 -0
  9. data/app/forms/decidim/upload_validation_form.rb +1 -1
  10. data/app/helpers/decidim/layout_helper.rb +28 -0
  11. data/app/helpers/decidim/menu_helper.rb +1 -1
  12. data/app/helpers/decidim/scopes_helper.rb +5 -2
  13. data/app/models/decidim/action_log.rb +11 -1
  14. data/app/packs/src/decidim/a11y.js +11 -15
  15. data/app/packs/src/decidim/append_redirect_url_to_modals.js +14 -12
  16. data/app/packs/src/decidim/direct_uploads/upload_modal.js +3 -0
  17. data/app/packs/stylesheets/decidim/_buttons.scss +1 -1
  18. data/app/packs/stylesheets/decidim/_modal_update.scss +4 -0
  19. data/app/presenters/decidim/menu_item_presenter.rb +1 -1
  20. data/app/queries/decidim/last_activity.rb +16 -5
  21. data/app/views/decidim/devise/omniauth_registrations/new.html.erb +1 -1
  22. data/app/views/decidim/offline/show.html.erb +1 -1
  23. data/app/views/decidim/pages/_tabbed.html.erb +3 -3
  24. data/app/views/decidim/shared/_filters.html.erb +5 -5
  25. data/app/views/decidim/shared/_orders.html.erb +3 -2
  26. data/app/views/decidim/shared/filters/_check_boxes_tree.html.erb +1 -1
  27. data/app/views/decidim/shared/filters/_collection.html.erb +1 -1
  28. data/app/views/layouts/decidim/_head.html.erb +1 -1
  29. data/app/views/layouts/decidim/shared/_layout_user_profile.html.erb +2 -2
  30. data/config/locales/ar.yml +0 -1
  31. data/config/locales/bg.yml +0 -1
  32. data/config/locales/ca.yml +1 -1
  33. data/config/locales/cs.yml +1 -1
  34. data/config/locales/de.yml +2 -2
  35. data/config/locales/el.yml +0 -1
  36. data/config/locales/en.yml +1 -1
  37. data/config/locales/es-MX.yml +1 -1
  38. data/config/locales/es-PY.yml +1 -1
  39. data/config/locales/es.yml +1 -1
  40. data/config/locales/eu.yml +4 -4
  41. data/config/locales/fi-plain.yml +1 -1
  42. data/config/locales/fi.yml +1 -1
  43. data/config/locales/fr-CA.yml +1 -1
  44. data/config/locales/fr.yml +1 -1
  45. data/config/locales/gl.yml +0 -1
  46. data/config/locales/hu.yml +0 -1
  47. data/config/locales/ja.yml +3 -3
  48. data/config/locales/lt.yml +0 -1
  49. data/config/locales/pl.yml +0 -1
  50. data/config/locales/pt-BR.yml +199 -1
  51. data/config/locales/ro-RO.yml +61 -48
  52. data/config/locales/sv.yml +446 -75
  53. data/config/locales/zh-TW.yml +0 -1
  54. data/lib/decidim/core/engine.rb +6 -0
  55. data/lib/decidim/core/test/shared_examples/comments_examples.rb +10 -0
  56. data/lib/decidim/core/test/shared_examples/system_endorse_resource_examples.rb +112 -14
  57. data/lib/decidim/core/version.rb +1 -1
  58. data/lib/decidim/core.rb +11 -0
  59. data/lib/decidim/organization_settings.rb +4 -1
  60. data/lib/decidim/view_model.rb +1 -1
  61. data/lib/tasks/upgrade/decidim_attachments.rake +14 -0
  62. metadata +8 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7ed7b2e2e440e7ab68c508dc8242f6adbee52c292cfa8fd3fd43e42fc75e8f8f
4
- data.tar.gz: ee75d95c1002bc872483de673a2e21e23c100d387d2bd50d86bb05ed5a91d1fa
3
+ metadata.gz: 3ec3e95f4dbf1ac0e6178188a46ddf5d702bea045e85d76f64c1193af3c0e2ed
4
+ data.tar.gz: 684aeb5ae98c9d8fe9fa9488721d153fbc42be5dcd1cd13d1328e34da3ebdef8
5
5
  SHA512:
6
- metadata.gz: d82a46910165f8510bec81d79677b26057d49e88ddc9ddd3fda2443b0d8529804faebb2eb8949313b4cf4c25fc8fd406da049dc2e33d172430d7614dc043b9cd
7
- data.tar.gz: e86a808c22abc5db470d2bcf7d9427a2d8ea13588a73fcbde936fbd22c381d606f30b45353e3638f39150e16966cf75edcf6d81698164b3bdef9055b1881a02f
6
+ metadata.gz: fee3f0d928f2853e9953dc65e5232aae720997c23d7933e4e08a3154246ae6612a7688e4b9dc0c7af196b9f7043aacd08b7bee72e60ebe69b6b9ce057e17149c
7
+ data.tar.gz: 02fb38ba880953a3b819f4ff1b3d88d6cde4dcd66a2753ddb5178fa524d73f8e8db14b4bcf4e862651ff16c45c1f6be4044520a6daf8d8f94b1ff9dfae299ec1
@@ -17,7 +17,7 @@ module Decidim
17
17
  end
18
18
 
19
19
  def cache_expiry_time
20
- 10.minutes
20
+ Decidim.stats_cache_expiry_time
21
21
  end
22
22
  end
23
23
  end
@@ -77,7 +77,7 @@ module Decidim
77
77
  end
78
78
 
79
79
  def user_has_verified_groups?
80
- current_user && Decidim::UserGroups::ManageableUserGroups.for(current_user).verified.any?
80
+ current_user && current_organization.user_groups_enabled? && Decidim::UserGroups::ManageableUserGroups.for(current_user).verified.any?
81
81
  end
82
82
 
83
83
  def endorse_translated
@@ -1,12 +1,12 @@
1
1
  <div class="participatory-space__nav-container">
2
- <button id="dropdown-trigger-participatory-space" data-component="dropdown" data-target="dropdown-menu-participatory-space" data-auto-close="true" data-scroll-to-menu="true">
2
+ <button id="dropdown-trigger-participatory-space" data-component="dropdown" data-target="dropdown-menu-participatory-space" data-auto-close="true" data-scroll-to-menu="true" data-open-md="true">
3
3
  <span><%= t("decidim.searches.filters.jump_to") %></span>
4
4
  <%= icon "arrow-down-s-line" %>
5
5
  <%= icon "arrow-up-s-line" %>
6
6
  </button>
7
- <ul id="dropdown-menu-participatory-space" class="participatory-space__nav" aria-hidden="true">
7
+ <ul id="dropdown-menu-participatory-space" class="participatory-space__nav">
8
8
  <% model.each do |item| %>
9
- <li>
9
+ <li role="menuitem">
10
10
  <%= link_to item[:url], class: "participatory-space__nav-item" do %>
11
11
  <%= item[:name] %>
12
12
  <%= icon "arrow-right-line" %>
@@ -1,5 +1,5 @@
1
1
  <div id="<%= id %>" class="filter-container">
2
- <button id="dropdown-trigger-resource" data-component="dropdown" data-target="dropdown-menu-resource" data-auto-close="true">
2
+ <button id="dropdown-trigger-resource" data-component="dropdown" data-target="dropdown-menu-resource" data-open-md="true">
3
3
  <% resource_types.each do |resource_type| %>
4
4
  <span data-value="<%= resource_type[0] %>" class="<%= "is-active" if filter_param == resource_type[0] %>">
5
5
  <%= text_with_resource_icon(*resource_type) %>
@@ -8,15 +8,14 @@
8
8
  <%= icon "arrow-down-s-line" %>
9
9
  <%= icon "arrow-up-s-line" %>
10
10
  </button>
11
- <%= filter_form_for filter, form_path, :class => "new_filter", :id => "dropdown-menu-resource", "aria-hidden" => true do |form| %>
12
- <%= form.collection_radio_buttons(
13
- filter_param_key,
14
- resource_types,
15
- :first,
16
- :last,
17
- { checked: filter_param }
18
- ) do |builder|
19
- builder.label { builder.radio_button(class: "reset-defaults", hidden: true) + content_tag(:span, text_with_resource_icon(builder.value, builder.text), class: "filter") }
20
- end %>
21
- <% end %>
11
+ <ul id="dropdown-menu-resource">
12
+ <% resource_types.each do |resource_type| %>
13
+ <li role="menuitem">
14
+ <%= link_to decidim.last_activities_path(filter: { with_resource_type: resource_type[0] } ), class: "filter#{" is-active" if filter_param == resource_type[0]}" do %>
15
+ <span class="sr-only"><%= resource_type[1] %></span>
16
+ <%= text_with_resource_icon(*resource_type) %>
17
+ <% end %>
18
+ </li>
19
+ <% end %>
20
+ </ul>
22
21
  </div>
@@ -53,6 +53,7 @@ module Decidim
53
53
  emendation.body = { I18n.locale => form.emendation_params.with_indifferent_access[:body] }
54
54
  emendation.component = amendable.component
55
55
  emendation.add_author(current_user, user_group)
56
+ emendation.category = amendable.category if amendable.respond_to?(:category)
56
57
  emendation.save!
57
58
  emendation
58
59
  end
@@ -12,7 +12,7 @@ module Decidim
12
12
  if user.present? && user.blocked?
13
13
  check_user_block_status(user)
14
14
  elsif user.needs_password_update?
15
- change_password_path
15
+ decidim.change_password_path
16
16
  elsif first_login_and_not_authorized?(user) && !user.admin? && !pending_redirect?(user)
17
17
  decidim_verifications.first_login_authorizations_path
18
18
  else
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module DirectUpload
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ include Decidim::NeedsOrganization
9
+ skip_before_action :verify_organization
10
+
11
+ before_action :check_organization!,
12
+ :check_authenticated!,
13
+ :check_user_belongs_to_organization,
14
+ :validate_direct_upload
15
+ end
16
+
17
+ protected
18
+
19
+ def validate_direct_upload
20
+ # We skip the validation if we are in system panel. `current_admin` refers to the main system admin user.
21
+ return if current_admin.present?
22
+
23
+ head :unprocessable_entity unless [
24
+ maximum_allowed_size.try(:to_i) >= blob_args[:byte_size].try(:to_i),
25
+ content_types.any? { |pattern| pattern.match?(blob_args[:content_type]) },
26
+ content_types.any? { |pattern| pattern.match?(MiniMime.lookup_by_extension(extension)&.content_type) },
27
+ allowed_extensions.any? { |pattern| pattern.match?(extension) }
28
+ ].all?
29
+ rescue NoMethodError
30
+ head :unprocessable_entity
31
+ end
32
+
33
+ def extension
34
+ File.extname(blob_args[:filename]).delete(".")
35
+ end
36
+
37
+ def maximum_allowed_size
38
+ current_organization.settings.upload_maximum_file_size
39
+ end
40
+
41
+ def check_organization!
42
+ head :unauthorized if current_organization.blank? && current_admin.blank?
43
+ end
44
+
45
+ def check_authenticated!
46
+ head :unauthorized if current_user.blank? && current_admin.blank?
47
+ end
48
+
49
+ def check_user_belongs_to_organization
50
+ return if current_admin.present?
51
+
52
+ head :unauthorized unless current_organization == current_user.organization
53
+ end
54
+
55
+ def allowed_extensions
56
+ if user_has_elevated_role?
57
+ current_organization.settings.upload_allowed_file_extensions_admin
58
+ else
59
+ current_organization.settings.upload_allowed_file_extensions
60
+ end
61
+ end
62
+
63
+ def content_types
64
+ if user_has_elevated_role?
65
+ current_organization.settings.upload_allowed_content_types_admin
66
+ else
67
+ current_organization.settings.upload_allowed_content_types
68
+ end
69
+ end
70
+
71
+ private
72
+
73
+ def user_has_elevated_role?
74
+ [
75
+ current_user&.admin?,
76
+ defined?(Decidim::Assemblies::AssembliesWithUserRole) && Decidim::Assemblies::AssembliesWithUserRole.for(current_user).any?,
77
+ defined?(Decidim::Conferences::ConferencesWithUserRole) && Decidim::Conferences::ConferencesWithUserRole.for(current_user).any?,
78
+ defined?(Decidim::ParticipatoryProcessesWithUserRole) && Decidim::ParticipatoryProcessesWithUserRole.for(current_user).any?
79
+ ].any?
80
+ end
81
+ end
82
+ end
@@ -10,7 +10,7 @@ module Decidim
10
10
  # Property is named as attribute in upload modal and passthru validator, but
11
11
  # it cannot be named as attribute here.
12
12
  attribute :property, String
13
- attribute :blob, String
13
+ attribute :blob, Decidim::Attributes::Blob
14
14
  attribute :form_class, String
15
15
 
16
16
  validates :resource_class, presence: true
@@ -169,6 +169,20 @@ module Decidim
169
169
  end
170
170
  end
171
171
 
172
+ def current_url(params = request.parameters)
173
+ return url_for(params) if respond_to?(:current_participatory_space) || respond_to?(:current_component)
174
+
175
+ each_decidim_engine do |helpers|
176
+ return helpers.url_for(params)
177
+ rescue ActionController::UrlGenerationError
178
+ # Continue to next engine in case the URL is not available.
179
+ end
180
+
181
+ main_app.url_for(params)
182
+ rescue ActionController::UrlGenerationError
183
+ "#{request.base_url}#{"?#{params.to_query}" unless params.empty?}"
184
+ end
185
+
172
186
  private
173
187
 
174
188
  def empty_organization_description?
@@ -177,6 +191,20 @@ module Decidim
177
191
  organization_description.blank? || organization_description == "<p></p>"
178
192
  end
179
193
 
194
+ def each_decidim_engine
195
+ Rails.application.railties.each do |engine|
196
+ next unless engine.is_a?(Rails::Engine)
197
+ next unless engine.isolated?
198
+ next unless engine.engine_name.start_with?("decidim_")
199
+ next unless respond_to?(engine.engine_name)
200
+
201
+ yield public_send(engine.engine_name)
202
+ end
203
+ return unless respond_to?(:decidim)
204
+
205
+ yield decidim
206
+ end
207
+
180
208
  def tag_builder
181
209
  @tag_builder ||= ActionView::Helpers::TagHelper::TagBuilder.new(self)
182
210
  end
@@ -49,7 +49,7 @@ module Decidim
49
49
  self,
50
50
  element_class: "font-semibold underline",
51
51
  active_class: "is-active",
52
- container_options: { class: "space-y-4 break-inside-avoid" },
52
+ container_options: { class: "space-y-4 break-inside-avoid", role: :menu },
53
53
  label: t("layouts.decidim.footer.decidim_title")
54
54
  )
55
55
  end
@@ -53,11 +53,14 @@ module Decidim
53
53
  # options - An optional Hash with options:
54
54
  #
55
55
  # Returns nothing.
56
- def scopes_select_field(form, name, root: false, options: {})
56
+ def scopes_select_field(form, name, root: false, options: {}, html_options: {})
57
+ options = options.merge(include_blank: I18n.t("decidim.scopes.prompt")) unless options.has_key?(:include_blank)
58
+
57
59
  form.select(
58
60
  name,
59
61
  ordered_scopes_descendants_for_select(root),
60
- options.merge(include_blank: I18n.t("decidim.scopes.prompt"))
62
+ options,
63
+ html_options
61
64
  )
62
65
  end
63
66
 
@@ -138,6 +138,7 @@ module Decidim
138
138
  Decidim::Proposals::Proposal
139
139
  Decidim::Surveys::Survey
140
140
  Decidim::Assembly
141
+ Decidim::Conference
141
142
  Decidim::Initiative
142
143
  Decidim::ParticipatoryProcess
143
144
  ).select do |klass|
@@ -154,7 +155,16 @@ module Decidim
154
155
  end
155
156
 
156
157
  def self.publicable_public_resource_types
157
- @publicable_public_resource_types ||= public_resource_types.select { |klass| klass.constantize.column_names.include?("published_at") }
158
+ @publicable_public_resource_types ||= public_resource_types
159
+ .select { |klass| klass.constantize.column_names.include?("published_at") } - publicable_exceptions
160
+ end
161
+
162
+ def self.publicable_exceptions
163
+ @publicable_exceptions = %w(
164
+ Decidim::Blogs::Post
165
+ ).select do |klass|
166
+ klass.safe_constantize.present?
167
+ end
158
168
  end
159
169
 
160
170
  def self.ransackable_scopes(auth_object = nil)
@@ -59,7 +59,6 @@ const createDropdown = (component) => {
59
59
  const dropdownOptions = {};
60
60
  dropdownOptions.dropdown = component.dataset.target;
61
61
  dropdownOptions.hover = component.dataset.hover === "true";
62
- dropdownOptions.isOpen = component.dataset.open === "true";
63
62
  dropdownOptions.autoClose = component.dataset.autoClose === "true";
64
63
 
65
64
  // This snippet allows to disable the dropdown based on the current viewport
@@ -78,6 +77,17 @@ const createDropdown = (component) => {
78
77
  return
79
78
  }
80
79
 
80
+ dropdownOptions.isOpen = component.dataset.open === "true";
81
+
82
+ const isOpen = Object.keys(screens).some((key) => {
83
+ if (!isScreenSize(key)) {
84
+ return false;
85
+ }
86
+ return Boolean(component.dataset[`open-${key}`.replace(/-([a-z])/g, (str) => str[1].toUpperCase())]);
87
+ });
88
+
89
+ dropdownOptions.isOpen = dropdownOptions.isOpen || isOpen;
90
+
81
91
  if (!component.id) {
82
92
  // when component has no id, we enforce to have it one
83
93
  component.id = `dropdown-${Math.random().toString(36).substring(7)}`
@@ -104,20 +114,6 @@ const createDropdown = (component) => {
104
114
  });
105
115
  }
106
116
 
107
- // Disable focus on children elements so we can pass the AXE accessibility tests
108
- const dropdownMenu = document.getElementById(dropdownOptions.dropdown);
109
- if (dropdownMenu.getAttribute("aria-hidden") === "true") {
110
- dropdownMenu.
111
- querySelectorAll("a, input, button").
112
- forEach((element) => { element.tabIndex = -1 })
113
- }
114
-
115
- component.addEventListener("click", () => {
116
- dropdownMenu.
117
- querySelectorAll("a, input, button").
118
- forEach((element) => { element.tabIndex = 0 })
119
- })
120
-
121
117
  Dropdowns.render(component.id, dropdownOptions);
122
118
  }
123
119
 
@@ -53,21 +53,23 @@ $(() => {
53
53
  }
54
54
 
55
55
  $(document).on("click.zf.trigger", (event) => {
56
- const target = `#${$(event.target).data("open")}`;
56
+ const target = `#${$(event.target).data("dialogOpen")}`;
57
57
  const redirectUrl = $(event.target).data("redirectUrl");
58
58
 
59
- if (target && redirectUrl) {
60
- $("<input type='hidden' />").
61
- attr("id", "redirect_url").
62
- attr("name", "redirect_url").
63
- attr("value", redirectUrl).
64
- appendTo(`${target} form`);
65
-
66
- $(`${target} a`).attr("href", (index, href) => {
67
- const querystring = jQuery.param({"redirect_url": redirectUrl});
68
- return href + (href.match(/\?/) ? "&" : "?") + querystring;
69
- });
59
+ if (!target || !redirectUrl) {
60
+ return;
70
61
  }
62
+
63
+ $("<input type='hidden' />").
64
+ attr("id", "redirect_url").
65
+ attr("name", "redirect_url").
66
+ attr("value", redirectUrl).
67
+ appendTo(`${target} form`);
68
+
69
+ $(`${target} a`).attr("href", (index, href) => {
70
+ const querystring = jQuery.param({ "redirect_url": redirectUrl });
71
+ return href + (href.match(/\?/) ? "&" : "?") + querystring;
72
+ });
71
73
  });
72
74
 
73
75
  $(document).on("closed.zf.reveal", (event) => {
@@ -77,6 +77,9 @@ export default class UploadModal {
77
77
  uploader.upload.create((error, blob) => {
78
78
  if (error) {
79
79
  uploader.errors = [error]
80
+ this.uploadItems.replaceChild(this.createUploadItem(file, [error], { value: 100 }), item);
81
+ this.updateDropZone();
82
+
80
83
  } else {
81
84
  // attach the file hash to submit the form, when the file has been uploaded
82
85
  file.hiddenField = blob.signed_id
@@ -67,7 +67,7 @@
67
67
  }
68
68
 
69
69
  &.is-hover,
70
- &:not([disabled]):not([class*="button__text"]):hover {
70
+ &:not([disabled]):not([class*="button__text"]):not(label):hover {
71
71
  @apply text-white;
72
72
 
73
73
  background: linear-gradient(0deg, rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0.3)),
@@ -6,6 +6,10 @@
6
6
  @apply py-14;
7
7
  }
8
8
 
9
+ &.is-disabled label.button__secondary {
10
+ @apply text-gray-2 bg-background-3 border border-gray-2 cursor-not-allowed;
11
+ }
12
+
9
13
  &-container {
10
14
  @apply mt-4 md:mt-12 space-y-4;
11
15
  }
@@ -26,7 +26,7 @@ module Decidim
26
26
  delegate :content_tag, :safe_join, :link_to, :active_link_to_class, :is_active_link?, :icon, to: :@view
27
27
 
28
28
  def render
29
- content_tag :li, class: link_wrapper_classes do
29
+ content_tag :li, role: :menuitem, class: link_wrapper_classes do
30
30
  output = if url == "#"
31
31
  [content_tag(:span, composed_label, class: "sidebar-menu__item-disabled")]
32
32
  else
@@ -56,13 +56,24 @@ module Decidim
56
56
 
57
57
  condition = if klass.include?(Decidim::HasPrivateUsers)
58
58
  Arel.sql(
59
- [
60
- "decidim_action_logs.participatory_space_type = '#{manifest.model_class_name}'",
61
- "decidim_action_logs.participatory_space_id IN (#{Arel.sql(klass.visible_for(current_user).select(:id).to_sql)})"
62
- ].join(" AND ")
59
+ <<~SQL.squish
60
+ (
61
+ decidim_action_logs.participatory_space_type = '#{manifest.model_class_name}' AND#{" "}
62
+ decidim_action_logs.participatory_space_id IN (#{Arel.sql(klass.visible_for(current_user).select(:id).to_sql)})
63
+ ) OR#{" "}
64
+ (
65
+ decidim_action_logs.resource_type = '#{manifest.model_class_name}' AND#{" "}
66
+ decidim_action_logs.resource_id IN (#{Arel.sql(klass.visible_for(current_user).select(:id).to_sql)})
67
+ )
68
+ SQL
63
69
  ).to_s
64
70
  else
65
- Arel.sql("decidim_action_logs.participatory_space_type = '#{manifest.model_class_name}'").to_s
71
+ Arel.sql(
72
+ [
73
+ "decidim_action_logs.resource_type = '#{manifest.model_class_name}'",
74
+ "decidim_action_logs.participatory_space_type = '#{manifest.model_class_name}'"
75
+ ].join(" OR ")
76
+ ).to_s
66
77
  end
67
78
 
68
79
  conditions << "(#{condition})"
@@ -13,7 +13,7 @@
13
13
  <%= form_required_explanation %>
14
14
  </div>
15
15
 
16
- <%= decidim_form_for(@form, namespace: "registration", as: resource_name, url: omniauth_registrations_path(resource_name)) do |f| %>
16
+ <%= decidim_form_for(@form, namespace: "registration", as: resource_name, url: decidim.omniauth_registrations_path(resource_name)) do |f| %>
17
17
 
18
18
  <div class="form__wrapper">
19
19
  <%= f.text_field :name, help_text: t("decidim.devise.omniauth_registrations.new.username_help"), autocomplete: "name", placeholder: "John Doe" %>
@@ -1,6 +1,6 @@
1
1
  <% add_decidim_page_title(t("decidim.offline.name")) %>
2
2
 
3
- <main id="offline-fallback-html" class="text-center mt-8">
3
+ <main id="offline-fallback-html" class="text-center my-8">
4
4
  <div class="flex justify-center">
5
5
  <svg xmlns="http://www.w3.org/2000/svg" width="5rem" height="r5em" viewBox="0 0 25 25">
6
6
  <path
@@ -11,16 +11,16 @@
11
11
 
12
12
  <div class="vertical-tabs">
13
13
  <nav>
14
- <button id="dropdown-trigger-pages" data-component="dropdown" data-target="dropdown-menu-pages" data-auto-close="true">
14
+ <button id="dropdown-trigger-pages" data-component="dropdown" data-target="dropdown-menu-pages" data-open-md="true" data-auto-close="true">
15
15
  <span>
16
16
  <%= translated_attribute(page.title) %>
17
17
  </span>
18
18
  <%= icon "arrow-down-s-line" %>
19
19
  <%= icon "arrow-up-s-line" %>
20
20
  </button>
21
- <ul id="dropdown-menu-pages" class="vertical-tabs__list" aria-hidden="true">
21
+ <ul id="dropdown-menu-pages" class="vertical-tabs__list" role="menu">
22
22
  <% pages.each do |sibling| %>
23
- <li class="<%= "is-active" if page == sibling %>">
23
+ <li class="<%= "is-active" if page == sibling %>" role="menuitem">
24
24
  <%= link_to translated_attribute(sibling.title), page_path(sibling.slug) %>
25
25
  </li>
26
26
  <% end %>
@@ -4,7 +4,7 @@
4
4
  <% if filter_sections.present? || local_assigns.has_key?(:search_variable) %>
5
5
  <%= filter_form_for filter, url_for, class: "new_filter self-stretch", data: { filters: "", component: "accordion" } do |form| %>
6
6
 
7
- <button id="dropdown-trigger-filters" data-component="dropdown" data-target="dropdown-menu-filters">
7
+ <button id="dropdown-trigger-filters" data-component="dropdown" data-target="dropdown-menu-filters" data-open-md="true">
8
8
  <%= icon "arrow-down-s-line" %>
9
9
  <%= icon "arrow-up-s-line" %>
10
10
  <span>
@@ -12,14 +12,14 @@
12
12
  </span>
13
13
  </button>
14
14
 
15
- <div id="dropdown-menu-filters" aria-hidden="true">
15
+ <div id="dropdown-menu-filters">
16
16
  <% if local_assigns.has_key?(:skip_to_id) %>
17
- <%= link_to t("skip", scope: "decidim.shared.filter_form_help"), "##{skip_to_id}", class: "filter-skip" %>
17
+ <%= link_to t("skip", scope: "decidim.shared.filter_form_help"), "##{skip_to_id}", class: "filter-skip", role: "menuitem" %>
18
18
  <% end %>
19
- <p class="filter-help"><%= t("help", scope: "decidim.shared.filter_form_help") %></p>
19
+ <p class="filter-help" role="menuitem" aria-disabled="true"><%= t("help", scope: "decidim.shared.filter_form_help") %></p>
20
20
 
21
21
  <% if local_assigns.has_key?(:search_variable) %>
22
- <div class="filter-search filter-container">
22
+ <div class="filter-search filter-container" role="menuitem">
23
23
  <%= form.search_field search_variable,
24
24
  label: false,
25
25
  placeholder: search_label,
@@ -1,13 +1,14 @@
1
- <button class="order-by__button" id="dropdown-trigger-order" data-component="dropdown" data-target="dropdown-menu-order" data-open="false">
1
+ <button class="order-by__button" id="dropdown-trigger-order" data-component="dropdown" data-target="dropdown-menu-order" data-open-md="true">
2
2
  <%= icon "arrow-down-s-line" %>
3
3
  <%= icon "arrow-up-s-line" %>
4
4
  <span><%= t("#{i18n_scope}.label") %></span>
5
5
  </button>
6
- <div id="dropdown-menu-order" class="order-by" aria-hidden="true">
6
+ <div id="dropdown-menu-order" class="order-by">
7
7
  <% orders.each do |order_name| %>
8
8
  <%= order_link order_name,
9
9
  i18n_scope:,
10
10
  title: t("#{i18n_scope}.label"),
11
+ role: :menuitem,
11
12
  class: "button button__sm button__text-secondary #{order_name == order ? "underline font-bold" : "font-normal"}" %>
12
13
  <% end %>
13
14
  </div>
@@ -1,4 +1,4 @@
1
- <div class="filter-container">
1
+ <div class="filter-container" role="menuitem">
2
2
  <button id="trigger-menu-<%= id %>" data-controls="panel-dropdown-menu-<%= id %>" data-open="false" data-open-md="true">
3
3
  <%= icon "arrow-down-s-line" %>
4
4
  <%= icon "arrow-up-s-line" %>
@@ -1,4 +1,4 @@
1
- <div class="filter-container">
1
+ <div class="filter-container" role="menuitem">
2
2
  <button id="trigger-menu-<%= id %>" data-controls="panel-dropdown-menu-<%= id %>" data-open="false" data-open-md="true">
3
3
  <%= icon "arrow-down-s-line" %>
4
4
  <%= icon "arrow-up-s-line" %>
@@ -2,7 +2,7 @@
2
2
 
3
3
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
4
4
  <% available_locales.each do |locale| %>
5
- <link rel="alternate" href="<%= url_for(request.parameters.merge(locale:)) %>" hreflang="<%= locale %>">
5
+ <link rel="alternate" href="<%= current_url(request.parameters.merge(locale:)) %>" hreflang="<%= locale %>">
6
6
  <% end %>
7
7
 
8
8
  <meta name="twitter:card" content="summary_large_image">
@@ -10,12 +10,12 @@
10
10
 
11
11
  <div class="vertical-tabs">
12
12
  <nav aria-label="menu-vertical">
13
- <button id="dropdown-trigger-profile" data-component="dropdown" data-target="dropdown-menu-profile">
13
+ <button id="dropdown-trigger-profile" data-open-md="true" data-component="dropdown" data-target="dropdown-menu-profile">
14
14
  <span><%= user_menu.active_item&.label || t("decidim.searches.filters.jump_to") %></span>
15
15
  <%= icon "arrow-down-s-line" %>
16
16
  <%= icon "arrow-up-s-line" %>
17
17
  </button>
18
- <ul id="dropdown-menu-profile" class="vertical-tabs__list" aria-hidden="true">
18
+ <ul id="dropdown-menu-profile" class="vertical-tabs__list">
19
19
  <%= user_menu.render %>
20
20
  </ul>
21
21
  </nav>
@@ -813,7 +813,6 @@ ar:
813
813
  title_required: العنوان مطلوب!
814
814
  uploaded: تم التحميل
815
815
  validating: جارية المصادقة...
816
- validation_error: خطأ في المصادقة!
817
816
  select_file: اختيار ملف
818
817
  upload_help:
819
818
  dropzone: قم بإسقاط الملفات هنا أو انقر للتحميل
@@ -923,7 +923,6 @@ bg:
923
923
  title_required: Заглавието е задължително!
924
924
  uploaded: Качено
925
925
  validating: Валидиране...
926
- validation_error: Грешка при валидирането!
927
926
  select_file: Избор на файл
928
927
  upload_help:
929
928
  dropzone: Пуснете файлове тук или щракнете върху бутона за качване
@@ -918,7 +918,7 @@ ca:
918
918
  title_required: Un títol és necessari!
919
919
  uploaded: Pujat
920
920
  validating: Validant...
921
- validation_error: Error de validació!
921
+ validation_error: Error en la validació! Si us plau, revisa que l'arxiu tingui una extensió o una mida permesa.
922
922
  select_file: Selecciona un fitxer
923
923
  upload_help:
924
924
  dropzone: Arrossega-hi els arxius o fes clic per a pujar-los
@@ -961,7 +961,7 @@ cs:
961
961
  title_required: Název je povinný!
962
962
  uploaded: Nahráno
963
963
  validating: Probíhá ověřování...
964
- validation_error: Chyba ověření!
964
+ validation_error: Chyba ověření! Zkontrolujte, zda má soubor povolenou příponu nebo velikost.
965
965
  select_file: Vyberte soubor
966
966
  upload_help:
967
967
  dropzone: Přetáhněte soubory sem nebo klikněte na tlačítko pro nahrání
@@ -923,7 +923,7 @@ de:
923
923
  title_required: Titel ist erforderlich!
924
924
  uploaded: Hochgeladen
925
925
  validating: Wird validiert...
926
- validation_error: Validierungsfehler!
926
+ validation_error: Validierungsfehler! Überprüfen Sie, ob die Datei einen erlaubten Dateityp oder Größe hat.
927
927
  select_file: Datei auswählen
928
928
  upload_help:
929
929
  dropzone: Dateien hier ablegen oder die Schaltfläche zum Hochladen benutzen
@@ -1468,7 +1468,7 @@ de:
1468
1468
  more: Mehr
1469
1469
  unfold: Entfalten
1470
1470
  filter_form_help:
1471
- help: Das untenstehende Formular filtert die Suchergebnisse dynamisch, wenn die Suchbedingungen geändert werden.
1471
+ help: Die Suchresultate werden bei geänderten Filtereinstellungen automatisch aktualisiert.
1472
1472
  skip: Zu Ergebnissen springen
1473
1473
  flag_modal:
1474
1474
  already_reported: Dieser Inhalt wurde bereits gemeldet und wird von einem Administrator überprüft.