decidim-core 0.28.3 → 0.28.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/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.