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
|
||||
@dossier = dossier_with_champs
|
||||
|
||||
errors = update_dossier_and_compute_errors
|
||||
|
||||
if errors.present?
|
||||
flash.now.alert = errors
|
||||
render :modifier
|
||||
if check_conditions?
|
||||
assign_dossier_and_check_conditions
|
||||
render :update_brouillon
|
||||
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
|
||||
|
||||
|
@ -303,6 +308,18 @@ module Users
|
|||
|
||||
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
|
||||
# else first filled tab
|
||||
# else en-cours
|
||||
|
|
|
@ -31,6 +31,14 @@ module ChampHelper
|
|||
champ.dossier&.brouillon? && !champ.repetition?
|
||||
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)
|
||||
case geo_area.source
|
||||
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
|
||||
|
||||
- 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
|
||||
= dossier.procedure.routing_criteria_name
|
||||
%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?
|
||||
%h3.header-subsection= champ.libelle
|
||||
- if champ.description.present?
|
||||
|
|
Loading…
Reference in a new issue