decidim-core 0.31.3 → 0.31.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/content_blocks/html_cell.rb +1 -1
- data/app/cells/decidim/content_blocks/static_page/section_cell.rb +1 -1
- data/app/cells/decidim/content_blocks/static_page/summary_cell.rb +1 -1
- data/app/cells/decidim/content_blocks/static_page/two_pane_section_cell.rb +2 -2
- data/app/cells/decidim/data_consent/category.erb +5 -5
- data/app/cells/decidim/nav_links/show.erb +3 -3
- data/app/cells/decidim/participatory_space_private_user/show.erb +6 -6
- data/app/cells/decidim/participatory_space_private_user_cell.rb +0 -4
- data/app/cells/decidim/upload_modal_cell.rb +5 -0
- data/app/controllers/decidim/download_your_data_controller.rb +1 -1
- data/app/controllers/decidim/notifications_subscriptions_controller.rb +8 -0
- data/app/controllers/decidim/private_downloads_controller.rb +29 -0
- data/app/helpers/decidim/mailer_helper.rb +36 -0
- data/app/helpers/decidim/menu_helper.rb +2 -1
- data/app/helpers/decidim/newsletters_helper.rb +4 -22
- data/app/mailers/decidim/application_mailer.rb +4 -0
- data/app/models/decidim/attachment.rb +20 -2
- data/app/models/decidim/authorization.rb +7 -0
- data/app/models/decidim/private_download.rb +61 -0
- data/app/models/decidim/private_export.rb +6 -0
- data/app/packs/src/decidim/controllers/accordion/accordion.test.js +118 -0
- data/app/packs/src/decidim/controllers/accordion/controller.js +24 -0
- data/app/packs/src/decidim/controllers/dropdown/controller.js +26 -0
- data/app/packs/src/decidim/controllers/dropdown/dropdown.test.js +187 -0
- data/app/packs/src/decidim/controllers/form_validator/form_validator.js +3 -2
- data/app/packs/src/decidim/controllers/form_validator/form_validator.test.js +5 -0
- data/app/packs/src/decidim/editor/extensions/image/index.js +49 -11
- data/app/packs/src/decidim/editor/extensions/image/node_view.js +9 -1
- data/app/packs/src/decidim/editor/extensions/link/bubble_menu.js +34 -6
- data/app/packs/src/decidim/editor/extensions/link/index.js +45 -12
- data/app/packs/src/decidim/editor/test/extensions/image_links.test.js +161 -0
- data/app/packs/src/decidim/sw/push-permissions.js +48 -13
- data/app/packs/stylesheets/decidim/_rich_text.scss +17 -0
- data/app/packs/stylesheets/decidim/editor.scss +10 -0
- data/app/presenters/decidim/menu_item_presenter.rb +7 -1
- data/app/services/decidim/notifications_subscriptions_persistor.rb +6 -0
- data/app/services/decidim/push_subscription_endpoint_validator.rb +34 -0
- data/app/services/decidim/send_push_notification.rb +5 -1
- data/app/views/decidim/devise/registrations/new.html.erb +1 -0
- data/app/views/decidim/devise/shared/_tos_fields.html.erb +3 -3
- data/app/views/decidim/notification_mailer/event_received.html.erb +3 -3
- data/app/views/decidim/notifications_settings/show.html.erb +5 -5
- data/app/views/decidim/pages/_tabbed.html.erb +3 -3
- data/app/views/decidim/shared/_filters.html.erb +5 -5
- data/app/views/decidim/shared/filters/_check_boxes_tree.html.erb +1 -1
- data/app/views/decidim/shared/filters/_collection.html.erb +1 -1
- data/config/locales/ca-IT.yml +1 -0
- data/config/locales/ca.yml +1 -0
- data/config/locales/cs.yml +2 -0
- data/config/locales/de.yml +27 -0
- data/config/locales/en.yml +1 -0
- data/config/locales/es-MX.yml +1 -0
- data/config/locales/es-PY.yml +1 -0
- data/config/locales/es.yml +1 -0
- data/config/locales/eu.yml +4 -0
- data/config/locales/fi-plain.yml +5 -0
- data/config/locales/fi.yml +7 -2
- data/config/locales/fr-CA.yml +1 -0
- data/config/locales/fr.yml +1 -0
- data/config/locales/it.yml +10 -0
- data/config/locales/pt-BR.yml +1 -1
- data/config/locales/sk.yml +1417 -0
- data/config/locales/sv.yml +1 -0
- data/config/routes.rb +1 -0
- data/lib/decidim/content_parsers/blob_parser.rb +3 -3
- data/lib/decidim/content_renderers/blob_renderer.rb +2 -2
- data/lib/decidim/core/test/shared_examples/participatory_space_members_shared_examples.rb +121 -0
- data/lib/decidim/core/version.rb +1 -1
- data/lib/decidim/participatory_space_user.rb +1 -1
- metadata +14 -6
|
@@ -1,16 +1,38 @@
|
|
|
1
|
-
|
|
1
|
+
document.addEventListener("turbo:load", async () => {
|
|
2
2
|
const GRANTED_PERMISSION = "granted"
|
|
3
3
|
|
|
4
4
|
const hideReminder = function() {
|
|
5
|
-
const reminder = document.querySelector("
|
|
5
|
+
const reminder = document.querySelector("[data-push-notifications-reminder]")
|
|
6
|
+
if (!reminder) {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
|
|
6
10
|
reminder.classList.add("hide")
|
|
7
11
|
}
|
|
8
12
|
|
|
13
|
+
const showError = (message) => {
|
|
14
|
+
const container = document.querySelector("[data-push-notifications-container]")
|
|
15
|
+
if (!container) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const existingError = container.querySelector("[data-push-notifications-error]")
|
|
20
|
+
if (existingError) {
|
|
21
|
+
existingError.remove()
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const errorElement = document.createElement("div")
|
|
25
|
+
errorElement.dataset.pushNotificationsError = "true"
|
|
26
|
+
errorElement.classList.add("flash", "alert", "push-notifications__error")
|
|
27
|
+
errorElement.innerText = message
|
|
28
|
+
container.prepend(errorElement)
|
|
29
|
+
}
|
|
30
|
+
|
|
9
31
|
const subscribeToNotifications = async (registration) => {
|
|
10
32
|
const permission = await window.Notification.requestPermission();
|
|
11
33
|
|
|
12
34
|
if (registration && permission === GRANTED_PERMISSION) {
|
|
13
|
-
const vapidElement = document.querySelector("
|
|
35
|
+
const vapidElement = document.querySelector("[data-push-vapid-public-key]")
|
|
14
36
|
// element could not exist in DOM
|
|
15
37
|
if (vapidElement) {
|
|
16
38
|
const vapidPublicKeyElement = JSON.parse(vapidElement.value)
|
|
@@ -20,7 +42,7 @@ window.addEventListener("turbo:load", async () => {
|
|
|
20
42
|
});
|
|
21
43
|
|
|
22
44
|
if (subscription) {
|
|
23
|
-
await fetch("/notifications_subscriptions", {
|
|
45
|
+
const response = await fetch("/notifications_subscriptions", {
|
|
24
46
|
headers: {
|
|
25
47
|
"Content-Type": "application/json",
|
|
26
48
|
"X-CSRF-Token": document.querySelector("meta[name=csrf-token]")?.content
|
|
@@ -28,6 +50,11 @@ window.addEventListener("turbo:load", async () => {
|
|
|
28
50
|
method: "POST",
|
|
29
51
|
body: JSON.stringify(subscription)
|
|
30
52
|
});
|
|
53
|
+
|
|
54
|
+
if (!response.ok) {
|
|
55
|
+
const body = await response.json()
|
|
56
|
+
throw new Error(body.error)
|
|
57
|
+
}
|
|
31
58
|
}
|
|
32
59
|
}
|
|
33
60
|
hideReminder()
|
|
@@ -57,10 +84,13 @@ window.addEventListener("turbo:load", async () => {
|
|
|
57
84
|
hideReminder()
|
|
58
85
|
if (currentSubscription) {
|
|
59
86
|
const auth = currentSubscription.toJSON().keys.auth
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
87
|
+
const subKeysElement = document.querySelector("[data-push-sub-keys]")
|
|
88
|
+
if (subKeysElement) {
|
|
89
|
+
const subKeys = JSON.parse(subKeysElement.value)
|
|
90
|
+
// Subscribed && browser notifications enabled
|
|
91
|
+
if (subKeys.includes(auth)) {
|
|
92
|
+
toggleChecked = true
|
|
93
|
+
}
|
|
64
94
|
}
|
|
65
95
|
}
|
|
66
96
|
}
|
|
@@ -68,7 +98,7 @@ window.addEventListener("turbo:load", async () => {
|
|
|
68
98
|
}
|
|
69
99
|
|
|
70
100
|
if ("serviceWorker" in navigator) {
|
|
71
|
-
const toggle = document.
|
|
101
|
+
const toggle = document.querySelector("[data-push-notifications-toggle]")
|
|
72
102
|
|
|
73
103
|
if (toggle) {
|
|
74
104
|
const registration = await navigator.serviceWorker.ready
|
|
@@ -76,10 +106,15 @@ window.addEventListener("turbo:load", async () => {
|
|
|
76
106
|
setToggleState(registration, toggle)
|
|
77
107
|
|
|
78
108
|
toggle.addEventListener("change", async ({ target }) => {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
109
|
+
try {
|
|
110
|
+
if (target.checked) {
|
|
111
|
+
await subscribeToNotifications(registration)
|
|
112
|
+
} else {
|
|
113
|
+
await unsubscribeFromNotifications(registration)
|
|
114
|
+
}
|
|
115
|
+
} catch (error) {
|
|
116
|
+
target.checked = false
|
|
117
|
+
showError(error.message)
|
|
83
118
|
}
|
|
84
119
|
})
|
|
85
120
|
}
|
|
@@ -106,4 +106,21 @@
|
|
|
106
106
|
.editor-indent-10 {
|
|
107
107
|
@apply ml-40;
|
|
108
108
|
}
|
|
109
|
+
|
|
110
|
+
// Style for external link icon inside linked images
|
|
111
|
+
a:has(.editor-content-image) [data-external-link="true"] {
|
|
112
|
+
@apply block relative;
|
|
113
|
+
|
|
114
|
+
margin: -1.5rem 0 1em auto;
|
|
115
|
+
width: fit-content;
|
|
116
|
+
|
|
117
|
+
svg {
|
|
118
|
+
@apply w-4 h-4;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Make sure the anchor with image is positioned for proper icon placement
|
|
123
|
+
a:has(.editor-content-image) {
|
|
124
|
+
@apply block relative;
|
|
125
|
+
}
|
|
109
126
|
}
|
|
@@ -130,6 +130,16 @@
|
|
|
130
130
|
[data-image-resizer-wrapper] {
|
|
131
131
|
@apply relative inline-block;
|
|
132
132
|
|
|
133
|
+
[data-image-resizer-control],
|
|
134
|
+
[data-image-resizer-dimensions] {
|
|
135
|
+
z-index: 1;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
> a {
|
|
139
|
+
position: relative;
|
|
140
|
+
z-index: 0;
|
|
141
|
+
}
|
|
142
|
+
|
|
133
143
|
[data-image-resizer-control] {
|
|
134
144
|
@apply absolute hidden w-2.5 h-2.5 rounded-none border border-solid border-[#000] bg-[#fff] opacity-80;
|
|
135
145
|
}
|
|
@@ -29,7 +29,7 @@ module Decidim
|
|
|
29
29
|
delegate :content_tag, :safe_join, :link_to, :active_link_to_class, :is_active_link?, :icon, to: :@view
|
|
30
30
|
|
|
31
31
|
def render
|
|
32
|
-
content_tag :li, role:
|
|
32
|
+
content_tag :li, role: menuitem_role, class: link_wrapper_classes do
|
|
33
33
|
output = if url == "#"
|
|
34
34
|
[content_tag(:span, composed_label, class: "sidebar-menu__item-disabled")]
|
|
35
35
|
else
|
|
@@ -69,6 +69,12 @@ module Decidim
|
|
|
69
69
|
[@options.element_wrapper_class, active_class].compact.join(" ")
|
|
70
70
|
end
|
|
71
71
|
|
|
72
|
+
def menuitem_role
|
|
73
|
+
return if @options.role == false
|
|
74
|
+
|
|
75
|
+
@options.role || :menuitem
|
|
76
|
+
end
|
|
77
|
+
|
|
72
78
|
def active_class
|
|
73
79
|
active_link_to_class(
|
|
74
80
|
url,
|
|
@@ -4,6 +4,10 @@ module Decidim
|
|
|
4
4
|
# This class manages the creation and deletion of user notifications
|
|
5
5
|
|
|
6
6
|
class NotificationsSubscriptionsPersistor
|
|
7
|
+
include PushSubscriptionEndpointValidator
|
|
8
|
+
|
|
9
|
+
class UnsupportedPushSubscriptionEndpointError < StandardError; end
|
|
10
|
+
|
|
7
11
|
attr_reader :user
|
|
8
12
|
|
|
9
13
|
def initialize(user)
|
|
@@ -11,6 +15,8 @@ module Decidim
|
|
|
11
15
|
end
|
|
12
16
|
|
|
13
17
|
def add_subscription(params)
|
|
18
|
+
raise UnsupportedPushSubscriptionEndpointError unless supported_push_subscription_endpoint?(params[:endpoint])
|
|
19
|
+
|
|
14
20
|
subscriptions = user.notification_settings["subscriptions"] || {}
|
|
15
21
|
filtered_params = filter_params(params)
|
|
16
22
|
new_subscription = { filtered_params[:auth] => filtered_params }
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Decidim
|
|
4
|
+
# Shared validation for browser push subscription endpoints.
|
|
5
|
+
module PushSubscriptionEndpointValidator
|
|
6
|
+
private
|
|
7
|
+
|
|
8
|
+
def supported_push_subscription_endpoint?(endpoint)
|
|
9
|
+
return false if endpoint.blank?
|
|
10
|
+
|
|
11
|
+
uri = URI.parse(endpoint)
|
|
12
|
+
return false unless uri.is_a?(URI::HTTPS)
|
|
13
|
+
|
|
14
|
+
host = uri.host&.downcase
|
|
15
|
+
return false if host.blank?
|
|
16
|
+
|
|
17
|
+
allowed_push_subscription_endpoint_patterns.any? { |pattern| pattern.match?(host) }
|
|
18
|
+
rescue URI::InvalidURIError
|
|
19
|
+
false
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Override this method to customize the browser push endpoint allowlist.
|
|
23
|
+
def allowed_push_subscription_endpoint_patterns
|
|
24
|
+
[
|
|
25
|
+
/\A(?:.*\.)?push\.services\.mozilla\.com\z/,
|
|
26
|
+
/\A(?:.*\.)?fcm\.googleapis\.com\z/,
|
|
27
|
+
/\A(?:.*\.)?android\.googleapis\.com\z/,
|
|
28
|
+
/\A(?:.*\.)?push\.apple\.com\z/,
|
|
29
|
+
/\A(?:.*\.)?opera\.com\z/,
|
|
30
|
+
/\A(?:.*\.)?notify\.windows\.com\z/
|
|
31
|
+
]
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -10,6 +10,7 @@ module Decidim
|
|
|
10
10
|
|
|
11
11
|
class SendPushNotification
|
|
12
12
|
include ActionView::Helpers::UrlHelper
|
|
13
|
+
include PushSubscriptionEndpointValidator
|
|
13
14
|
|
|
14
15
|
# Send the push notification. Returns `nil` if the user did not allowed push notifications
|
|
15
16
|
# or if the subscription to push notifications does not exist
|
|
@@ -24,9 +25,12 @@ module Decidim
|
|
|
24
25
|
raise ArgumentError, "Need to provide a title if the notification is a PushNotificationMessage" if notification.is_a?(Decidim::PushNotificationMessage) && title.nil?
|
|
25
26
|
|
|
26
27
|
user = notification.user
|
|
28
|
+
subscriptions = user.notifications_subscriptions.values.select do |subscription|
|
|
29
|
+
supported_push_subscription_endpoint?(subscription["endpoint"])
|
|
30
|
+
end
|
|
27
31
|
|
|
28
32
|
I18n.with_locale(user.locale || user.organization.default_locale) do
|
|
29
|
-
|
|
33
|
+
subscriptions.map do |subscription|
|
|
30
34
|
payload = build_payload(message_params(notification, title), subscription)
|
|
31
35
|
# Capture webpush exceptions in order to avoid this call to be repeated by the background job runner
|
|
32
36
|
# Webpush::Error class is the parent class of all defined errors
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
<%= f.text_field :name, help_text: t("decidim.devise.registrations.new.username_help"), autocomplete: "name", placeholder: "John Doe" %>
|
|
35
35
|
|
|
36
36
|
<%= f.email_field :email, autocomplete: "email", placeholder: t("placeholder_email", scope: "decidim.devise.shared") %>
|
|
37
|
+
<span class="sr-only"><%= t("placeholder_email", scope: "decidim.devise.shared") %></span>
|
|
37
38
|
|
|
38
39
|
<%= render partial: "decidim/account/password_fields", locals: { form: f, user: :user } %>
|
|
39
40
|
</div>
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
<div id="card__tos" class="form__wrapper-block border-y-2">
|
|
2
2
|
<h2 class="h4"><%= t("decidim.devise.registrations.new.tos_title") %></h2>
|
|
3
|
+
<span class="sr-only"><%= t("forms.required") %></span>
|
|
3
4
|
|
|
4
|
-
<div>
|
|
5
|
+
<div id="terms_of_service_summary">
|
|
5
6
|
<% terms_of_service_summary_content_blocks.each do |content_block| %>
|
|
6
7
|
<%= cell content_block.manifest.cell, content_block %>
|
|
7
8
|
<% end %>
|
|
8
9
|
</div>
|
|
9
|
-
|
|
10
|
-
<%= form.check_box :tos_agreement, label: t("decidim.devise.registrations.new.tos_agreement", link: link_to(t("decidim.devise.registrations.new.terms"), decidim.page_path("terms-of-service"))), label_options: { class: "form__wrapper-checkbox-label" } %>
|
|
10
|
+
<%= form.check_box :tos_agreement, label: t("decidim.devise.registrations.new.tos_agreement", link: link_to(t("decidim.devise.registrations.new.terms"), decidim.page_path("terms-of-service"))), label_options: { class: "form__wrapper-checkbox-label" }, "aria-describedby": "terms_of_service_summary" %>
|
|
11
11
|
</div>
|
|
12
12
|
|
|
13
13
|
<div id="card__newsletter" class="form__wrapper-block">
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
|
|
16
16
|
<blockquote>
|
|
17
17
|
<p>
|
|
18
|
-
<%= @event_instance.safe_resource_text %>
|
|
18
|
+
<%= decidim_transform_image_urls(@event_instance.safe_resource_text, @organization.host).html_safe %>
|
|
19
19
|
</p>
|
|
20
20
|
</blockquote>
|
|
21
21
|
<% end %>
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
<p style="font-weight: bold"><%= t(".translated_text") %></p>
|
|
29
29
|
<blockquote>
|
|
30
30
|
<p>
|
|
31
|
-
<%= @event_instance.safe_resource_translated_text %>
|
|
31
|
+
<%= decidim_transform_image_urls(@event_instance.safe_resource_translated_text, @organization.host).html_safe %>
|
|
32
32
|
</p>
|
|
33
33
|
</blockquote>
|
|
34
34
|
<% end %>
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
<table>
|
|
41
41
|
<tr>
|
|
42
42
|
<td>
|
|
43
|
-
<%= link_to @event_instance.button_text, @event_instance.button_url, target: :blank %>
|
|
43
|
+
<%= link_to decidim_sanitize(@event_instance.button_text, strip_tags: true), @event_instance.button_url, target: :blank %>
|
|
44
44
|
</td>
|
|
45
45
|
</tr>
|
|
46
46
|
</table>
|
|
@@ -167,20 +167,20 @@
|
|
|
167
167
|
<% end %>
|
|
168
168
|
|
|
169
169
|
<% if @notifications_settings.meet_push_notifications_requirements? %>
|
|
170
|
-
<div class="push-notifications js-sw-mandatory">
|
|
170
|
+
<div class="push-notifications js-sw-mandatory" data-push-notifications-container>
|
|
171
171
|
<label>
|
|
172
172
|
<%= t("push_notifications", scope: "decidim.notifications_settings.show") %>
|
|
173
173
|
</label>
|
|
174
|
-
<p id="push-notifications-reminder" class="push-notifications__reminder block my-4">
|
|
174
|
+
<p id="push-notifications-reminder" class="push-notifications__reminder block my-4" data-push-notifications-reminder>
|
|
175
175
|
<%= t("push_notifications_reminder", scope: "decidim.notifications_settings.show") %>
|
|
176
176
|
</p>
|
|
177
177
|
<div class="toggle__switch-trigger">
|
|
178
178
|
<label class="toggle__switch-toggle" for="allow_push_notifications">
|
|
179
179
|
<span>
|
|
180
180
|
<input
|
|
181
|
-
<%== %(checked="checked") if @notifications_settings.meet_push_notifications_requirements? %>
|
|
182
181
|
id="allow_push_notifications"
|
|
183
182
|
type="checkbox"
|
|
183
|
+
data-push-notifications-toggle
|
|
184
184
|
name="allow_push_notifications">
|
|
185
185
|
<span class="toggle__switch-toggle-content">
|
|
186
186
|
</span>
|
|
@@ -194,8 +194,8 @@
|
|
|
194
194
|
</div>
|
|
195
195
|
</div>
|
|
196
196
|
|
|
197
|
-
<input id="vapidPublicKey" name="vapid_public_key" type="hidden" value="<%= Base64.urlsafe_decode64(Decidim.vapid_public_key.to_s).bytes %>">
|
|
198
|
-
<input id="subKeys" name="sub_key" type="hidden" value="<%= current_user.notifications_subscriptions.keys %>">
|
|
197
|
+
<input id="vapidPublicKey" name="vapid_public_key" data-push-vapid-public-key type="hidden" value="<%= Base64.urlsafe_decode64(Decidim.vapid_public_key.to_s).bytes.to_json %>">
|
|
198
|
+
<input id="subKeys" name="sub_key" data-push-sub-keys type="hidden" value="<%= current_user.notifications_subscriptions.keys.to_json %>">
|
|
199
199
|
<% end %>
|
|
200
200
|
|
|
201
201
|
<div class="form__wrapper-block">
|
|
@@ -11,16 +11,16 @@
|
|
|
11
11
|
|
|
12
12
|
<div class="vertical-tabs">
|
|
13
13
|
<nav role="navigation" aria-label="<%= I18n.t("layouts.decidim.navigation.aria_label", title: translated_attribute(page.title)) %>">
|
|
14
|
-
<button id="dropdown-trigger-pages" data-controller="dropdown" data-target="dropdown-menu-pages" data-open-md="true" data-auto-close="true">
|
|
14
|
+
<button id="dropdown-trigger-pages" data-controller="dropdown" data-target="dropdown-menu-pages" data-open-md="true" data-auto-close="true" data-add-aria-roles="false">
|
|
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"
|
|
21
|
+
<ul id="dropdown-menu-pages" class="vertical-tabs__list">
|
|
22
22
|
<% pages.each do |sibling| %>
|
|
23
|
-
<li class="<%= "is-active" if page == sibling %>"
|
|
23
|
+
<li class="<%= "is-active" if page == sibling %>">
|
|
24
24
|
<%= link_to translated_attribute(sibling.title), page_path(sibling.slug), "aria-current": ("page" if page == sibling) %>
|
|
25
25
|
</li>
|
|
26
26
|
<% end %>
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
<% search_label = t("decidim.searches.filters.search") unless local_assigns.has_key?(:search_label) %>
|
|
3
3
|
|
|
4
4
|
<% if filter_sections.present? || local_assigns.has_key?(:search_variable) %>
|
|
5
|
-
<%= filter_form_for filter, url_for, class: "new_filter self-stretch", data: { filters: "", controller: "accordion form-filter" } do |form| %>
|
|
5
|
+
<%= filter_form_for filter, url_for, class: "new_filter self-stretch", data: { filters: "", controller: "accordion form-filter", panel_role: "group" } do |form| %>
|
|
6
6
|
|
|
7
|
-
<button id="dropdown-trigger-filters" data-controller="dropdown" data-target="dropdown-menu-filters" data-open-md="true">
|
|
7
|
+
<button id="dropdown-trigger-filters" data-controller="dropdown" data-target="dropdown-menu-filters" data-open-md="true" data-add-aria-roles="false">
|
|
8
8
|
<%= icon "arrow-down-s-line" %>
|
|
9
9
|
<%= icon "arrow-up-s-line" %>
|
|
10
10
|
<span>
|
|
@@ -14,13 +14,13 @@
|
|
|
14
14
|
|
|
15
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", "data-skip-to-content": true %>
|
|
18
18
|
<% end %>
|
|
19
19
|
|
|
20
|
-
<p id="filter-help-text" class="filter-help"
|
|
20
|
+
<p id="filter-help-text" class="filter-help" aria-disabled="true"><%= t("help", scope: "decidim.shared.filter_form_help") %></p>
|
|
21
21
|
|
|
22
22
|
<% if local_assigns.has_key?(:search_variable) %>
|
|
23
|
-
<div class="filter-search filter-container"
|
|
23
|
+
<div class="filter-search filter-container">
|
|
24
24
|
<%= form.search_field search_variable,
|
|
25
25
|
label: false,
|
|
26
26
|
placeholder: search_label,
|
data/config/locales/ca-IT.yml
CHANGED
|
@@ -1338,6 +1338,7 @@ ca-IT:
|
|
|
1338
1338
|
own_activity: La meva pròpia activitat, com quan algú fa comentaris a la meva proposta o em menciona
|
|
1339
1339
|
push_notifications: Notificacions emergents
|
|
1340
1340
|
push_notifications_reminder: Per rebre notificacions de la plataforma, primer les has de permetre a la configuració del teu navegador.
|
|
1341
|
+
push_notifications_unsupported_browser: El navegador no és compatible.
|
|
1341
1342
|
receive_notifications_about: Vull rebre notificacions
|
|
1342
1343
|
update_notifications_settings: Guardar canvis
|
|
1343
1344
|
update:
|
data/config/locales/ca.yml
CHANGED
|
@@ -1338,6 +1338,7 @@ ca:
|
|
|
1338
1338
|
own_activity: La meva pròpia activitat, com quan algú fa comentaris a la meva proposta o em menciona
|
|
1339
1339
|
push_notifications: Notificacions emergents
|
|
1340
1340
|
push_notifications_reminder: Per rebre notificacions de la plataforma, primer les has de permetre a la configuració del teu navegador.
|
|
1341
|
+
push_notifications_unsupported_browser: El navegador no és compatible.
|
|
1341
1342
|
receive_notifications_about: Vull rebre notificacions
|
|
1342
1343
|
update_notifications_settings: Guardar canvis
|
|
1343
1344
|
update:
|
data/config/locales/cs.yml
CHANGED
|
@@ -837,6 +837,7 @@ cs:
|
|
|
837
837
|
delete_reason: Důvod pro odstranění tohoto uživatele
|
|
838
838
|
deleted_at: Datum a čas, kdy byl tento uživatel odstraněn
|
|
839
839
|
email: E-mailová adresa tohoto uživatele
|
|
840
|
+
followers_count: Počet účastníků, kteří sledují tohoto uživatele
|
|
840
841
|
following_count: Počet účastníků, které tento uživatel sleduje
|
|
841
842
|
id: Jedinečný identifikátor tohoto uživatele
|
|
842
843
|
invitation_accepted_at: Datum a čas, kdy byla pozvánka přijata
|
|
@@ -1184,6 +1185,7 @@ cs:
|
|
|
1184
1185
|
create_with_space: "%{user_name} vytvořil %{resource_name} v %{space_name}"
|
|
1185
1186
|
delete: "%{user_name} odstraněno %{resource_name}"
|
|
1186
1187
|
delete_with_space: "%{user_name} smazán %{resource_name} v %{space_name}"
|
|
1188
|
+
publish: "%{user_name} publikoval %{resource_name}"
|
|
1187
1189
|
publish_with_space: "%{user_name} publikoval %{resource_name} v %{space_name}"
|
|
1188
1190
|
unknown_action: "%{user_name} provedla nějakou akci na %{resource_name}"
|
|
1189
1191
|
unknown_action_with_space: "%{user_name} provedlo nějakou akci na %{resource_name} v %{space_name}"
|
data/config/locales/de.yml
CHANGED
|
@@ -1055,6 +1055,8 @@ de:
|
|
|
1055
1055
|
explanation: 'Anleitung für Bild:'
|
|
1056
1056
|
message_1: Vorzugsweise ein Bild im Querformat, das keinen Text enthält.
|
|
1057
1057
|
message_2: Der Dienst schneidet die Datei zu.
|
|
1058
|
+
import_file:
|
|
1059
|
+
message_1: Muss ein JSON-Dokument sein, das über die Exportfunktion heruntergeladen wurde.
|
|
1058
1060
|
file_validation:
|
|
1059
1061
|
allowed_file_extensions: 'Erlaubte Dateiformate: %{extensions}'
|
|
1060
1062
|
max_file_dimension: 'Maximale Dateigröße: %{resolution} Pixel'
|
|
@@ -1290,9 +1292,13 @@ de:
|
|
|
1290
1292
|
same_language: Der Inhalt wurde in Ihrer bevorzugten Sprache (%{language}) veröffentlicht, daher wird in dieser E-Mail keine automatisierte Übersetzung angezeigt.
|
|
1291
1293
|
translated_text: 'Automatisch übersetzter Text:'
|
|
1292
1294
|
notifications:
|
|
1295
|
+
action_error: Beim Aktualisieren der Benachrichtigungseinstellungen ist ein Fehler aufgetreten.
|
|
1293
1296
|
no_notifications: Noch keine Benachrichtigungen
|
|
1294
1297
|
show:
|
|
1298
|
+
deleted: Inhalt wurde vom Autor gelöscht.
|
|
1295
1299
|
missing_event: Hoppla, diese Benachrichtigung gehört zu einem Artikel, der nicht mehr verfügbar ist. Du kannst sie verwerfen.
|
|
1300
|
+
moderated: Inhalt wurde durch Moderation versteckt.
|
|
1301
|
+
not_available: Hoppla, diese Benachrichtigung gehört zu einem Artikel, der nicht mehr verfügbar ist. Es ist keine weitere Aktion erforderlich.
|
|
1296
1302
|
notifications_digest_mailer:
|
|
1297
1303
|
header:
|
|
1298
1304
|
daily: Tägliche Zusammenfassung
|
|
@@ -1301,6 +1307,7 @@ de:
|
|
|
1301
1307
|
hello: Hallo %{name}
|
|
1302
1308
|
intro:
|
|
1303
1309
|
daily: 'Dies sind die Benachrichtigungen vom letzten Tag basierend auf den Aktivitäten, denen Sie folgen:'
|
|
1310
|
+
real_time: 'Es gibt eine Benachrichtigung über die Aktivität, die Sie folgen:'
|
|
1304
1311
|
weekly: 'Dies sind die Benachrichtigungen der letzten Woche, basierend auf den Aktivitäten, die Sie folgen:'
|
|
1305
1312
|
outro: Sie haben diese Benachrichtigung erhalten, weil Sie diesen Inhalt oder seine Verfassenden folgen. Sie können dem Inhalt direkt auf seiner Seite entfolgen.
|
|
1306
1313
|
see_more: Weitere Benachrichtigungen ansehen
|
|
@@ -1443,7 +1450,9 @@ de:
|
|
|
1443
1450
|
title: Wie man diese Dateien öffnet und mit ihnen arbeitet
|
|
1444
1451
|
license:
|
|
1445
1452
|
body_1_html: Diese Datenbank von %{organization_name} wird unter %{link_database} zur Verfügung gestellt. Alle Rechte an einzelnen Inhalten der Datenbank sind unter %{link_contents} lizenziert.
|
|
1453
|
+
license_contents_link: https://opendatacommons.org/licenses/dbcl/1.0/
|
|
1446
1454
|
license_contents_name: Lizenz für Datenbankinhalte
|
|
1455
|
+
license_database_link: https://opendatacommons.org/licenses/odbl/1.0/
|
|
1447
1456
|
license_database_name: Offene Datenbanklizenz
|
|
1448
1457
|
title: Lizenz
|
|
1449
1458
|
title: Offene Daten
|
|
@@ -1726,9 +1735,23 @@ de:
|
|
|
1726
1735
|
notify_deprecation_to_owner:
|
|
1727
1736
|
body_1: 'Wir möchten Sie gerne über ein wichtiges Update ihres Gruppenprofil informieren: %{organization_name}.'
|
|
1728
1737
|
body_2: Wir möchten die Erfahrungen von Organisationen vereinfachen und verbessern und werden deshalb die Funktion "Benutzergruppen" abschalten. Ihre Gruppe, <strong>%{name}</strong>, wurde in ein reguläres Konto umgewandelt.
|
|
1738
|
+
body_3: Um weiterhin auf Ihr Konto zuzugreifen und den Zugriff freizugeben, müssen Sie ein Passwort festlegen. Sobald gesetzt, können Sie die Anmeldedaten (E-Mail und Passwort) an jeden weitergeben.
|
|
1729
1739
|
greeting: Hallo %{name},
|
|
1740
|
+
instructions_1: 'Klicken Sie auf den Link unten, um Ihr Passwort zu setzen:'
|
|
1741
|
+
instructions_2: 'Teilen Sie die Anmeldedaten (E-Mail: %{email} und das neue Passwort) mit Ihren Kollegen.'
|
|
1742
|
+
instructions_title: "<strong>Was sie tun müssen</strong>"
|
|
1730
1743
|
set_password: Passwort festlegen
|
|
1731
1744
|
subject: Wichtige Aktualisierung für Ihr Gruppenprofil
|
|
1745
|
+
notify_user_group_patched:
|
|
1746
|
+
body_1_html: 'Wir möchten Sie gerne über ein wichtiges Update ihres Gruppenprofil informieren: %{organization_name}.'
|
|
1747
|
+
body_2_html: Wir möchten die Erfahrungen von Organisationen vereinfachen und verbessern und werden deshalb die Funktion "Benutzergruppen" abschalten. Ihre Gruppe, <strong>%{name}</strong>, wurde in ein reguläres Konto umgewandelt.
|
|
1748
|
+
body_3_html: Um weiterhin auf Ihr Konto zuzugreifen und den Zugriff freizugeben, müssen Sie eine neue E-Mail und ein neues Passwort setzen. Bitte beachten Sie, dass jedes Mitglied deiner Gruppe diese E-Mail erhält. Um den weiteren Zugriff sicherzustellen, müssen Sie sich intern auf die gemeinsamen Zugangsdaten (E-Mail und Passwort) einigen, die jeder verwenden wird.
|
|
1749
|
+
greeting: Hallo %{name},
|
|
1750
|
+
instructions_1_html: 'Verwenden Sie die folgenden temporären Anmeldeinformationen, um sich einzuloggen: <br><br> Benutzername: <strong>%{email}</strong> <br> Passwort: <strong>%{password}</strong><br><br>'
|
|
1751
|
+
instructions_2_html: Geben Sie eine neue E-Mail-Adresse und ein Passwort ein.
|
|
1752
|
+
instructions_3_html: Teilen Sie die ausgewählten Anmeldedaten mit Ihren Kollegen, damit die gesamte Gruppe weiterhin auf das Konto zugreifen kann.
|
|
1753
|
+
instructions_title_html: "<strong>Was Sie tun müssen</strong>"
|
|
1754
|
+
subject: Wichtige Aktualisierung für Ihr Gruppenprofil
|
|
1732
1755
|
user_report_mailer:
|
|
1733
1756
|
notify:
|
|
1734
1757
|
body_1: Benutzer %{user} wurde von %{token} gemeldet
|
|
@@ -1778,6 +1801,7 @@ de:
|
|
|
1778
1801
|
send_paranoid_instructions: Wenn Ihre E-Mail-Adresse in unserer Datenbank vorhanden ist, erhalten Sie innerhalb weniger Minuten eine E-Mail mit Anweisungen zur Bestätigung Ihrer E-Mail-Adresse.
|
|
1779
1802
|
failure:
|
|
1780
1803
|
already_authenticated: Sie sind bereits angemeldet.
|
|
1804
|
+
csrf_token: Ihre Anfrage konnte nicht verifiziert werden. Bitte versuchen Sie es erneut.
|
|
1781
1805
|
inactive: Dein Benutzerkonto ist noch nicht aktiviert.
|
|
1782
1806
|
invalid: Ungültige %{authentication_keys} oder Passwort
|
|
1783
1807
|
invited: Sie haben eine ausstehende Einladung, akzeptieren Sie sie, um die Erstellung Ihres Kontos abzuschließen.
|
|
@@ -1792,6 +1816,7 @@ de:
|
|
|
1792
1816
|
nickname_help: Ihr Pseudonym auf %{organization}. Kann nur Buchstaben, Zahlen, '-' und '_' enthalten.
|
|
1793
1817
|
submit_button: Speichern
|
|
1794
1818
|
subtitle: Wenn Sie die Einladung annehmen, geben Sie bitte Ihren Kontonamen und Ihr Passwort ein.
|
|
1819
|
+
subtitle_no_password: Wenn Sie die Einladung annehmen, geben Sie bitte Ihren Kontonamen ein.
|
|
1795
1820
|
invitation_removed: Ihre Einladung wurde entfernt.
|
|
1796
1821
|
invitation_token_invalid: Das angegebene Einladungstoken ist nicht gültig!
|
|
1797
1822
|
new:
|
|
@@ -1799,6 +1824,8 @@ de:
|
|
|
1799
1824
|
submit_button: Eine Einladung schicken
|
|
1800
1825
|
no_invitations_remaining: Keine Einladungen übrig
|
|
1801
1826
|
send_instructions: Eine Einladungs-E-Mail wurde an %{email}gesendet.
|
|
1827
|
+
updated: Einladung erfolgreich angenommen. Sie sind jetzt angemeldet.
|
|
1828
|
+
updated_not_active: Einladung erfolgreich angenommen.
|
|
1802
1829
|
mailer:
|
|
1803
1830
|
confirmation_instructions:
|
|
1804
1831
|
action: Konto bestätigen
|
data/config/locales/en.yml
CHANGED
|
@@ -1345,6 +1345,7 @@ en:
|
|
|
1345
1345
|
own_activity: My own activity, like when someone comments in my proposal or mentions me
|
|
1346
1346
|
push_notifications: Push notifications
|
|
1347
1347
|
push_notifications_reminder: To get notifications from the platform, you will need to allow them in your browser settings first.
|
|
1348
|
+
push_notifications_unsupported_browser: Your browser is not supported.
|
|
1348
1349
|
receive_notifications_about: I want to get notifications about
|
|
1349
1350
|
update_notifications_settings: Save changes
|
|
1350
1351
|
update:
|
data/config/locales/es-MX.yml
CHANGED
|
@@ -1341,6 +1341,7 @@ es-MX:
|
|
|
1341
1341
|
own_activity: Mi propia actividad, como cuando alguien comenta en mi propuesta o me menciona.
|
|
1342
1342
|
push_notifications: Notificaciones emergentes
|
|
1343
1343
|
push_notifications_reminder: Para obtener notificaciones de la plataforma, primero tienes que permitirlas en la configuración de tu navegador.
|
|
1344
|
+
push_notifications_unsupported_browser: Tu navegador no es compatible.
|
|
1344
1345
|
receive_notifications_about: Quiero recibir notificaciones sobre
|
|
1345
1346
|
update_notifications_settings: Guardar cambios
|
|
1346
1347
|
update:
|
data/config/locales/es-PY.yml
CHANGED
|
@@ -1341,6 +1341,7 @@ es-PY:
|
|
|
1341
1341
|
own_activity: Mi propia actividad, como cuando alguien comenta en mi propuesta o me menciona.
|
|
1342
1342
|
push_notifications: Notificaciones emergentes
|
|
1343
1343
|
push_notifications_reminder: Para obtener notificaciones de la plataforma, primero tienes que permitirlas en la configuración de tu navegador.
|
|
1344
|
+
push_notifications_unsupported_browser: Tu navegador no es compatible.
|
|
1344
1345
|
receive_notifications_about: Quiero recibir notificaciones sobre
|
|
1345
1346
|
update_notifications_settings: Guardar cambios
|
|
1346
1347
|
update:
|
data/config/locales/es.yml
CHANGED
|
@@ -1338,6 +1338,7 @@ es:
|
|
|
1338
1338
|
own_activity: Mi propia actividad, como cuando alguien comenta en mi propuesta o me menciona
|
|
1339
1339
|
push_notifications: Notificaciones emergentes
|
|
1340
1340
|
push_notifications_reminder: Para recibir notificaciones de la plataforma, primero tienes que permitirlas en la configuración de tu navegador.
|
|
1341
|
+
push_notifications_unsupported_browser: Tu navegador no es compatible.
|
|
1341
1342
|
receive_notifications_about: Quiero recibir notificaciones
|
|
1342
1343
|
update_notifications_settings: Guardar cambios
|
|
1343
1344
|
update:
|
data/config/locales/eu.yml
CHANGED
|
@@ -1338,6 +1338,7 @@ eu:
|
|
|
1338
1338
|
own_activity: Neure jarduera, norbaitek nire proposamenean iruzkina egiten duenean bezala, edo aipatzen nauenean
|
|
1339
1339
|
push_notifications: Push jakinarazpenak
|
|
1340
1340
|
push_notifications_reminder: Plataformaren jakinarazpenak jasotzeko, lehen zure nabigatzailearen konfigurazioan baimendu behar dituzu.
|
|
1341
|
+
push_notifications_unsupported_browser: Zure nabigatzaileak ez du euskarririk.
|
|
1341
1342
|
receive_notifications_about: Jakinarazpenak jaso nahi ditut
|
|
1342
1343
|
update_notifications_settings: Gorde aldaketak
|
|
1343
1344
|
update:
|
|
@@ -1819,6 +1820,7 @@ eu:
|
|
|
1819
1820
|
nickname_help: Zure ezizena %{organization}-an. Letrak, zenbakiak, '-' eta '_' soilik eduki ditzake.
|
|
1820
1821
|
submit_button: Gorde
|
|
1821
1822
|
subtitle: Gonbidapena onartzen baduzu, mesedez, ezarri zure ezizena eta pasahitza.
|
|
1823
|
+
subtitle_no_password: Gonbidapena onartzen baduzu, jarri zure ezizena.
|
|
1822
1824
|
invitation_removed: Zure gonbidapena kendu egin da.
|
|
1823
1825
|
invitation_token_invalid: Gonbidapen token hori ez da baliozkoa!
|
|
1824
1826
|
new:
|
|
@@ -1826,6 +1828,8 @@ eu:
|
|
|
1826
1828
|
submit_button: Bidali gonbidapena
|
|
1827
1829
|
no_invitations_remaining: Ez da gonbidapenik geratzen
|
|
1828
1830
|
send_instructions: Gonbidapen-mezu elektroniko bat %{email} helbidera bidali da.
|
|
1831
|
+
updated: Gonbidapena behar bezala onartu da. Orain erregistratuta zaude.
|
|
1832
|
+
updated_not_active: Gonbidapena behar bezala onartu da.
|
|
1829
1833
|
mailer:
|
|
1830
1834
|
confirmation_instructions:
|
|
1831
1835
|
action: Berretsi nire kontua
|
data/config/locales/fi-plain.yml
CHANGED
|
@@ -1821,6 +1821,7 @@ fi-pl:
|
|
|
1821
1821
|
nickname_help: Nimimerkkisi palvelussa %{organization}. Voi sisältää ainoastaan kirjaimia, numeroita sekä yhdysmerkkejä "-" ja alaviivoja "_".
|
|
1822
1822
|
submit_button: Tallenna
|
|
1823
1823
|
subtitle: Jos hyväksyt kutsun, aseta käyttäjänimesi ja salasana.
|
|
1824
|
+
subtitle_no_password: Jos hyväksyt kutsun, aseta tilillesi nimi.
|
|
1824
1825
|
invitation_removed: Kutsusi peruutettiin.
|
|
1825
1826
|
invitation_token_invalid: Käyttämäsi kutsuavain ei ole voimassa!
|
|
1826
1827
|
new:
|
|
@@ -1828,6 +1829,8 @@ fi-pl:
|
|
|
1828
1829
|
submit_button: Lähetä kutsu
|
|
1829
1830
|
no_invitations_remaining: Ei kutsuja jäljellä
|
|
1830
1831
|
send_instructions: Kutsuviesti on lähetetty %{email}.
|
|
1832
|
+
updated: Kutsun hyväksyminen onnistui. Olet nyt kirjautunut sisään.
|
|
1833
|
+
updated_not_active: Kutsun hyväksyminen onnistui.
|
|
1831
1834
|
mailer:
|
|
1832
1835
|
confirmation_instructions:
|
|
1833
1836
|
action: Vahvista käyttäjätilini
|
|
@@ -1887,6 +1890,8 @@ fi-pl:
|
|
|
1887
1890
|
confirm_new_password: Vahvista uusi salasana
|
|
1888
1891
|
new_password: Uusi salasana
|
|
1889
1892
|
old_password_help: Vahvistaaksesi muutokset käyttäjätiliisi, anna nykyinen salasanasi.
|
|
1893
|
+
password_help: "Vähintään %{minimum_characters} merkkiä, vähintään 5 eri merkkiä, ei voi olla yleisesti käytetty salasana (esim. 123456), eikä voi vastata nimeäsi, nimimerkkiäsi, sähköpostiosoitettasi tai tämän palvelun verkko-osoitetta."
|
|
1894
|
+
password_help_admin: "Vähintään %{minimum_characters} merkkiä, vähintään 5 eri merkkiä, ei voi olla yleisesti käytetty salasana (esim. 123456), eikä voi vastata nimeäsi, nimimerkkiäsi, sähköpostiosoitettasi tai tämän palvelun verkko-osoitetta. Et myöskään voi käyttää aikaisempia salasanojasi."
|
|
1890
1895
|
title: Salasanan vaihto
|
|
1891
1896
|
new:
|
|
1892
1897
|
forgot_your_password: Unohditko salasanasi?
|