decidim-core 0.31.2 → 0.31.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/app/cells/decidim/content_blocks/highlighted_elements_with_cell_for_list_cell.rb +5 -1
  3. data/app/cells/decidim/nav_links/show.erb +3 -3
  4. data/app/cells/decidim/participatory_space_private_user/show.erb +6 -6
  5. data/app/cells/decidim/participatory_space_private_user_cell.rb +0 -4
  6. data/app/cells/decidim/report_button/already_reported_modal.erb +1 -1
  7. data/app/cells/decidim/report_button/flag_modal.erb +1 -1
  8. data/app/cells/decidim/report_user_button/already_reported_modal.erb +1 -1
  9. data/app/cells/decidim/report_user_button/flag_modal.erb +1 -1
  10. data/app/cells/decidim/share_text_widget/modal.erb +1 -1
  11. data/app/cells/decidim/upload_modal/files.erb +5 -1
  12. data/app/cells/decidim/upload_modal_cell.rb +10 -1
  13. data/app/commands/decidim/multiple_attachments_methods.rb +20 -3
  14. data/app/helpers/decidim/mailer_helper.rb +36 -0
  15. data/app/helpers/decidim/menu_helper.rb +2 -1
  16. data/app/helpers/decidim/newsletters_helper.rb +4 -22
  17. data/app/jobs/decidim/find_and_update_descendants_job.rb +8 -2
  18. data/app/jobs/decidim/update_search_indexes_job.rb +2 -2
  19. data/app/mailers/decidim/application_mailer.rb +4 -0
  20. data/app/packs/src/decidim/a11y.js +29 -0
  21. data/app/packs/src/decidim/a11y.test.js +81 -0
  22. data/app/packs/src/decidim/confirm.js +8 -1
  23. data/app/packs/src/decidim/confirm.test.js +225 -0
  24. data/app/packs/src/decidim/controllers/accordion/accordion.test.js +118 -0
  25. data/app/packs/src/decidim/controllers/accordion/controller.js +24 -0
  26. data/app/packs/src/decidim/controllers/dropdown/controller.js +26 -0
  27. data/app/packs/src/decidim/controllers/dropdown/dropdown.test.js +187 -0
  28. data/app/packs/src/decidim/controllers/form_validator/form_validator.js +3 -2
  29. data/app/packs/src/decidim/controllers/form_validator/form_validator.test.js +5 -0
  30. data/app/packs/src/decidim/controllers/language_change/controller.js +1 -0
  31. data/app/packs/src/decidim/controllers/language_change/language_change.test.js +13 -0
  32. data/app/packs/src/decidim/datepicker/datepicker_functions.js +26 -0
  33. data/app/packs/src/decidim/datepicker/generate_datepicker.js +2 -1
  34. data/app/packs/src/decidim/datepicker/generate_timepicker.js +3 -2
  35. data/app/packs/src/decidim/datepicker/test/datepicker_functions_adjust_picker_position.test.js +234 -0
  36. data/app/packs/src/decidim/editor/extensions/image/index.js +49 -11
  37. data/app/packs/src/decidim/editor/extensions/image/node_view.js +9 -1
  38. data/app/packs/src/decidim/editor/extensions/link/bubble_menu.js +34 -6
  39. data/app/packs/src/decidim/editor/extensions/link/index.js +45 -12
  40. data/app/packs/src/decidim/editor/test/extensions/image_links.test.js +161 -0
  41. data/app/packs/src/decidim/refactor/moved/focus_guard.js +4 -4
  42. data/app/packs/stylesheets/decidim/_cards.scss +12 -4
  43. data/app/packs/stylesheets/decidim/_flash.scss +1 -1
  44. data/app/packs/stylesheets/decidim/_rich_text.scss +17 -0
  45. data/app/packs/stylesheets/decidim/editor.scss +10 -0
  46. data/app/presenters/decidim/menu_item_presenter.rb +7 -1
  47. data/app/views/decidim/devise/invitations/edit.html.erb +3 -3
  48. data/app/views/decidim/devise/registrations/new.html.erb +1 -0
  49. data/app/views/decidim/devise/shared/_tos_fields.html.erb +3 -3
  50. data/app/views/decidim/notification_mailer/event_received.html.erb +3 -3
  51. data/app/views/decidim/pages/_tabbed.html.erb +3 -3
  52. data/app/views/decidim/shared/_filters.html.erb +5 -5
  53. data/app/views/decidim/shared/filters/_check_boxes_tree.html.erb +1 -1
  54. data/app/views/decidim/shared/filters/_collection.html.erb +1 -1
  55. data/config/initializers/devise.rb +6 -0
  56. data/config/locales/ar.yml +3 -3
  57. data/config/locales/bg.yml +0 -4
  58. data/config/locales/ca-IT.yml +7 -6
  59. data/config/locales/ca.yml +7 -6
  60. data/config/locales/cs.yml +5 -8
  61. data/config/locales/de.yml +31 -8
  62. data/config/locales/el.yml +0 -2
  63. data/config/locales/en.yml +5 -4
  64. data/config/locales/es-MX.yml +10 -9
  65. data/config/locales/es-PY.yml +10 -9
  66. data/config/locales/es.yml +12 -11
  67. data/config/locales/eu.yml +7 -5
  68. data/config/locales/fi-plain.yml +10 -4
  69. data/config/locales/fi.yml +11 -5
  70. data/config/locales/fr-CA.yml +7 -5
  71. data/config/locales/fr.yml +8 -7
  72. data/config/locales/gl.yml +0 -2
  73. data/config/locales/hu.yml +4 -8
  74. data/config/locales/id-ID.yml +0 -2
  75. data/config/locales/it.yml +1 -3
  76. data/config/locales/ja.yml +7 -8
  77. data/config/locales/lb.yml +0 -2
  78. data/config/locales/lt.yml +1 -3
  79. data/config/locales/lv.yml +0 -2
  80. data/config/locales/nl.yml +0 -2
  81. data/config/locales/no.yml +0 -2
  82. data/config/locales/pl.yml +0 -4
  83. data/config/locales/pt-BR.yml +4 -5
  84. data/config/locales/pt.yml +0 -2
  85. data/config/locales/ro-RO.yml +1 -5
  86. data/config/locales/ru.yml +0 -2
  87. data/config/locales/sk.yml +0 -4
  88. data/config/locales/sv.yml +8 -7
  89. data/config/locales/tr-TR.yml +17 -5
  90. data/config/locales/zh-CN.yml +0 -2
  91. data/config/locales/zh-TW.yml +1 -3
  92. data/lib/decidim/assets/tailwind/tailwind.config.js.erb +1 -1
  93. data/lib/decidim/content_parsers/blob_parser.rb +3 -3
  94. data/lib/decidim/content_renderers/blob_renderer.rb +2 -2
  95. data/lib/decidim/core/test/shared_examples/participatory_space_members_shared_examples.rb +121 -0
  96. data/lib/decidim/core/version.rb +1 -1
  97. data/lib/decidim/form_builder.rb +58 -36
  98. data/lib/decidim/maintenance/taxonomy_importer.rb +1 -1
  99. data/lib/decidim/participatory_space_user.rb +1 -1
  100. data/lib/decidim/searchable.rb +4 -4
  101. metadata +14 -6
