Skip to content

Commit 09935bc

Browse files
authored
Merge pull request #8 from gencat/feat/changes_in_stratified_sortitions_form
Changes in stratified sortitions form
2 parents 10d3508 + ab1c311 commit 09935bc

File tree

10 files changed

+191
-42
lines changed

10 files changed

+191
-42
lines changed

app/forms/decidim/stratified_sortitions/admin/stratified_sortitions_form.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class StratifiedSortitionsForm < Decidim::Form
2424
attribute :num_candidates, Integer
2525
attribute :strata, [StratumForm]
2626

27-
validates :title, :description, :selection_criteria, :selected_profiles_description, translatable_presence: true
27+
validates :title, :description, translatable_presence: true
2828
validates :num_candidates,
2929
presence: true,
3030
numericality: {

app/packs/entrypoints/decidim_stratified_sortitions_admin.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,5 @@ import "src/decidim/stratified_sortitions/substratum_fields"
44
import "chartkick/chart.js"
55

66
import "entrypoints/decidim_stratified_sortitions_admin.scss"
7+
8+
import "src/decidim/stratified_sortitions/upload_sample"

app/packs/src/decidim/stratified_sortitions/stratum_fields.js

Lines changed: 100 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import AutoButtonsByPositionComponent from "src/decidim/admin/auto_buttons_by_po
22
import AutoLabelByPositionComponent from "src/decidim/admin/auto_label_by_position.component"
33
import createSortList from "src/decidim/admin/sort_list.component"
44
import { initializeSubstrataWrapper } from "src/decidim/stratified_sortitions/substratum_fields"
5+
import { createAccordion } from "src/decidim/a11y"
56

67
$(() => {
78
const wrapperSelector = ".stratified-sortition-strata";
@@ -44,19 +45,62 @@ $(() => {
4445
autoButtonsByPosition.run();
4546
};
4647

48+
const expandStratum = ($stratum) => {
49+
const $toggle = $stratum.find('.stratum--collapse');
50+
if ($toggle.length === 0) return;
51+
const ctrl = $toggle.attr('data-controls');
52+
const panel = ctrl ? document.getElementById(ctrl) : null;
53+
const isExpanded = $toggle.attr('aria-expanded') === 'true';
54+
55+
if (!isExpanded) {
56+
$toggle.trigger('click');
57+
58+
setTimeout(() => {
59+
const nowExpanded = $toggle.attr('aria-expanded') === 'true';
60+
if (!nowExpanded && panel) {
61+
$toggle.attr('aria-expanded', 'true');
62+
panel.setAttribute('aria-hidden', 'false');
63+
$(panel).show();
64+
}
65+
}, 0);
66+
}
67+
};
68+
69+
const createCollapsibleStratum = ($target) => {
70+
const $collapsible = $target.find(".collapsible");
71+
if ($collapsible.length > 0) {
72+
const collapsibleId = $collapsible.attr("id").replace("-stratum-card", "");
73+
const toggleAttr = `${collapsibleId}-stratum-card`;
74+
75+
$target.find(".stratum--collapse")
76+
.attr("data-controls", toggleAttr)
77+
.attr("aria-controls", toggleAttr)
78+
.each((_i, btn) => {
79+
if (!btn.id) {
80+
btn.id = `${toggleAttr}-toggle`;
81+
}
82+
if (!btn.hasAttribute("aria-expanded")) {
83+
btn.setAttribute("aria-expanded", "false");
84+
}
85+
});
86+
}
87+
};
88+
4789
$(document).on("click", ".add-stratum", function(e) {
4890
e.preventDefault();
4991
e.stopPropagation();
5092

5193
const $button = $(this);
5294
const $wrapper = $button.closest(wrapperSelector);
53-
const $container = $(".stratified-sortition-strata-list");
54-
const $template = $wrapper.find("script.decidim-template");
95+
const $container = $wrapper.find(".stratified-sortition-strata-list");
96+
const $template = $wrapper.find("template.decidim-template, script.decidim-template");
5597

5698
if ($template.length && $container.length) {
99+
57100
const templateContent = $template.html();
58101
const uniqueId = new Date().getTime();
59102
let newField = templateContent.replace(/(?<!SUB)STRATUM_ID/g, uniqueId);
103+
newField = newField.replace(/stratified-sortition-stratum-id/g, `stratified-sortition-stratum-${uniqueId}`);
60104
newField = newField.replace(/substrata-\d+/g, `substrata-${uniqueId}`);
61105
$container.append(newField);
62106

@@ -73,9 +117,29 @@ $(() => {
73117
});
74118

75119
updateSubstratumFieldsVisibility($newField);
120+
createCollapsibleStratum($newField);
121+
122+
const $newPanel = $newField.find('.collapsible');
123+
const $newToggle = $newField.find('.stratum--collapse');
124+
if ($newPanel.length && $newToggle.length) {
125+
$newToggle.attr('aria-expanded', 'false');
126+
$newPanel.attr('aria-hidden', 'true').hide();
127+
}
76128

77129
createSortableList();
78130
runComponents();
131+
132+
const newAccordion = $newField[0].querySelector('[data-component="accordion"]');
133+
if (newAccordion) {
134+
try { createAccordion(newAccordion); } catch (_e) {}
135+
}
136+
137+
if (document && typeof document.dispatchEvent === "function") {
138+
try {
139+
document.dispatchEvent(new CustomEvent("ajax:loaded", { detail: $newField[0] }));
140+
} catch (_e) {}
141+
}
142+
79143
}
80144
});
81145

@@ -155,6 +219,8 @@ $(() => {
155219
hasEmptyName = true;
156220
$nameField.addClass("is-invalid-input");
157221

222+
expandStratum($stratum);
223+
158224
if (!$firstInvalidStratum) {
159225
$firstInvalidStratum = $stratum;
160226
}
@@ -177,9 +243,41 @@ $(() => {
177243
const $target = $(el);
178244
hideDeletedStratum($target);
179245
updateSubstratumFieldsVisibility($target);
246+
createCollapsibleStratum($target);
180247
});
181248

182249
makeRequiredCatalanFields();
183250

184251
runComponents();
252+
253+
if (document && typeof document.dispatchEvent === "function") {
254+
try {
255+
const $root = $(wrapperSelector).first();
256+
if ($root.length) {
257+
document.dispatchEvent(new CustomEvent("ajax:loaded", { detail: $root[0] }));
258+
}
259+
} catch (_e) {}
260+
}
185261
})
262+
263+
$(document).on("click", ".stratified-sortition-stratum .stratum--collapse", function(e) {
264+
const btn = this;
265+
266+
if (btn.hasAttribute("role")) return;
267+
268+
const ctrl = btn.getAttribute("data-controls");
269+
if (!ctrl) return;
270+
const panel = document.getElementById(ctrl);
271+
if (!panel) return;
272+
273+
const expanded = btn.getAttribute("aria-expanded") === "true";
274+
const next = !expanded;
275+
btn.setAttribute("aria-expanded", next ? "true" : "false");
276+
panel.setAttribute("aria-hidden", next ? "false" : "true");
277+
278+
if (next) {
279+
$(panel).show();
280+
} else {
281+
$(panel).hide();
282+
}
283+
});
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
document.addEventListener('DOMContentLoaded', () => {
2+
const fileInput = document.getElementById('sample-file-input');
3+
const submitButton = document.getElementById('sample-submit-button');
4+
5+
if (!fileInput || !submitButton) return;
6+
7+
const toggle = () => {
8+
const hasFile = fileInput.files && fileInput.files.length > 0;
9+
submitButton.disabled = !hasFile;
10+
};
11+
12+
toggle();
13+
fileInput.addEventListener('change', toggle);
14+
});

app/packs/stylesheets/decidim/stratified_sortitions/admin/stratified_sortitions.scss

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,25 @@
5252
max-width: 100%;
5353
}
5454
}
55+
56+
.stratified-sortition-stratum {
57+
button[aria-expanded="true"] {
58+
.icon-collapse {
59+
@apply block;
60+
}
61+
62+
.icon-expand {
63+
@apply hidden;
64+
}
65+
}
66+
67+
button[aria-expanded="false"] {
68+
.icon-collapse {
69+
@apply hidden;
70+
}
71+
72+
.icon-expand {
73+
@apply block;
74+
}
75+
}
76+
}

app/views/decidim/stratified_sortitions/admin/stratified_sortitions/_strata.html.erb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,11 @@
22
<%= field_errors_block(form, :strata) %>
33

44
<div class="stratified-sortition-strata row column">
5-
<button class="button button__sm button__secondary add-stratum" type="button"><%= t(".add_stratum") %></button>
6-
<script type="text/template" class="decidim-template">
5+
<template class="decidim-template">
76
<%= fields_for "stratified_sortition[strata][STRATUM_ID]", blank_stratum do |stratum_form| %>
87
<%= render "stratum", form: stratum_form, id: tabs_id_for_stratum(blank_stratum) %>
98
<% end %>
10-
</script>
9+
</template>
1110

1211
<div class="stratified-sortition-strata-list">
1312
<% form.object.strata.each do |stratum| %>
@@ -16,5 +15,6 @@
1615
<% end %>
1716
<% end %>
1817
</div>
18+
<button class="button button__sm button__secondary add-stratum mt-2" type="button"><%= t(".add_stratum") %></button>
1919
</div>
2020
</div>
Lines changed: 40 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,23 @@
11
<% stratum = form.object %>
22

3-
<div class="card stratified-sortition-stratum" id="<%= id %>-field">
3+
<div class="card stratified-sortition-stratum" data-component="accordion" id="accordion-<%= id %>-field">
44
<div class="card-divider stratum-divider">
5-
<h2 class="card-title mb-4">
6-
<span><%= t(".title") %></span>
5+
<h2 class="card-title flex items-center">
6+
<span>
7+
<%= icon("drag-move-2-fill") %>
8+
<%= t(".title") %>
9+
</span>
710

8-
<div class="ml-auto flex gap-x-4">
11+
<div class="ml-auto flex flex-row-reverse items-center gap-x-4">
12+
<button type="button" class="stratum--collapse" data-controls="panel-<%= id %>-stratum-card">
13+
<span class="icon-collapse">
14+
<%== icon("arrow-up-s-line", role: "img") %>
15+
</span>
16+
17+
<span class="icon-expand">
18+
<%== icon("arrow-down-s-line", role: "img") %>
19+
</span>
20+
</button>
921
<button type="button" class="button button__sm button__transparent-secondary small alert move-up-stratum button--title">
1022
<%= icon "arrow-up-line" %> <%= t(".up") %>
1123
</button>
@@ -21,29 +33,30 @@
2133
</h2>
2234
</div>
2335

24-
<div class="card-divider stratum-fields">
25-
<div class="translated-field">
26-
<%= form.translated(
27-
:text_field,
28-
:name,
29-
tabs_id: id,
30-
label: t(".name"),
31-
maxlength: 100) %>
32-
</div>
33-
<div>
34-
<%= form.select :kind,
35-
[[t("decidim.stratified_sortitions.admin.stratified_sortitions.stratum.kind.value"), "value"],
36-
[t("decidim.stratified_sortitions.admin.stratified_sortitions.stratum.kind.numeric_range"), "numeric_range"]],
37-
label: t("decidim.stratified_sortitions.admin.stratified_sortitions.stratum.kind.title") %>
36+
<div id="panel-<%= id %>-stratum-card" class="card-divider collapsible">
37+
<div class="card-section stratum-fields">
38+
<div class="translated-field">
39+
<%= form.translated(
40+
:text_field,
41+
:name,
42+
tabs_id: id,
43+
label: t(".name"),
44+
maxlength: 100) %>
45+
</div>
46+
<div>
47+
<%= form.select :kind,
48+
[[t("decidim.stratified_sortitions.admin.stratified_sortitions.stratum.kind.value"), "value"],
49+
[t("decidim.stratified_sortitions.admin.stratified_sortitions.stratum.kind.numeric_range"), "numeric_range"]],
50+
label: t("decidim.stratified_sortitions.admin.stratified_sortitions.stratum.kind.title") %>
51+
</div>
3852
</div>
39-
</div>
53+
<%= form.hidden_field :position, value: form.object.position || 0 %>
54+
<%= form.hidden_field :deleted, value: false %>
4055

41-
<%= form.hidden_field :position, value: form.object.position || 0 %>
42-
<%= form.hidden_field :deleted, value: false %>
43-
44-
<% blank_substratum = Decidim::StratifiedSortitions::Admin::SubstratumForm.new(stratum: stratum) %>
45-
<%= render "substrata",
46-
form: form,
47-
stratum: stratum,
48-
blank_substratum: blank_substratum %>
56+
<% blank_substratum = Decidim::StratifiedSortitions::Admin::SubstratumForm.new(stratum: stratum) %>
57+
<%= render "substrata",
58+
form: form,
59+
stratum: stratum,
60+
blank_substratum: blank_substratum %>
61+
</div>
4962
</div>

app/views/decidim/stratified_sortitions/admin/stratified_sortitions/_substrata.html.erb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,6 @@
22
<%= field_errors_block(form, :substrata) %>
33

44
<div class="stratified-sortition-substrata row column" id="substrata-<%= form.object.object_id %>">
5-
<button
6-
class="button button__sm button__secondary add-substratum"
7-
type="button">
8-
<%= t(".add_substratum") %>
9-
</button>
105

116
<script type="text/template" class="decidim-template">
127
<% new_substratum = Decidim::StratifiedSortitions::Admin::SubstratumForm.new(stratum: form.object) %>
@@ -30,5 +25,10 @@
3025
<% end %>
3126
<% end %>
3227
</div>
28+
<button
29+
class="button button__sm button__secondary add-substratum mt-2"
30+
type="button">
31+
<%= t(".add_substratum") %>
32+
</button>
3333
</div>
3434
</div>

app/views/decidim/stratified_sortitions/admin/stratified_sortitions/upload_sample.html.erb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@
2323
<%= form_tag samples_path(id: @stratified_sortition.id), multipart: true, class: 'form' do %>
2424
<div class="flex">
2525

26-
<%= file_field_tag :file %>
26+
<%= file_field_tag :file, id: 'sample-file-input' %>
2727

2828
<% if @stratified_sortition.strata_and_substrata_configured? %>
29-
<%= submit_tag t('.title'), class: 'button button__sm button__secondary hollow tiny button--title' %>
29+
<%= submit_tag t('.title'), id: 'sample-submit-button', class: 'button button__sm button__secondary hollow tiny button--title', disabled: true %>
3030
<% else %>
3131
<p class="mr-2"><%= t('.configure_strata_first') %></p>
3232
<%= submit_tag t('.title'), class: 'button button__sm button__secondary hollow tiny button--title', disabled: true, title: t('.configure_strata_first') %>

spec/forms/decidim/sortitions/admin/stratified_sortitions_form_spec.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,13 +99,13 @@ module Admin
9999
context "when selection_criteria is blank" do
100100
let(:selection_criteria) { { en: "", es: "", ca: "" } }
101101

102-
it { is_expected.to be_invalid }
102+
it { is_expected.to be_valid }
103103
end
104104

105105
context "when selected_profiles_description is blank" do
106106
let(:selected_profiles_description) { { en: "", es: "", ca: "" } }
107107

108-
it { is_expected.to be_invalid }
108+
it { is_expected.to be_valid }
109109
end
110110
end
111111
end

0 commit comments

Comments
 (0)