feat(dossier): check conditions on en construction dossier

This commit is contained in:
Paul Chavard 2022-07-12 18:32:16 +02:00
parent 982e604b07
commit d00a91aea5
5 changed files with 120 additions and 8 deletions

View file

@ -189,13 +189,18 @@ module Users
def update def update
@dossier = dossier_with_champs @dossier = dossier_with_champs
errors = update_dossier_and_compute_errors if check_conditions?
assign_dossier_and_check_conditions
if errors.present? render :update_brouillon
flash.now.alert = errors
render :modifier
else else
redirect_to demande_dossier_path(@dossier) errors = update_dossier_and_compute_errors
if errors.present?
flash.now.alert = errors
render :modifier
else
redirect_to demande_dossier_path(@dossier)
end
end end
end end
@ -303,6 +308,18 @@ module Users
private private
def check_conditions?
params[:check_conditions] && champs_params[:dossier]
end
def assign_dossier_and_check_conditions
@dossier.assign_attributes(champs_params[:dossier])
# We need to set dossier on champs, otherwise dossier will be reloaded
@dossier.champs.each do |champ|
champ.association(:dossier).target = @dossier
end
end
# if the status tab is filled, then this tab # if the status tab is filled, then this tab
# else first filled tab # else first filled tab
# else en-cours # else en-cours

View file

@ -31,6 +31,14 @@ module ChampHelper
champ.dossier&.brouillon? && !champ.repetition? champ.dossier&.brouillon? && !champ.repetition?
end end
def autosave_controller(champ)
if autosave_available?(champ)
{ controller: 'autosave' }
elsif !champ.repetition? && champ.dossier&.en_construction?
{ controller: 'check-conditions' }
end
end
def geo_area_label(geo_area) def geo_area_label(geo_area)
case geo_area.source case geo_area.source
when GeoArea.sources.fetch(:cadastre) when GeoArea.sources.fetch(:cadastre)

View file

@ -0,0 +1,87 @@
import {
httpRequest,
isSelectElement,
isCheckboxOrRadioInputElement,
isTextInputElement,
getConfig
} from '@utils';
import { ApplicationController } from './application_controller';
const {
autosave: { debounce_delay }
} = getConfig();
const AUTOSAVE_DEBOUNCE_DELAY = debounce_delay;
const AUTOSAVE_TIMEOUT_DELAY = 60000;
export class CheckConditionsController extends ApplicationController {
#abortController?: AbortController;
#latestPromise = Promise.resolve();
connect() {
this.#latestPromise = Promise.resolve();
this.on('change', (event) => this.onChange(event));
this.on('input', (event) => this.onInput(event));
}
disconnect() {
this.#abortController?.abort();
this.#latestPromise = Promise.resolve();
}
private onChange(event: Event) {
const target = event.target as HTMLInputElement;
if (!target.disabled) {
if (target.type == 'hidden') {
this.debounce(this.enqueueCheckRequest, AUTOSAVE_DEBOUNCE_DELAY);
} else if (
isSelectElement(target) ||
isCheckboxOrRadioInputElement(target)
) {
this.enqueueCheckRequest();
}
}
}
private onInput(event: Event) {
const target = event.target as HTMLInputElement;
if (!target.disabled) {
if (
target.getAttribute('role') != 'combobox' &&
isTextInputElement(target)
) {
this.debounce(this.enqueueCheckRequest, AUTOSAVE_DEBOUNCE_DELAY);
}
}
}
private enqueueCheckRequest() {
this.#latestPromise = this.#latestPromise.finally(() =>
this.sendCheckRequest().catch(() => null)
);
}
private sendCheckRequest(): Promise<void> {
this.#abortController = new AbortController();
const form = this.form;
if (!form) {
return Promise.resolve();
}
const formData = new FormData(form);
formData.set('check_conditions', 'true');
return httpRequest(form.action, {
method: 'patch',
body: formData,
signal: this.#abortController.signal,
timeout: AUTOSAVE_TIMEOUT_DELAY
}).turbo();
}
private get form() {
return this.element.closest('form');
}
}

View file

@ -23,7 +23,7 @@
%hr %hr
- if dossier.show_groupe_instructeur_selector? - if dossier.show_groupe_instructeur_selector?
%span{ data: dossier.brouillon? ? { controller: 'autosave' } : {} } %span{ data: { controller: dossier.brouillon? ? 'autosave' : 'check-conditions' } }
= f.label :groupe_instructeur_id do = f.label :groupe_instructeur_id do
= dossier.procedure.routing_criteria_name = dossier.procedure.routing_criteria_name
%span.mandatory * %span.mandatory *

View file

@ -1,4 +1,4 @@
.editable-champ{ class: "editable-champ-#{champ.type_champ} #{champ.visible? ? '' : 'hidden'}", id: champ.input_group_id, data: autosave_available?(champ) ? { controller: 'autosave' } : {} } .editable-champ{ class: "editable-champ-#{champ.type_champ} #{champ.visible? ? '' : 'hidden'}", id: champ.input_group_id, data: autosave_controller(champ) }
- if champ.repetition? - if champ.repetition?
%h3.header-subsection= champ.libelle %h3.header-subsection= champ.libelle
- if champ.description.present? - if champ.description.present?