decidim-admin 0.30.1 → 0.31.0.rc1
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/commands/decidim/admin/update_organization.rb +18 -3
- data/app/controllers/concerns/decidim/admin/content_blocks/landing_page_content_blocks.rb +1 -1
- data/app/controllers/concerns/decidim/admin/filterable.rb +1 -1
- data/app/controllers/decidim/admin/area_types_controller.rb +2 -2
- data/app/controllers/decidim/admin/areas_controller.rb +2 -2
- data/app/controllers/decidim/admin/block_user_controller.rb +2 -2
- data/app/controllers/decidim/admin/component_permissions_controller.rb +1 -1
- data/app/controllers/decidim/admin/components_controller.rb +2 -2
- data/app/controllers/decidim/admin/concerns/has_attachment_collections.rb +2 -2
- data/app/controllers/decidim/admin/concerns/has_attachments.rb +2 -2
- data/app/controllers/decidim/admin/concerns/has_private_users.rb +3 -3
- data/app/controllers/decidim/admin/concerns/has_private_users_csv_import.rb +1 -1
- data/app/controllers/decidim/admin/conflicts_controller.rb +1 -1
- data/app/controllers/decidim/admin/dashboard_controller.rb +0 -9
- data/app/controllers/decidim/admin/impersonations_controller.rb +1 -1
- data/app/controllers/decidim/admin/imports_controller.rb +1 -1
- data/app/controllers/decidim/admin/managed_users/promotions_controller.rb +1 -1
- data/app/controllers/decidim/admin/newsletters_controller.rb +4 -4
- data/app/controllers/decidim/admin/organization_appearance_controller.rb +1 -3
- data/app/controllers/decidim/admin/organization_controller.rb +3 -5
- data/app/controllers/decidim/admin/organization_external_domain_allowlist_controller.rb +1 -1
- data/app/controllers/decidim/admin/organization_homepage_controller.rb +4 -0
- data/app/controllers/decidim/admin/participatory_space/user_role_controller.rb +2 -2
- data/app/controllers/decidim/admin/reminders_controller.rb +1 -1
- data/app/controllers/decidim/admin/resource_permissions_controller.rb +1 -1
- data/app/controllers/decidim/admin/scope_types_controller.rb +2 -2
- data/app/controllers/decidim/admin/scopes_controller.rb +2 -2
- data/app/controllers/decidim/admin/share_tokens_controller.rb +8 -8
- data/app/controllers/decidim/admin/static_page_topics_controller.rb +2 -2
- data/app/controllers/decidim/admin/static_pages_controller.rb +2 -2
- data/app/controllers/decidim/admin/statistics_controller.rb +34 -0
- data/app/controllers/decidim/admin/taxonomies_controller.rb +2 -2
- data/app/controllers/decidim/admin/taxonomy_filters_controller.rb +2 -2
- data/app/controllers/decidim/admin/taxonomy_items_controller.rb +2 -2
- data/app/controllers/decidim/admin/users_controller.rb +1 -1
- data/app/forms/decidim/admin/block_user_form.rb +1 -1
- data/app/forms/decidim/admin/block_users_form.rb +1 -1
- data/app/forms/decidim/admin/organization_form.rb +35 -6
- data/app/helpers/decidim/admin/filterable_helper.rb +27 -8
- data/app/helpers/decidim/admin/icon_link_helper.rb +2 -3
- data/app/helpers/decidim/admin/icon_with_tooltip_helper.rb +1 -2
- data/app/helpers/decidim/admin/imports_helper.rb +0 -5
- data/app/helpers/decidim/admin/menu_helper.rb +3 -2
- data/app/helpers/decidim/admin/moderations/reports_helper.rb +1 -1
- data/app/helpers/decidim/admin/resource_permissions_helper.rb +13 -13
- data/app/helpers/decidim/admin/settings_helper.rb +11 -3
- data/app/jobs/decidim/admin/newsletter_job.rb +1 -0
- data/app/packs/entrypoints/decidim_admin.js +2 -3
- data/app/packs/entrypoints/decidim_admin.scss +1 -1
- data/app/packs/entrypoints/decidim_admin_overrides.scss +1 -1
- data/app/packs/src/decidim/admin/admin_autocomplete.js +2 -2
- data/app/packs/src/decidim/admin/application.js +11 -10
- data/app/packs/src/decidim/admin/budget_rule_toggler.component.js +84 -34
- data/app/packs/src/decidim/admin/controllers/slug/controller.js +25 -0
- data/app/packs/src/decidim/admin/controllers/slug/slug.test.js +239 -0
- data/app/packs/src/decidim/admin/css_preview.js +1 -1
- data/app/packs/src/decidim/admin/draggable-list.js +1 -1
- data/app/packs/src/decidim/admin/draggable-table.js +1 -1
- data/app/packs/src/decidim/admin/dynamic_fields.component.js +13 -12
- data/app/packs/src/decidim/admin/external_domain_allowlist.js +1 -1
- data/app/packs/src/decidim/admin/form.js +21 -4
- data/app/packs/src/decidim/admin/global_moderations.js +2 -2
- data/app/packs/src/decidim/admin/managed_moderated_users.js +2 -2
- data/app/packs/src/decidim/admin/moderations.js +1 -1
- data/app/packs/src/decidim/admin/newsletters.js +1 -1
- data/app/packs/src/decidim/admin/officializations.js +1 -1
- data/app/packs/src/decidim/admin/participatory_space_search.js +2 -2
- data/app/packs/src/decidim/admin/proposal_infinite_edit.js +1 -1
- data/app/packs/src/decidim/admin/resources_permissions.js +1 -1
- data/app/packs/src/decidim/admin/sortable.js +1 -1
- data/app/packs/src/decidim/admin/sync_radio_buttons.js +1 -1
- data/app/packs/src/decidim/admin/tab_focus.js +1 -1
- data/app/packs/src/decidim/admin/text_copy.js +1 -1
- data/app/packs/src/decidim/admin/triadic_color_picker.js +1 -1
- data/app/packs/stylesheets/decidim/admin/_datepicker.scss +2 -2
- data/app/packs/stylesheets/decidim/admin/_dropdown.scss +12 -2
- data/app/packs/stylesheets/decidim/admin/_filters.scss +1 -57
- data/app/packs/stylesheets/decidim/admin/_forms.scss +1 -10
- data/app/packs/stylesheets/decidim/admin/_item_edit.scss +2 -10
- data/app/packs/stylesheets/decidim/admin/_item_show.scss +1 -5
- data/app/packs/stylesheets/decidim/admin/_legacy_foundation.scss +0 -412
- data/app/packs/stylesheets/decidim/admin/_main-nav.scss +75 -3
- data/app/packs/stylesheets/decidim/admin/_secondary-nav.scss +6 -10
- data/app/packs/stylesheets/decidim/admin/_select_picker.scss +1 -1
- data/app/packs/stylesheets/decidim/admin/_sidebar-menu.scss +2 -2
- data/app/packs/stylesheets/decidim/admin/_table-list.scss +25 -7
- data/app/packs/stylesheets/decidim/admin/_tabs.scss +4 -0
- data/app/packs/stylesheets/decidim/admin/_taxonomies.scss +6 -2
- data/app/packs/stylesheets/decidim/admin/application.scss +28 -29
- data/app/permissions/decidim/admin/permissions.rb +17 -5
- data/app/presenters/decidim/admin/dashboard_statistic_charts_presenter.rb +18 -0
- data/app/queries/decidim/admin/user_filter.rb +3 -3
- data/app/views/decidim/admin/area_types/index.html.erb +34 -11
- data/app/views/decidim/admin/areas/index.html.erb +32 -12
- data/app/views/decidim/admin/attachment_collections/index.html.erb +42 -14
- data/app/views/decidim/admin/attachments/index.html.erb +32 -13
- data/app/views/decidim/admin/block_user/bulk_new.html.erb +1 -1
- data/app/views/decidim/admin/block_user/new.html.erb +1 -1
- data/app/views/decidim/admin/components/_actions.html.erb +114 -54
- data/app/views/decidim/admin/components/_component_row.html.erb +5 -5
- data/app/views/decidim/admin/components/_components_table.html.erb +1 -1
- data/app/views/decidim/admin/components/_form.html.erb +4 -4
- data/app/views/decidim/admin/components/index.html.erb +12 -13
- data/app/views/decidim/admin/dashboard/show.html.erb +9 -21
- data/app/views/decidim/admin/exports/_dropdown.html.erb +16 -14
- data/app/views/decidim/admin/help_sections/_form.html.erb +1 -1
- data/app/views/decidim/admin/impersonatable_users/index.html.erb +68 -33
- data/app/views/decidim/admin/imports/_dropdown.html.erb +13 -11
- data/app/views/decidim/admin/imports/new.html.erb +13 -12
- data/app/views/decidim/admin/moderated_users/bulk_actions/_dropdown.html.erb +29 -32
- data/app/views/decidim/admin/moderated_users/index.html.erb +61 -21
- data/app/views/decidim/admin/moderations/_moderation-tr.html.erb +87 -32
- data/app/views/decidim/admin/moderations/_report.html.erb +2 -4
- data/app/views/decidim/admin/moderations/bulk_actions/_dropdown.html.erb +30 -34
- data/app/views/decidim/admin/moderations/index.html.erb +1 -1
- data/app/views/decidim/admin/moderations/reports/index.html.erb +1 -2
- data/app/views/decidim/admin/newsletters/index.html.erb +64 -21
- data/app/views/decidim/admin/officializations/index.html.erb +91 -32
- data/app/views/decidim/admin/organization/_form.html.erb +6 -92
- data/app/views/decidim/admin/organization/edit.html.erb +1 -5
- data/app/views/decidim/admin/organization/form/_admin_terms_of_service.html.erb +15 -0
- data/app/views/decidim/admin/organization/form/_basic_configuration.html.erb +31 -0
- data/app/views/decidim/admin/{organization_appearance → organization}/form/_colors.html.erb +9 -9
- data/app/views/decidim/admin/organization/form/_extra_features.html.erb +84 -0
- data/app/views/decidim/admin/{organization_appearance/form/_images.html.erb → organization/form/_logos.html.erb} +4 -4
- data/app/views/decidim/admin/organization/form/_welcome_notification.html.erb +25 -0
- data/app/views/decidim/admin/organization_external_domain_allowlist/_external_domain.html.erb +8 -6
- data/app/views/decidim/admin/participatory_space_private_users/index.html.erb +49 -22
- data/app/views/decidim/admin/resource_permissions/edit.html.erb +1 -1
- data/app/views/decidim/admin/scope_types/index.html.erb +31 -12
- data/app/views/decidim/admin/scopes/index.html.erb +40 -13
- data/app/views/decidim/admin/share_tokens/_form.html.erb +1 -1
- data/app/views/decidim/admin/share_tokens/edit.html.erb +1 -1
- data/app/views/decidim/admin/share_tokens/index.html.erb +69 -12
- data/app/views/decidim/admin/share_tokens/new.html.erb +1 -1
- data/app/views/decidim/admin/shared/_filters.html.erb +8 -10
- data/app/views/decidim/admin/shared/landing_page/_content_blocks.html.erb +14 -11
- data/app/views/decidim/admin/shared/landing_page_content_blocks/edit.html.erb +2 -4
- data/app/views/decidim/admin/static_page_topics/index.html.erb +31 -10
- data/app/views/decidim/admin/static_pages/_form.html.erb +1 -1
- data/app/views/decidim/admin/static_pages/_topic.html.erb +46 -16
- data/app/views/decidim/admin/statistics/_statistics.html.erb +13 -0
- data/app/views/decidim/admin/statistics/index.html.erb +6 -0
- data/app/views/decidim/admin/taxonomies/_form.html.erb +1 -1
- data/app/views/decidim/admin/taxonomies/_row.html.erb +24 -6
- data/app/views/decidim/admin/taxonomies/_table.html.erb +2 -2
- data/app/views/decidim/admin/taxonomies/_taxonomy_actions.html.erb +48 -15
- data/app/views/decidim/admin/taxonomies/edit.html.erb +10 -0
- data/app/views/decidim/admin/taxonomy_filters/_form.html.erb +1 -1
- data/app/views/decidim/admin/taxonomy_filters/_table.html.erb +52 -15
- data/app/views/decidim/admin/taxonomy_filters/new.html.erb +1 -1
- data/app/views/decidim/admin/taxonomy_filters_selector/_component_table.html.erb +38 -23
- data/app/views/decidim/admin/taxonomy_items/_form.html.erb +1 -1
- data/app/views/decidim/admin/users/index.html.erb +48 -24
- data/app/views/layouts/decidim/admin/_application.html.erb +3 -6
- data/app/views/layouts/decidim/admin/_header.html.erb +3 -1
- data/app/views/layouts/decidim/admin/_js_configuration.html.erb +11 -12
- data/app/views/layouts/decidim/admin/_sidebar_menu.html.erb +1 -1
- data/app/views/layouts/decidim/admin/_title_bar.html.erb +4 -4
- data/app/views/layouts/decidim/admin/_title_bar_responsive.html.erb +4 -4
- data/app/views/layouts/decidim/admin/insights.html.erb +6 -0
- data/config/assets.rb +2 -2
- data/config/locales/ar.yml +2 -86
- data/config/locales/bg.yml +4 -105
- data/config/locales/bs-BA.yml +0 -44
- data/config/locales/ca-IT.yml +59 -117
- data/config/locales/ca.yml +59 -117
- data/config/locales/cs.yml +51 -119
- data/config/locales/de.yml +63 -121
- data/config/locales/el.yml +5 -97
- data/config/locales/en.yml +61 -119
- data/config/locales/eo.yml +0 -4
- data/config/locales/es-MX.yml +60 -118
- data/config/locales/es-PY.yml +60 -118
- data/config/locales/es.yml +60 -118
- data/config/locales/eu.yml +65 -123
- data/config/locales/fi-plain.yml +62 -109
- data/config/locales/fi.yml +62 -109
- data/config/locales/fr-CA.yml +69 -120
- data/config/locales/fr.yml +69 -120
- data/config/locales/ga-IE.yml +4 -28
- data/config/locales/gl.yml +3 -89
- data/config/locales/he-IL.yml +0 -8
- data/config/locales/hu.yml +5 -100
- data/config/locales/id-ID.yml +0 -58
- data/config/locales/is-IS.yml +1 -36
- data/config/locales/it.yml +202 -96
- data/config/locales/ja.yml +61 -110
- data/config/locales/kaa.yml +0 -12
- data/config/locales/ko.yml +0 -76
- data/config/locales/lb.yml +5 -89
- data/config/locales/lt.yml +4 -99
- data/config/locales/lv.yml +2 -70
- data/config/locales/nl.yml +5 -90
- data/config/locales/no.yml +5 -89
- data/config/locales/pl.yml +5 -103
- data/config/locales/pt-BR.yml +130 -105
- data/config/locales/pt.yml +2 -90
- data/config/locales/ro-RO.yml +13 -97
- data/config/locales/ru.yml +2 -50
- data/config/locales/sk.yml +2 -68
- data/config/locales/sl.yml +1 -18
- data/config/locales/sq-AL.yml +0 -43
- data/config/locales/sr-CS.yml +1 -44
- data/config/locales/sv.yml +59 -120
- data/config/locales/th-TH.yml +0 -5
- data/config/locales/tr-TR.yml +6 -83
- data/config/locales/uk.yml +1 -45
- data/config/locales/val-ES.yml +0 -1
- data/config/locales/zh-CN.yml +0 -68
- data/config/locales/zh-TW.yml +4 -97
- data/config/routes.rb +1 -12
- data/lib/decidim/admin/engine.rb +5 -1
- data/lib/decidim/admin/form_builder.rb +1 -1
- data/lib/decidim/admin/menu.rb +32 -16
- data/lib/decidim/admin/test/filterable_examples.rb +8 -18
- data/lib/decidim/admin/test/invite_participatory_space_admins_shared_examples.rb +4 -4
- data/lib/decidim/admin/test/invite_participatory_space_collaborators_shared_examples.rb +2 -2
- data/lib/decidim/admin/test/invite_participatory_space_moderators_shared_examples.rb +9 -6
- data/lib/decidim/admin/test/invite_participatory_space_users_shared_context.rb +1 -0
- data/lib/decidim/admin/test/manage_attachment_collections_examples.rb +5 -1
- data/lib/decidim/admin/test/manage_attachments_examples.rb +5 -1
- data/lib/decidim/admin/test/manage_component_permissions_examples.rb +31 -4
- data/lib/decidim/admin/test/manage_moderations_examples.rb +12 -5
- data/lib/decidim/admin/test/manage_participatory_space_publications_examples.rb +12 -6
- data/lib/decidim/admin/test/manage_resource_soft_deletion_examples.rb +19 -4
- data/lib/decidim/admin/test/manage_taxonomy_filters_examples.rb +28 -8
- data/lib/decidim/admin/version.rb +1 -1
- metadata +22 -35
- data/app/commands/decidim/admin/process_user_group_verification_csv.rb +0 -44
- data/app/commands/decidim/admin/reject_user_group.rb +0 -42
- data/app/commands/decidim/admin/update_organization_appearance.rb +0 -39
- data/app/commands/decidim/admin/update_user_groups.rb +0 -44
- data/app/commands/decidim/admin/verify_user_group.rb +0 -43
- data/app/controllers/concerns/decidim/admin/user_groups/filterable.rb +0 -45
- data/app/controllers/concerns/decidim/admin/user_groups.rb +0 -24
- data/app/controllers/decidim/admin/metrics_controller.rb +0 -23
- data/app/controllers/decidim/admin/user_groups_controller.rb +0 -76
- data/app/controllers/decidim/admin/user_groups_csv_verifications_controller.rb +0 -36
- data/app/forms/decidim/admin/organization_appearance_form.rb +0 -88
- data/app/forms/decidim/admin/user_group_csv_verification_form.rb +0 -25
- data/app/jobs/decidim/admin/verify_user_group_from_csv_job.rb +0 -30
- data/app/packs/src/decidim/admin/welcome_notification.js +0 -32
- data/app/packs/stylesheets/decidim/admin/_bulk_actions.scss +0 -16
- data/app/presenters/decidim/admin/dashboard_metric_charts_presenter.rb +0 -33
- data/app/queries/decidim/admin/user_groups_evaluation.rb +0 -56
- data/app/views/decidim/admin/metrics/_metrics.html.erb +0 -16
- data/app/views/decidim/admin/metrics/index.html.erb +0 -7
- data/app/views/decidim/admin/organization_appearance/_form.html.erb +0 -100
- data/app/views/decidim/admin/organization_appearance/edit.html.erb +0 -18
- data/app/views/decidim/admin/organization_appearance/form/_header_snippets.html.erb +0 -17
- data/app/views/decidim/admin/user_groups/index.html.erb +0 -68
- data/app/views/decidim/admin/user_groups_csv_verifications/new.html.erb +0 -31
- /data/app/views/decidim/admin/{organization_appearance → organization}/form/_minimap.html.erb +0 -0
@@ -0,0 +1,239 @@
|
|
1
|
+
/* global jest */
|
2
|
+
|
3
|
+
import { Application } from "@hotwired/stimulus"
|
4
|
+
import SlugController from "./controller"
|
5
|
+
|
6
|
+
describe("SlugController", () => {
|
7
|
+
let application = null;
|
8
|
+
let controller = null;
|
9
|
+
let element = null;
|
10
|
+
let input = null;
|
11
|
+
let target = null;
|
12
|
+
|
13
|
+
beforeEach(() => {
|
14
|
+
// Set up the DOM structure
|
15
|
+
document.body.innerHTML = `
|
16
|
+
<div data-controller="slug" class="slug-wrapper">
|
17
|
+
<input type="text" placeholder="Enter slug" />
|
18
|
+
<span class="slug-url-value"></span>
|
19
|
+
</div>
|
20
|
+
`
|
21
|
+
|
22
|
+
element = document.querySelector('[data-controller="slug"]')
|
23
|
+
input = element.querySelector("input")
|
24
|
+
target = element.querySelector("span.slug-url-value")
|
25
|
+
|
26
|
+
// Set up Stimulus application
|
27
|
+
application = Application.start()
|
28
|
+
application.register("slug", SlugController)
|
29
|
+
|
30
|
+
return new Promise((resolve) => {
|
31
|
+
setTimeout(() => {
|
32
|
+
controller = application.getControllerForElementAndIdentifier(element, "slug")
|
33
|
+
resolve();
|
34
|
+
}, 0);
|
35
|
+
});
|
36
|
+
})
|
37
|
+
|
38
|
+
afterEach(() => {
|
39
|
+
controller.disconnect()
|
40
|
+
application.stop()
|
41
|
+
document.body.innerHTML = ""
|
42
|
+
})
|
43
|
+
|
44
|
+
describe("connect", () => {
|
45
|
+
it("finds and stores the input element", () => {
|
46
|
+
expect(controller.input).toBe(input)
|
47
|
+
})
|
48
|
+
|
49
|
+
it("finds and stores the target element", () => {
|
50
|
+
expect(controller.target).toBe(target)
|
51
|
+
})
|
52
|
+
|
53
|
+
it("adds keyup event listener to input when input exists", () => {
|
54
|
+
const addEventListenerSpy = jest.spyOn(input, "addEventListener")
|
55
|
+
|
56
|
+
controller.connect()
|
57
|
+
|
58
|
+
expect(addEventListenerSpy).toHaveBeenCalledWith("keyup", controller.boundUpdate)
|
59
|
+
})
|
60
|
+
|
61
|
+
it("binds the slugUpdater method correctly", () => {
|
62
|
+
controller.connect()
|
63
|
+
|
64
|
+
expect(controller.boundUpdate).toBeDefined()
|
65
|
+
expect(typeof controller.boundUpdate).toBe("function")
|
66
|
+
})
|
67
|
+
|
68
|
+
it("handles missing input gracefully", () => {
|
69
|
+
// Remove input from DOM
|
70
|
+
input.remove()
|
71
|
+
|
72
|
+
controller.disconnect()
|
73
|
+
controller.connect()
|
74
|
+
|
75
|
+
expect(() => controller.connect()).not.toThrow()
|
76
|
+
expect(controller.boundUpdate).toBeNull()
|
77
|
+
})
|
78
|
+
})
|
79
|
+
|
80
|
+
describe("disconnect", () => {
|
81
|
+
beforeEach(() => {
|
82
|
+
controller.connect()
|
83
|
+
})
|
84
|
+
|
85
|
+
it("removes keyup event listener when boundUpdate exists", () => {
|
86
|
+
const removeEventListenerSpy = jest.spyOn(controller.input, "removeEventListener")
|
87
|
+
|
88
|
+
let bound = controller.boundUpdate;
|
89
|
+
|
90
|
+
controller.disconnect()
|
91
|
+
|
92
|
+
expect(removeEventListenerSpy).toHaveBeenCalledWith("keyup", bound)
|
93
|
+
})
|
94
|
+
|
95
|
+
it("handles disconnect when boundUpdate is undefined", () => {
|
96
|
+
// eslint-disable-next-line no-undefined
|
97
|
+
controller.boundUpdate = undefined
|
98
|
+
|
99
|
+
expect(() => controller.disconnect()).not.toThrow()
|
100
|
+
})
|
101
|
+
})
|
102
|
+
|
103
|
+
describe("slugUpdater", () => {
|
104
|
+
beforeEach(() => {
|
105
|
+
controller.connect()
|
106
|
+
})
|
107
|
+
|
108
|
+
it("updates target innerHTML with input value", () => {
|
109
|
+
const mockEvent = {
|
110
|
+
target: {
|
111
|
+
value: "test-slug"
|
112
|
+
}
|
113
|
+
}
|
114
|
+
|
115
|
+
controller.slugUpdater(mockEvent)
|
116
|
+
|
117
|
+
expect(target.innerHTML).toBe("test-slug")
|
118
|
+
})
|
119
|
+
|
120
|
+
it("handles empty input value", () => {
|
121
|
+
const mockEvent = {
|
122
|
+
target: {
|
123
|
+
value: ""
|
124
|
+
}
|
125
|
+
}
|
126
|
+
|
127
|
+
controller.slugUpdater(mockEvent)
|
128
|
+
|
129
|
+
expect(target.innerHTML).toBe("")
|
130
|
+
})
|
131
|
+
|
132
|
+
it("handles special characters in input value", () => {
|
133
|
+
const mockEvent = {
|
134
|
+
target: {
|
135
|
+
value: "test-slug-with-special-chars-123"
|
136
|
+
}
|
137
|
+
}
|
138
|
+
|
139
|
+
controller.slugUpdater(mockEvent)
|
140
|
+
|
141
|
+
expect(target.innerHTML).toBe("test-slug-with-special-chars-123")
|
142
|
+
})
|
143
|
+
})
|
144
|
+
|
145
|
+
describe("integration tests", () => {
|
146
|
+
beforeEach(() => {
|
147
|
+
controller.connect()
|
148
|
+
})
|
149
|
+
|
150
|
+
it("updates target when typing in input", () => {
|
151
|
+
input.value = "my-new-slug"
|
152
|
+
|
153
|
+
// Simulate keyup event
|
154
|
+
const keyupEvent = new KeyboardEvent("keyup", { bubbles: true })
|
155
|
+
Reflect.defineProperty(keyupEvent, "target", {
|
156
|
+
value: input,
|
157
|
+
enumerable: true
|
158
|
+
})
|
159
|
+
|
160
|
+
input.dispatchEvent(keyupEvent)
|
161
|
+
|
162
|
+
expect(target.innerHTML).toBe("my-new-slug")
|
163
|
+
})
|
164
|
+
|
165
|
+
it("updates target multiple times as user types", () => {
|
166
|
+
const testValues = ["m", "my", "my-", "my-s", "my-sl", "my-slug"]
|
167
|
+
|
168
|
+
testValues.forEach((value) => {
|
169
|
+
input.value = value
|
170
|
+
const keyupEvent = new KeyboardEvent("keyup", { bubbles: true })
|
171
|
+
Reflect.defineProperty(keyupEvent, "target", {
|
172
|
+
value: input,
|
173
|
+
enumerable: true
|
174
|
+
})
|
175
|
+
input.dispatchEvent(keyupEvent)
|
176
|
+
|
177
|
+
expect(target.innerHTML).toBe(value)
|
178
|
+
})
|
179
|
+
})
|
180
|
+
})
|
181
|
+
|
182
|
+
describe("edge cases", () => {
|
183
|
+
it("handles DOM structure without input", async () => {
|
184
|
+
// Stop the current application to avoid conflicts
|
185
|
+
application.stop()
|
186
|
+
|
187
|
+
// Set up new DOM without input
|
188
|
+
document.body.innerHTML = `
|
189
|
+
<div data-controller="slug" class="slug-wrapper">
|
190
|
+
<span class="slug-url-value"></span>
|
191
|
+
</div>
|
192
|
+
`
|
193
|
+
|
194
|
+
// Start a fresh application
|
195
|
+
application = Application.start()
|
196
|
+
application.register("slug", SlugController)
|
197
|
+
|
198
|
+
const elementWithoutInput = document.querySelector('[data-controller="slug"]')
|
199
|
+
let controllerWithoutInput = null
|
200
|
+
|
201
|
+
await new Promise((resolve) => {
|
202
|
+
setTimeout(() => {
|
203
|
+
controllerWithoutInput = application.getControllerForElementAndIdentifier(elementWithoutInput, "slug")
|
204
|
+
resolve();
|
205
|
+
}, 0);
|
206
|
+
});
|
207
|
+
|
208
|
+
expect(() => controllerWithoutInput.connect()).not.toThrow()
|
209
|
+
expect(controllerWithoutInput.input).toBeNull()
|
210
|
+
})
|
211
|
+
|
212
|
+
it("handles DOM structure without target", async () => {
|
213
|
+
document.body.innerHTML = `
|
214
|
+
<div data-controller="slug" class="slug-wrapper">
|
215
|
+
<input type="text" placeholder="Enter slug" />
|
216
|
+
</div>
|
217
|
+
`
|
218
|
+
|
219
|
+
const elementWithoutTarget = document.querySelector('[data-controller="slug"]')
|
220
|
+
let controllerWithoutInput = null
|
221
|
+
|
222
|
+
await new Promise((resolve) => {
|
223
|
+
setTimeout(() => {
|
224
|
+
controllerWithoutInput = application.getControllerForElementAndIdentifier(elementWithoutTarget, "slug")
|
225
|
+
resolve();
|
226
|
+
}, 0);
|
227
|
+
});
|
228
|
+
|
229
|
+
|
230
|
+
controllerWithoutInput.connect()
|
231
|
+
|
232
|
+
expect(controllerWithoutInput.target).toBeNull()
|
233
|
+
|
234
|
+
// Should not throw when trying to update nonexistent target
|
235
|
+
const mockEvent = { target: { value: "test" } }
|
236
|
+
expect(() => controllerWithoutInput.slugUpdater(mockEvent)).toThrow()
|
237
|
+
})
|
238
|
+
})
|
239
|
+
})
|
@@ -23,7 +23,7 @@
|
|
23
23
|
// for example:
|
24
24
|
// strong[data-css-example]:color:#0000ff; strong[data-css-example]:backgroundColor:#eeeeee;
|
25
25
|
//
|
26
|
-
|
26
|
+
document.addEventListener("turbo:load", () => {
|
27
27
|
document.querySelectorAll("input[data-css-preview=true]").forEach((element) => {
|
28
28
|
element.addEventListener("change", (event) => {
|
29
29
|
const updateRules = event.target.dataset.cssPreviewUpdates.split(";");
|
@@ -9,7 +9,7 @@ import createSortList from "src/decidim/admin/sort_list.component"
|
|
9
9
|
* - data-draggable-table: The table that will be draggable.
|
10
10
|
* - data-sort-url: The URL where the order will be sent.
|
11
11
|
*/
|
12
|
-
|
12
|
+
document.addEventListener("turbo:load", () => {
|
13
13
|
createSortList("[data-draggable-table]", {
|
14
14
|
onSortUpdate: ($children) => {
|
15
15
|
const children = $children.toArray();
|
@@ -34,9 +34,12 @@ class DynamicFieldsComponent {
|
|
34
34
|
}
|
35
35
|
|
36
36
|
$.fn.template = function(placeholder, value) {
|
37
|
+
// Clean up the template HTML to ensure it only contains elements.
|
38
|
+
const $template = $(this).filter((_idx, el) => el.nodeType === Node.ELEMENT_NODE);
|
39
|
+
|
37
40
|
// See the comment below in the `_addField()` method regarding the
|
38
41
|
// `<template>` tag support in IE11.
|
39
|
-
const $subtemplate = $
|
42
|
+
const $subtemplate = $template.find("template, .decidim-template");
|
40
43
|
|
41
44
|
if ($subtemplate.length > 0) {
|
42
45
|
$subtemplate.html((index, oldHtml) => $(oldHtml).template(placeholder, value)[0].outerHTML);
|
@@ -44,7 +47,7 @@ class DynamicFieldsComponent {
|
|
44
47
|
|
45
48
|
// Handle those subtemplates that are mapped with the `data-template`
|
46
49
|
// attribute. This is also because of the IE11 support.
|
47
|
-
const $subtemplateParents = $
|
50
|
+
const $subtemplateParents = $template.find("[data-template]");
|
48
51
|
|
49
52
|
if ($subtemplateParents.length > 0) {
|
50
53
|
$subtemplateParents.each((_i, elem) => {
|
@@ -64,15 +67,15 @@ class DynamicFieldsComponent {
|
|
64
67
|
});
|
65
68
|
}
|
66
69
|
|
67
|
-
$
|
68
|
-
$
|
69
|
-
$
|
70
|
-
$
|
71
|
-
$
|
72
|
-
$
|
73
|
-
$
|
70
|
+
$template.replaceAttribute("id", placeholder, value);
|
71
|
+
$template.replaceAttribute("name", placeholder, value);
|
72
|
+
$template.replaceAttribute("data-tabs-content", placeholder, value);
|
73
|
+
$template.replaceAttribute("for", placeholder, value);
|
74
|
+
$template.replaceAttribute("tabs_id", placeholder, value);
|
75
|
+
$template.replaceAttribute("href", placeholder, value);
|
76
|
+
$template.replaceAttribute("value", placeholder, value);
|
74
77
|
|
75
|
-
return
|
78
|
+
return $template;
|
76
79
|
}
|
77
80
|
}
|
78
81
|
|
@@ -147,9 +150,7 @@ class DynamicFieldsComponent {
|
|
147
150
|
// as they are submitted with them.
|
148
151
|
$template = $wrapper.children(`template, ${templateClass}`);
|
149
152
|
}
|
150
|
-
|
151
153
|
const $newField = $($template.html()).template(this.placeholderId, this._getUID());
|
152
|
-
|
153
154
|
$newField.find("ul.tabs").attr("data-tabs", true);
|
154
155
|
|
155
156
|
const $lastQuestion = $container.find(this.fieldSelector).last()
|
@@ -3,7 +3,7 @@ import AutoLabelByPositionComponent from "src/decidim/admin/auto_label_by_positi
|
|
3
3
|
import createDynamicFields from "src/decidim/admin/dynamic_fields.component"
|
4
4
|
import createSortList from "src/decidim/admin/sort_list.component"
|
5
5
|
|
6
|
-
|
6
|
+
document.addEventListener("turbo:load", () => {
|
7
7
|
const dynamicFieldDefinitions = [
|
8
8
|
{
|
9
9
|
placeHolderId: "external-domain-id",
|
@@ -4,12 +4,29 @@ import BudgetRuleTogglerComponent from "src/decidim/admin/budget_rule_toggler.co
|
|
4
4
|
|
5
5
|
// Checks if the form contains fields with special CSS classes added in
|
6
6
|
// Decidim::Admin::SettingsHelper and acts accordingly.
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
document.addEventListener("turbo:load", () => {
|
8
|
+
|
9
|
+
const budgetTogglerRadios = Array.from(
|
10
|
+
document.querySelectorAll(
|
11
|
+
"input[type='radio'][name='component[settings][voting_rule]']"
|
12
|
+
)
|
13
|
+
);
|
14
|
+
|
15
|
+
const budgetTogglerMapping = {
|
16
|
+
thresholdPercent: [".vote_threshold_percent_container"],
|
17
|
+
minimumProjects: [".vote_minimum_budget_projects_number_container"],
|
18
|
+
selectedProjects: [
|
19
|
+
".vote_selected_projects_minimum_container",
|
20
|
+
".vote_selected_projects_maximum_container"
|
21
|
+
]
|
22
|
+
};
|
23
|
+
|
24
|
+
const budgetToggler = new BudgetRuleTogglerComponent({
|
25
|
+
ruleRadios: budgetTogglerRadios,
|
26
|
+
mapping: budgetTogglerMapping
|
10
27
|
});
|
11
28
|
|
12
|
-
|
29
|
+
budgetToggler.init();
|
13
30
|
|
14
31
|
// Prevents readonly containers from being modified.
|
15
32
|
const $readonlyContainer = $(".readonly_container input");
|
@@ -2,7 +2,7 @@
|
|
2
2
|
/* eslint no-unused-vars: 0 */
|
3
3
|
/* eslint id-length: ["error", { "exceptions": ["e"] }] */
|
4
4
|
|
5
|
-
document.addEventListener("
|
5
|
+
document.addEventListener("turbo:load", () => {
|
6
6
|
const selectedModerationsCount = () => {
|
7
7
|
return document.querySelectorAll(".table-list .js-check-all-moderations:checked").length;
|
8
8
|
};
|
@@ -69,7 +69,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
69
69
|
hideBulkActionForms();
|
70
70
|
bulkActionsButton.classList.add("hide");
|
71
71
|
|
72
|
-
document.querySelectorAll("#js-bulk-actions-dropdown
|
72
|
+
document.querySelectorAll("#js-bulk-actions-dropdown li button").forEach((button) => {
|
73
73
|
button.addEventListener("click", (event) => {
|
74
74
|
const bulkActionsDropdown = document.getElementById("js-bulk-actions-dropdown");
|
75
75
|
bulkActionsDropdown.classList.remove("is-open");
|
@@ -2,7 +2,7 @@
|
|
2
2
|
/* eslint no-unused-vars: 0 */
|
3
3
|
/* eslint id-length: ["error", { "exceptions": ["e"] }] */
|
4
4
|
|
5
|
-
document.addEventListener("
|
5
|
+
document.addEventListener("turbo:load", () => {
|
6
6
|
const selectedModeratedUsersCount = () => {
|
7
7
|
return document.querySelectorAll(".table-list .js-check-all-moderated_users:checked").length;
|
8
8
|
};
|
@@ -69,7 +69,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
|
69
69
|
hideBulkActionForms();
|
70
70
|
bulkActionsButton.classList.add("hide");
|
71
71
|
|
72
|
-
document.querySelectorAll("#js-bulk-actions-dropdown
|
72
|
+
document.querySelectorAll("#js-bulk-actions-dropdown li button").forEach((button) => {
|
73
73
|
button.addEventListener("click", (event) => {
|
74
74
|
const bulkActionsDropdown = document.getElementById("js-bulk-actions-dropdown");
|
75
75
|
bulkActionsDropdown.classList.remove("is-open");
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import TomSelect from "tom-select/dist/cjs/tom-select.popular";
|
2
2
|
|
3
|
-
document.addEventListener("
|
3
|
+
document.addEventListener("turbo:load", () => {
|
4
4
|
const isOnSelectRecipientsPage = window.location.pathname.includes("/select_recipients_to_deliver");
|
5
5
|
|
6
6
|
const selectors = {
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import AutoComplete from "src/decidim/autocomplete";
|
1
|
+
import AutoComplete from "src/decidim/refactor/moved/autocomplete";
|
2
2
|
|
3
3
|
/**
|
4
4
|
* Sends a query to the API and resolves the resulting data in the returned
|
@@ -252,7 +252,7 @@ const createAutocomplete = (searchInput, spaces, inputIndex) => {
|
|
252
252
|
return ac;
|
253
253
|
}
|
254
254
|
|
255
|
-
document.addEventListener("
|
255
|
+
document.addEventListener("turbo:load", () => {
|
256
256
|
const searchElements = document.querySelectorAll("input.participatory-space-search")
|
257
257
|
if (searchElements.length < 1) {
|
258
258
|
return;
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
document.addEventListener("turbo:load", () => {
|
2
2
|
const $limitedTimeRadioButton = $("#component_settings_proposal_edit_time_limited");
|
3
3
|
const $infiniteTimeRadioButton = $("#component_settings_proposal_edit_time_infinite");
|
4
4
|
const $editTimeContainer = $(".edit_time_container");
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import SubformMultiTogglerComponent from "src/decidim/admin/subform_multi_toggler.component"
|
2
2
|
|
3
|
-
|
3
|
+
document.addEventListener("turbo:load", () => {
|
4
4
|
const subformMultiToggler = new SubformMultiTogglerComponent({
|
5
5
|
controllerSelect: $("input[name$=\\[authorization_handlers\\]\\[\\]]"),
|
6
6
|
subformWrapperClass: "authorization-handler",
|
@@ -10,7 +10,7 @@ import sortable from "html5sortable/dist/html5sortable.es";
|
|
10
10
|
console.log('The new order is:', event.target.children);
|
11
11
|
});
|
12
12
|
*/
|
13
|
-
|
13
|
+
document.addEventListener("turbo:load", () => {
|
14
14
|
const draggables = document.querySelectorAll(".js-sortable");
|
15
15
|
|
16
16
|
if (draggables) {
|
@@ -14,7 +14,7 @@
|
|
14
14
|
// } %>
|
15
15
|
// ```
|
16
16
|
//
|
17
|
-
|
17
|
+
document.addEventListener("turbo:load", () => {
|
18
18
|
document.querySelectorAll("input[data-sync-radio-buttons=true]").forEach((element) => {
|
19
19
|
element.addEventListener("change", (event) => {
|
20
20
|
const value = event.target.dataset.syncRadioButtonsValue;
|
@@ -1,7 +1,7 @@
|
|
1
1
|
/**
|
2
2
|
* When switching tabs in i18n fields, autofocus on the input to save clicks #212
|
3
3
|
*/
|
4
|
-
|
4
|
+
document.addEventListener("turbo:load", () => {
|
5
5
|
// Event launched by foundation
|
6
6
|
$("[data-tabs]").on("change.zf.tabs", (event) => {
|
7
7
|
const $container = $(event.target).parent().next(".tabs-content").find(".tabs-panel.is-active");
|
@@ -9,7 +9,7 @@
|
|
9
9
|
// </div>
|
10
10
|
// ```
|
11
11
|
//
|
12
|
-
|
12
|
+
document.addEventListener("turbo:load", () => {
|
13
13
|
document.querySelectorAll("input[data-text-copy=true], textarea[data-text-copy=true]").forEach((element) => {
|
14
14
|
element.addEventListener("change", (event) => {
|
15
15
|
const target = document.querySelector(event.target.dataset.target);
|
@@ -93,7 +93,7 @@ const setTheme = (primary, saturation) => {
|
|
93
93
|
(document.getElementById("preview-tertiary") || {}).value = tertiary;
|
94
94
|
}
|
95
95
|
|
96
|
-
document.addEventListener("
|
96
|
+
document.addEventListener("turbo:load", () => {
|
97
97
|
const selector = document.querySelector("#primary-selector")
|
98
98
|
|
99
99
|
if (selector) {
|
@@ -8,11 +8,11 @@
|
|
8
8
|
}
|
9
9
|
|
10
10
|
.dropdown__trigger {
|
11
|
-
@apply flex
|
11
|
+
@apply flex p-0;
|
12
12
|
}
|
13
13
|
|
14
14
|
.dropdown {
|
15
|
-
@apply divide-y divide-gray-3
|
15
|
+
@apply divide-y divide-gray-3;
|
16
16
|
|
17
17
|
&.button {
|
18
18
|
@apply z-10;
|
@@ -33,3 +33,13 @@
|
|
33
33
|
}
|
34
34
|
}
|
35
35
|
}
|
36
|
+
|
37
|
+
.dropdown {
|
38
|
+
&[aria-hidden="true"] {
|
39
|
+
@apply hidden;
|
40
|
+
}
|
41
|
+
|
42
|
+
&[aria-hidden="false"] {
|
43
|
+
@apply block;
|
44
|
+
}
|
45
|
+
}
|
@@ -7,18 +7,6 @@
|
|
7
7
|
}
|
8
8
|
}
|
9
9
|
|
10
|
-
.dropdown .is-dropdown-submenu a {
|
11
|
-
@apply w-full inline-block;
|
12
|
-
}
|
13
|
-
|
14
|
-
.dropdown .is-dropdown-submenu li {
|
15
|
-
@apply w-full relative;
|
16
|
-
}
|
17
|
-
|
18
|
-
.dropdown {
|
19
|
-
@apply relative p-0 border-0;
|
20
|
-
}
|
21
|
-
|
22
10
|
.button,
|
23
11
|
.input-group {
|
24
12
|
@apply mb-0;
|
@@ -33,36 +21,7 @@
|
|
33
21
|
}
|
34
22
|
|
35
23
|
.input-group-button {
|
36
|
-
@apply absolute right-4
|
37
|
-
}
|
38
|
-
|
39
|
-
.dropdown.menu {
|
40
|
-
z-index: 5;
|
41
|
-
|
42
|
-
li {
|
43
|
-
@apply p-0;
|
44
|
-
}
|
45
|
-
|
46
|
-
.button {
|
47
|
-
@apply drop-shadow-none;
|
48
|
-
}
|
49
|
-
|
50
|
-
& > li.is-dropdown-submenu-parent > a {
|
51
|
-
@apply px-4 py-1 text-white bg-secondary flex items-center gap-x-2;
|
52
|
-
|
53
|
-
&:hover {
|
54
|
-
@apply text-white bg-secondary;
|
55
|
-
}
|
56
|
-
}
|
57
|
-
|
58
|
-
li.is-active > a,
|
59
|
-
li.is-active li.is-submenu-item > a:hover {
|
60
|
-
@apply text-white bg-secondary;
|
61
|
-
}
|
62
|
-
|
63
|
-
.dropdown-filter-icon {
|
64
|
-
@apply fill-white w-5 h-5 p-0;
|
65
|
-
}
|
24
|
+
@apply absolute right-4 h-full top-[0.35rem];
|
66
25
|
}
|
67
26
|
}
|
68
27
|
|
@@ -75,20 +34,5 @@
|
|
75
34
|
.type-icon {
|
76
35
|
@apply align-top;
|
77
36
|
}
|
78
|
-
|
79
|
-
.action-icon {
|
80
|
-
span {
|
81
|
-
@apply ml-1;
|
82
|
-
}
|
83
|
-
|
84
|
-
&.action-icon--remove {
|
85
|
-
color: #e66a5d;
|
86
|
-
margin-left: 0.3rem;
|
87
|
-
|
88
|
-
&:hover {
|
89
|
-
color: #e66a5d;
|
90
|
-
}
|
91
|
-
}
|
92
|
-
}
|
93
37
|
}
|
94
38
|
}
|
@@ -16,7 +16,7 @@
|
|
16
16
|
input[type="week"],
|
17
17
|
select,
|
18
18
|
textarea {
|
19
|
-
@apply mt-
|
19
|
+
@apply mt-2;
|
20
20
|
}
|
21
21
|
|
22
22
|
& label:not(&-checkbox-label),
|
@@ -24,10 +24,6 @@
|
|
24
24
|
@apply text-sm;
|
25
25
|
}
|
26
26
|
|
27
|
-
.help-text {
|
28
|
-
@apply mt-1;
|
29
|
-
}
|
30
|
-
|
31
27
|
.row .columns,
|
32
28
|
.row.column {
|
33
29
|
@apply mb-4;
|
@@ -43,11 +39,6 @@
|
|
43
39
|
@apply block my-2;
|
44
40
|
}
|
45
41
|
|
46
|
-
textarea#component_step_settings_1_automatic_hashtags,
|
47
|
-
textarea#component_step_settings_1_suggested_hashtags {
|
48
|
-
@apply block w-full;
|
49
|
-
}
|
50
|
-
|
51
42
|
#choose-template label {
|
52
43
|
@apply block my-2;
|
53
44
|
}
|