feat(dossier): check conditions on en construction dossier
This commit is contained in:
parent
982e604b07
commit
d00a91aea5
5 changed files with 120 additions and 8 deletions
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
87
app/javascript/controllers/check_conditions_controller.ts
Normal file
87
app/javascript/controllers/check_conditions_controller.ts
Normal 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');
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 *
|
||||||
|
|
|
@ -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?
|
||||||
|
|
Loading…
Reference in a new issue