decidim-core 0.32.0.rc3 → 0.32.1
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/author_cell.rb +0 -4
- data/app/cells/decidim/comments_button_cell.rb +9 -1
- data/app/cells/decidim/content_blocks/highlighted_content_banner_cell.rb +1 -1
- data/app/cells/decidim/content_blocks/highlighted_participatory_spaces_cell.rb +1 -1
- data/app/cells/decidim/data_consent/category.erb +20 -33
- data/app/cells/decidim/footer_topics/show.erb +5 -8
- data/app/cells/decidim/share_widget/qr_code_modal.erb +1 -1
- data/app/commands/decidim/destroy_account.rb +12 -1
- data/app/commands/decidim/multiple_attachments_methods.rb +28 -27
- data/app/helpers/decidim/menu_helper.rb +0 -2
- data/app/jobs/decidim/process_inactive_participant_job.rb +0 -7
- data/app/mailers/decidim/delete_user_mailer.rb +14 -0
- data/app/mailers/decidim/participants_account_mailer.rb +0 -16
- data/app/models/decidim/user.rb +2 -2
- data/app/packs/src/decidim/controllers/accordion/accordion.test.js +196 -42
- data/app/packs/src/decidim/controllers/accordion/controller.js +93 -17
- data/app/packs/src/decidim/controllers/dropdown/controller.js +6 -0
- data/app/packs/src/decidim/controllers/dropdown/dropdown.test.js +28 -0
- data/app/packs/src/decidim/controllers/main_menu/controller.js +37 -0
- data/app/packs/src/decidim/controllers/main_menu/main_menu.test.js +100 -0
- data/app/packs/src/decidim/controllers/mention/controller.js +296 -140
- data/app/packs/src/decidim/controllers/mention/input_mentions.test.js +120 -457
- data/app/packs/src/decidim/controllers/multiple_mentions/controller.js +68 -32
- data/app/packs/src/decidim/controllers/multiple_mentions/input_multiple_mentions.test.js +30 -23
- data/app/packs/src/decidim/controllers/password_toggler/controller.js +22 -1
- data/app/packs/src/decidim/controllers/password_toggler/password_toggler.test.js +11 -20
- data/app/packs/src/decidim/direct_uploads/upload_modal.js +2 -1
- data/app/packs/src/decidim/editor/common/suggestion.js +3 -1
- data/app/packs/src/decidim/editor/extensions/indent/index.js +9 -0
- data/app/packs/src/decidim/geocoding/reverse_geocoding.js +15 -5
- data/app/packs/src/decidim/geocoding/reverse_geocoding.test.js +197 -0
- data/app/packs/src/decidim/index.js +2 -2
- data/app/packs/src/decidim/map/controller.js +10 -1
- data/app/packs/src/decidim/refactor/moved/focus_guard.js +12 -12
- data/app/packs/src/decidim/refactor/moved/focus_guard.test.js +136 -0
- data/app/packs/stylesheets/decidim/_cards.scss +1 -1
- data/app/packs/stylesheets/decidim/_conversations.scss +14 -0
- data/app/packs/stylesheets/decidim/_cookies.scss +13 -5
- data/app/packs/stylesheets/decidim/_documents.scss +1 -1
- data/app/packs/stylesheets/decidim/_dropdown.scss +1 -1
- data/app/packs/stylesheets/decidim/_editor_suggestions.scss +49 -0
- data/app/packs/stylesheets/decidim/_footer.scss +33 -1
- data/app/packs/stylesheets/decidim/_header.scss +12 -8
- data/app/packs/stylesheets/decidim/_participatory_spaces.scss +1 -1
- data/app/packs/stylesheets/decidim/_tom_select.scss +23 -0
- data/app/packs/stylesheets/decidim/application.scss +2 -0
- data/app/packs/stylesheets/decidim/editor.scss +2 -33
- data/app/packs/stylesheets/decidim/geocoding_addons.scss +10 -2
- data/app/presenters/decidim/footer_menu_presenter.rb +2 -4
- data/app/resolvers/decidim/meta_image_url_resolver.rb +7 -0
- data/app/uploaders/decidim/image_uploader.rb +1 -1
- data/app/views/decidim/delete_user_mailer/delete.html.erb +6 -0
- data/app/views/decidim/messaging/conversations/_error_modal.html.erb +11 -19
- data/app/views/decidim/messaging/conversations/error.js.erb +12 -7
- data/app/views/decidim/searches/_filters.html.erb +1 -1
- data/app/views/layouts/decidim/footer/_main.html.erb +1 -1
- data/app/views/layouts/decidim/footer/_main_links.html.erb +56 -28
- data/app/views/layouts/decidim/header/_menu_breadcrumb_mobile.html.erb +2 -1
- data/config/locales/ar.yml +0 -2
- data/config/locales/bg.yml +0 -2
- data/config/locales/ca-IT.yml +27 -10
- data/config/locales/ca.yml +27 -10
- data/config/locales/cs.yml +26 -9
- data/config/locales/de.yml +4 -13
- data/config/locales/el.yml +0 -1
- data/config/locales/en.yml +26 -9
- data/config/locales/es-MX.yml +26 -9
- data/config/locales/es-PY.yml +26 -9
- data/config/locales/es.yml +26 -9
- data/config/locales/eu.yml +41 -10
- data/config/locales/fi-plain.yml +25 -8
- data/config/locales/fi.yml +25 -8
- data/config/locales/fr-CA.yml +30 -9
- data/config/locales/fr.yml +30 -9
- data/config/locales/hu.yml +0 -2
- data/config/locales/it.yml +0 -2
- data/config/locales/ja.yml +84 -19
- data/config/locales/lb.yml +0 -2
- data/config/locales/lt.yml +0 -2
- data/config/locales/nl.yml +0 -2
- data/config/locales/no.yml +0 -2
- data/config/locales/pl.yml +4 -4
- data/config/locales/pt-BR.yml +2 -11
- data/config/locales/pt.yml +0 -2
- data/config/locales/ro-RO.yml +1 -10
- data/config/locales/sk.yml +1 -10
- data/config/locales/sv.yml +0 -9
- data/config/locales/tr-TR.yml +0 -2
- data/config/locales/zh-CN.yml +0 -2
- data/config/locales/zh-TW.yml +0 -2
- data/db/migrate/20250217192438_convert_user_groups_into_users.rb +3 -2
- data/decidim-core.gemspec +4 -1
- data/lib/decidim/attachment_attributes.rb +58 -9
- data/lib/decidim/command.rb +1 -1
- data/lib/decidim/core/content_blocks/registry_manager.rb +4 -4
- data/lib/decidim/core/engine.rb +8 -0
- data/lib/decidim/core/test/factories.rb +3 -0
- data/lib/decidim/core/test/shared_examples/access_mode_restricted_participatory_spaces.rb +8 -5
- data/lib/decidim/core/test/shared_examples/access_mode_transparent_participatory_spaces.rb +14 -11
- data/lib/decidim/core/test/shared_examples/admin_resource_gallery_examples.rb +10 -10
- data/lib/decidim/core/test/shared_examples/comments_examples.rb +32 -6
- data/lib/decidim/core/version.rb +1 -1
- data/lib/decidim/core.rb +1 -1
- data/lib/decidim/map/autocomplete.rb +4 -3
- data/lib/decidim/map/dynamic_map.rb +3 -1
- data/lib/decidim/searchable.rb +5 -0
- data/lib/decidim/view_model.rb +1 -1
- data/lib/tasks/decidim_mailers_tasks.rake +31 -9
- metadata +31 -9
- data/app/commands/decidim/gallery_methods.rb +0 -107
- data/app/packs/src/decidim/vendor/tribute.js +0 -1890
- data/app/packs/stylesheets/decidim/_tribute.scss +0 -36
- data/app/views/decidim/participants_account_mailer/removal_notification.html.erb +0 -11
|
@@ -29,7 +29,16 @@ export default class MapController {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
load() {
|
|
32
|
-
|
|
32
|
+
const zoomControl = L.control.zoom({
|
|
33
|
+
zoomInTitle: this.config.zoomInText || "Zoom in",
|
|
34
|
+
zoomOutTitle: this.config.zoomOutText || "Zoom out"
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
this.map = L.map(this.mapId, {
|
|
38
|
+
zoomControl: false
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
this.map.addControl(zoomControl);
|
|
33
42
|
|
|
34
43
|
this.map.scrollWheelZoom.disable();
|
|
35
44
|
|
|
@@ -5,14 +5,12 @@ const focusableDisableableNodes = ["BUTTON", "INPUT", "TEXTAREA", "SELECT"];
|
|
|
5
5
|
export default class FocusGuard {
|
|
6
6
|
constructor(container) {
|
|
7
7
|
this.container = container;
|
|
8
|
-
this.
|
|
9
|
-
this.triggerElement = null;
|
|
8
|
+
this.stack = [];
|
|
10
9
|
}
|
|
11
10
|
|
|
12
11
|
trap(element, trigger) {
|
|
13
12
|
this.enable();
|
|
14
|
-
this.
|
|
15
|
-
this.triggerElement = trigger;
|
|
13
|
+
this.stack.push({ element, trigger });
|
|
16
14
|
}
|
|
17
15
|
|
|
18
16
|
enable() {
|
|
@@ -45,14 +43,15 @@ export default class FocusGuard {
|
|
|
45
43
|
}
|
|
46
44
|
|
|
47
45
|
disable() {
|
|
48
|
-
const
|
|
49
|
-
guards.forEach((guard) => guard.remove());
|
|
46
|
+
const current = this.stack.pop();
|
|
50
47
|
|
|
51
|
-
this.
|
|
48
|
+
if (this.stack.length === 0) {
|
|
49
|
+
const guards = this.container.querySelectorAll(`:scope > .${focusGuardClass}`);
|
|
50
|
+
guards.forEach((guard) => guard.remove());
|
|
51
|
+
}
|
|
52
52
|
|
|
53
|
-
if (
|
|
54
|
-
|
|
55
|
-
this.triggerElement = null;
|
|
53
|
+
if (current && current.trigger) {
|
|
54
|
+
current.trigger.focus();
|
|
56
55
|
}
|
|
57
56
|
}
|
|
58
57
|
|
|
@@ -67,12 +66,13 @@ export default class FocusGuard {
|
|
|
67
66
|
};
|
|
68
67
|
|
|
69
68
|
handleContainerFocus(guard) {
|
|
70
|
-
|
|
69
|
+
const current = this.stack[this.stack.length - 1];
|
|
70
|
+
if (!current || !current.element) {
|
|
71
71
|
guard.blur();
|
|
72
72
|
return;
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
const visibleNodes = Array.from(
|
|
75
|
+
const visibleNodes = Array.from(current.element.querySelectorAll("*")).filter((item) => {
|
|
76
76
|
return this.isVisible(item);
|
|
77
77
|
});
|
|
78
78
|
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/* global jest */
|
|
2
|
+
|
|
3
|
+
import FocusGuard from "src/decidim/refactor/moved/focus_guard"
|
|
4
|
+
|
|
5
|
+
describe("FocusGuard", () => {
|
|
6
|
+
let focusGuard = null;
|
|
7
|
+
|
|
8
|
+
beforeEach(() => {
|
|
9
|
+
document.body.innerHTML = "";
|
|
10
|
+
focusGuard = new FocusGuard(document.body);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
afterEach(() => {
|
|
14
|
+
document.body.innerHTML = "";
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
describe("single dialog", () => {
|
|
18
|
+
it("creates focus guards on trap", () => {
|
|
19
|
+
const dialog = document.createElement("div");
|
|
20
|
+
const trigger = document.createElement("button");
|
|
21
|
+
document.body.appendChild(dialog);
|
|
22
|
+
document.body.appendChild(trigger);
|
|
23
|
+
|
|
24
|
+
focusGuard.trap(dialog, trigger);
|
|
25
|
+
const guards = document.body.querySelectorAll(".focusguard");
|
|
26
|
+
expect(guards.length).toBe(2);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it("removes focus guards and returns focus on disable", () => {
|
|
30
|
+
const dialog = document.createElement("div");
|
|
31
|
+
const trigger = document.createElement("button");
|
|
32
|
+
document.body.appendChild(dialog);
|
|
33
|
+
document.body.appendChild(trigger);
|
|
34
|
+
|
|
35
|
+
focusGuard.trap(dialog, trigger);
|
|
36
|
+
focusGuard.disable();
|
|
37
|
+
|
|
38
|
+
const guards = document.body.querySelectorAll(".focusguard");
|
|
39
|
+
expect(guards.length).toBe(0);
|
|
40
|
+
expect(document.activeElement).toBe(trigger);
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
describe("nested dialogs", () => {
|
|
45
|
+
it("keeps guards when inner dialog is disabled", () => {
|
|
46
|
+
const outerDialog = document.createElement("div");
|
|
47
|
+
const outerTrigger = document.createElement("button");
|
|
48
|
+
const innerDialog = document.createElement("div");
|
|
49
|
+
const innerTrigger = document.createElement("button");
|
|
50
|
+
|
|
51
|
+
document.body.appendChild(outerDialog);
|
|
52
|
+
document.body.appendChild(outerTrigger);
|
|
53
|
+
document.body.appendChild(innerDialog);
|
|
54
|
+
document.body.appendChild(innerTrigger);
|
|
55
|
+
|
|
56
|
+
focusGuard.trap(outerDialog, outerTrigger);
|
|
57
|
+
focusGuard.trap(innerDialog, innerTrigger);
|
|
58
|
+
|
|
59
|
+
expect(document.body.querySelectorAll(".focusguard").length).toBe(2);
|
|
60
|
+
|
|
61
|
+
focusGuard.disable();
|
|
62
|
+
|
|
63
|
+
expect(document.body.querySelectorAll(".focusguard").length).toBe(2);
|
|
64
|
+
expect(document.activeElement).toBe(innerTrigger);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it("removes guards when outer dialog is disabled last", () => {
|
|
68
|
+
const outerDialog = document.createElement("div");
|
|
69
|
+
const outerTrigger = document.createElement("button");
|
|
70
|
+
const innerDialog = document.createElement("div");
|
|
71
|
+
const innerTrigger = document.createElement("button");
|
|
72
|
+
|
|
73
|
+
document.body.appendChild(outerDialog);
|
|
74
|
+
document.body.appendChild(outerTrigger);
|
|
75
|
+
document.body.appendChild(innerDialog);
|
|
76
|
+
document.body.appendChild(innerTrigger);
|
|
77
|
+
|
|
78
|
+
focusGuard.trap(outerDialog, outerTrigger);
|
|
79
|
+
focusGuard.trap(innerDialog, innerTrigger);
|
|
80
|
+
|
|
81
|
+
focusGuard.disable();
|
|
82
|
+
focusGuard.disable();
|
|
83
|
+
|
|
84
|
+
expect(document.body.querySelectorAll(".focusguard").length).toBe(0);
|
|
85
|
+
expect(document.activeElement).toBe(outerTrigger);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it("cycles focus to the current top dialog when a guard receives focus", () => {
|
|
89
|
+
jest.spyOn(focusGuard, "isVisible").mockReturnValue(true);
|
|
90
|
+
|
|
91
|
+
const outerDialog = document.createElement("div");
|
|
92
|
+
const outerInput = document.createElement("input");
|
|
93
|
+
outerDialog.appendChild(outerInput);
|
|
94
|
+
|
|
95
|
+
const innerDialog = document.createElement("div");
|
|
96
|
+
const innerInput = document.createElement("input");
|
|
97
|
+
innerDialog.appendChild(innerInput);
|
|
98
|
+
|
|
99
|
+
document.body.appendChild(outerDialog);
|
|
100
|
+
document.body.appendChild(innerDialog);
|
|
101
|
+
|
|
102
|
+
focusGuard.trap(outerDialog, null);
|
|
103
|
+
focusGuard.trap(innerDialog, null);
|
|
104
|
+
|
|
105
|
+
const endGuard = document.body.querySelector('.focusguard[data-position="end"]');
|
|
106
|
+
endGuard.focus();
|
|
107
|
+
|
|
108
|
+
expect(document.activeElement).toBe(innerInput);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it("cycles focus backward to the current top dialog when the start guard receives focus", () => {
|
|
112
|
+
jest.spyOn(focusGuard, "isVisible").mockReturnValue(true);
|
|
113
|
+
|
|
114
|
+
const outerDialog = document.createElement("div");
|
|
115
|
+
const outerInput = document.createElement("input");
|
|
116
|
+
outerDialog.appendChild(outerInput);
|
|
117
|
+
|
|
118
|
+
const innerDialog = document.createElement("div");
|
|
119
|
+
const innerInput = document.createElement("input");
|
|
120
|
+
const innerButton = document.createElement("button");
|
|
121
|
+
innerDialog.appendChild(innerInput);
|
|
122
|
+
innerDialog.appendChild(innerButton);
|
|
123
|
+
|
|
124
|
+
document.body.appendChild(outerDialog);
|
|
125
|
+
document.body.appendChild(innerDialog);
|
|
126
|
+
|
|
127
|
+
focusGuard.trap(outerDialog, null);
|
|
128
|
+
focusGuard.trap(innerDialog, null);
|
|
129
|
+
|
|
130
|
+
const startGuard = document.body.querySelector('.focusguard[data-position="start"]');
|
|
131
|
+
startGuard.focus();
|
|
132
|
+
|
|
133
|
+
expect(document.activeElement).toBe(innerButton);
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
});
|
|
@@ -88,6 +88,20 @@
|
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
&__modal {
|
|
91
|
+
&-error {
|
|
92
|
+
[data-dialog-closable] {
|
|
93
|
+
@apply top-6 right-6;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
[data-dialog-container] {
|
|
97
|
+
@apply inline grid-cols-none;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
[data-dialog-title] {
|
|
101
|
+
@apply col-span-2 md:col-span-1 md:col-start-2 grid grid-cols-[auto_1fr] items-start md:items-center gap-2 pb-4 text-left text-xl text-gray-2 md:border-b md:border-gray-3;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
91
105
|
&-results {
|
|
92
106
|
@apply mb-20 flex flex-wrap gap-x-8 gap-y-4;
|
|
93
107
|
}
|
|
@@ -65,17 +65,25 @@
|
|
|
65
65
|
&-panel {
|
|
66
66
|
@apply divide-y divide-gray-3 [&>*]:py-4 [&>p]:text-gray-2;
|
|
67
67
|
|
|
68
|
-
|
|
69
|
-
@apply
|
|
68
|
+
table {
|
|
69
|
+
@apply w-full border-collapse;
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
|
|
73
|
-
@apply
|
|
72
|
+
thead tr {
|
|
73
|
+
@apply bg-background-4;
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
|
|
76
|
+
th {
|
|
77
|
+
@apply w-1/4 p-2 text-gray-2 font-bold text-sm text-left;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
td {
|
|
77
81
|
@apply w-1/4 p-2 text-gray-2 text-xs;
|
|
78
82
|
}
|
|
83
|
+
|
|
84
|
+
tbody tr {
|
|
85
|
+
@apply border-b border-gray-3;
|
|
86
|
+
}
|
|
79
87
|
}
|
|
80
88
|
|
|
81
89
|
&-toggle {
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
.editor-suggestions-props {
|
|
2
|
+
--editor-suggestions-border-color: #000;
|
|
3
|
+
--editor-suggestions-background-color: #eee;
|
|
4
|
+
--editor-suggestions-selected-highlight-color: #ccc;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.editor-suggestions {
|
|
8
|
+
@apply editor-suggestions-props border-0 bg-[var(--editor-suggestions-background-color)] max-w-sm drop-shadow-md rounded-md;
|
|
9
|
+
|
|
10
|
+
&:hover {
|
|
11
|
+
.editor-suggestions-item[data-selected]:not(:hover) {
|
|
12
|
+
@apply bg-transparent;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.editor-suggestions-item {
|
|
17
|
+
@apply flex items-center gap-2 w-full text-left py-[0.375rem] px-1.5 border-0 rounded-none text-sm;
|
|
18
|
+
|
|
19
|
+
&:first-child {
|
|
20
|
+
@apply rounded-t-md;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
&:last-child {
|
|
24
|
+
@apply rounded-b-md;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
&:hover,
|
|
28
|
+
&[data-selected] {
|
|
29
|
+
@apply bg-[var(--editor-suggestions-selected-highlight-color)];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.editor-suggestions-item-avatar {
|
|
33
|
+
@apply rounded-full w-6 h-6 object-cover flex-none;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.editor-suggestions-item-label {
|
|
37
|
+
@apply truncate;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.editor-suggestions-item-disabled {
|
|
42
|
+
@apply cursor-default;
|
|
43
|
+
|
|
44
|
+
&:hover,
|
|
45
|
+
&[data-selected] {
|
|
46
|
+
@apply bg-transparent;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -3,12 +3,44 @@ footer {
|
|
|
3
3
|
@apply bg-gray-4;
|
|
4
4
|
|
|
5
5
|
&__top {
|
|
6
|
-
@apply
|
|
6
|
+
@apply flex flex-col lg:flex-row gap-0 lg:gap-8 container py-10;
|
|
7
7
|
|
|
8
8
|
.prose a,
|
|
9
9
|
.prose strong {
|
|
10
10
|
@apply text-white;
|
|
11
11
|
}
|
|
12
|
+
|
|
13
|
+
.footer__nav {
|
|
14
|
+
@apply border-b border-white/20 lg:border-0;
|
|
15
|
+
|
|
16
|
+
ul {
|
|
17
|
+
@apply space-y-4 break-inside-avoid mb-4;
|
|
18
|
+
|
|
19
|
+
li a {
|
|
20
|
+
@apply font-semibold underline decoration-1 underline-offset-1;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
> [data-controls] {
|
|
25
|
+
@apply flex items-center justify-between w-full py-4 lg:pointer-events-none lg:cursor-default text-left text-white font-semibold;
|
|
26
|
+
|
|
27
|
+
svg {
|
|
28
|
+
@apply w-4 h-4 fill-current transition-transform lg:hidden;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
&[aria-expanded="true"] svg {
|
|
32
|
+
@apply rotate-180;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
[id*="panel"][aria-hidden="true"] {
|
|
37
|
+
@apply hidden lg:block;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
[id*="panel"][aria-hidden="false"] {
|
|
41
|
+
@apply block;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
12
44
|
}
|
|
13
45
|
|
|
14
46
|
&__down {
|
|
@@ -248,6 +248,10 @@ header {
|
|
|
248
248
|
.account-container {
|
|
249
249
|
@apply before:block before:absolute before:top-16 before:right-14 before:content-[""] before:bg-white before:w-2 before:h-12 before:-mt-8;
|
|
250
250
|
}
|
|
251
|
+
|
|
252
|
+
#dropdown-trigger-links-mobile-close {
|
|
253
|
+
@apply relative z-10;
|
|
254
|
+
}
|
|
251
255
|
}
|
|
252
256
|
|
|
253
257
|
&__item {
|
|
@@ -337,12 +341,8 @@ header {
|
|
|
337
341
|
@apply min-w-0;
|
|
338
342
|
}
|
|
339
343
|
|
|
340
|
-
.no-interactive {
|
|
341
|
-
@apply font-normal px-0 min-w-0;
|
|
342
|
-
}
|
|
343
|
-
|
|
344
344
|
&__dropdown-trigger {
|
|
345
|
-
@apply flex flex-none rounded py-1 z-20 font-semibold;
|
|
345
|
+
@apply flex flex-none rounded px-2 py-1 z-20 font-semibold focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-inset;
|
|
346
346
|
|
|
347
347
|
&--truncatable {
|
|
348
348
|
@apply min-w-0 overflow-hidden;
|
|
@@ -357,6 +357,10 @@ header {
|
|
|
357
357
|
}
|
|
358
358
|
}
|
|
359
359
|
|
|
360
|
+
.no-interactive {
|
|
361
|
+
@apply font-normal px-0 min-w-0;
|
|
362
|
+
}
|
|
363
|
+
|
|
360
364
|
&__dropdown-wrapper {
|
|
361
365
|
@apply flex flex-none items-center cursor-pointer underline;
|
|
362
366
|
}
|
|
@@ -449,15 +453,15 @@ header {
|
|
|
449
453
|
}
|
|
450
454
|
|
|
451
455
|
&__label-wrapper {
|
|
452
|
-
@apply block min-w-0 flex-1
|
|
456
|
+
@apply block min-w-0 flex-1;
|
|
453
457
|
}
|
|
454
458
|
|
|
455
459
|
&__label {
|
|
456
|
-
@apply flex w-
|
|
460
|
+
@apply flex w-11/12 items-center gap-x-2 min-w-0;
|
|
457
461
|
}
|
|
458
462
|
|
|
459
463
|
.menu-bar__breadcrumb-item {
|
|
460
|
-
@apply
|
|
464
|
+
@apply flex flex-1 min-w-0 items-center gap-x-1 whitespace-nowrap font-semibold underline focus:outline focus:outline-2 focus:outline-offset-2 rounded-sm;
|
|
461
465
|
}
|
|
462
466
|
|
|
463
467
|
/* overwrite default dropdown styles */
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
@use "tom-select/dist/scss/tom-select";
|
|
2
|
+
|
|
3
|
+
.ts {
|
|
4
|
+
&-control {
|
|
5
|
+
@apply border-gray text-md min-h-[40px];
|
|
6
|
+
|
|
7
|
+
input {
|
|
8
|
+
@apply font-normal text-black text-md;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
&-dropdown {
|
|
13
|
+
@apply text-md text-gray-2 font-normal;
|
|
14
|
+
|
|
15
|
+
.option img {
|
|
16
|
+
@apply inline;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.active {
|
|
20
|
+
@apply bg-gray-3;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
// Datepicker
|
|
7
7
|
@use "stylesheets/decidim/vendor/datepicker_light";
|
|
8
8
|
@use "stylesheets/decidim/datepicker";
|
|
9
|
+
// TomSelect
|
|
10
|
+
@use "stylesheets/decidim/tom_select";
|
|
9
11
|
// On the other hand, the following styles match with specific routes
|
|
10
12
|
@use "stylesheets/decidim/header";
|
|
11
13
|
@use "stylesheets/decidim/footer";
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
@use "stylesheets/decidim/editor_suggestions";
|
|
2
|
+
|
|
1
3
|
.editor-props {
|
|
2
4
|
--editor-active-color: #487bda;
|
|
3
5
|
--editor-disabled-color: #eee;
|
|
@@ -5,12 +7,6 @@
|
|
|
5
7
|
--editor-bubble-shadow-color: #333;
|
|
6
8
|
}
|
|
7
9
|
|
|
8
|
-
.editor-suggestions-props {
|
|
9
|
-
--editor-suggestions-border-color: #000;
|
|
10
|
-
--editor-suggestions-background-color: #eee;
|
|
11
|
-
--editor-suggestions-selected-highlight-color: #ccc;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
10
|
.editor-active {
|
|
15
11
|
@apply outline outline-4 outline-[var(--editor-active-color)];
|
|
16
12
|
}
|
|
@@ -186,30 +182,3 @@
|
|
|
186
182
|
}
|
|
187
183
|
}
|
|
188
184
|
}
|
|
189
|
-
|
|
190
|
-
.editor-suggestions {
|
|
191
|
-
@apply editor-suggestions-props border-0 bg-[var(--editor-suggestions-background-color)] max-w-sm drop-shadow-md rounded-md;
|
|
192
|
-
|
|
193
|
-
&:hover {
|
|
194
|
-
.editor-suggestions-item[data-selected]:not(:hover) {
|
|
195
|
-
@apply bg-transparent;
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
.editor-suggestions-item {
|
|
200
|
-
@apply block w-full text-left py-[0.375rem] px-1.5 border-0 rounded-none truncate text-sm;
|
|
201
|
-
|
|
202
|
-
&:first-child {
|
|
203
|
-
@apply rounded-t-md;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
&:last-child {
|
|
207
|
-
@apply rounded-b-md;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
&:hover,
|
|
211
|
-
&[data-selected] {
|
|
212
|
-
@apply bg-[var(--editor-suggestions-selected-highlight-color)];
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
}
|
|
@@ -1,5 +1,13 @@
|
|
|
1
|
-
.geocoding
|
|
2
|
-
.
|
|
1
|
+
.geocoding {
|
|
2
|
+
&__locate .geocoding__button {
|
|
3
3
|
@apply mt-4;
|
|
4
|
+
|
|
5
|
+
&--locating {
|
|
6
|
+
@apply opacity-70 cursor-wait;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.geocoding__spinner {
|
|
10
|
+
@apply inline-block w-4 h-4 rounded-full animate-spin border-2 border-l-transparent border-y-transparent border-r-secondary align-middle;
|
|
11
|
+
}
|
|
4
12
|
}
|
|
5
13
|
}
|
|
@@ -3,10 +3,8 @@
|
|
|
3
3
|
module Decidim
|
|
4
4
|
# A presenter to render footer menu
|
|
5
5
|
class FooterMenuPresenter < MenuPresenter
|
|
6
|
-
def
|
|
7
|
-
|
|
8
|
-
safe_join([content_tag(:h2, @options[:label], class: "h5 mb-4"), render_menu])
|
|
9
|
-
end
|
|
6
|
+
def render_menu_items
|
|
7
|
+
render_menu
|
|
10
8
|
end
|
|
11
9
|
end
|
|
12
10
|
end
|
|
@@ -79,6 +79,9 @@ module Decidim
|
|
|
79
79
|
image_url = image_element["src"]
|
|
80
80
|
next if image_url.blank?
|
|
81
81
|
|
|
82
|
+
blob = find_blob_by_id(image_url.split("/").last)
|
|
83
|
+
return blob if blob.present?
|
|
84
|
+
|
|
82
85
|
blob = find_blob_by_key(image_url.split("/").second_to_last)
|
|
83
86
|
return blob if blob.present?
|
|
84
87
|
end
|
|
@@ -120,6 +123,10 @@ module Decidim
|
|
|
120
123
|
ActiveStorage::Blob.find_signed(blob_key) if blob_key.present?
|
|
121
124
|
end
|
|
122
125
|
|
|
126
|
+
def find_blob_by_id(blob_id)
|
|
127
|
+
ActiveStorage::Blob.find_by(id: blob_id) if blob_id.present?
|
|
128
|
+
end
|
|
129
|
+
|
|
123
130
|
def blob_from_attached_file(file)
|
|
124
131
|
return unless file.respond_to?(:attached?) && file.attached?
|
|
125
132
|
|
|
@@ -8,7 +8,7 @@ module Decidim
|
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def content_type_allowlist
|
|
11
|
-
extension_allowlist.
|
|
11
|
+
extension_allowlist.filter_map { |ext| MiniMime.lookup_by_extension(ext)&.content_type }.uniq
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
# Fetches info about different variants, their processors and dimensions
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<p class="email-greeting"><%= t(".hello", username: @user_name) %></p>
|
|
2
|
+
|
|
3
|
+
<p class="email-instructions"><%= t ".body_1" %></p>
|
|
4
|
+
<p class="email-instructions"><%= t ".body_2" %></p>
|
|
5
|
+
|
|
6
|
+
<p class="email-closing"><%= t(".greetings_html", organization_name: organization_name(@organization), organization_url: decidim.root_url(host: @organization.host)) %></p>
|
|
@@ -1,21 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
<div>
|
|
3
|
-
<h2><%= error %></h2>
|
|
4
|
-
<
|
|
5
|
-
|
|
6
|
-
<
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
<p>
|
|
12
|
-
<%= messages.join("<br>") %>
|
|
13
|
-
</p>
|
|
14
|
-
<p><%= t(".correct_errors") %></p>
|
|
15
|
-
</div>
|
|
16
|
-
<div>
|
|
17
|
-
<div>
|
|
18
|
-
<a class="button" role="button" href="#" data-close aria-label="<%= t(".ok") %>"><%= t(".ok") %></a>
|
|
1
|
+
<%= decidim_modal id: "messageErrorModal", class: "conversation__modal-error" do %>
|
|
2
|
+
<div data-dialog-container>
|
|
3
|
+
<h2 id="dialog-title-messageErrorModal" tabindex="-1" data-dialog-title><%= error %></h2>
|
|
4
|
+
<div id="dialog-desc-messageErrorModal" class="mt-4">
|
|
5
|
+
<p><%= t(".intro") %></p>
|
|
6
|
+
<p><%= safe_join(messages, tag.br) %></p>
|
|
7
|
+
<p><%= t(".correct_errors") %></p>
|
|
8
|
+
</div>
|
|
9
|
+
<div data-dialog-actions>
|
|
10
|
+
<button type="button" class="button button__sm lg:button__lg button__secondary" data-dialog-close="messageErrorModal" aria-label="<%= t(".ok") %>"><%= t(".ok") %></button>
|
|
19
11
|
</div>
|
|
20
12
|
</div>
|
|
21
|
-
|
|
13
|
+
<% end %>
|
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
var
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
var messageError = document.getElementById("messageErrorModal")
|
|
2
|
+
|
|
3
|
+
if (messageError) {
|
|
4
|
+
messageError.remove();
|
|
4
5
|
}
|
|
6
|
+
document.body.insertAdjacentHTML("beforeend", "<%= j(render "error_modal", error:, messages:).html_safe %>");
|
|
5
7
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
+
messageError = document.getElementById("messageErrorModal")
|
|
9
|
+
if (messageError) {
|
|
10
|
+
window.createDialog(messageError);
|
|
8
11
|
|
|
9
|
-
|
|
10
|
-
|
|
12
|
+
if (Decidim.currentDialogs.messageErrorModal) {
|
|
13
|
+
window.Decidim.currentDialogs.messageErrorModal.open();
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
</button>
|
|
17
17
|
<% end %>
|
|
18
18
|
</div>
|
|
19
|
-
<button id="dropdown-trigger-search" data-controller="dropdown" data-target="dropdown-menu-search" data-auto-close="true"
|
|
19
|
+
<button id="dropdown-trigger-search" data-controller="dropdown" data-target="dropdown-menu-search" data-auto-close="true">
|
|
20
20
|
<%= content_tag :span, t("decidim.searches.filters_small_view.filter_by"), class: "#{"is-active" if params.dig(:filter, :with_resource_type) == nil}" %>
|
|
21
21
|
<% @blocks.each do |elements| %>
|
|
22
22
|
<% elements.each do |type, results| %>
|