@@ -0,0 +1,161 @@
1
+ /* global jest, global */
2
+
3
+ import { createBasicEditor, updateContent, sleep } from "src/decidim/editor/test/helpers";
4
+
5
+ import Dialog from "src/decidim/editor/extensions/dialog";
6
+ import Image from "src/decidim/editor/extensions/image";
7
+ import uploadTemplates from "src/decidim/editor/test/fixtures/upload_templates";
8
+
9
+ class DummyDialog {
10
+ constructor(element) { this.element = element; }
11
+
12
+ open() { this.element.dataset.dialogOpen = true; }
13
+
14
+ close() { this.element.dataset.dialogOpen = null; }
15
+ }
16
+
17
+ // Not implemented in Jest
18
+ global.Touch = class Touch {
19
+ constructor(options) {
20
+ this.pageX = options.pageX;
21
+ this.pageY = options.pageY;
22
+ }
23
+ }
24
+
25
+ describe("Image (links)", () => {
26
+ let editor = null;
27
+ let editorElement = null;
28
+ let uploadDialogElement = null;
29
+
30
+ beforeEach(() => {
31
+ document.body.innerHTML = "";
32
+
33
+ const dialogWrapper = document.createElement("div");
34
+ dialogWrapper.innerHTML = uploadTemplates.redesign;
35
+ uploadDialogElement = dialogWrapper.firstElementChild;
36
+ uploadDialogElement.dataset.dialog = "testDialog";
37
+ uploadDialogElement.dialog = new DummyDialog(uploadDialogElement);
38
+ window.Decidim.currentDialogs = { testDialog: uploadDialogElement.dialog };
39
+ document.body.append(uploadDialogElement);
40
+
41
+ editor = createBasicEditor({
42
+ extensions: [Dialog, Image.configure({ uploadDialogSelector: "#upload_dialog", uploadImagesPath: "/editor_images", contentTypes: ["image/png"] })]
43
+ });
44
+ editorElement = editor.view.dom;
45
+
46
+ const csrf = document.createElement("meta");
47
+ csrf.setAttribute("name", "csrf-token");
48
+ csrf.setAttribute("content", "abcdef0123456789");
49
+ document.head.append(csrf);
50
+
51
+ global.fetch = jest.fn(() => Promise.resolve({ ok: true, json: () => Promise.resolve({ url: "/path/to/image.jpg" }) }));
52
+ });
53
+
54
+ afterEach(() => {
55
+ jest.restoreAllMocks();
56
+ });
57
+
58
+ it("allows setting an image with href and target attributes", async () => {
59
+ editorElement.focus();
60
+ editor.commands.setImage({ src: "/path/to/image.jpg", alt: "Test image", href: "https://example.com", target: "_blank" });
61
+ await sleep(0);
62
+
63
+ expect(editor.getHTML()).toMatchHtml(`
64
+ <a href="https://example.com" target="_blank" rel="noopener noreferrer">
65
+ <div class="editor-content-image" data-image="">
66
+ <img src="/path/to/image.jpg" alt="Test image">
67
+ </div>
68
+ </a>
69
+ `);
70
+ });
71
+
72
+ it("allows setting an image with href but no target", async () => {
73
+ editorElement.focus();
74
+ editor.commands.setImage({ src: "/path/to/image.jpg", alt: "Test image", href: "https://example.com" });
75
+ await sleep(0);
76
+
77
+ expect(editor.getHTML()).toMatchHtml(`
78
+ <a href="https://example.com">
79
+ <div class="editor-content-image" data-image="">
80
+ <img src="/path/to/image.jpg" alt="Test image">
81
+ </div>
82
+ </a>
83
+ `);
84
+ });
85
+
86
+ it("parses existing HTML with linked images", async () => {
87
+ editorElement.focus();
88
+ await updateContent(editorElement,
89
+ '<a href="https://example.com" target="_blank"><div class="editor-content-image" data-image=""><img src="/path/to/image.jpg" alt="Test image"></div></a>',
90
+ editor
91
+ );
92
+
93
+ expect(editor.getHTML()).toMatchHtml(`
94
+ <a href="https://example.com" target="_blank" rel="noopener noreferrer">
95
+ <div class="editor-content-image" data-image="">
96
+ <img src="/path/to/image.jpg" alt="Test image">
97
+ </div>
98
+ </a>
99
+ `);
100
+ });
101
+
102
+ it("parses existing HTML with linked images without target", async () => {
103
+ editorElement.focus();
104
+ await updateContent(editorElement,
105
+ '<a href="https://example.com"><div class="editor-content-image" data-image=""><img src="/path/to/image.jpg" alt="Test image"></div></a>',
106
+ editor
107
+ );
108
+
109
+ expect(editor.getHTML()).toMatchHtml(`
110
+ <a href="https://example.com">
111
+ <div class="editor-content-image" data-image="">
112
+ <img src="/path/to/image.jpg" alt="Test image">
113
+ </div>
114
+ </a>
115
+ `);
116
+ });
117
+
118
+ it("allows updating image link attributes", async () => {
119
+ editorElement.focus();
120
+ editor.commands.setImage({ src: "/path/to/image.jpg", alt: "Test image", href: "https://example.com", target: "_blank" });
121
+ await sleep(0);
122
+
123
+ editor.commands.setImage({ src: "/path/to/image.jpg", alt: "Test image", href: "https://docs.example.com" });
124
+ await sleep(0);
125
+
126
+ expect(editor.getHTML()).toMatchHtml(`
127
+ <a href="https://docs.example.com">
128
+ <div class="editor-content-image" data-image="">
129
+ <img src="/path/to/image.jpg" alt="Test image">
130
+ </div>
131
+ </a>
132
+ `);
133
+ });
134
+
135
+ it("allows removing link from image", async () => {
136
+ editorElement.focus();
137
+ editor.commands.setImage({ src: "/path/to/image.jpg", alt: "Test image", href: "https://example.com", target: "_blank" });
138
+ await sleep(0);
139
+
140
+ editor.commands.setImage({ src: "/path/to/image.jpg", alt: "Test image", href: null, target: null });
141
+ await sleep(0);
142
+
143
+ expect(editor.getHTML()).toMatchHtml(`
144
+ <div class="editor-content-image" data-image="">
145
+ <img src="/path/to/image.jpg" alt="Test image">
146
+ </div>
147
+ `);
148
+ });
149
+
150
+ it("renders images without links correctly", async () => {
151
+ editorElement.focus();
152
+ editor.commands.setImage({ src: "/path/to/image.jpg", alt: "Test image" });
153
+ await sleep(0);
154
+
155
+ expect(editor.getHTML()).toMatchHtml(`
156
+ <div class="editor-content-image" data-image="">
157
+ <img src="/path/to/image.jpg" alt="Test image">
158
+ </div>
159
+ `);
160
+ });
161
+ });
@@ -78,16 +78,16 @@ export default class FocusGuard {
78
78
 
79
79
  let target = null;
80
80
  if (guard.dataset.position === "start") {
81
- // Focus at the start guard, so focus the first focusable element after that
82
- for (let ind = 0; ind < visibleNodes.length; ind += 1) {
81
+ // Focus at the start guard, so focus the last focusable element (cycle forward to end)
82
+ for (let ind = visibleNodes.length - 1; ind >= 0; ind -= 1) {
83
83
  if (!this.isFocusGuard(visibleNodes[ind]) && this.isFocusable(visibleNodes[ind])) {
84
84
  target = visibleNodes[ind];
85
85
  break;
86
86
  }
87
87
  }
88
88
  } else {
89
- // Focus at the end guard, so focus the first focusable element after that
90
- for (let ind = visibleNodes.length - 1; ind >= 0; ind -= 1) {
89
+ // Focus at the end guard, so focus the first focusable element (cycle back to start)
90
+ for (let ind = 0; ind < visibleNodes.length; ind += 1) {
91
91
  if (!this.isFocusGuard(visibleNodes[ind]) && this.isFocusable(visibleNodes[ind])) {
92
92
  target = visibleNodes[ind];
93
93
  break;
@@ -116,7 +116,7 @@
116
116
  }
117
117
 
118
118
  &__calendar {
119
- @apply w-14 flex flex-col justify-start rounded overflow-hidden bg-background text-center;
119
+ @apply w-20 flex flex-col justify-start rounded overflow-hidden bg-background text-center;
120
120
 
121
121
  /* overwrite defaults */
122
122
  &-list__reset {
@@ -128,17 +128,25 @@
128
128
  }
129
129
 
130
130
  &-day {
131
- @apply text-black text-2xl font-bold;
131
+ @apply text-black text-xl font-semibold;
132
132
  }
133
133
 
134
134
  &-year {
135
- @apply text-black text-xs;
135
+ @apply text-black text-xs mb-0.5;
136
136
  }
137
137
 
138
138
  &-month,
139
139
  &-day,
140
140
  &-year {
141
- @apply inline-flex items-center justify-evenly empty:[&>div]:hidden;
141
+ @apply inline-flex items-center justify-center empty:[&>div]:hidden;
142
+ }
143
+
144
+ &-separator {
145
+ @apply mx-2 font-normal text-sm;
146
+ }
147
+
148
+ .card__list-content {
149
+ @apply mt-0.5;
142
150
  }
143
151
  }
144
152
 
@@ -1,5 +1,5 @@
1
1
  .flash {
2
- @apply flex justify-start gap-4 border-l-4 border-secondary my-4 p-4 bg-secondary/5 break-all;
2
+ @apply flex justify-start gap-4 border-l-4 border-secondary my-4 p-4 bg-secondary/5;
3
3
 
4
4
  &__icon {
5
5
  svg {
@@ -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: :menuitem, class: link_wrapper_classes do
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,7 +4,7 @@
4
4
  <h1 class="title-decorator inline-block text-left mb-12"><%= t "devise.invitations.edit.header" %></h1>
5
5
 
6
6
  <p class="text-lg text-gray-2">
7
- <%= t("devise.invitations.edit.subtitle").html_safe %>
7
+ <%= current_organization.users_registration_mode_disabled? ? t("devise.invitations.edit.subtitle_no_password").html_safe : t("devise.invitations.edit.subtitle").html_safe %>
8
8
  </p>
9
9
  </div>
10
10
 
@@ -16,8 +16,8 @@
16
16
 
17
17
  <%= f.text_field :nickname, help_text: t("devise.invitations.edit.nickname_help", organization: current_organization_name), required: "required", autocomplete: "nickname" %>
18
18
 
19
- <% if f.object.class.require_password_on_accepting %>
20
- <%= render partial: "decidim/account/password_fields", locals: { form: f, user: :user } %>
19
+ <% unless current_organization.users_registration_mode_disabled? %>
20
+ <%= render partial: "decidim/account/password_fields", locals: { form: f, user: resource.admin? ? :admin : :user } %>
21
21
  <% end %>
22
22
  </div>
23
23
 
@@ -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>
@@ -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" role="menu">
21
+ <ul id="dropdown-menu-pages" class="vertical-tabs__list">
22
22
  <% pages.each do |sibling| %>
23
- <li class="<%= "is-active" if page == sibling %>" role="menuitem">
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", role: "menuitem", "data-skip-to-content": true %>
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" role="menuitem" aria-disabled="true"><%= t("help", scope: "decidim.shared.filter_form_help") %></p>
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" role="menuitem">
23
+ <div class="filter-search filter-container">
24
24
  <%= form.search_field search_variable,
25
25
  label: false,
26
26
  placeholder: search_label,
@@ -1,4 +1,4 @@
1
- <div class="filter-container" role="menuitem">
1
+ <div class="filter-container">
2
2
  <button id="trigger-menu-<%= id %>" data-controls="panel-dropdown-menu-<%= id %>" data-open="false" data-open-md="true">
3
3
  <%= icon "arrow-down-s-line" %>
4
4
  <%= icon "arrow-up-s-line" %>
@@ -1,4 +1,4 @@
1
- <div class="filter-container" role="menuitem">
1
+ <div class="filter-container">
2
2
  <button id="trigger-menu-<%= id %>" data-controls="panel-dropdown-menu-<%= id %>" data-open="false" data-open-md="true">
3
3
  <%= icon "arrow-down-s-line" %>
4
4
  <%= icon "arrow-up-s-line" %>
@@ -175,6 +175,12 @@ Devise.setup do |config|
175
175
  # Default: true
176
176
  config.allow_insecure_sign_in_after_accept = true
177
177
 
178
+ # Require password when user accepts the invitation.
179
+ # Disable if you do not want to ask for or enforce setting a password while accepting,
180
+ # because it is set when the user is invited or will be set later.
181
+ # Default: true
182
+ config.require_password_on_accepting = false
183
+
178
184
  # A period that the user is allowed to confirm their account before their
179
185
  # token becomes invalid. For example, if set to 3.days, the user can confirm
180
186
  # their account within 3 days after the mail was sent, but on the fourth day
@@ -1123,8 +1123,6 @@ ar:
1123
1123
  submit_button: ارسل دعوة
1124
1124
  no_invitations_remaining: لا توجد دعوات متبقية
1125
1125
  send_instructions: تم إرسال دعوة بريد إلكتروني إلى %{email}.
1126
- updated: تم ضبط كلمة مرورك بنجاح. انت الآن مسجل دخولك.
1127
- updated_not_active: تم ضبط كلمة مرورك بنجاح.
1128
1126
  mailer:
1129
1127
  confirmation_instructions:
1130
1128
  action: تأكيد حسابي
@@ -1186,6 +1184,7 @@ ar:
1186
1184
  links:
1187
1185
  back: الى الخلف
1188
1186
  forgot_your_password: نسيت رقمك السري؟
1187
+ log_in: تسجيل الدخول
1189
1188
  log_in_with_provider: تسجيل الدخول باستخدام %{provider}
1190
1189
  minimum_password_length:
1191
1190
  zero: "(%{count} حرف كحد أدنى)"
@@ -1274,7 +1273,7 @@ ar:
1274
1273
  description: وصف
1275
1274
  name: اسم
1276
1275
  service: الخدمة
1277
- type: نوع
1276
+ type: النوع
1278
1277
  items:
1279
1278
  _session_id:
1280
1279
  description: يسمح للمواقع بتذكر المستخدم داخل الموقع عندما ينتقل بين صفحات الويب.
@@ -1324,6 +1323,7 @@ ar:
1324
1323
  data_consent_settings: إعدادات ملفات تعريف الارتباط
1325
1324
  decidim_logo: شعار Decidim
1326
1325
  decidim_title: Decidim
1326
+ log_in: تسجيل الدخول
1327
1327
  made_with_open_source: موقع تم إنشاؤه <a target="_blank" href="https://github.com/decidim/decidim">بالبرمجيات الحرة</a>.
1328
1328
  resources: الموارد
1329
1329
  header:
@@ -1314,8 +1314,6 @@ bg:
1314
1314
  submit_button: Изпрати покана
1315
1315
  no_invitations_remaining: Няма останали покани
1316
1316
  send_instructions: Писмо с покана беше изпратено до %{email}.
1317
- updated: Вашата парола беше зададена успешно. Вече сте влезли.
1318
- updated_not_active: Вашата парола беше зададена успешно.
1319
1317
  mailer:
1320
1318
  confirmation_instructions:
1321
1319
  action: Потвърди профила ми
@@ -1372,8 +1370,6 @@ bg:
1372
1370
  confirm_new_password: Потвърди нова парола
1373
1371
  new_password: Нова парола
1374
1372
  old_password_help: За да потвърдите промените във вашия акаунт, моля, въведете текущата си парола.
1375
- password_help: "Минимум %{minimum_characters} символа, не трябва да са разпространени (например, 123456) и трябва да са различни от вашите име и ел. поща."
1376
- password_help_admin: "Минимум %{minimum_characters} символа, не трябва да са разпространени (например, 123456) и трябва да са различни от вашите име и ел. поща."
1377
1373
  title: Промяна на паролата
1378
1374
  new:
1379
1375
  forgot_your_password: Забравили сте паролата си?
@@ -1422,7 +1422,7 @@ ca-IT:
1422
1422
  download:
1423
1423
  components: Components
1424
1424
  core: Nucli
1425
- spaces: Espai participatiu
1425
+ spaces: Espais de participació
1426
1426
  title: Descarregar recursos
1427
1427
  download_open_data: Descarrega tots els fitxers de dades obertes
1428
1428
  download_resource: Descarregar "%{resource_name}" en format CSV
@@ -1550,7 +1550,7 @@ ca-IT:
1550
1550
  user:
1551
1551
  actions:
1552
1552
  disabled_message: Missatge
1553
- edit_profile: Edita el perfil
1553
+ edit_profile: Editar el perfil
1554
1554
  message: Missatge
1555
1555
  resend_email_confirmation_instructions: Reenvia un correu electrònic amb les instruccions de confirmació
1556
1556
  qr:
@@ -1819,6 +1819,7 @@ ca-IT:
1819
1819
  nickname_help: El teu àlies a %{organization}. Només pot contenir lletres, números, '-' i '_'.
1820
1820
  submit_button: Desa
1821
1821
  subtitle: Si acceptes la invitació, si us plau, estableix el teu àlies i contrasenya.
1822
+ subtitle_no_password: Si acceptes la invitació, si us plau, estableix el teu àlies o sobrenom.
1822
1823
  invitation_removed: S'ha eliminat la teva invitació.
1823
1824
  invitation_token_invalid: El token de invitació proporcionat no és vàlid!
1824
1825
  new:
@@ -1826,8 +1827,8 @@ ca-IT:
1826
1827
  submit_button: Enviar una invitació
1827
1828
  no_invitations_remaining: No queden invitacions
1828
1829
  send_instructions: S'ha enviat una invitació via correu electrònic a %{email}.
1829
- updated: La teva contrasenya s'ha establert correctament. Ja has iniciat sessió.
1830
- updated_not_active: La teva contrasenya s'ha establert correctament.
1830
+ updated: La invitació s'ha acceptat correctament. S'ha iniciat la teva sessió.
1831
+ updated_not_active: La invitació s'ha acceptat correctament.
1831
1832
  mailer:
1832
1833
  confirmation_instructions:
1833
1834
  action: Confirma el meu compte
@@ -1886,8 +1887,8 @@ ca-IT:
1886
1887
  confirm_new_password: Confirmar la nova contrasenya
1887
1888
  new_password: Nova contrasenya
1888
1889
  old_password_help: Per tal de confirmar els canvis al teu compte, si us plau, proporciona'ns la teva contrasenya actual.
1889
- password_help: "%{minimum_characters} caràcters mínim, no ha de ser massa comú (per exemple 123456) i ha de ser diferent del teu àlies i la teva adreça de correu electrònic."
1890
- password_help_admin: "%{minimum_characters} caràcters mínim, no ha de ser massa comú (per exemple 123456) i ha de ser diferent del teu àlies, del teu correu electrònic i de les teves antigues contrasenyes."
1890
+ password_help: "La contrasenya ha de tenir com a mínim %{minimum_characters} caràcters, d'aquests, almenys 5 caràcters han de ser diferents, no han de ser massa comuns (p. ex. 123456) i ha de ser diferent del número, sobrenom, correu electrònic i del domini de la plataforma."
1891
+ password_help_admin: "La contrasenya ha de tenir com a mínim %{minimum_characters} caràcters, d'aquests, almenys 5 caràcters han de ser diferents, no han de ser massa comuns (p. ex. 123456) i ha de ser diferent del número, sobrenom, correu electrònic, domini de la plataforma o contrasenyes antigues."
1891
1892
  title: Canvi de contrasenya
1892
1893
  new:
1893
1894
  forgot_your_password: Has oblidat la teva contrasenya?
@@ -1422,7 +1422,7 @@ ca:
1422
1422
  download:
1423
1423
  components: Components
1424
1424
  core: Nucli
1425
- spaces: Espai participatiu
1425
+ spaces: Espais de participació
1426
1426
  title: Descarregar recursos
1427
1427
  download_open_data: Descarrega tots els fitxers de dades obertes
1428
1428
  download_resource: Descarregar "%{resource_name}" en format CSV
@@ -1550,7 +1550,7 @@ ca:
1550
1550
  user:
1551
1551
  actions:
1552
1552
  disabled_message: Missatge
1553
- edit_profile: Edita el perfil
1553
+ edit_profile: Editar el perfil
1554
1554
  message: Missatge
1555
1555
  resend_email_confirmation_instructions: Reenvia un correu electrònic amb les instruccions de confirmació
1556
1556
  qr:
@@ -1819,6 +1819,7 @@ ca:
1819
1819
  nickname_help: El teu àlies a %{organization}. Només pot contenir lletres, números, '-' i '_'.
1820
1820
  submit_button: Desa
1821
1821
  subtitle: Si acceptes la invitació, si us plau, estableix el teu àlies i contrasenya.
1822
+ subtitle_no_password: Si acceptes la invitació, si us plau, estableix el teu àlies o sobrenom.
1822
1823
  invitation_removed: S'ha eliminat la teva invitació.
1823
1824
  invitation_token_invalid: El token de invitació proporcionat no és vàlid!
1824
1825
  new:
@@ -1826,8 +1827,8 @@ ca:
1826
1827
  submit_button: Enviar una invitació
1827
1828
  no_invitations_remaining: No queden invitacions
1828
1829
  send_instructions: S'ha enviat una invitació via correu electrònic a %{email}.
1829
- updated: La teva contrasenya s'ha establert correctament. Ja has iniciat sessió.
1830
- updated_not_active: La teva contrasenya s'ha establert correctament.
1830
+ updated: La invitació s'ha acceptat correctament. S'ha iniciat la teva sessió.
1831
+ updated_not_active: La invitació s'ha acceptat correctament.
1831
1832
  mailer:
1832
1833
  confirmation_instructions:
1833
1834
  action: Confirma el meu compte
@@ -1886,8 +1887,8 @@ ca:
1886
1887
  confirm_new_password: Confirmar la nova contrasenya
1887
1888
  new_password: Nova contrasenya
1888
1889
  old_password_help: Per tal de confirmar els canvis al teu compte, si us plau, proporciona'ns la teva contrasenya actual.
1889
- password_help: "%{minimum_characters} caràcters mínim, no ha de ser massa comú (per exemple 123456) i ha de ser diferent del teu àlies i la teva adreça de correu electrònic."
1890
- password_help_admin: "%{minimum_characters} caràcters mínim, no ha de ser massa comú (per exemple 123456) i ha de ser diferent del teu àlies, del teu correu electrònic i de les teves antigues contrasenyes."
1890
+ password_help: "La contrasenya ha de tenir com a mínim %{minimum_characters} caràcters, d'aquests, almenys 5 caràcters han de ser diferents, no han de ser massa comuns (p. ex. 123456) i ha de ser diferent del número, sobrenom, correu electrònic i del domini de la plataforma."
1891
+ password_help_admin: "La contrasenya ha de tenir com a mínim %{minimum_characters} caràcters, d'aquests, almenys 5 caràcters han de ser diferents, no han de ser massa comuns (p. ex. 123456) i ha de ser diferent del número, sobrenom, correu electrònic, domini de la plataforma o contrasenyes antigues."
1891
1892
  title: Canvi de contrasenya
1892
1893
  new:
1893
1894
  forgot_your_password: Has oblidat la teva contrasenya?