feat(autosave): conditional spinner on all manager champs

This commit is contained in:
Colin Darie 2023-01-23 14:49:54 +01:00
parent c6bdfc7401
commit 26236a11ba
8 changed files with 21 additions and 11 deletions

View file

@ -1,4 +1,4 @@
= @form.check_box :value, = @form.check_box :value,
{ required: @champ.required?, id: @champ.input_id, checked: @champ.true?, aria: { describedby: @champ.describedby_id } }, { required: @champ.required?, id: @champ.input_id, checked: @champ.true?, aria: { describedby: @champ.describedby_id }, data: data_dependent_conditions },
'true', 'true',
'false' 'false'

View file

@ -3,4 +3,5 @@
aria: { describedby: @champ.describedby_id }, aria: { describedby: @champ.describedby_id },
step: :any, step: :any,
placeholder: "3.14", placeholder: "3.14",
required: @champ.required? required: @champ.required?,
data: data_dependent_conditions

View file

@ -1,6 +1,6 @@
- if @champ.options? - if @champ.options?
- if @champ.render_as_radios? - if @champ.render_as_radios?
%fieldset.radios %fieldset.radios{ data: data_dependent_conditions }
- @champ.enabled_non_empty_options.each do |option| - @champ.enabled_non_empty_options.each do |option|
%label %label
= @form.radio_button :value, option = @form.radio_button :value, option
@ -16,7 +16,7 @@
= @form.radio_button :value, Champs::DropDownListChamp::OTHER, checked: @champ.other_value_present? = @form.radio_button :value, Champs::DropDownListChamp::OTHER, checked: @champ.other_value_present?
Autre Autre
- else - else
= @form.select :value, @champ.options_without_empty_value_when_mandatory(@champ.options), { selected: @champ.selected }, required: @champ.mandatory?, id: @champ.input_id, aria: { describedby: @champ.describedby_id } = @form.select :value, @champ.options_without_empty_value_when_mandatory(@champ.options), { selected: @champ.selected }, required: @champ.mandatory?, id: @champ.input_id, aria: { describedby: @champ.describedby_id }, data: data_dependent_conditions
- if @champ.drop_down_other? - if @champ.drop_down_other?
= render EditableChamp::DropDownOtherInputComponent.new(form: @form, champ: @champ) = render EditableChamp::DropDownOtherInputComponent.new(form: @form, champ: @champ)

View file

@ -1,4 +1,4 @@
.drop_down_other{ class: @champ.other_value_present? ? '' : 'hidden' } .drop_down_other{ class: @champ.other_value_present? ? '' : 'hidden' }
.notice .notice
%p Veuillez saisir votre autre choix %p Veuillez saisir votre autre choix
= @form.text_field :value_other, maxlength: 200, size: nil, disabled: !@champ.other_value_present? = @form.text_field :value_other, maxlength: 200, size: nil, disabled: !@champ.other_value_present?, data: data_dependent_conditions

View file

@ -1,6 +1,6 @@
- if @champ.options? - if @champ.options?
- if @champ.render_as_checkboxes? - if @champ.render_as_checkboxes?
= @form.collection_check_boxes(:value, @champ.enabled_non_empty_options, :to_s, :to_s) do |b| = @form.collection_check_boxes(:value, @champ.enabled_non_empty_options, :to_s, :to_s, data: data_dependent_conditions) do |b|
- tag.div(class: 'editable-champ editable-champ-checkbox') do - tag.div(class: 'editable-champ editable-champ-checkbox') do
- b.label do - b.label do
- b.check_box({ multiple: true, checked: @champ&.selected_options&.include?(b.value), aria: { describedby: @champ.describedby_id } }) + b.text - b.check_box({ multiple: true, checked: @champ&.selected_options&.include?(b.value), aria: { describedby: @champ.describedby_id } }) + b.text

View file

@ -1,4 +1,4 @@
%fieldset.radios %fieldset.radios{ data: data_dependent_conditions }
%label %label
= @form.radio_button :value, true = @form.radio_button :value, true
Oui Oui

View file

@ -21,6 +21,7 @@ const {
const AUTOSAVE_DEBOUNCE_DELAY = debounce_delay; const AUTOSAVE_DEBOUNCE_DELAY = debounce_delay;
const AUTOSAVE_TIMEOUT_DELAY = 60000; const AUTOSAVE_TIMEOUT_DELAY = 60000;
const AUTOSAVE_CONDITIONAL_SPINNER_DEBOUNCE_DELAY = 200;
// This is a controller we attach to each "champ" in the main form. It performs // This is a controller we attach to each "champ" in the main form. It performs
// the save and dispatches a few events that allow `AutosaveStatusController` to // the save and dispatches a few events that allow `AutosaveStatusController` to
@ -114,19 +115,26 @@ export class AutosaveController extends ApplicationController {
this.showSpinner(target); this.showSpinner(target);
return; return;
} }
// for some champs, like checkbox, spinner is attached on fieldset
const parentFieldset = target.closest('fieldset');
if (parentFieldset?.dataset?.dependentConditions) {
this.showSpinner(parentFieldset);
}
} }
private showSpinner(champElement: HTMLElement) { private showSpinner(champElement: HTMLElement) {
this.#spinnerTimeoutId = setTimeout(() => { this.#spinnerTimeoutId = setTimeout(() => {
// do not do anything if there is already a spinner // do not do anything if there is already a spinner for this champ, like SIRET champ
if (!champElement.nextElementSibling?.classList.contains('spinner')) { if (!champElement.nextElementSibling?.classList.contains('spinner')) {
const spinner = document.createElement('div'); const spinner = document.createElement('div');
spinner.classList.add('spinner'); spinner.classList.add('spinner', 'spinner-removable');
spinner.setAttribute('aria-live', 'live'); spinner.setAttribute('aria-live', 'live');
spinner.setAttribute('aria-label', 'Chargement en cours…'); spinner.setAttribute('aria-label', 'Chargement en cours…');
champElement.after(spinner); champElement.after(spinner);
} }
}, 200); }, AUTOSAVE_CONDITIONAL_SPINNER_DEBOUNCE_DELAY);
} }
private get saveOnInput() { private get saveOnInput() {

View file

@ -7,4 +7,5 @@
= turbo_stream.morph champ.input_group_id do = turbo_stream.morph champ.input_group_id do
= render EditableChamp::EditableChampComponent.new champ:, form: = render EditableChamp::EditableChampComponent.new champ:, form:
= turbo_stream.remove_all(".editable-champ .spinner"); = turbo_stream.remove_all(".editable-champ .spinner-removable");
= turbo_stream.hide_all(".editable-champ .spinner");