decidim-core 0.29.4 → 0.29.5
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.
- checksums.yaml +4 -4
- data/app/cells/decidim/activity/show.erb +6 -6
- data/app/cells/decidim/content_blocks/participatory_space_main_data/title.erb +11 -2
- data/app/cells/decidim/footer_topics/show.erb +2 -2
- data/app/cells/decidim/group_admins/show.erb +3 -1
- data/app/cells/decidim/group_members/show.erb +6 -2
- data/app/cells/decidim/images_panel/show.erb +5 -2
- data/app/cells/decidim/report_button/flag_modal.erb +11 -9
- data/app/cells/decidim/report_user_button/flag_modal.erb +11 -10
- data/app/cells/decidim/upload_modal/files.erb +4 -4
- data/app/cells/decidim/upload_modal_cell.rb +5 -3
- data/app/commands/decidim/amendable/accept.rb +2 -1
- data/app/controllers/concerns/decidim/headers/browser_feature_permissions.rb +50 -0
- data/app/controllers/decidim/amendments_controller.rb +3 -3
- data/app/controllers/decidim/application_controller.rb +1 -0
- data/app/helpers/decidim/amendments_helper.rb +2 -1
- data/app/helpers/decidim/filters_helper.rb +25 -0
- data/app/helpers/decidim/layout_helper.rb +6 -0
- data/app/packs/images/decidim/default-avatar.svg +1 -1
- data/app/packs/src/decidim/callout.js +13 -8
- data/app/packs/src/decidim/confirm.js +79 -59
- data/app/packs/src/decidim/datepicker/generate_datepicker.js +2 -0
- data/app/packs/src/decidim/datepicker/generate_timepicker.js +2 -0
- data/app/packs/src/decidim/direct_uploads/upload_field.js +3 -4
- data/app/packs/src/decidim/direct_uploads/upload_modal.js +8 -9
- data/app/packs/src/decidim/dropdown_menu.js +18 -0
- data/app/packs/src/decidim/editor/common/suggestion.js +11 -1
- data/app/packs/src/decidim/form_remote.js +1 -1
- data/app/packs/src/decidim/impersonation.js +1 -1
- data/app/packs/src/decidim/index.js +5 -1
- data/app/packs/src/decidim/session_timeouter.js +1 -1
- data/app/packs/src/decidim/utilities/dom.js +148 -0
- data/app/packs/stylesheets/decidim/_activity.scss +4 -4
- data/app/packs/stylesheets/decidim/_cards.scss +5 -1
- data/app/packs/stylesheets/decidim/_filters.scss +1 -1
- data/app/packs/stylesheets/decidim/_header.scss +11 -3
- data/app/packs/stylesheets/decidim/_layout.scss +2 -2
- data/app/packs/stylesheets/decidim/_modal.scss +1 -5
- data/app/packs/stylesheets/decidim/_modal_update.scss +5 -1
- data/app/permissions/decidim/permissions.rb +13 -1
- data/app/views/decidim/errors/internal_server_error.html.erb +1 -1
- data/app/views/decidim/errors/not_found.html.erb +1 -1
- data/app/views/decidim/newsletters/unsubscribe.html.erb +16 -4
- data/app/views/decidim/searches/_filters.html.erb +48 -13
- data/app/views/decidim/shared/_component_announcement.html.erb +1 -1
- data/app/views/decidim/shared/_confirm_modal.html.erb +3 -5
- data/app/views/decidim/shared/_filters.html.erb +6 -4
- data/app/views/layouts/decidim/_js_configuration.html.erb +1 -0
- data/app/views/layouts/decidim/footer/_main.html.erb +1 -1
- data/app/views/layouts/decidim/footer/_main_intro.html.erb +1 -1
- data/app/views/layouts/decidim/footer/_mini.html.erb +2 -2
- data/app/views/layouts/decidim/header/_main.html.erb +2 -2
- data/app/views/layouts/decidim/header/_main_links_desktop.html.erb +6 -0
- data/app/views/layouts/decidim/header/_main_links_dropdown.html.erb +2 -0
- data/app/views/layouts/decidim/header/_main_links_mobile_account.html.erb +1 -1
- data/app/views/layouts/decidim/header/_mobile_language_choose.html.erb +1 -1
- data/config/locales/ar.yml +0 -3
- data/config/locales/bg-BG.yml +2 -2
- data/config/locales/bg.yml +0 -5
- data/config/locales/ca-IT.yml +29 -5
- data/config/locales/ca.yml +29 -5
- data/config/locales/cs.yml +15 -6
- data/config/locales/de.yml +47 -23
- data/config/locales/el.yml +0 -4
- data/config/locales/en.yml +29 -5
- data/config/locales/es-MX.yml +29 -5
- data/config/locales/es-PY.yml +29 -5
- data/config/locales/es.yml +29 -5
- data/config/locales/eu.yml +63 -39
- data/config/locales/fi-plain.yml +58 -5
- data/config/locales/fi.yml +59 -6
- data/config/locales/fr-CA.yml +29 -5
- data/config/locales/fr-LU.yml +3 -3
- data/config/locales/fr.yml +29 -5
- data/config/locales/gl.yml +0 -3
- data/config/locales/hu.yml +0 -5
- data/config/locales/id-ID.yml +0 -3
- data/config/locales/is-IS.yml +0 -1
- data/config/locales/it.yml +124 -3
- data/config/locales/ja.yml +29 -5
- data/config/locales/lb-LU.yml +2 -2
- data/config/locales/lb.yml +0 -3
- data/config/locales/lt.yml +0 -5
- data/config/locales/lv.yml +0 -3
- data/config/locales/nl.yml +0 -3
- data/config/locales/no.yml +0 -3
- data/config/locales/pl.yml +0 -5
- data/config/locales/pt-BR.yml +1 -4
- data/config/locales/pt.yml +0 -3
- data/config/locales/ro-RO.yml +0 -4
- data/config/locales/ru.yml +0 -3
- data/config/locales/sk-SK.yml +3 -3
- data/config/locales/sk.yml +2 -3
- data/config/locales/sv.yml +28 -4
- data/config/locales/tr-TR.yml +0 -3
- data/config/locales/uk.yml +0 -2
- data/config/locales/zh-CN.yml +0 -3
- data/config/locales/zh-TW.yml +0 -5
- data/lib/decidim/assets/tailwind/tailwind.config.js.erb +2 -1
- data/lib/decidim/core/test/factories.rb +2 -2
- data/lib/decidim/core/test/shared_examples/announcements_examples.rb +4 -0
- data/lib/decidim/core/version.rb +1 -1
- data/lib/decidim/form_builder.rb +14 -0
- metadata +9 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a294fcf54a5fa31a1d5e44af9a717e30ab8eab2df35ae131b9873e0d600dc630
|
4
|
+
data.tar.gz: 41703d211fa0d4d30c760cf00629bfebda559481e039298ac6a30679a46fe77c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 28e137934317b858031cda83491fb067b5ee54349fb50f037c1c0e4aa6f223afeb13899e28df90492ee53b5097a09a3d7c1add57e4d0aa0b080997a706646c89
|
7
|
+
data.tar.gz: 2e153e8e591bd91f1c6fb0ec14b5a7de5ce126191aa89ba698bf64a9a4389d4fb5e8bceb84cc5d43dc77f669b2549971c7d4e2cdfaed4cca6b8dce17172a3829
|
@@ -1,19 +1,19 @@
|
|
1
1
|
<div class="activity" data-activity>
|
2
|
-
<
|
2
|
+
<p class="activity__time">
|
3
3
|
<%= created_at %>
|
4
|
-
</
|
4
|
+
</p>
|
5
5
|
<div class="activity__content">
|
6
|
-
<
|
6
|
+
<div>
|
7
7
|
<% if title.present? %>
|
8
|
-
<
|
8
|
+
<p>
|
9
9
|
<%= title_icon %>
|
10
10
|
<%= title %>
|
11
|
-
</
|
11
|
+
</p>
|
12
12
|
<% end %>
|
13
13
|
<a href="<%= resource_link_path %>">
|
14
14
|
<%= html_truncate decidim_sanitize(resource_link_text, strip_tags: true), length: 80 %>
|
15
15
|
</a>
|
16
|
-
</
|
16
|
+
</div>
|
17
17
|
<% unless hide_participatory_space? %>
|
18
18
|
<span>
|
19
19
|
<%= participatory_space_link %>
|
@@ -11,11 +11,11 @@
|
|
11
11
|
<div class="content-block__description editor-content" <%= "data-component='accordion'" if should_truncate %>>
|
12
12
|
<% if should_truncate %>
|
13
13
|
<% seed = SecureRandom.hex(4) %>
|
14
|
-
<div id="panel-view-more-<%= seed %>" aria-hidden="true">
|
14
|
+
<div id="panel-view-more-<%= seed %>" aria-hidden="true" inert>
|
15
15
|
<%= description_text %>
|
16
16
|
</div>
|
17
17
|
|
18
|
-
<button class="button button__sm button__text-secondary mt-2" data-controls="panel-view-more-<%= seed %>" aria-expanded="false">
|
18
|
+
<button class="button button__sm button__text-secondary mt-2" data-controls="panel-view-more-<%= seed %>" aria-expanded="false" onclick="document.querySelector('div[id^=panel-view-more]').toggleAttribute('inert')">
|
19
19
|
<span>
|
20
20
|
<%= t("view_more", scope: "layouts.decidim.announcements") %>
|
21
21
|
</span>
|
@@ -30,3 +30,12 @@
|
|
30
30
|
<% end %>
|
31
31
|
</div>
|
32
32
|
<% end %>
|
33
|
+
<script>
|
34
|
+
const button = document.querySelector('button[data-controls^="panel-view-more"]')
|
35
|
+
button.addEventListener('keydown', function(e){
|
36
|
+
// press space or enter
|
37
|
+
if (e.keyCode === 32 || e.keyCode === 13){
|
38
|
+
document.querySelector('div[id^=panel-view-more]').toggleAttribute('inert')
|
39
|
+
}
|
40
|
+
})
|
41
|
+
</script>
|
@@ -1,5 +1,5 @@
|
|
1
|
-
<nav role="navigation" aria-label="
|
2
|
-
<h2 class="h4 mb-4"
|
1
|
+
<nav role="navigation" aria-label="<%= t("layouts.decidim.footer.help") %>">
|
2
|
+
<h2 class="h4 mb-4"><%= t("layouts.decidim.footer.help") %></h2>
|
3
3
|
<ul class="space-y-4 break-inside-avoid">
|
4
4
|
<% topics.each do |topic| %>
|
5
5
|
<%= topic_item(topic, class: "font-semibold underline") %>
|
@@ -21,7 +21,9 @@
|
|
21
21
|
<%= link_to(
|
22
22
|
decidim.demote_group_manage_user_path(model.nickname, membership),
|
23
23
|
method: :post,
|
24
|
-
data: { confirm: t("decidim.group_admins.actions.
|
24
|
+
data: { confirm: t("decidim.group_admins.actions.confirm_remove_from_admin"),
|
25
|
+
confirm_title: t("decidim.group_admins.actions.confirm_modal.title_remove"),
|
26
|
+
confirm_button: t("decidim.group_admins.actions.confirm_modal.ok_remove") },
|
25
27
|
class: "button button__sm button__transparent-secondary"
|
26
28
|
) do %>
|
27
29
|
<span><%= t("decidim.group_admins.actions.demote_admin") %></span>
|
@@ -24,14 +24,18 @@
|
|
24
24
|
t("decidim.group_members.actions.promote_to_admin"),
|
25
25
|
decidim.promote_group_manage_user_path(model.nickname, membership),
|
26
26
|
method: :post,
|
27
|
-
data: { confirm: t("decidim.group_members.actions.
|
27
|
+
data: { confirm: t("decidim.group_members.actions.confirm_promote_to_admin"),
|
28
|
+
confirm_title: t("decidim.group_admins.actions.confirm_modal.title_add"),
|
29
|
+
confirm_button: t("decidim.group_admins.actions.confirm_modal.ok_add") },
|
28
30
|
class: "button button__sm button__transparent-secondary"
|
29
31
|
) %>
|
30
32
|
|
31
33
|
<%= link_to(
|
32
34
|
decidim.group_manage_user_path(model.nickname, membership),
|
33
35
|
method: :delete,
|
34
|
-
data: { confirm: t("decidim.group_members.actions.
|
36
|
+
data: { confirm: t("decidim.group_members.actions.confirm_remove_from_group"),
|
37
|
+
confirm_title: t("decidim.group_members.actions.confirm_modal.title_remove"),
|
38
|
+
confirm_button: t("decidim.group_members.actions.confirm_modal.ok_remove") },
|
35
39
|
class: "button button__sm button__transparent-secondary"
|
36
40
|
) do %>
|
37
41
|
<span><%= t("decidim.group_members.actions.remove_from_group") %></span>
|
@@ -1,7 +1,10 @@
|
|
1
1
|
<div class="grid grid-cols-1 md:grid-cols-4 gap-6">
|
2
|
-
<% photos.each_with_index do |photo
|
2
|
+
<% photos.each_with_index do |photo| %>
|
3
3
|
<%= link_to photo.big_url, target: "_blank", rel: "noopener", class: "overflow-hidden rounded aspect-video" do %>
|
4
|
-
<%= image_tag photo.thumbnail_url,
|
4
|
+
<%= image_tag photo.thumbnail_url,
|
5
|
+
class: "w-full h-full object-cover",
|
6
|
+
role: "presentation",
|
7
|
+
"data-filename": strip_tags(translated_attribute(photo.title)) %>
|
5
8
|
<% end %>
|
6
9
|
<% end %>
|
7
10
|
</div>
|
@@ -6,16 +6,18 @@
|
|
6
6
|
<div>
|
7
7
|
<div class="form__wrapper flag-modal__form">
|
8
8
|
<p id="dialog-desc-<%= modal_id %>" class="flag-modal__form-description"><%= t("decidim.shared.flag_modal.description") %></p>
|
9
|
-
<
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
9
|
+
<fieldset class="mt-6">
|
10
|
+
<legend class="flag-modal__form-reason"><%= t("decidim.shared.flag_modal.reason") %>:</legend>
|
11
|
+
<%= f.collection_radio_buttons :reason, [
|
12
|
+
[:spam, t("decidim.shared.flag_modal.spam")],
|
13
|
+
[:offensive, t("decidim.shared.flag_modal.offensive")],
|
14
|
+
[:does_not_belong, t("decidim.shared.flag_modal.does_not_belong", organization_name: current_organization_name)]
|
15
|
+
], :first, :last do |builder|
|
16
|
+
builder.label(for: "#{builder.value.to_s}-#{modal_id}", class: "form__wrapper-checkbox-label") { builder.radio_button(id: "#{builder.value.to_s}-#{modal_id}") + builder.text }
|
17
|
+
end %>
|
18
|
+
</fieldset>
|
17
19
|
|
18
|
-
<%= f.text_area :details, rows: 4, label_options: { class: "flag-modal__form-textarea-label", for:
|
20
|
+
<%= f.text_area :details, rows: 4, label_options: { class: "flag-modal__form-textarea-label", for: "additional-comments-#{modal_id}" }, id: "additional-comments-#{modal_id}" %>
|
19
21
|
|
20
22
|
<% if frontend_administrable? %>
|
21
23
|
<%= f.check_box :hide,
|
@@ -6,16 +6,17 @@
|
|
6
6
|
<div>
|
7
7
|
<div class="form__wrapper flag-modal__form">
|
8
8
|
<p class="flag-modal__form-description"><%= t("decidim.shared.flag_user_modal.description") %></p>
|
9
|
-
<
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
9
|
+
<fieldset class="mt-6">
|
10
|
+
<legend class="flag-modal__form-reason"><%= t("decidim.shared.flag_modal.reason") %>:</legend>
|
11
|
+
<%= f.collection_radio_buttons :reason, [
|
12
|
+
[:spam, t("decidim.shared.flag_user_modal.spam")],
|
13
|
+
[:offensive, t("decidim.shared.flag_user_modal.offensive")],
|
14
|
+
[:does_not_belong, t("decidim.shared.flag_user_modal.does_not_belong", organization_name: current_organization_name)]
|
15
|
+
], :first, :last do |builder|
|
16
|
+
builder.label(for: "#{builder.value.to_s}-#{modal_id}", class: "form__wrapper-checkbox-label") { builder.radio_button(id: "#{builder.value.to_s}-#{modal_id}") + builder.text }
|
17
|
+
end %>
|
18
|
+
</fieldset>
|
19
|
+
<%= f.text_area :details, rows: 4, label_options: { class: "flag-modal__form-textarea-label", for: "additional-comments-#{modal_id}" }, id: "additional-comments-#{modal_id}" %>
|
19
20
|
|
20
21
|
<% if frontend_administrable? %>
|
21
22
|
<%= f.check_box :block,
|
@@ -25,19 +25,19 @@
|
|
25
25
|
|
26
26
|
<div class="attachment-details" data-attachment-id="<%= attachment.id %>" data-title="<%= title_for(attachment) %>" data-filename="<%= file_name_for(attachment) %>" data-state="uploaded">
|
27
27
|
<% if file_attachment_path(attachment) && blob(attachment).image? %>
|
28
|
-
<div><%= image_tag(file_attachment_path(attachment), alt:
|
28
|
+
<div><%= image_tag(file_attachment_path(attachment), alt: "") %></div>
|
29
29
|
<% elsif uploader_default_image_path(attribute).present? %>
|
30
30
|
<div><%= image_tag uploader_default_image_path(attribute) %></div>
|
31
31
|
<% end %>
|
32
32
|
|
33
33
|
<% if has_title? %>
|
34
|
-
<span><%= title_for(attachment)
|
34
|
+
<span><%= title_for(attachment) %></span>
|
35
35
|
<%= form.hidden_field attribute, multiple: true, value: attachment.id, id: attachment.id %>
|
36
36
|
<% else %>
|
37
37
|
<% if blob(attachment).image? %>
|
38
|
-
<span><%=
|
38
|
+
<span><%= title_for(attachment) %></span>
|
39
39
|
<% else %>
|
40
|
-
<%= link_to
|
40
|
+
<%= link_to title_for(attachment), file_attachment_path(attachment), class: "w-full break-all mb-2" %>
|
41
41
|
<% end %>
|
42
42
|
<% end %>
|
43
43
|
</div>
|
@@ -132,9 +132,11 @@ module Decidim
|
|
132
132
|
end
|
133
133
|
|
134
134
|
def title_for(attachment)
|
135
|
-
|
136
|
-
|
137
|
-
|
135
|
+
if has_title?
|
136
|
+
decidim_html_escape(decidim_sanitize(translated_attribute(attachment.title)))
|
137
|
+
else
|
138
|
+
decidim_html_escape(decidim_sanitize(determine_filename(attachment)))
|
139
|
+
end
|
138
140
|
end
|
139
141
|
|
140
142
|
def truncated_file_name_for(attachment, max_length = 31)
|
@@ -62,7 +62,8 @@ module Decidim
|
|
62
62
|
@amendable.save!
|
63
63
|
@amendable
|
64
64
|
end
|
65
|
-
|
65
|
+
|
66
|
+
@amendable.add_coauthor(@amender, user_group: @user_group) if @amendable.is_a?(Decidim::Coauthorable)
|
66
67
|
end
|
67
68
|
|
68
69
|
def notify_emendation_state_change!
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/concern"
|
4
|
+
|
5
|
+
module Decidim
|
6
|
+
module Headers
|
7
|
+
# This module controls the "Permissions-Policy" header to define the
|
8
|
+
# specific sets of browser features that the website is able to use.
|
9
|
+
module BrowserFeaturePermissions
|
10
|
+
extend ActiveSupport::Concern
|
11
|
+
|
12
|
+
included do
|
13
|
+
after_action :define_permissions_policy
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def define_permissions_policy
|
19
|
+
return if response.media_type != "text/html"
|
20
|
+
return if response.headers["Permissions-Policy"].present?
|
21
|
+
|
22
|
+
# Allow the "unload" and "onbeforeunload" events to be used at the
|
23
|
+
# current domain to prevent the user unintentionally changing the page
|
24
|
+
# when they have something important to do on the page, such as an
|
25
|
+
# unsaved form.
|
26
|
+
#
|
27
|
+
# This header is required because Chrome is phasing this event out due
|
28
|
+
# to some performance issues with the back/forward cache feature of the
|
29
|
+
# browser. However, currently there are no alternative events that would
|
30
|
+
# allow preventing accidental page reloads, tab closing or window
|
31
|
+
# closing.
|
32
|
+
#
|
33
|
+
# For further information, see:
|
34
|
+
# https://developer.chrome.com/docs/web-platform/deprecating-unload
|
35
|
+
# https://github.com/fergald/docs/blob/master/explainers/permissions-policy-unload.md
|
36
|
+
#
|
37
|
+
# Note that even Google suggests using the "beforeunload" for this
|
38
|
+
# particular use case:
|
39
|
+
# https://developer.chrome.com/docs/web-platform/page-lifecycle-api#events
|
40
|
+
#
|
41
|
+
# beforeunload
|
42
|
+
# Important: the beforeunload event should only be used to alert the
|
43
|
+
# user of unsaved changes. Once those changes are saved, the event
|
44
|
+
# should be removed. It should never be added unconditionally to the
|
45
|
+
# page, as doing so can hurt performance in some cases.
|
46
|
+
response.headers["Permissions-Policy"] = "unload=(self)"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -107,7 +107,7 @@ module Decidim
|
|
107
107
|
end
|
108
108
|
|
109
109
|
def reject
|
110
|
-
enforce_permission_to :reject, :amendment, current_component: amendable.component
|
110
|
+
enforce_permission_to :reject, :amendment, amendable:, current_component: amendable.component
|
111
111
|
|
112
112
|
@form = form(Decidim::Amendable::RejectForm).from_model(amendment)
|
113
113
|
|
@@ -143,13 +143,13 @@ module Decidim
|
|
143
143
|
end
|
144
144
|
|
145
145
|
def review
|
146
|
-
enforce_permission_to :accept, :amendment, current_component: amendable.component
|
146
|
+
enforce_permission_to :accept, :amendment, amendable:, current_component: amendable.component
|
147
147
|
|
148
148
|
@form = form(Decidim::Amendable::ReviewForm).from_params(params)
|
149
149
|
end
|
150
150
|
|
151
151
|
def accept
|
152
|
-
enforce_permission_to :accept, :amendment, current_component: amendable.component
|
152
|
+
enforce_permission_to :accept, :amendment, amendable:, current_component: amendable.component
|
153
153
|
|
154
154
|
@form = form(Decidim::Amendable::ReviewForm).from_params(params)
|
155
155
|
|
@@ -70,8 +70,9 @@ module Decidim
|
|
70
70
|
# Checks if the user can accept and reject the emendation
|
71
71
|
def allowed_to_accept_and_reject?(emendation)
|
72
72
|
return unless emendation.amendment.evaluating?
|
73
|
+
return current_user.admin? if emendation.amendable.respond_to?(:official?) && emendation.amendable.official?
|
73
74
|
|
74
|
-
emendation.amendable.created_by?(current_user)
|
75
|
+
emendation.amendable.created_by?(current_user)
|
75
76
|
end
|
76
77
|
|
77
78
|
# Checks if the user can promote the emendation
|
@@ -32,6 +32,31 @@ module Decidim
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
+
def filter_search_label(label, id)
|
36
|
+
I18n.t("decidim.searches.filters.resource", label:, collection: filter_for_resource(id))
|
37
|
+
end
|
38
|
+
|
39
|
+
def filter_for_resource(skip_to_id)
|
40
|
+
case skip_to_id
|
41
|
+
when "proposals"
|
42
|
+
I18n.t("decidim/proposals/proposal.other", scope: "activerecord.models")
|
43
|
+
when "meetings"
|
44
|
+
I18n.t("decidim/meetings/meeting.other", scope: "activerecord.models")
|
45
|
+
when "debates"
|
46
|
+
I18n.t("decidim/debates/debate.other", scope: "activerecord.models")
|
47
|
+
when "sortitions"
|
48
|
+
I18n.t("decidim/sortitions/sortition.other", scope: "activerecord.models")
|
49
|
+
when "surveys"
|
50
|
+
I18n.t("decidim/surveys/survey.other", scope: "activerecord.models")
|
51
|
+
when "projects"
|
52
|
+
I18n.t("decidim/budgets/project.other", scope: "activerecord.models")
|
53
|
+
when "initiatives"
|
54
|
+
I18n.t("decidim/initiative.other", scope: "activerecord.models")
|
55
|
+
else
|
56
|
+
""
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
35
60
|
private
|
36
61
|
|
37
62
|
# Creates a unique namespace for a filter form to prevent duplicate IDs in
|
@@ -60,6 +60,12 @@ module Decidim
|
|
60
60
|
html_properties = options.with_indifferent_access.transform_keys(&:dasherize).slice("width", "height", "aria-label", "role", "aria-hidden", "class", "style")
|
61
61
|
html_properties = default_html_properties.merge(html_properties)
|
62
62
|
|
63
|
+
if name == "wechat-line"
|
64
|
+
html_properties = html_properties.merge({ "aria-label" => I18n.t("decidim.author.comments.other") }).except("aria-hidden")
|
65
|
+
elsif name == "heart-line"
|
66
|
+
html_properties = html_properties.merge({ "aria-label" => I18n.t("decidim.author.endorsements.other") }).except("aria-hidden")
|
67
|
+
end
|
68
|
+
|
63
69
|
href = Decidim.cors_enabled ? "" : asset_pack_path("media/images/remixicon.symbol.svg")
|
64
70
|
|
65
71
|
content_tag :svg, html_properties do
|
@@ -1 +1 @@
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="Layer_1" width="200" height="200" x="0" y="0" enable-background="new 0 0 200 200" version="1.1" viewBox="0 0 200 200" xml:space="preserve"><g><path fill="#
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="Layer_1" width="200" height="200" x="0" y="0" enable-background="new 0 0 200 200" version="1.1" viewBox="0 0 200 200" xml:space="preserve"><g><path fill="#908e8e" d="M200-0.5H0v200h26.099c2.885-35.293,24.07-64.381,52.419-74.319C64.372,117.596,54.75,102.674,54.75,85.5 c0-24.853,20.146-45,45-45c24.853,0,45,20.147,45,45c0,17.095-9.533,31.963-23.572,39.58c28.5,9.837,49.828,39.002,52.724,74.42 H200V-0.5z"/><path fill="#FFF" d="M121.178,125.08c14.039-7.617,23.572-22.485,23.572-39.58c0-24.853-20.147-45-45-45 c-24.854,0-45,20.147-45,45c0,17.174,9.622,32.096,23.768,39.681c-28.349,9.938-49.534,39.026-52.419,74.319h147.803 C171.006,164.082,149.678,134.917,121.178,125.08z"/></g></svg>
|
@@ -4,13 +4,18 @@
|
|
4
4
|
* reload without this.
|
5
5
|
*/
|
6
6
|
|
7
|
-
|
8
|
-
const
|
9
|
-
if (
|
10
|
-
|
11
|
-
// The content insertion is to try to hint some of the screen readers
|
12
|
-
// that the alert content has changed and needs to be announced.
|
13
|
-
$callout.attr("tabindex", "0").focus().html(`${$callout.html()} `);
|
14
|
-
}, 500);
|
7
|
+
document.addEventListener("turbo:load", () => {
|
8
|
+
const callout = document.querySelector(".flash[role='alert']");
|
9
|
+
if (!callout) {
|
10
|
+
return;
|
15
11
|
}
|
12
|
+
|
13
|
+
setTimeout(() => {
|
14
|
+
callout.setAttribute("tabindex", "0");
|
15
|
+
callout.focus();
|
16
|
+
|
17
|
+
// The content insertion is to try to hint some of the screen readers
|
18
|
+
// that the alert content has changed and needs to be announced.
|
19
|
+
callout.innerHTML += " ";
|
20
|
+
}, 500);
|
16
21
|
});
|
@@ -5,12 +5,14 @@
|
|
5
5
|
* it to gain control over the confirm events BEFORE rails-ujs is loaded.
|
6
6
|
*/
|
7
7
|
|
8
|
-
|
8
|
+
const { Rails } = window;
|
9
9
|
|
10
10
|
class ConfirmDialog {
|
11
11
|
constructor(sourceElement) {
|
12
12
|
this.$modal = $("#confirm-modal");
|
13
|
-
|
13
|
+
if (sourceElement) {
|
14
|
+
this.$source = $(sourceElement);
|
15
|
+
}
|
14
16
|
this.$content = $("[data-confirm-modal-content]", this.$modal);
|
15
17
|
this.$buttonConfirm = $("[data-confirm-ok]", this.$modal);
|
16
18
|
this.$buttonCancel = $("[data-confirm-cancel]", this.$modal);
|
@@ -29,22 +31,37 @@ class ConfirmDialog {
|
|
29
31
|
this.$buttonConfirm.on("click", (ev) => {
|
30
32
|
ev.preventDefault();
|
31
33
|
|
32
|
-
|
33
|
-
resolve(true);
|
34
|
-
this.$source.focus();
|
34
|
+
this.close(() => resolve(true));
|
35
35
|
});
|
36
36
|
|
37
37
|
this.$buttonCancel.on("click", (ev) => {
|
38
38
|
ev.preventDefault();
|
39
39
|
|
40
|
-
|
41
|
-
resolve(false);
|
42
|
-
this.$source.focus();
|
40
|
+
this.close(() => resolve(false));
|
43
41
|
});
|
44
42
|
});
|
45
43
|
}
|
44
|
+
|
45
|
+
close(afterClose) {
|
46
|
+
window.Decidim.currentDialogs["confirm-modal"].close()
|
47
|
+
afterClose();
|
48
|
+
if (this.$source) {
|
49
|
+
this.$source.focus();
|
50
|
+
}
|
51
|
+
}
|
46
52
|
}
|
47
53
|
|
54
|
+
const runConfirm = (message, sourceElement = null) => new Promise((resolve) => {
|
55
|
+
const dialog = new ConfirmDialog(sourceElement);
|
56
|
+
dialog.confirm(message).then((answer) => {
|
57
|
+
let completed = true;
|
58
|
+
if (sourceElement) {
|
59
|
+
completed = Rails.fire(sourceElement, "confirm:complete", [answer]);
|
60
|
+
}
|
61
|
+
resolve(answer && completed);
|
62
|
+
});
|
63
|
+
});
|
64
|
+
|
48
65
|
// Override the default confirm dialog by Rails
|
49
66
|
// See:
|
50
67
|
// https://github.com/rails/rails/blob/fba1064153d8e2f4654df7762a7d3664b93e9fc8/actionview/app/assets/javascripts/rails-ujs/features/confirm.coffee
|
@@ -64,37 +81,35 @@ const allowAction = (ev, element) => {
|
|
64
81
|
return false;
|
65
82
|
}
|
66
83
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
(
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
)
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
newEv = new origEv.constructor(origEv.type, origEv);
|
95
|
-
}
|
96
|
-
ev.target.dispatchEvent(newEv);
|
84
|
+
runConfirm(message, element).then((answer) => {
|
85
|
+
if (!answer) {
|
86
|
+
return;
|
87
|
+
}
|
88
|
+
|
89
|
+
// Allow the event to propagate normally and re-dispatch it without
|
90
|
+
// the confirm data attribute which the Rails internal method is
|
91
|
+
// checking.
|
92
|
+
$(element).data("confirm", null);
|
93
|
+
$(element).removeAttr("data-confirm");
|
94
|
+
|
95
|
+
// The submit button click events will not do anything if they are
|
96
|
+
// dispatched as is. In these cases, just submit the underlying form.
|
97
|
+
if (ev.type === "click" &&
|
98
|
+
(
|
99
|
+
$(element).is('button[type="submit"]') ||
|
100
|
+
$(element).is('input[type="submit"]')
|
101
|
+
)
|
102
|
+
) {
|
103
|
+
$(element).parents("form").submit();
|
104
|
+
} else {
|
105
|
+
let origEv = ev.originalEvent || ev;
|
106
|
+
let newEv = origEv;
|
107
|
+
if (typeof Event === "function") {
|
108
|
+
// Clone the event because otherwise some click events may not
|
109
|
+
// work properly when re-dispatched.
|
110
|
+
newEv = new origEv.constructor(origEv.type, origEv);
|
97
111
|
}
|
112
|
+
ev.target.dispatchEvent(newEv);
|
98
113
|
}
|
99
114
|
});
|
100
115
|
|
@@ -129,26 +144,31 @@ const handleDocumentEvent = (ev, matchSelectors) => {
|
|
129
144
|
});
|
130
145
|
};
|
131
146
|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
147
|
+
// Note that this needs to be run **before** Rails.start()
|
148
|
+
export const initializeConfirm = () => {
|
149
|
+
document.addEventListener("click", (ev) => {
|
150
|
+
return handleDocumentEvent(ev, [
|
151
|
+
Rails.linkClickSelector,
|
152
|
+
Rails.buttonClickSelector,
|
153
|
+
Rails.formInputClickSelector
|
154
|
+
]);
|
155
|
+
});
|
156
|
+
document.addEventListener("change", (ev) => {
|
157
|
+
return handleDocumentEvent(ev, [Rails.inputChangeSelector]);
|
158
|
+
});
|
159
|
+
document.addEventListener("submit", (ev) => {
|
160
|
+
return handleDocumentEvent(ev, [Rails.formSubmitSelector]);
|
161
|
+
});
|
145
162
|
|
146
|
-
// This is needed for the confirm dialog to work with Foundation Abide.
|
147
|
-
// Abide registers its own submit click listeners since Foundation 5.6.x
|
148
|
-
// which will be handled before the document listeners above. This would
|
149
|
-
// break the custom confirm functionality when used with Foundation Abide.
|
150
|
-
document.addEventListener("DOMContentLoaded", function() {
|
151
|
-
|
152
|
-
|
163
|
+
// This is needed for the confirm dialog to work with Foundation Abide.
|
164
|
+
// Abide registers its own submit click listeners since Foundation 5.6.x
|
165
|
+
// which will be handled before the document listeners above. This would
|
166
|
+
// break the custom confirm functionality when used with Foundation Abide.
|
167
|
+
document.addEventListener("DOMContentLoaded", function() {
|
168
|
+
$(Rails.formInputClickSelector).on("click.confirm", (ev) => {
|
169
|
+
handleConfirm(ev, getMatchingEventTarget(ev, Rails.formInputClickSelector));
|
170
|
+
});
|
153
171
|
});
|
154
|
-
}
|
172
|
+
};
|
173
|
+
|
174
|
+
export default runConfirm;
|
@@ -13,11 +13,13 @@ export default function generateDatePicker(input, row, formats) {
|
|
13
13
|
const date = document.createElement("input");
|
14
14
|
date.setAttribute("id", `${input.id}_date`);
|
15
15
|
date.setAttribute("type", "text");
|
16
|
+
date.setAttribute("aria-label", input.dataset.dateLabel);
|
16
17
|
|
17
18
|
const calendar = document.createElement("button");
|
18
19
|
calendar.innerHTML = icon("calendar-line");
|
19
20
|
calendar.setAttribute("class", "datepicker__calendar-button");
|
20
21
|
calendar.setAttribute("type", "button");
|
22
|
+
calendar.setAttribute("aria-label", input.dataset.buttonDateLabel);
|
21
23
|
|
22
24
|
dateColumn.appendChild(date);
|
23
25
|
dateColumn.appendChild(calendar);
|
@@ -13,11 +13,13 @@ export default function generateTimePicker(input, row, formats) {
|
|
13
13
|
const time = document.createElement("input");
|
14
14
|
time.setAttribute("id", `${input.id}_time`);
|
15
15
|
time.setAttribute("type", "text");
|
16
|
+
time.setAttribute("aria-label", input.dataset.timeLabel);
|
16
17
|
|
17
18
|
const clock = document.createElement("button");
|
18
19
|
clock.innerHTML = icon("time-line")
|
19
20
|
clock.setAttribute("class", "datepicker__clock-button");
|
20
21
|
clock.setAttribute("type", "button");
|
22
|
+
clock.setAttribute("aria-label", input.dataset.buttonTimeLabel);
|
21
23
|
|
22
24
|
timeColumn.appendChild(time);
|
23
25
|
timeColumn.appendChild(clock);
|