decidim-core 0.30.1 → 0.30.2
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/commands/decidim/create_omniauth_registration.rb +1 -1
- data/app/controllers/decidim/amendments_controller.rb +3 -3
- 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 +15 -3
- 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/index.js +1 -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/validators/translated_etiquette_validator.rb +2 -0
- 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/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 +28 -5
- data/config/locales/ca.yml +28 -5
- data/config/locales/cs.yml +15 -6
- data/config/locales/de.yml +53 -21
- data/config/locales/el.yml +0 -4
- data/config/locales/en.yml +28 -5
- data/config/locales/es-MX.yml +28 -5
- data/config/locales/es-PY.yml +28 -5
- data/config/locales/es.yml +28 -5
- data/config/locales/eu.yml +66 -43
- data/config/locales/fi-plain.yml +76 -5
- data/config/locales/fi.yml +77 -6
- data/config/locales/fr-CA.yml +28 -5
- data/config/locales/fr-LU.yml +3 -3
- data/config/locales/fr.yml +28 -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 +165 -3
- data/config/locales/ja.yml +36 -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 +0 -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 +27 -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/test/shared_examples/comments_examples.rb +7 -5
- data/lib/decidim/core/version.rb +1 -1
- data/lib/decidim/form_builder.rb +14 -0
- metadata +7 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 42ebd59c0047d75695c9819c2bb0482423b4f5022f31258703b0d0ee476ca793
|
4
|
+
data.tar.gz: bb3a77b79383688f58f120b1ce7824282061b503e1a11553f2c883360b8b8fb4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c12dc0996382e5ad172ae4b70008bcd2df5d1181e9938f0815ef004efe353b210fa78ed7ab8ab7ba8068542c08cb1e431a011e1f6e5401a1aae0c987cd4c330e
|
7
|
+
data.tar.gz: 2a641e595999e29a1a68285315d35e5312842c6b997929df48d2fd53bf6cff51ef3279e92ed11dc5c43364238a6486aebc5f07715d49119b611806c103fc2ce7
|
@@ -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!
|
@@ -69,7 +69,7 @@ module Decidim
|
|
69
69
|
@user.email = (verified_email || form.email)
|
70
70
|
@user.name = form.name.gsub(REGEXP_SANITIZER, "")
|
71
71
|
@user.nickname = form.normalized_nickname
|
72
|
-
@user.newsletter_notifications_at =
|
72
|
+
@user.newsletter_notifications_at = form.newsletter_at
|
73
73
|
@user.password = SecureRandom.hex
|
74
74
|
attach_avatar(form.avatar_url) if form.avatar_url.present?
|
75
75
|
@user.tos_agreement = form.tos_agreement
|
@@ -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
|
|
@@ -61,8 +61,9 @@ module Decidim
|
|
61
61
|
# Checks if the user can accept and reject the emendation
|
62
62
|
def allowed_to_accept_and_reject?(emendation)
|
63
63
|
return unless emendation.amendment.evaluating?
|
64
|
+
return current_user.admin? if emendation.amendable.respond_to?(:official?) && emendation.amendable.official?
|
64
65
|
|
65
|
-
emendation.amendable.created_by?(current_user)
|
66
|
+
emendation.amendable.created_by?(current_user)
|
66
67
|
end
|
67
68
|
|
68
69
|
# 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
|
});
|
@@ -10,13 +10,25 @@ const { Rails } = window;
|
|
10
10
|
class ConfirmDialog {
|
11
11
|
constructor(sourceElement) {
|
12
12
|
this.$modal = $("#confirm-modal");
|
13
|
-
if (sourceElement) {
|
14
|
-
this.$source = $(sourceElement);
|
15
|
-
}
|
16
13
|
this.$content = $("[data-confirm-modal-content]", this.$modal);
|
14
|
+
this.$title = $("[data-dialog-title]", this.$modal);
|
17
15
|
this.$buttonConfirm = $("[data-confirm-ok]", this.$modal);
|
18
16
|
this.$buttonCancel = $("[data-confirm-cancel]", this.$modal);
|
19
17
|
|
18
|
+
if (sourceElement) {
|
19
|
+
this.$source = $(sourceElement);
|
20
|
+
|
21
|
+
const confirmTitle = this.$source.data("confirm-title");
|
22
|
+
const confirmButton = this.$source.data("confirm-button");
|
23
|
+
|
24
|
+
this.$title.text(confirmTitle)
|
25
|
+
|
26
|
+
const $buttonSpan = this.$buttonConfirm.find("span");
|
27
|
+
if ($buttonSpan.length > 0) {
|
28
|
+
$buttonSpan.text(confirmButton);
|
29
|
+
}
|
30
|
+
}
|
31
|
+
|
20
32
|
window.Decidim.currentDialogs["confirm-modal"].open()
|
21
33
|
}
|
22
34
|
|
@@ -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);
|
@@ -1,5 +1,4 @@
|
|
1
1
|
import UploadModal from "src/decidim/direct_uploads/upload_modal";
|
2
|
-
import { truncateFilename } from "src/decidim/direct_uploads/upload_utility";
|
3
2
|
import { escapeHtml, escapeQuotes } from "src/decidim/utilities/text";
|
4
3
|
|
5
4
|
const updateModalTitle = (modal) => {
|
@@ -30,7 +29,7 @@ const updateActiveUploads = (modal) => {
|
|
30
29
|
const [removeFiles, addFiles] = [modal.items.filter(({ removable }) => removable), modal.items.filter(({ removable }) => !removable)]
|
31
30
|
|
32
31
|
addFiles.forEach((file, ix) => {
|
33
|
-
let title =
|
32
|
+
let title = file.name
|
34
33
|
|
35
34
|
let hidden = ""
|
36
35
|
if (file.hiddenField) {
|
@@ -79,8 +78,8 @@ const updateActiveUploads = (modal) => {
|
|
79
78
|
|
80
79
|
const template = `
|
81
80
|
<div ${attachmentIdOrHiddenField} data-filename="${escapeQuotes(file.name)}" data-title="${escapeQuotes(title)}">
|
82
|
-
${(/image/).test(file.type) &&
|
83
|
-
<span>${escapeHtml(title)}
|
81
|
+
${(/image/).test(file.type) && "<div><img src=\"data:,\" role=\"presentation\" /></div>" || ""}
|
82
|
+
<span>${escapeHtml(title)}</span>
|
84
83
|
${hidden}
|
85
84
|
</div>
|
86
85
|
`
|
@@ -1,6 +1,5 @@
|
|
1
1
|
import { Uploader } from "src/decidim/direct_uploads/uploader";
|
2
2
|
import icon from "src/decidim/icon";
|
3
|
-
import { truncateFilename } from "src/decidim/direct_uploads/upload_utility";
|
4
3
|
import { escapeHtml, escapeQuotes } from "src/decidim/utilities/text";
|
5
4
|
|
6
5
|
const STATUS = {
|
@@ -42,7 +41,7 @@ export default class UploadModal {
|
|
42
41
|
|
43
42
|
this.emptyItems = this.modal.querySelector("[data-dropzone-no-items]");
|
44
43
|
this.uploadItems = this.modal.querySelector("[data-dropzone-items]");
|
45
|
-
this.input = this.dropZone.querySelector("input");
|
44
|
+
this.input = this.dropZone.querySelector("input[type=file]");
|
46
45
|
this.items = []
|
47
46
|
|
48
47
|
this.attachmentCounter = 0;
|
@@ -171,29 +170,29 @@ export default class UploadModal {
|
|
171
170
|
|
172
171
|
createUploadItem(file, errors, opts = {}) {
|
173
172
|
const okTemplate = `
|
174
|
-
<img src="data:,"
|
175
|
-
<span>${escapeHtml(
|
173
|
+
<img src="data:,", role="presentation" />
|
174
|
+
<span class="upload-modal__span">${escapeHtml(file.name)}</span>
|
176
175
|
`
|
177
176
|
|
178
177
|
const errorTemplate = `
|
179
178
|
<div>${icon("error-warning-line")}</div>
|
180
179
|
<div>
|
181
|
-
<span>${escapeHtml(
|
180
|
+
<span class="upload-modal__span">${escapeHtml(file.name)}</span>
|
182
181
|
<span>${this.locales.validation_error}</span>
|
183
182
|
<ul>${errors.map((error) => `<li>${error}</li>`).join("\n")}</ul>
|
184
183
|
</div>
|
185
184
|
`
|
186
185
|
|
187
186
|
const titleTemplate = `
|
188
|
-
<img src="data:,"
|
187
|
+
<img src="data:," role="presentation" />
|
189
188
|
<div>
|
190
189
|
<div>
|
191
190
|
<label>${this.locales.filename}</label>
|
192
|
-
<span>${escapeHtml(
|
191
|
+
<span class="upload-modal__span">${escapeHtml(file.name)}</span>
|
193
192
|
</div>
|
194
193
|
<div>
|
195
|
-
<label>${this.locales.title}</label>
|
196
|
-
<input class="sm" type="text" value="${escapeQuotes(opts.title ||
|
194
|
+
<label for="${file.name}">${this.locales.title}</label>
|
195
|
+
<input class="sm" type="text" value="${escapeQuotes(opts.title || file.name)}" id="${file.name}" />
|
197
196
|
</div>
|
198
197
|
</div>
|
199
198
|
`
|
@@ -0,0 +1,18 @@
|
|
1
|
+
// changes the value "menu" of role attribute set by a11y on div dropdown-menu-account and
|
2
|
+
// dropdown-menu-account-mobile which are inappropriate for accessibility
|
3
|
+
document.addEventListener("DOMContentLoaded", () => {
|
4
|
+
const dropdownDiv = document.querySelector("#dropdown-menu-account");
|
5
|
+
const dropdownMobileDiv = document.querySelector("#dropdown-menu-account-mobile");
|
6
|
+
if (dropdownDiv) {
|
7
|
+
setTimeout(() => {
|
8
|
+
dropdownDiv.setAttribute("role", "dialog")
|
9
|
+
dropdownMobileDiv.setAttribute("role", "dialog")
|
10
|
+
}, 300)
|
11
|
+
}
|
12
|
+
const triggerButtonMobile = document.querySelector("#dropdown-trigger-links-mobile");
|
13
|
+
if (triggerButtonMobile) {
|
14
|
+
triggerButtonMobile.addEventListener("click", () => {
|
15
|
+
dropdownMobileDiv.setAttribute("aria-modal", "true")
|
16
|
+
})
|
17
|
+
}
|
18
|
+
});
|
@@ -98,7 +98,17 @@ export const createSuggestionRenderer = (node, { itemConverter } = {}) => () =>
|
|
98
98
|
suggestionItem.textContent = label;
|
99
99
|
suggestion.append(suggestionItem);
|
100
100
|
|
101
|
-
suggestionItem.addEventListener("click", () =>
|
101
|
+
suggestionItem.addEventListener("click", (ev) => {
|
102
|
+
ev.preventDefault();
|
103
|
+
|
104
|
+
if (currentRange) {
|
105
|
+
// Increase the current range by 1 since the ENTER key would do the
|
106
|
+
// same when doing the selection through keyboard.
|
107
|
+
currentRange.to += 1;
|
108
|
+
}
|
109
|
+
|
110
|
+
selectItem(idx);
|
111
|
+
});
|
102
112
|
});
|
103
113
|
}
|
104
114
|
|
@@ -52,6 +52,7 @@ import "src/decidim/sw"
|
|
52
52
|
import "src/decidim/sticky_header"
|
53
53
|
import "src/decidim/sticky_footer"
|
54
54
|
import "src/decidim/attachments"
|
55
|
+
import "src/decidim/dropdown_menu"
|
55
56
|
|
56
57
|
// local deps that require initialization
|
57
58
|
import ConfirmDialog, { initializeConfirm } from "src/decidim/confirm"
|
@@ -12,12 +12,12 @@
|
|
12
12
|
&__content {
|
13
13
|
@apply col-span-2 md:col-span-1 order-first md:order-none space-y-2;
|
14
14
|
|
15
|
-
>
|
16
|
-
|
17
|
-
@apply text-gray-2 text-sm;
|
15
|
+
> div:first-child {
|
16
|
+
p {
|
17
|
+
@apply text-gray-2 text-sm inline-block;
|
18
18
|
|
19
19
|
svg {
|
20
|
-
@apply text-gray fill-current;
|
20
|
+
@apply text-gray fill-current inline;
|
21
21
|
}
|
22
22
|
}
|
23
23
|
|
@@ -163,11 +163,15 @@
|
|
163
163
|
/* shared styles */
|
164
164
|
&__highlight-metadata,
|
165
165
|
&__grid-metadata {
|
166
|
-
@apply mt-auto flex items-center justify-between flex-wrap
|
166
|
+
@apply mt-auto flex items-center justify-between flex-wrap text-sm text-gray-2 [&>*]:flex [&>*]:items-center [&>*]:gap-1 first:[&>*]:flex-none;
|
167
167
|
|
168
168
|
svg {
|
169
169
|
@apply flex-none text-gray fill-current;
|
170
170
|
}
|
171
|
+
|
172
|
+
[data-author] {
|
173
|
+
@apply flex first:[&>*]:max-w-40 -mr-8;
|
174
|
+
}
|
171
175
|
}
|
172
176
|
|
173
177
|
/* shared styles */
|