- save progress;
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
"@xyflow/react": "12.3.1",
|
||||
"codice-fiscale-js": "2.3.22",
|
||||
"deep-object-diff": "^1.1.9",
|
||||
"dompurify": "3.1.7",
|
||||
"dompurify": "^3.1.7",
|
||||
"fast-deep-equal": "3.1.3",
|
||||
"html-react-parser": "5.1.16",
|
||||
"jwt-decode": "4.0.0",
|
||||
|
||||
@@ -38,6 +38,10 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&[disabled] {
|
||||
background: var(--message-info-background);
|
||||
}
|
||||
|
||||
span {
|
||||
color: #FFF;
|
||||
font-size: 17.25px;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import { classNames } from 'primereact/utils';
|
||||
import { Controller } from 'react-hook-form';
|
||||
import { isNil, isEmpty } from 'ramda';
|
||||
import { isNil, isEmpty, is } from 'ramda';
|
||||
|
||||
// components
|
||||
import { InputSwitch } from 'primereact/inputswitch';
|
||||
@@ -28,7 +28,7 @@ const Switch = ({
|
||||
render={({ field, fieldState }) => (
|
||||
<InputSwitch
|
||||
inputId={fieldName}
|
||||
checked={field.value}
|
||||
checked={is(String, field.value) ? 'true' === field.value : field.value}
|
||||
disabled={disabled}
|
||||
onChange={(e) => field.onChange(e.value)}
|
||||
className={classNames({ 'p-invalid': fieldState.invalid })}/>
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import parse from 'html-react-parser';
|
||||
import { isNil } from 'ramda';
|
||||
import DOMPurify from 'dompurify';
|
||||
|
||||
const renderHtmlContent = (content = '') => !isNil(content) ? parse(content) : '';
|
||||
const renderHtmlContent = (content = '') => {
|
||||
const clean = DOMPurify.sanitize(content);
|
||||
return !isNil(clean) ? parse(clean) : '';
|
||||
}
|
||||
|
||||
export default renderHtmlContent;
|
||||
@@ -25,6 +25,7 @@ import {
|
||||
} from '../../helpers/validators';
|
||||
import renderHtmlContent from '../../helpers/renderHtmlContent';
|
||||
import set404FromErrorResponse from '../../helpers/set404FromErrorResponse';
|
||||
import getFormatedFileSizeText from '../../helpers/getFormatedFileSizeText';
|
||||
|
||||
// components
|
||||
import { Skeleton } from 'primereact/skeleton';
|
||||
@@ -36,7 +37,7 @@ import ApplicationSteps from './ApplicationSteps';
|
||||
import BlockingOverlay from '../../components/BlockingOverlay';
|
||||
import { Dialog } from 'primereact/dialog';
|
||||
import FileuploadApplicationSignedPdf from '../../components/FileuploadApplicationSignedPdf';
|
||||
import getFormatedFileSizeText from '../../helpers/getFormatedFileSizeText';
|
||||
|
||||
import { defaultMaxFileSize } from '../../configData';
|
||||
|
||||
const BandoApplication = () => {
|
||||
@@ -47,7 +48,6 @@ const BandoApplication = () => {
|
||||
const [bandoTitle, setBandoTitle] = useState('');
|
||||
const [formId, setFormId] = useState('');
|
||||
const [totalSteps, setTotalSteps] = useState(0);
|
||||
//const [completedSteps, setCompletedSteps] = useState(0);
|
||||
const [visibleConfirmation, setVisibleConfirmation] = useState(false);
|
||||
const [applicationStatus, setApplicationStatus] = useState('');
|
||||
const [activeStep, setActiveStep] = useState(1);
|
||||
@@ -91,68 +91,9 @@ const BandoApplication = () => {
|
||||
storeSet.main.setAsyncRequest();
|
||||
formMsgs.current.clear();
|
||||
|
||||
/*ApplicationService.updateStatusApplication(applId, {}, submitApplicationCallback, errSubmitApplicationCallback, [
|
||||
['status', 'SUBMIT']
|
||||
]);*/
|
||||
ApplicationService.validateApplication(applId, {}, validateApplicationCallback, errValidateApplicationCallback);
|
||||
};
|
||||
|
||||
/*const submitApplicationCallback = (data) => {
|
||||
if (data.status === 'SUCCESS') {
|
||||
if (data.data.status) {
|
||||
setApplicationStatus(data.data.status); // ask why not 'applicationStatus'?
|
||||
}
|
||||
}
|
||||
storeSet.main.unsetAsyncRequest();
|
||||
}
|
||||
|
||||
const errSubmitApplicationCallback = (data) => {
|
||||
storeSet.main.unsetAsyncRequest();
|
||||
if (data.status === 'VALIDATION_ERROR') {
|
||||
if (formMsgs.current) {
|
||||
formMsgs.current.show([
|
||||
{
|
||||
id: '99',
|
||||
sticky: true, severity: 'error', summary: '',
|
||||
detail: data.data.join(', '),
|
||||
closable: true
|
||||
}
|
||||
]);
|
||||
}
|
||||
} else if (data.status === 'EXCEPTION_ERROR') {
|
||||
if (formMsgs.current) {
|
||||
formMsgs.current.show([
|
||||
{
|
||||
id: '99',
|
||||
sticky: true, severity: 'error', summary: '',
|
||||
detail: data.message,
|
||||
closable: true
|
||||
}
|
||||
]);
|
||||
}
|
||||
} else if (data.status === 'BAD_REQUEST') {
|
||||
if (formMsgs.current) {
|
||||
formMsgs.current.show([
|
||||
{
|
||||
id: '99',
|
||||
sticky: true, severity: 'error', summary: '',
|
||||
detail: data.message,
|
||||
closable: true
|
||||
}
|
||||
]);
|
||||
}
|
||||
if (toast.current) {
|
||||
toast.current.show({
|
||||
severity: 'error',
|
||||
summary: '',
|
||||
detail: data.message
|
||||
});
|
||||
}
|
||||
} else {
|
||||
set404FromErrorResponse(data);
|
||||
}
|
||||
}*/
|
||||
|
||||
const validateApplicationCallback = (data) => {
|
||||
if (data.status === 'SUCCESS') {
|
||||
if (data.data.status) {
|
||||
@@ -461,7 +402,8 @@ const BandoApplication = () => {
|
||||
useEffect(() => {
|
||||
if (formInitialData) {
|
||||
//reset();
|
||||
Object.keys(formInitialData).map(k => setValue(k, formInitialData[k]))
|
||||
Object.keys(formInitialData).map(k => setValue(k, formInitialData[k]));
|
||||
trigger();
|
||||
}
|
||||
}, [formInitialData]);
|
||||
|
||||
@@ -487,7 +429,7 @@ const BandoApplication = () => {
|
||||
|
||||
<div className="appPage__spacer"></div>
|
||||
|
||||
{'SUBMIT' !== applicationStatus
|
||||
{'DRAFT' === applicationStatus
|
||||
? <ApplicationSteps totalSteps={totalSteps} activeStepIndex={activeStepIndex}/>
|
||||
: null}
|
||||
|
||||
@@ -510,12 +452,12 @@ const BandoApplication = () => {
|
||||
<div className="appPage__content">
|
||||
<BlockingOverlay shouldDisplay={isAsyncRequest}/>
|
||||
<form className="appForm" onSubmit={handleSubmit(onSubmit)}>
|
||||
{'SUBMIT' !== applicationStatus
|
||||
{'DRAFT' === applicationStatus
|
||||
? <div className="appPageSection">
|
||||
{actionBtns}
|
||||
</div> : null}
|
||||
|
||||
{'SUBMIT' !== applicationStatus
|
||||
{'DRAFT' === applicationStatus
|
||||
? formData.map(o => {
|
||||
const label = head(o.settings.filter(o => o.name === 'label'));
|
||||
const text = head(o.settings.filter(o => o.name === 'text'));
|
||||
@@ -576,7 +518,7 @@ const BandoApplication = () => {
|
||||
})
|
||||
: null}
|
||||
|
||||
{'SUBMIT' === applicationStatus
|
||||
{'AWAIT' === applicationStatus
|
||||
? <div className="appPageSection">
|
||||
<div className="appForm__field">
|
||||
<label>
|
||||
@@ -585,14 +527,14 @@ const BandoApplication = () => {
|
||||
</div>
|
||||
<Button
|
||||
type="button"
|
||||
disabled={'SUBMIT' !== applicationStatus}
|
||||
disabled={'SUBMIT' === applicationStatus}
|
||||
onClick={onDownloadApplicationPdf}
|
||||
label={__('Scarica PDF', 'gepafin')}
|
||||
icon="pi pi-download"
|
||||
iconPos="right"/>
|
||||
</div> : null}
|
||||
|
||||
{'SUBMIT' === applicationStatus
|
||||
{'AWAIT' === applicationStatus
|
||||
? <div className="appPageSection">
|
||||
<div className="appForm__field">
|
||||
<label htmlFor="signedPdfFile">
|
||||
@@ -617,12 +559,12 @@ const BandoApplication = () => {
|
||||
|
||||
<div className="appPage__spacer"></div>
|
||||
|
||||
{'SUBMIT' !== applicationStatus
|
||||
{'DRAFT' === applicationStatus
|
||||
? <div className="appPageSection__hr">
|
||||
<span>{__('Azioni rapide', 'gepafin')}</span>
|
||||
</div> : null}
|
||||
|
||||
{'SUBMIT' !== applicationStatus
|
||||
{'DRAFT' === applicationStatus
|
||||
? <div className="appPageSection">
|
||||
{actionBtns}
|
||||
</div> : null}
|
||||
|
||||
@@ -78,7 +78,7 @@ const BandoEdit = () => {
|
||||
|
||||
const validateCallback = (data) => {
|
||||
if (data.status === 'SUCCESS') {
|
||||
setData({...data, status: data.data.status});
|
||||
setData({ ...data, status: data.data.status });
|
||||
if (bandoMsgs.current) {
|
||||
bandoMsgs.current.show([
|
||||
{
|
||||
@@ -148,6 +148,10 @@ const BandoEdit = () => {
|
||||
detail: __('Pubblicato!', 'gepafin')
|
||||
});
|
||||
}
|
||||
if (data.data.docs) {
|
||||
data.data.docs = data.data.docs
|
||||
.filter(o => o.source === 'CALL' && o.type === 'DOCUMENT');
|
||||
}
|
||||
setData(data.data);
|
||||
}
|
||||
storeSet.main.unsetAsyncRequest();
|
||||
@@ -191,7 +195,10 @@ const BandoEdit = () => {
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
if (data.data.docs) {
|
||||
data.data.docs = data.data.docs
|
||||
.filter(o => o.source === 'CALL' && o.type === 'DOCUMENT');
|
||||
}
|
||||
setData(data.data);
|
||||
}
|
||||
storeSet.main.unsetAsyncRequest();
|
||||
@@ -248,7 +255,8 @@ const BandoEdit = () => {
|
||||
}
|
||||
} else {
|
||||
BandoService.getBando(id, getCallback, errGetCallback);
|
||||
FormsService.getFormsForCall(id, getFormsCallback, () => {});
|
||||
FormsService.getFormsForCall(id, getFormsCallback, () => {
|
||||
});
|
||||
}
|
||||
}, [id]);
|
||||
|
||||
@@ -275,7 +283,7 @@ const BandoEdit = () => {
|
||||
<div className="appPage__spacer"></div>
|
||||
|
||||
<Messages ref={bandoMsgs}/>
|
||||
<Toast ref={toast} />
|
||||
<Toast ref={toast}/>
|
||||
|
||||
{!isEmpty(data)
|
||||
? <>
|
||||
|
||||
@@ -157,7 +157,7 @@ const BandoView = () => {
|
||||
<div className="appPageSection__withBorder">
|
||||
<h2>{__('Documentazione Richiesta', 'gepafin')}</h2>
|
||||
<div className="row rowContent">
|
||||
<p>{renderHtmlContent(data.documentationRequested)}</p>
|
||||
{renderHtmlContent(data.documentationRequested)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -177,7 +177,7 @@ const BandoView = () => {
|
||||
<div className="row rowContent">
|
||||
<ul>
|
||||
{data.docs
|
||||
.filter(o => o.source === 'CALL')
|
||||
.filter(o => o.source === 'CALL' && o.type === 'DOCUMENT')
|
||||
.map((o, i) => <li key={i}>
|
||||
<a href={o.filePath} target="_blank" rel="noreferrer">{o.name}</a>
|
||||
</li>)}
|
||||
|
||||
@@ -26,6 +26,7 @@ import { Messages } from 'primereact/messages';
|
||||
import { Message } from 'primereact/message';
|
||||
import { Toast } from 'primereact/toast';
|
||||
import { Editor } from 'primereact/editor';
|
||||
import { Dialog } from 'primereact/dialog';
|
||||
|
||||
const BandoViewBeneficiario = () => {
|
||||
const isAsyncRequest = useStore().main.isAsyncRequest();
|
||||
@@ -35,16 +36,25 @@ const BandoViewBeneficiario = () => {
|
||||
const [data, setData] = useState({});
|
||||
const [newQuestion, setNewQuestion] = useState('');
|
||||
const [applicationObj, setApplicationObj] = useState(true);
|
||||
const [isVisibleConfidiPopup, setIsVisibleConfidiPopup] = useState(false);
|
||||
const bandoMsgs = useRef(null);
|
||||
const toast = useRef(null);
|
||||
|
||||
/*const scaricaBando = () => {
|
||||
const displayConfidiPopup = () => {
|
||||
setIsVisibleConfidiPopup(true);
|
||||
}
|
||||
|
||||
}*/
|
||||
const hideConfidiPopup = () => {
|
||||
setIsVisibleConfidiPopup(false)
|
||||
}
|
||||
|
||||
const scaricaModulistica = () => {
|
||||
const bandoId = getBandoId();
|
||||
BandoService.getBandoPdf(bandoId, getCallPdfCallback, errCallPdfCallback);
|
||||
if (data.confidi) {
|
||||
displayConfidiPopup();
|
||||
} else {
|
||||
const bandoId = getBandoId();
|
||||
BandoService.getBandoPdf(bandoId, getCallPdfCallback, errCallPdfCallback);
|
||||
}
|
||||
}
|
||||
|
||||
const getCallPdfCallback = (data) => {
|
||||
@@ -77,11 +87,15 @@ const BandoViewBeneficiario = () => {
|
||||
}
|
||||
|
||||
const submitApplication = () => {
|
||||
if (applicationObj && applicationObj.id) {
|
||||
navigate(`/imieibandi/${applicationObj.id}`);
|
||||
if (data.confidi) {
|
||||
displayConfidiPopup();
|
||||
} else {
|
||||
const bandoId = getBandoId();
|
||||
ApplicationService.createApplication(bandoId, {}, createApplCallback, errCreateApplCallback, [['companyId', chosenCompanyId]]);
|
||||
if (applicationObj && applicationObj.id) {
|
||||
navigate(`/imieibandi/${applicationObj.id}`);
|
||||
} else {
|
||||
const bandoId = getBandoId();
|
||||
ApplicationService.createApplication(bandoId, {}, createApplCallback, errCreateApplCallback, [['companyId', chosenCompanyId]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -308,7 +322,7 @@ const BandoViewBeneficiario = () => {
|
||||
<div className="appPageSection__withBorder">
|
||||
<h2>{__('Documentazione Richiesta', 'gepafin')}</h2>
|
||||
<div className="row rowContent">
|
||||
<p>{renderHtmlContent(data.documentationRequested)}</p>
|
||||
{renderHtmlContent(data.documentationRequested)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -328,7 +342,7 @@ const BandoViewBeneficiario = () => {
|
||||
<div className="row rowContent">
|
||||
<ul>
|
||||
{data.docs
|
||||
.filter(o => o.source === 'CALL')
|
||||
.filter(o => o.source === 'CALL' && o.type === 'DOCUMENT')
|
||||
.map((o, i) => <li key={i}>
|
||||
<a href={o.filePath} target="_blank" rel="noreferrer">{o.name}</a>
|
||||
</li>)}
|
||||
@@ -380,10 +394,14 @@ const BandoViewBeneficiario = () => {
|
||||
: null}
|
||||
|
||||
{data.confidi
|
||||
? <>
|
||||
<Message severity="error"
|
||||
text={__('Non sei abilitato a partecipare a questo Bando', 'gepafin')}/>
|
||||
</>
|
||||
? <Dialog header={data.name}
|
||||
visible={isVisibleConfidiPopup}
|
||||
style={{ width: '50vw' }}
|
||||
onHide={hideConfidiPopup}>
|
||||
<p>
|
||||
{__('Non risultano convenzioni attive', 'gepafin')}
|
||||
</p>
|
||||
</Dialog>
|
||||
: null}
|
||||
|
||||
<div className="appPageSection">
|
||||
@@ -398,14 +416,13 @@ const BandoViewBeneficiario = () => {
|
||||
icon="pi pi-download" iconPos="right"/>*/}
|
||||
<Button
|
||||
type="button"
|
||||
disabled={data.confidi}
|
||||
outlined
|
||||
onClick={scaricaModulistica}
|
||||
label={__('Scarica Bando Completo e Modulistica', 'gepafin')}
|
||||
icon="pi pi-download" iconPos="right"/>
|
||||
<Button
|
||||
type="button"
|
||||
disabled={isAsyncRequest || chosenCompanyId === 0 || data.confidi}
|
||||
disabled={isAsyncRequest || chosenCompanyId === 0}
|
||||
onClick={submitApplication}
|
||||
label={__('Presenta Domanda', 'gepafin')}
|
||||
icon="pi pi-save" iconPos="right"/>
|
||||
|
||||
@@ -15,6 +15,7 @@ import LatestBandiTable from './components/LatestBandiTable';
|
||||
//import LatestUsersActivityTable from './components/LatestUsersActivityTable';
|
||||
import { Button } from 'primereact/button';
|
||||
import MyEvaluationsTable from '../DashboardInstructor/components/MyEvaluationsTable';
|
||||
import AllDomandeTable from '../Domande/components/AllDomandeTable';
|
||||
|
||||
const Dashboard = () => {
|
||||
const navigate = useNavigate();
|
||||
@@ -130,7 +131,7 @@ const Dashboard = () => {
|
||||
|
||||
<div className="appPageSection">
|
||||
<h2>{__('Ultime domande pubblicate', 'gepafin')}</h2>
|
||||
<MyEvaluationsTable/>
|
||||
<AllDomandeTable/>
|
||||
</div>
|
||||
|
||||
{/*<div className="appPage__spacer"></div>
|
||||
|
||||
@@ -125,10 +125,14 @@ const AllDomandeTable = ({ openDialogFn }) => {
|
||||
};
|
||||
|
||||
const actionsBodyTemplate = (rowData) => {
|
||||
return <Button severity="info"
|
||||
return openDialogFn
|
||||
? <Button severity="info"
|
||||
onClick={() => openDialogFn(rowData.id)}
|
||||
label={__('Assegnare', 'gepafin')}
|
||||
icon="pi pi-pencil" size="small" iconPos="right" />
|
||||
: <Link to={'/domande'}>
|
||||
<Button severity="info" label={__('Gestire', 'gepafin')} size="small" />
|
||||
</Link>
|
||||
}
|
||||
|
||||
const header = renderHeader();
|
||||
|
||||
@@ -25,14 +25,15 @@ const Login = () => {
|
||||
const errorMsgs = useRef(null);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [visibleCacheFaq, setVisibleCacheFaq] = useState(false);
|
||||
const [isMaintenance] = useState(false);
|
||||
let [searchParams] = useSearchParams();
|
||||
const { origin } = window.location;
|
||||
|
||||
const loginWithSpid = () => {
|
||||
if (!loading) {
|
||||
if (!loading && !isMaintenance) {
|
||||
if (APP_HUB_ID) {
|
||||
window.location.replace(`${API_BASE_URL}/saml2/authenticate/loginumbria?hubId=${APP_HUB_ID}`);
|
||||
}else {
|
||||
} else {
|
||||
window.location.replace(`${API_BASE_URL}/saml2/authenticate/loginumbria`);
|
||||
}
|
||||
}
|
||||
@@ -46,25 +47,29 @@ const Login = () => {
|
||||
userData: data.data.user
|
||||
});
|
||||
} else {
|
||||
errorMsgs.current.show([
|
||||
{
|
||||
sticky: true, severity: 'error', summary: '',
|
||||
detail: data.message,
|
||||
closable: true
|
||||
}
|
||||
]);
|
||||
if (errorMsgs.current) {
|
||||
errorMsgs.current.show([
|
||||
{
|
||||
sticky: true, severity: 'error', summary: '',
|
||||
detail: data.message,
|
||||
closable: true
|
||||
}
|
||||
]);
|
||||
}
|
||||
}
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
const validateError = (err) => {
|
||||
errorMsgs.current.show([
|
||||
{
|
||||
sticky: true, severity: 'error', summary: '',
|
||||
detail: sprintf(__('%s', 'gepafin'), err.message),
|
||||
closable: true
|
||||
}
|
||||
]);
|
||||
if (errorMsgs.current) {
|
||||
errorMsgs.current.show([
|
||||
{
|
||||
sticky: true, severity: 'error', summary: '',
|
||||
detail: sprintf(__('%s', 'gepafin'), err.message),
|
||||
closable: true
|
||||
}
|
||||
]);
|
||||
}
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
@@ -77,6 +82,20 @@ const Login = () => {
|
||||
setVisibleCacheFaq(false);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (isMaintenance) {
|
||||
if (errorMsgs.current) {
|
||||
errorMsgs.current.show([
|
||||
{
|
||||
sticky: true, severity: 'info', summary: '',
|
||||
detail: __('Piattaforma in manutenzione', 'gepafin'),
|
||||
closable: false
|
||||
}
|
||||
]);
|
||||
}
|
||||
}
|
||||
}, [isMaintenance])
|
||||
|
||||
useEffect(() => {
|
||||
if (!isEmpty(token)) {
|
||||
window.location.replace('/')
|
||||
@@ -103,7 +122,7 @@ const Login = () => {
|
||||
|
||||
<Messages ref={errorMsgs}/>
|
||||
|
||||
<button className="appPageLogin__spidBtn" onClick={loginWithSpid}>
|
||||
<button className="appPageLogin__spidBtn" onClick={loginWithSpid} disabled={isMaintenance}>
|
||||
<svg width="31" height="31" viewBox="0 0 31 31" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clipPath="url(#clip0_1156_13356)">
|
||||
<path
|
||||
|
||||
Reference in New Issue
Block a user