demarches-normaliennes/app/javascript/controllers/batch_operation_controller.ts

203 lines
5.9 KiB
TypeScript
Raw Normal View History

import { ApplicationController } from './application_controller';
2023-01-20 11:21:06 +01:00
import { disable, enable, show, hide } from '@utils';
import invariant from 'tiny-invariant';
export class BatchOperationController extends ApplicationController {
static targets = ['menu', 'input', 'dropdown'];
2023-07-04 10:15:58 +02:00
declare readonly menuTargets: HTMLButtonElement[];
declare readonly inputTargets: HTMLInputElement[];
declare readonly dropdownTargets: HTMLButtonElement[];
onCheckOne() {
this.toggleSubmitButtonWhenNeeded();
2023-01-20 11:21:06 +01:00
deleteSelection();
}
onCheckAll(event: Event) {
2022-12-02 17:16:29 +01:00
const target = event.target as HTMLInputElement;
this.inputTargets.forEach((e) => (e.checked = target.checked));
this.toggleSubmitButtonWhenNeeded();
2023-01-20 11:21:06 +01:00
const pagination = document.querySelector('tfoot .fr-pagination');
2023-01-23 09:42:35 +01:00
if (pagination) {
displayNotice(this.inputTargets);
}
2023-04-05 10:59:59 +02:00
// add focus on button for a11y
const button = document.getElementById('js_select_more');
if (button) {
button.focus();
}
2023-01-20 11:21:06 +01:00
}
2023-01-26 15:14:36 +01:00
onSelectMore(event: {
preventDefault: () => void;
target: HTMLInputElement;
}) {
2023-01-20 11:21:06 +01:00
event.preventDefault();
const target = event.target as HTMLInputElement;
const dossierIds = target.getAttribute('data-dossiers');
2023-01-26 15:14:36 +01:00
const hidden_input_multiple_ids = document.querySelector<HTMLInputElement>(
'#input_multiple_ids_batch_operation'
);
if (hidden_input_multiple_ids) {
hidden_input_multiple_ids.value = dossierIds || '';
}
2023-01-20 11:21:06 +01:00
hide(document.querySelector('#not_selected'));
show(document.querySelector('#selected'));
2023-04-05 10:59:59 +02:00
// add focus on button for a11y
const button = document.getElementById('js_delete_selection');
if (button) {
button.focus();
}
2023-01-20 11:21:06 +01:00
}
onSubmitInstruction(event: { srcElement: HTMLInputElement }) {
const field_refuse = document.querySelector<HTMLInputElement>(
'.js_batch_operation_motivation_refuse'
);
const field_without_continuation = document.querySelector<HTMLInputElement>(
'.js_batch_operation_motivation_without-continuation'
);
if (field_refuse != null) {
if (event.srcElement.value == 'refuser' && field_refuse.value == '') {
field_refuse.setCustomValidity('La motivation doit être remplie');
} else {
field_refuse.setCustomValidity('');
}
}
if (field_without_continuation != null) {
if (
event.srcElement.value == 'classer_sans_suite' &&
field_without_continuation.value == ''
) {
field_without_continuation.setCustomValidity(
'La motivation doit être remplie'
);
} else {
field_without_continuation.setCustomValidity('');
}
}
}
2023-01-26 15:14:36 +01:00
onDeleteSelection(event: { preventDefault: () => void }) {
2023-01-20 11:21:06 +01:00
event.preventDefault();
emptyCheckboxes();
deleteSelection();
2023-01-23 09:42:35 +01:00
this.toggleSubmitButtonWhenNeeded();
}
toggleSubmitButtonWhenNeeded() {
const buttons = [
...this.element.querySelectorAll<HTMLButtonElement>('[data-operation]')
];
const checked = this.inputTargets.filter((input) => input.checked);
if (checked.length) {
const available = buttons.filter((button) => {
const operation = button.dataset.operation;
invariant(operation, 'data-operation is required');
const available = checked.every(isInputForOperation(operation));
switchButton(button, available);
return available;
});
2023-07-04 10:15:58 +02:00
if (this.menuTargets.length) {
if (available.length) {
2023-07-04 10:15:58 +02:00
this.menuTargets.forEach((e) => enable(e));
} else {
2023-07-04 10:15:58 +02:00
this.menuTargets.forEach((e) => disable(e));
}
}
this.dropdownTargets.forEach((dropdown) => {
const buttons = Array.from(
document.querySelectorAll<HTMLButtonElement>(
`[aria-labelledby='${dropdown.id}'] button[data-operation]`
)
);
const disabled = buttons.every((button) => button.disabled);
if (disabled) {
disable(dropdown);
} else {
enable(dropdown);
}
});
// pour chaque chaque dropdown, on va chercher tous les boutons
// si tous les boutons sont disabled, on disable le dropdown
} else {
this.menuTargets.forEach((e) => disable(e));
buttons.forEach((button) => switchButton(button, false));
this.dropdownTargets.forEach((e) => disable(e));
}
}
}
function isInputForOperation(operation: string) {
return (input: HTMLInputElement) =>
(input.dataset.operations?.split(',') ?? []).includes(operation);
}
function switchButton(button: HTMLButtonElement, flag: boolean) {
if (flag) {
enable(button);
button.querySelectorAll('button').forEach((button) => enable(button));
} else {
disable(button);
button.querySelectorAll('button').forEach((button) => disable(button));
}
}
2023-01-20 11:21:06 +01:00
2023-01-26 15:14:36 +01:00
function displayNotice(inputs: HTMLInputElement[]) {
const checkbox_all = document.querySelector<HTMLInputElement>(
'#checkbox_all_batch_operation'
);
if (checkbox_all) {
if (checkbox_all.checked) {
show(document.querySelector('#js_batch_select_more'));
2023-01-26 15:14:36 +01:00
hide(document.querySelector('#selected'));
show(document.querySelector('#not_selected'));
} else {
hide(document.querySelector('#js_batch_select_more'));
2023-01-26 15:14:36 +01:00
deleteSelection();
}
}
const dynamic_number = document.querySelector('#dynamic_number');
2023-01-20 11:21:06 +01:00
2023-01-26 15:14:36 +01:00
if (dynamic_number) {
dynamic_number.textContent = inputs.length.toString();
}
2023-01-20 11:21:06 +01:00
}
function deleteSelection() {
2023-01-26 15:14:36 +01:00
const hidden_input_multiple_ids = document.querySelector<HTMLInputElement>(
'#input_multiple_ids_batch_operation'
);
if (hidden_input_multiple_ids) {
hidden_input_multiple_ids.value = '';
}
2023-01-20 11:21:06 +01:00
hide(document.querySelector('#js_batch_select_more'));
2023-01-20 11:21:06 +01:00
}
function emptyCheckboxes() {
2023-01-26 15:14:36 +01:00
const inputs = document.querySelectorAll<HTMLInputElement>(
'div[data-controller="batch-operation"] input[type=checkbox]'
);
2023-01-20 11:21:06 +01:00
inputs.forEach((e) => (e.checked = false));
}