357 lines
13 KiB
JavaScript
357 lines
13 KiB
JavaScript
import React, { useEffect, useState, useCallback, useRef } from 'react';
|
|
import { __, sprintf } from '@wordpress/i18n';
|
|
import { useNavigate, useParams } from 'react-router-dom';
|
|
import { isEmpty, head } from 'ramda';
|
|
|
|
// store
|
|
import { storeGet, storeSet, useStore } from '../../store';
|
|
|
|
// api
|
|
import FormsService from '../../service/forms-service';
|
|
|
|
// tools
|
|
import set404FromErrorResponse from '../../helpers/set404FromErrorResponse';
|
|
|
|
// components
|
|
import { Button } from 'primereact/button';
|
|
import { Dropdown } from 'primereact/dropdown';
|
|
import FlowBuilder from '../../components/FlowBuilder';
|
|
import { Messages } from 'primereact/messages';
|
|
import FlowService from '../../service/flow-service';
|
|
import { confirmPopup, ConfirmPopup } from 'primereact/confirmpopup';
|
|
import { Toast } from 'primereact/toast';
|
|
|
|
const BandoFlowEdit = () => {
|
|
const { id } = useParams();
|
|
const navigate = useNavigate();
|
|
const forms = useStore().main.flowForms();
|
|
const flowData = useStore().main.flowData();
|
|
const flowEdges = useStore().main.flowEdges();
|
|
const [formOptions, setFormOptions] = useState([]);
|
|
const [initialForm, setInitialForm] = useState(0);
|
|
const [mainFieldOptions, setMainFieldOptions] = useState([]);
|
|
const [mainField, setMainField] = useState('');
|
|
const [bandoStatus, setBandoStatus] = useState('');
|
|
const [isFlowAllowed, setIsFlowAllowed] = useState(false);
|
|
const [finalForm, setFinalForm] = useState(0);
|
|
const flowMsgs = useRef(null);
|
|
const toast = useRef(null);
|
|
|
|
const getBandoId = () => {
|
|
const parsed = parseInt(id)
|
|
return !isNaN(parsed) ? parsed : 0;
|
|
}
|
|
|
|
const goBack = () => {
|
|
const bandoId = getBandoId();
|
|
navigate(`/bandi/${bandoId}/forms`);
|
|
}
|
|
|
|
const confirmDelete = (event) => {
|
|
confirmPopup({
|
|
target: event.currentTarget,
|
|
message: __('Sei sicuro di reset questo flow?', 'gepafin'),
|
|
acceptLabel: __('Si', 'gepafin'),
|
|
icon: 'pi pi-info-circle',
|
|
defaultFocus: 'reject',
|
|
acceptClassName: 'p-button-danger',
|
|
accept: doDelete,
|
|
reject: () => {}
|
|
});
|
|
};
|
|
|
|
const doDelete = () => {
|
|
if (flowMsgs.current) {
|
|
flowMsgs.current.clear();
|
|
}
|
|
storeSet.main.flowData([]);
|
|
storeSet.main.flowEdges([]);
|
|
setInitialForm(0);
|
|
setMainFieldOptions([]);
|
|
setMainField('');
|
|
setIsFlowAllowed(false);
|
|
setFinalForm(0);
|
|
}
|
|
|
|
const updateInitialForm = (value) => {
|
|
setInitialForm(value);
|
|
if (forms.length === 2) {
|
|
const finalForm = head(forms.filter(o => o.id !== value));
|
|
if (finalForm) {
|
|
setFinalForm(finalForm.id);
|
|
}
|
|
}
|
|
}
|
|
|
|
const shoudDisableSaving = useCallback(() => {
|
|
return forms.length > 2
|
|
? isEmpty(flowData) || isEmpty(flowEdges) || isEmpty(initialForm) || isEmpty(finalForm)
|
|
|| flowData.length < forms.length - 1 || 'PUBLISH' === bandoStatus
|
|
: isEmpty(flowEdges) || isEmpty(initialForm) || 'PUBLISH' === bandoStatus;
|
|
}, [flowData, flowEdges]);
|
|
|
|
const doSave = () => {
|
|
storeSet.main.setAsyncRequest();
|
|
const bandoId = getBandoId();
|
|
const body = {
|
|
initialForm,
|
|
finalForm,
|
|
flowData,
|
|
flowEdges
|
|
};
|
|
if (flowMsgs.current) {
|
|
flowMsgs.current.clear();
|
|
}
|
|
|
|
FlowService.createFlow(bandoId, body, getFlowCreateCallback, errGetFlowCreateCallback);
|
|
}
|
|
|
|
const getFlowCreateCallback = (data) => {
|
|
if (data.status === 'SUCCESS') {
|
|
if (toast.current) {
|
|
toast.current.show({
|
|
severity: 'success',
|
|
summary: '',
|
|
detail: __('Il flusso è stato aggiornato corretamente!', 'gepafin')
|
|
});
|
|
}
|
|
}
|
|
storeSet.main.unsetAsyncRequest();
|
|
}
|
|
|
|
const errGetFlowCreateCallback = (data) => {
|
|
set404FromErrorResponse(data);
|
|
storeSet.main.unsetAsyncRequest();
|
|
}
|
|
|
|
const getFormsCallback = (data) => {
|
|
if (data.status === 'SUCCESS') {
|
|
const formOptions = data.data.map(o => ({ label: o.label, value: o.id }))
|
|
storeSet.main.flowForms(data.data);
|
|
setFormOptions([{label: '', value: ''}, ...formOptions]);
|
|
}
|
|
storeSet.main.unsetAsyncRequest();
|
|
}
|
|
|
|
const errGetFormsCallback = (data) => {
|
|
set404FromErrorResponse(data);
|
|
storeSet.main.unsetAsyncRequest();
|
|
}
|
|
|
|
const getFlowCallback = (data) => {
|
|
if (data.status === 'SUCCESS' && data.data) {
|
|
storeSet.main.flowData(data.data.flowData);
|
|
storeSet.main.flowEdges(data.data.flowEdges);
|
|
setInitialForm(data.data.initialForm);
|
|
setFinalForm(data.data.finalForm);
|
|
setBandoStatus(data.data.callStatus);
|
|
const flowDataItem = head(data.data.flowData.filter(o => !isEmpty(o.chosenField)));
|
|
|
|
if (flowDataItem) {
|
|
setMainField(flowDataItem.chosenField);
|
|
}
|
|
}
|
|
storeSet.main.unsetAsyncRequest();
|
|
}
|
|
|
|
const errGetFlowCallback = (data) => {
|
|
set404FromErrorResponse(data);
|
|
storeSet.main.unsetAsyncRequest();
|
|
}
|
|
|
|
useEffect(() => {
|
|
const flowForms = storeGet.main.flowForms();
|
|
const form = head(flowForms.filter(o => String(o.id) === String(initialForm)))
|
|
const field = form ? head(form.content.filter(o => o.id === mainField)) : null;
|
|
let options = [];
|
|
|
|
if (field) {
|
|
options = head(field.settings.filter(o => o.name === 'options'));
|
|
}
|
|
|
|
if (field && options.value && options.value.length === flowForms.length - 2) {
|
|
setIsFlowAllowed(true);
|
|
const data = {
|
|
formId: String(initialForm),
|
|
chosenField: mainField,
|
|
chosenValue: ''
|
|
}
|
|
storeSet.main.addFlowData(data);
|
|
} else {
|
|
setIsFlowAllowed(false);
|
|
let msg = 'Non è possibile creare il flusso. Il campo principale deve avere esattamente %s opzioni.';
|
|
|
|
if (flowForms.length - 2 === 1) {
|
|
msg = 'Non è possibile creare il flusso. Il campo principale deve avere esattamente %s opzione.';
|
|
}
|
|
|
|
if (flowMsgs.current && !isEmpty(mainField)) {
|
|
flowMsgs.current.clear();
|
|
flowMsgs.current.show([
|
|
{
|
|
id: '1',
|
|
sticky: true, severity: 'error', summary: '',
|
|
detail: sprintf(
|
|
__(msg, 'gepafin'),
|
|
flowForms.length - 2
|
|
),
|
|
closable: false
|
|
}
|
|
]);
|
|
}
|
|
}
|
|
}, [mainField]);
|
|
|
|
useEffect(() => {
|
|
setMainField('');
|
|
setMainFieldOptions([]);
|
|
const flowForms = storeGet.main.flowForms();
|
|
const form = head(flowForms.filter(o => String(o.id) === String(initialForm)))
|
|
const relevantFields = form
|
|
? form.content
|
|
.filter(o => ['radio', 'select'].includes(o.name))
|
|
.map(o => {
|
|
const label = head(o.settings.filter(o => o.name === 'label'));
|
|
return { value: o.id, label: label ? label.value : o.label };
|
|
})
|
|
: [];
|
|
setMainFieldOptions([
|
|
{label: isEmpty(relevantFields) ? __('Nessun scelta', 'gepafin') : '', value: ''},
|
|
...relevantFields]
|
|
);
|
|
|
|
if (flowForms.length === 2) {
|
|
setIsFlowAllowed(true)
|
|
}
|
|
}, [initialForm]);
|
|
|
|
useEffect(() => {
|
|
const bandoId = getBandoId();
|
|
storeSet.main.setAsyncRequest();
|
|
FormsService.getFormsForCall(bandoId, getFormsCallback, errGetFormsCallback);
|
|
FlowService.getFlow(bandoId, getFlowCallback, errGetFlowCallback)
|
|
}, [id]);
|
|
|
|
useEffect(() => {
|
|
if (flowMsgs.current && forms.length < 2) {
|
|
flowMsgs.current.clear();
|
|
flowMsgs.current.show([
|
|
{
|
|
id: '1',
|
|
sticky: true, severity: 'info', summary: '',
|
|
detail: __('Devi creare almeno 2 form.', 'gepafin'),
|
|
closable: false
|
|
}
|
|
]);
|
|
} else {
|
|
flowMsgs.current.clear();
|
|
}
|
|
}, [forms]);
|
|
|
|
useEffect(() => {
|
|
return () => {
|
|
storeSet.main.flowForms([]);
|
|
storeSet.main.flowData([]);
|
|
storeSet.main.flowEdges([]);
|
|
}
|
|
}, []);
|
|
|
|
return (
|
|
<div className="appPage">
|
|
<div className="appPage__pageHeader">
|
|
<h1>{__('Gestisci flusso dei form', 'gepafin')}</h1>
|
|
<p>
|
|
{__('Scegli un form iniziale e li form finale e aggiungi i form intermedi per questo bando', 'gepafin')}
|
|
</p>
|
|
</div>
|
|
|
|
<div className="appPage__spacer"></div>
|
|
|
|
<div className="appPageSection">
|
|
<div className="appForm__cols">
|
|
<div className="appForm__field">
|
|
<label htmlFor="initialForm">{__('Scegli form iniziale', 'gepafin')}</label>
|
|
<Dropdown
|
|
id="initialForm"
|
|
disabled={'PUBLISH' === bandoStatus}
|
|
value={initialForm}
|
|
onChange={(e) => updateInitialForm(e.value)}
|
|
optionDisabled={(opt) => finalForm === opt.value || isEmpty(opt.value)}
|
|
options={formOptions}
|
|
optionLabel="label"
|
|
optionValue="value"
|
|
placeholder={__('Scegli il form', 'gepafin')}/>
|
|
</div>
|
|
|
|
{forms.length > 2 && initialForm && mainFieldOptions
|
|
? <div className="appForm__field">
|
|
<label htmlFor="mainField">{__('Scegli il campo principale', 'gepafin')}</label>
|
|
<Dropdown
|
|
id="mainField"
|
|
disabled={'PUBLISH' === bandoStatus}
|
|
value={mainField}
|
|
onChange={(e) => setMainField(e.value)}
|
|
optionDisabled={(opt) => isEmpty(opt.value)}
|
|
options={mainFieldOptions}
|
|
optionLabel="label"
|
|
optionValue="value"
|
|
placeholder={__('Scegli il campo', 'gepafin')}/>
|
|
</div> : null}
|
|
|
|
{forms.length > 2 && mainField && isFlowAllowed || forms.length === 2 && isFlowAllowed
|
|
? <div className="appForm__field">
|
|
<label htmlFor="finalForm">{__('Scegli form finale', 'gepafin')}</label>
|
|
<Dropdown
|
|
id="finalForm"
|
|
disabled={'PUBLISH' === bandoStatus}
|
|
value={finalForm}
|
|
onChange={(e) => setFinalForm(e.value)}
|
|
optionDisabled={(opt) => initialForm === opt.value || isEmpty(opt.value)}
|
|
options={formOptions}
|
|
optionLabel="label"
|
|
optionValue="value"
|
|
placeholder={__('Scegli il form', 'gepafin')}/>
|
|
</div> : null}
|
|
</div>
|
|
</div>
|
|
|
|
<div className="appPage__spacer"></div>
|
|
|
|
<div className="appPageSection">
|
|
<Messages ref={flowMsgs}/>
|
|
{forms.length >= 2 && isFlowAllowed
|
|
? <FlowBuilder
|
|
initialForm={initialForm}
|
|
finalForm={finalForm}
|
|
mainField={mainField}/> : null}
|
|
</div>
|
|
|
|
<div className="appPage__spacer"></div>
|
|
|
|
<Toast ref={toast}/>
|
|
<div className="appPageSection">
|
|
<div className="appPageSection__actions">
|
|
<Button
|
|
onClick={goBack}
|
|
outlined
|
|
label={__('Indietro', 'gepafin')} icon="pi pi-arrow-left" iconPos="left"/>
|
|
<Button
|
|
onClick={doSave}
|
|
disabled={shoudDisableSaving()}
|
|
label={__('Salva', 'gepafin')} icon="pi pi-save" iconPos="right"/>
|
|
</div>
|
|
<div className="appPageSection__actions">
|
|
<ConfirmPopup/>
|
|
<Button
|
|
onClick={confirmDelete}
|
|
disabled={'PUBLISH' === bandoStatus}
|
|
severity="warning"
|
|
label={__('Reset', 'gepafin')} icon="pi pi-refresh" iconPos="right"/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
|
|
}
|
|
|
|
export default BandoFlowEdit; |