import React, { useEffect, useState, useCallback, useRef } from 'react'; import { __, sprintf } from '@wordpress/i18n'; import { useNavigate, useParams } from 'react-router-dom'; import { isEmpty, head, pathOr } from 'ramda'; // store import { storeSet } from '../../store'; // api import FormsService from '../../service/forms-service'; import FlowService from '../../service/flow-service'; // tools import set404FromErrorResponse from '../../helpers/set404FromErrorResponse'; // components import { Button } from 'primereact/button'; import { Dropdown } from 'primereact/dropdown'; import { Messages } from 'primereact/messages'; import { confirmPopup, ConfirmPopup } from 'primereact/confirmpopup'; import { Toast } from 'primereact/toast'; const BandoFlowEdit = () => { const { id } = useParams(); const navigate = useNavigate(); const [flowStructure, setFlowStructure] = useState({ initialForm: 0, finalForm: 0, flowData: [], flowEdges: [], chosenField: '' }); const [forms, setForms] = useState([]); const [formOptions, setFormOptions] = useState([]); const [chosenMainFieldOptions, setChosenMainFieldOptions] = useState([]); //const [chosenMainField, setChosenMainField] = useState(''); const [mainFieldSuboptions, setMainFieldSubOptions] = useState([]); const [bandoStatus, setBandoStatus] = useState(''); const [isFlowAllowed, setIsFlowAllowed] = useState(true); const flowMsgs = useRef(null); const toast = useRef(null); const itemRefs = useRef({}); const itemContainerRef = 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(); } setFlowStructure({ initialForm: 0, finalForm: 0, flowData: [], flowEdges: [], chosenField: '' }) setIsFlowAllowed(false); setChosenMainFieldOptions([]); } const updateInitialForm = useCallback((value) => { const finalFormObj = head(forms.filter(o => o.id !== value)); if (forms.length === 2 && finalFormObj) { setFlowStructure({ ...flowStructure, initialForm: value, finalForm: finalFormObj.id }); } else { setFlowStructure({ ...flowStructure, initialForm: value }); } }, [flowStructure]) const updateFinalForm = useCallback((value) => { const filtered = flowStructure.flowData.filter(o => o.formId === flowStructure.initialForm); const flowEdges = buildFlowEdges(flowStructure.initialForm, value); setFlowStructure({ ...flowStructure, flowEdges, flowData: filtered, finalForm: value }); }, [flowStructure]); const updateChosenField = useCallback((value) => { setFlowStructure({ ...flowStructure, chosenField: value }); }, [flowStructure]); const addFlowData = useCallback((data) => { const initial = flowStructure.flowData; const exists = initial ? initial.filter(o => parseInt(o.formId) === parseInt(data.formId)) : []; let final = []; if (exists.length) { final = initial.map(o => parseInt(o.formId) === parseInt(data.formId) ? data : o); } else { final = [...initial, data]; } setFlowStructure({ ...flowStructure, flowData: final }); }, [flowStructure]); const updateItermediateForm = (value, formId) => { const isUsed = flowStructure.flowData.map(o => o.chosenValue).filter(v => !isEmpty(v)).includes(value); if (!isUsed) { const data = { formId: parseInt(formId), chosenField: '', chosenValue: value } addFlowData(data); } } const displayChosenOptionValue = (id) => { const suboptionId = pathOr('', ['chosenValue'], head(flowStructure.flowData.filter(f => parseInt(f.formId) === parseInt(id)))); return pathOr('', ['label'], head(mainFieldSuboptions.filter(o => o.name === suboptionId))); } const disabledOptionForIntermediateForm = (opt) => { return flowStructure.flowData.map(o => o.chosenValue).filter(v => !isEmpty(v)).includes(opt.name); } const shoudDisableSaving = useCallback(() => { const nonEmptyFlowItems = flowStructure.flowData.filter(o => isEmpty(o.chosenField)).filter(o => !isEmpty(o.chosenValue)); /*if (flowForms.length > 2) { console.log('disable BTN:', nonEmptyFlowItems.length !== flowForms.length - 2, isEmpty(flowEdges), 'PUBLISH' === bandoStatus, isEmpty(initialForm), isEmpty(finalForm)); } else { console.log('disable BTN:', nonEmptyFlowItems.length !== 1, isEmpty(flowEdges), 'PUBLISH' === bandoStatus, isEmpty(initialForm), isEmpty(finalForm)); }*/ return forms.length > 2 ? nonEmptyFlowItems.length !== forms.length - 2 || isEmpty(flowStructure.flowEdges) || 'PUBLISH' === bandoStatus || isEmpty(flowStructure.initialForm) || isEmpty(flowStructure.finalForm) : nonEmptyFlowItems.length !== 1 || isEmpty(flowStructure.flowEdges) || 'PUBLISH' === bandoStatus || isEmpty(flowStructure.initialForm) || isEmpty(flowStructure.finalForm); }, [flowStructure, forms]); const doSave = () => { storeSet.main.setAsyncRequest(); const bandoId = getBandoId(); if (flowMsgs.current) { flowMsgs.current.clear(); } FlowService.createFlow(bandoId, flowStructure, getFlowCreateCallback, errGetFlowCreateCallback); } const getFlowCreateCallback = (data) => { if (data.status === 'SUCCESS') { if (toast.current) { toast.current.show({ severity: 'success', summary: '', detail: __('Il flusso è stato aggiornato correttamente!', 'gepafin') }); } } storeSet.main.unsetAsyncRequest(); } const errGetFlowCreateCallback = (data) => { set404FromErrorResponse(data); storeSet.main.unsetAsyncRequest(); } const getFormsCallback = (data) => { if (data.status === 'SUCCESS') { setForms(data.data); const formOptions = data.data.map(o => ({ label: o.label, value: o.id })) setFormOptions([{ label: '', value: '' }, ...formOptions]); const bandoId = getBandoId(); storeSet.main.setAsyncRequest(); FlowService.getFlow(bandoId, (resp) => getFlowCallback(resp, data.data), errGetFlowCallback); } storeSet.main.unsetAsyncRequest(); } const errGetFormsCallback = (data) => { set404FromErrorResponse(data); storeSet.main.unsetAsyncRequest(); } const getFlowCallback = (data, forms) => { if (data.status === 'SUCCESS' && data.data) { const chosenFieldItem = head(data.data.flowData.filter(o => !isEmpty(o.chosenField))); setBandoStatus(data.data.callStatus); if (chosenFieldItem) { setFlowStructure({ initialForm: data.data.initialForm, finalForm: data.data.finalForm, flowData: data.data.flowData, flowEdges: data.data.flowEdges, chosenField: chosenFieldItem.chosenField }); const form = head(forms.filter(o => o.id === data.data.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 }; }) : []; setChosenMainFieldOptions(relevantFields); const field = form ? head(form.content.filter(o => o.id === chosenFieldItem.chosenField)) : null; if (field) { const options = head(field.settings.filter(o => o.name === 'options')); setMainFieldSubOptions(options.value); } } else { setFlowStructure({ initialForm: data.data.initialForm, finalForm: data.data.finalForm, flowData: data.data.flowData, flowEdges: data.data.flowEdges, chosenField: '' }); } } storeSet.main.unsetAsyncRequest(); } const errGetFlowCallback = (data) => { set404FromErrorResponse(data); storeSet.main.unsetAsyncRequest(); } const setItemRef = (id, element) => { itemRefs.current[id] = element; }; const buildFlowEdges = (initialForm, finalForm) => { let edges = []; if (!isEmpty(initialForm) && !isEmpty(finalForm)) { // eslint-disable-next-line forms.map(o => { const formId = String(o.id); if (formId !== String(initialForm) && formId !== String(finalForm)) { edges.push({ id: `${initialForm}->${formId}`, source: String(initialForm), target: formId, type: 'smoothstep' }); } if (formId !== String(initialForm) && formId !== String(finalForm) && String(finalForm) !== '0') { edges.push({ id: `${formId}->${finalForm}`, source: formId, target: String(finalForm), type: 'smoothstep' }); } }); if (forms.length === 2 && initialForm && finalForm) { edges.push({ id: `${initialForm}->${finalForm}`, source: String(initialForm), target: String(finalForm), type: 'smoothstep' }); } } return edges; }; useEffect(() => { const bandoId = getBandoId(); storeSet.main.setAsyncRequest(); FormsService.getFormsForCall(bandoId, getFormsCallback, errGetFormsCallback); }, [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(); if (itemContainerRef.current) { itemContainerRef.current.dispatchEvent(new Event('scroll')); } } }, [forms]); useEffect(() => { const initialForm = flowStructure.initialForm; const finalForm = flowStructure.finalForm; const chosenField = flowStructure.chosenField; if (!isEmpty(initialForm) && !isEmpty(finalForm)) { const form = head(forms.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 }; }) : []; setChosenMainFieldOptions([ { label: isEmpty(relevantFields) ? __('Nessun scelta', 'gepafin') : '', value: '' }, ...relevantFields] ); if (forms.length === 2) { setIsFlowAllowed(true); } //const flowEdges = buildFlowEdges(initialForm, finalForm); if (!isEmpty(chosenField)) { const field = form ? head(form.content.filter(o => o.id === chosenField)) : null; let options = []; if (field) { options = head(field.settings.filter(o => o.name === 'options')); } if (field && options.value && options.value.length === forms.length - 2) { setIsFlowAllowed(true); const suboptions = [ { label: __('Nessun scelta', 'gepafin'), name: '' }, ...options.value ] setMainFieldSubOptions(suboptions); const data = { formId: parseInt(initialForm), chosenField: chosenField, chosenValue: '' } addFlowData(data); if (flowMsgs.current && !isEmpty(chosenField)) { flowMsgs.current.clear(); } } else { setIsFlowAllowed(false); let msg = 'Non è possibile creare il flusso. Il campo principale deve avere esattamente %s opzioni.'; if (forms.length - 2 === 1) { msg = 'Non è possibile creare il flusso. Il campo principale deve avere esattamente %s opzioni.'; } if (flowMsgs.current && !isEmpty(chosenField)) { flowMsgs.current.clear(); flowMsgs.current.show([ { id: '1', sticky: true, severity: 'error', summary: '', detail: sprintf( __(msg, 'gepafin'), forms.length - 2 ), closable: false } ]); } } } } }, [flowStructure.initialForm, flowStructure.finalForm, flowStructure.chosenField]); const { initialForm = 0, finalForm = 0, flowData = [], chosenField = '' } = flowStructure; const initialFormData = head(forms.filter(o => o.id === initialForm)); const finalFormData = head(forms.filter(o => o.id === finalForm)); const levelForms = forms.filter(o => o.id !== initialForm && o.id !== finalForm); return (
{__('Scegli un form iniziale e li form finale e aggiungi i form intermedi per questo bando', 'gepafin')}