- contract functionality;
This commit is contained in:
@@ -1,29 +1,49 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { Link, useNavigate } from 'react-router-dom';
|
||||
import { head, isEmpty, pathOr } from 'ramda';
|
||||
import NumberFlow from '@number-flow/react';
|
||||
import { wrap } from 'object-path-immutable';
|
||||
|
||||
// store
|
||||
import { useStoreValue } from '../../store';
|
||||
import { storeGet, storeSet, useStoreValue } from '../../store';
|
||||
|
||||
// api
|
||||
import DashboardService from '../../service/dashboard-service';
|
||||
import ApplicationContractService from '../../service/application-contract-service';
|
||||
|
||||
// tools
|
||||
import set404FromErrorResponse from '../../helpers/set404FromErrorResponse';
|
||||
import getFormatedFileSizeText from '../../helpers/getFormatedFileSizeText';
|
||||
|
||||
// components
|
||||
import { Button } from 'primereact/button';
|
||||
import ErrorBoundary from '../../components/ErrorBoundary';
|
||||
import LatestBandiBeneficiarioTableAsync from './components/LatestBandiBeneficiarioTableAsync';
|
||||
import MyLatestSubmissionsTableAsync from './components/MyLatestSubmissionsTableAsync';
|
||||
import { classNames } from 'primereact/utils';
|
||||
import { FileUpload } from 'primereact/fileupload';
|
||||
import { defaultMaxFileSize, mimeTypes } from '../../configData';
|
||||
import { Dialog } from 'primereact/dialog';
|
||||
import { Toast } from 'primereact/toast';
|
||||
|
||||
const REACT_APP_HUB_ID = process.env.REACT_APP_HUB_ID;
|
||||
|
||||
const DashboardBeneficiario = () => {
|
||||
const isAsyncRequest = useStoreValue('isAsyncRequest');
|
||||
const navigate = useNavigate();
|
||||
const [mainStats, setMainStats] = useState({});
|
||||
const [contractsData, setContractsData] = useState([]);
|
||||
const companies = useStoreValue('companies');
|
||||
const chosenCompanyId = useStoreValue('chosenCompanyId');
|
||||
const company = head(companies.filter(o => o.id === chosenCompanyId));
|
||||
const [isVisibleContractForm, setIsVisibleContractForm] = useState(false);
|
||||
const [contractFormData, setContractFormData] = useState({
|
||||
subject: '',
|
||||
text: ''
|
||||
});
|
||||
const contractFormFilesRef = useRef(null);
|
||||
const toast = useRef(null);
|
||||
|
||||
const goToAllSubmissions = () => {
|
||||
navigate('/bandi');
|
||||
@@ -42,11 +62,112 @@ const DashboardBeneficiario = () => {
|
||||
const errGetStats = () => {
|
||||
}
|
||||
|
||||
const getContracts = (data) => {
|
||||
if (data.status === 'SUCCESS') {
|
||||
setContractsData(data.data);
|
||||
}
|
||||
}
|
||||
|
||||
const errGetContracts = () => {
|
||||
}
|
||||
|
||||
const openSendContractForm = useCallback((id) => {
|
||||
const contract = head(contractsData.filter(o => o.id === id));
|
||||
|
||||
if (contract) {
|
||||
setContractFormData(contract)
|
||||
setIsVisibleContractForm(true);
|
||||
}
|
||||
}, [contractsData]);
|
||||
|
||||
const headerContractDialog = () => {
|
||||
return <span>{__('Invia il contratto', 'gepafin')}</span>;
|
||||
}
|
||||
|
||||
const hideContractDialog = () => {
|
||||
setIsVisibleContractForm(false);
|
||||
setContractFormData({
|
||||
subject: '',
|
||||
text: ''
|
||||
});
|
||||
}
|
||||
|
||||
const footerContractDialog = useCallback(() => {
|
||||
let isDisabled = !contractFormData.files || isEmpty(contractFormData.files) || isAsyncRequest;
|
||||
|
||||
return <div>
|
||||
<Button type="button" label={__('Annulla', 'gepafin')} onClick={hideContractDialog} outlined/>
|
||||
<Button
|
||||
type="button"
|
||||
disabled={isDisabled}
|
||||
label={__('Invia', 'gepafin')} onClick={doSendContract}/>
|
||||
</div>
|
||||
}, [contractFormData]);
|
||||
|
||||
const updateContractFormData = (value, path) => {
|
||||
const newData = wrap(contractFormData).set(path.split('.'), value).value();
|
||||
setContractFormData(newData);
|
||||
};
|
||||
|
||||
const doSendContract = useCallback(() => {
|
||||
if (contractFormData.files && !isEmpty(contractFormData.files) && !isAsyncRequest) {
|
||||
const formDataToSend = new FormData();
|
||||
|
||||
if (contractFormData.files && contractFormData.files.length > 0) {
|
||||
contractFormData.files.forEach((file) => {
|
||||
formDataToSend.append('beneficiaryContractDocuments', file);
|
||||
});
|
||||
}
|
||||
|
||||
storeSet('setAsyncRequest');
|
||||
|
||||
ApplicationContractService.updateApplicationContract(
|
||||
contractFormData.id,
|
||||
formDataToSend,
|
||||
getUploadApplicationContractCallback,
|
||||
errGetUploadApplicationContractCallback
|
||||
);
|
||||
}
|
||||
}, [contractFormData]);
|
||||
|
||||
const getUploadApplicationContractCallback = (data) => {
|
||||
if (data.status === 'SUCCESS') {
|
||||
//setData(getFormattedData(data.data));
|
||||
if (toast.current && data.message) {
|
||||
toast.current.show({
|
||||
severity: 'success',
|
||||
summary: '',
|
||||
detail: data.message
|
||||
});
|
||||
}
|
||||
}
|
||||
hideContractDialog();
|
||||
storeSet('unsetAsyncRequest');
|
||||
}
|
||||
|
||||
const errGetUploadApplicationContractCallback = (data) => {
|
||||
if (toast.current && data.message) {
|
||||
toast.current.show({
|
||||
severity: data.status === 'SUCCESS' ? 'info' : 'error',
|
||||
summary: '',
|
||||
detail: data.message
|
||||
});
|
||||
}
|
||||
hideContractDialog();
|
||||
set404FromErrorResponse(data);
|
||||
storeSet('unsetAsyncRequest');
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const existingCompany = head(companies.filter(o => o.id === chosenCompanyId));
|
||||
|
||||
if (existingCompany) {
|
||||
DashboardService.getBeneficiaryStatsForCompany(existingCompany.id, getStats, errGetStats);
|
||||
const userData = storeGet('userData');
|
||||
|
||||
ApplicationContractService.getContractByUserId(getContracts, errGetContracts, [
|
||||
['userId', userData.id]
|
||||
]);
|
||||
}
|
||||
}, [companies, chosenCompanyId]);
|
||||
|
||||
@@ -57,7 +178,28 @@ const DashboardBeneficiario = () => {
|
||||
{company ? <span className="companyName">{company.companyName}</span> : null}
|
||||
</div>
|
||||
|
||||
{contractsData && !isEmpty(contractsData)
|
||||
? <>
|
||||
<div className="appPage__spacer"></div>
|
||||
<div className="appPageSection__message warning">
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 10, width: '100%' }}>
|
||||
<div style={{ display: 'flex', gap: 10 }}>
|
||||
<i className="pi pi-info-circle"></i>
|
||||
<span className="summary">{__('You must upload contract for applications:', 'gepafin')}</span>
|
||||
</div>
|
||||
<ul>
|
||||
{contractsData.map(o => <li key={o.id}>
|
||||
<a href="#" onClick={() => openSendContractForm(o.id)}>
|
||||
{o.callName} - Domanda #{o.applicationId}
|
||||
</a>
|
||||
</li>)}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</> : null}
|
||||
|
||||
<div className="appPage__spacer"></div>
|
||||
<Toast ref={toast}/>
|
||||
|
||||
<div className="appPageSection statsBigBadges">
|
||||
<h2>{__('Panoramica di Sistema', 'gepafin')}</h2>
|
||||
@@ -162,6 +304,88 @@ const DashboardBeneficiario = () => {
|
||||
label={__('Contatta assistenza', 'gepafin')} icon="pi pi-envelope" iconPos="right"/>*/}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Dialog
|
||||
visible={isVisibleContractForm}
|
||||
modal
|
||||
header={headerContractDialog}
|
||||
footer={footerContractDialog}
|
||||
style={{ maxWidth: '600px', width: '100%' }}
|
||||
onHide={hideContractDialog}>
|
||||
<div className="appForm__field">
|
||||
<p>The administration requires you to download these documents:</p>
|
||||
<ul>
|
||||
{contractFormData?.instructorDocuments
|
||||
? contractFormData.instructorDocuments.map(o => <li key={o.id}>
|
||||
<a href={o.filePath} target="_blank" rel="noreferrer">{o.name}</a>
|
||||
</li>)
|
||||
: null}
|
||||
</ul>
|
||||
<p>Sign them digitally and upload them back in the form below:</p>
|
||||
</div>
|
||||
<div className="appForm__field">
|
||||
<label
|
||||
className={classNames({ 'p-error': !contractFormData.files || isEmpty(contractFormData.files) })}>
|
||||
{__('Files', 'gepafin')}*
|
||||
</label>
|
||||
<FileUpload
|
||||
ref={contractFormFilesRef}
|
||||
name="files[]"
|
||||
multiple
|
||||
accept={mimeTypes.map(o => o.code).join(',')}
|
||||
maxFileSize={defaultMaxFileSize}
|
||||
auto={false}
|
||||
customUpload={true}
|
||||
className={classNames({ 'p-invalid': !contractFormData.files || isEmpty(contractFormData.files) })}
|
||||
onSelect={(e) => {
|
||||
updateContractFormData(e.files, 'files');
|
||||
}}
|
||||
onRemove={(e) => {
|
||||
const updatedFiles = contractFormFilesRef.current.getFiles();
|
||||
updateContractFormData(updatedFiles, 'files');
|
||||
}}
|
||||
headerTemplate={(options) => {
|
||||
const { chooseButton } = options;
|
||||
return (
|
||||
<div className="p-fileupload-buttonbar" data-pc-section="buttonbar">
|
||||
{chooseButton}
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
chooseOptions={{
|
||||
label: __('Aggiungi i file', 'gepafin'),
|
||||
icon: 'pi pi-plus'
|
||||
}}
|
||||
itemTemplate={(file, props) => {
|
||||
return (
|
||||
<div className="p-fileupload-row" data-pc-section="file">
|
||||
<div data-pc-section="details" style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: '10px',
|
||||
textAlign: 'left'
|
||||
}}>
|
||||
<div className="p-fileupload-filename" data-pc-section="filename">
|
||||
{file.name}
|
||||
</div>
|
||||
<span
|
||||
data-pc-section="filesize">{getFormatedFileSizeText(file.size)}</span>
|
||||
</div>
|
||||
<div data-pc-section="actions">
|
||||
<Button
|
||||
type="button"
|
||||
icon="pi pi-times"
|
||||
className="p-button-rounded p-button-danger p-button-text"
|
||||
onClick={() => props.onRemove()}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
emptyTemplate={<p className="m-0">{__('Trascina i file qua')}</p>}
|
||||
/>
|
||||
</div>
|
||||
</Dialog>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,29 +1,49 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { __ } from '@wordpress/i18n';
|
||||
import { Link, useNavigate } from 'react-router-dom';
|
||||
import { head, isEmpty, pathOr } from 'ramda';
|
||||
import NumberFlow from '@number-flow/react';
|
||||
import { wrap } from 'object-path-immutable';
|
||||
|
||||
// store
|
||||
import { useStoreValue } from '../../store';
|
||||
import { storeGet, storeSet, useStoreValue } from '../../store';
|
||||
|
||||
// api
|
||||
import DashboardService from '../../service/dashboard-service';
|
||||
import ApplicationContractService from '../../service/application-contract-service';
|
||||
|
||||
// tools
|
||||
import getFormatedFileSizeText from '../../helpers/getFormatedFileSizeText';
|
||||
import set404FromErrorResponse from '../../helpers/set404FromErrorResponse';
|
||||
|
||||
// components
|
||||
import { Button } from 'primereact/button';
|
||||
import ErrorBoundary from '../../components/ErrorBoundary';
|
||||
import MyLatestSubmissionsTableAsync from '../DashboardBeneficiario/components/MyLatestSubmissionsTableAsync';
|
||||
import LatestBandiBeneficiarioTableAsync from '../DashboardBeneficiario/components/LatestBandiBeneficiarioTableAsync';
|
||||
import { classNames } from 'primereact/utils';
|
||||
import { FileUpload } from 'primereact/fileupload';
|
||||
import { defaultMaxFileSize, mimeTypes } from '../../configData';
|
||||
import { Dialog } from 'primereact/dialog';
|
||||
import { Toast } from 'primereact/toast';
|
||||
|
||||
const REACT_APP_HUB_ID = process.env.REACT_APP_HUB_ID;
|
||||
|
||||
const DashboardBeneficiarioConfidi = () => {
|
||||
const isAsyncRequest = useStoreValue('isAsyncRequest');
|
||||
const navigate = useNavigate();
|
||||
const [mainStats, setMainStats] = useState({});
|
||||
const [contractsData, setContractsData] = useState([]);
|
||||
const companies = useStoreValue('companies');
|
||||
const chosenCompanyId = useStoreValue('chosenCompanyId');
|
||||
const company = head(companies.filter(o => o.id === chosenCompanyId));
|
||||
const [isVisibleContractForm, setIsVisibleContractForm] = useState(false);
|
||||
const [contractFormData, setContractFormData] = useState({
|
||||
subject: '',
|
||||
text: ''
|
||||
});
|
||||
const contractFormFilesRef = useRef(null);
|
||||
const toast = useRef(null);
|
||||
|
||||
const goToAllSubmissions = () => {
|
||||
navigate('/bandi');
|
||||
@@ -42,11 +62,112 @@ const DashboardBeneficiarioConfidi = () => {
|
||||
const errGetStats = () => {
|
||||
}
|
||||
|
||||
const getContracts = (data) => {
|
||||
if (data.status === 'SUCCESS') {
|
||||
setContractsData(data.data);
|
||||
}
|
||||
}
|
||||
|
||||
const errGetContracts = () => {
|
||||
}
|
||||
|
||||
const openSendContractForm = useCallback((id) => {
|
||||
const contract = head(contractsData.filter(o => o.id === id));
|
||||
|
||||
if (contract) {
|
||||
setContractFormData(contract)
|
||||
setIsVisibleContractForm(true);
|
||||
}
|
||||
}, [contractsData]);
|
||||
|
||||
const headerContractDialog = () => {
|
||||
return <span>{__('Invia il contratto', 'gepafin')}</span>;
|
||||
}
|
||||
|
||||
const hideContractDialog = () => {
|
||||
setIsVisibleContractForm(false);
|
||||
setContractFormData({
|
||||
subject: '',
|
||||
text: ''
|
||||
});
|
||||
}
|
||||
|
||||
const footerContractDialog = useCallback(() => {
|
||||
let isDisabled = !contractFormData.files || isEmpty(contractFormData.files) || isAsyncRequest;
|
||||
|
||||
return <div>
|
||||
<Button type="button" label={__('Annulla', 'gepafin')} onClick={hideContractDialog} outlined/>
|
||||
<Button
|
||||
type="button"
|
||||
disabled={isDisabled}
|
||||
label={__('Invia', 'gepafin')} onClick={doSendContract}/>
|
||||
</div>
|
||||
}, [contractFormData]);
|
||||
|
||||
const updateContractFormData = (value, path) => {
|
||||
const newData = wrap(contractFormData).set(path.split('.'), value).value();
|
||||
setContractFormData(newData);
|
||||
};
|
||||
|
||||
const doSendContract = useCallback(() => {
|
||||
if (contractFormData.files && !isEmpty(contractFormData.files) && !isAsyncRequest) {
|
||||
const formDataToSend = new FormData();
|
||||
|
||||
if (contractFormData.files && contractFormData.files.length > 0) {
|
||||
contractFormData.files.forEach((file) => {
|
||||
formDataToSend.append('beneficiaryContractDocuments', file);
|
||||
});
|
||||
}
|
||||
|
||||
storeSet('setAsyncRequest');
|
||||
|
||||
ApplicationContractService.updateApplicationContract(
|
||||
contractFormData.id,
|
||||
formDataToSend,
|
||||
getUploadApplicationContractCallback,
|
||||
errGetUploadApplicationContractCallback
|
||||
);
|
||||
}
|
||||
}, [contractFormData]);
|
||||
|
||||
const getUploadApplicationContractCallback = (data) => {
|
||||
if (data.status === 'SUCCESS') {
|
||||
//setData(getFormattedData(data.data));
|
||||
if (toast.current && data.message) {
|
||||
toast.current.show({
|
||||
severity: 'success',
|
||||
summary: '',
|
||||
detail: data.message
|
||||
});
|
||||
}
|
||||
}
|
||||
hideContractDialog();
|
||||
storeSet('unsetAsyncRequest');
|
||||
}
|
||||
|
||||
const errGetUploadApplicationContractCallback = (data) => {
|
||||
if (toast.current && data.message) {
|
||||
toast.current.show({
|
||||
severity: data.status === 'SUCCESS' ? 'info' : 'error',
|
||||
summary: '',
|
||||
detail: data.message
|
||||
});
|
||||
}
|
||||
hideContractDialog();
|
||||
set404FromErrorResponse(data);
|
||||
storeSet('unsetAsyncRequest');
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const existingCompany = head(companies.filter(o => o.id === chosenCompanyId));
|
||||
|
||||
if (existingCompany) {
|
||||
DashboardService.getBeneficiaryStatsForCompany(existingCompany.id, getStats, errGetStats);
|
||||
const userData = storeGet('userData');
|
||||
|
||||
ApplicationContractService.getContractByUserId(getContracts, errGetContracts, [
|
||||
['userId', userData.id]
|
||||
]);
|
||||
}
|
||||
}, [companies, chosenCompanyId]);
|
||||
|
||||
@@ -57,7 +178,28 @@ const DashboardBeneficiarioConfidi = () => {
|
||||
{company ? <span className="companyName">{company.companyName}</span> : null}
|
||||
</div>
|
||||
|
||||
{contractsData && !isEmpty(contractsData)
|
||||
? <>
|
||||
<div className="appPage__spacer"></div>
|
||||
<div className="appPageSection__message warning">
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 10, width: '100%' }}>
|
||||
<div style={{ display: 'flex', gap: 10 }}>
|
||||
<i className="pi pi-info-circle"></i>
|
||||
<span className="summary">{__('You must upload contract for applications:', 'gepafin')}</span>
|
||||
</div>
|
||||
<ul>
|
||||
{contractsData.map(o => <li key={o.id}>
|
||||
<a href="#" onClick={() => openSendContractForm(o.id)}>
|
||||
{o.callName} - Domanda #{o.applicationId}
|
||||
</a>
|
||||
</li>)}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</> : null}
|
||||
|
||||
<div className="appPage__spacer"></div>
|
||||
<Toast ref={toast}/>
|
||||
|
||||
<div className="appPageSection statsBigBadges">
|
||||
<h2>{__('Panoramica di Sistema', 'gepafin')}</h2>
|
||||
@@ -102,7 +244,7 @@ const DashboardBeneficiarioConfidi = () => {
|
||||
<span className="summary">{__('Attenzione', 'gepafin')}</span>
|
||||
<span>
|
||||
{__('Per applicare ai bandi devi Registare un Azienda clicca', 'gepafin')}
|
||||
<Link to={`/agguingi-azienda`} style={{marginLeft: '0.5ch'}}>{__('qua', 'gepafin')}</Link>
|
||||
<Link to={`/agguingi-azienda`} style={{ marginLeft: '0.5ch' }}>{__('qua', 'gepafin')}</Link>
|
||||
</span>
|
||||
</div>
|
||||
<div className="appPage__spacer"></div>
|
||||
@@ -148,8 +290,102 @@ const DashboardBeneficiarioConfidi = () => {
|
||||
<Button
|
||||
onClick={goToAllSubmissions}
|
||||
label={__('Nuova domanda', 'gepafin')} icon="pi pi-plus" iconPos="right"/>
|
||||
{/*<Button
|
||||
disabled={true}
|
||||
outlined
|
||||
onClick={() => {
|
||||
}}
|
||||
label={__('Carica documento', 'gepafin')} icon="pi pi-upload" iconPos="right"/>
|
||||
<Button
|
||||
disabled={true}
|
||||
outlined
|
||||
onClick={() => {
|
||||
}}
|
||||
label={__('Contatta assistenza', 'gepafin')} icon="pi pi-envelope" iconPos="right"/>*/}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Dialog
|
||||
visible={isVisibleContractForm}
|
||||
modal
|
||||
header={headerContractDialog}
|
||||
footer={footerContractDialog}
|
||||
style={{ maxWidth: '600px', width: '100%' }}
|
||||
onHide={hideContractDialog}>
|
||||
<div className="appForm__field">
|
||||
<p>The administration requires you to download these documents:</p>
|
||||
<ul>
|
||||
{contractFormData?.instructorDocuments
|
||||
? contractFormData.instructorDocuments.map(o => <li key={o.id}>
|
||||
<a href={o.filePath} target="_blank" rel="noreferrer">{o.name}</a>
|
||||
</li>)
|
||||
: null}
|
||||
</ul>
|
||||
<p>Sign them digitally and upload them back in the form below:</p>
|
||||
</div>
|
||||
<div className="appForm__field">
|
||||
<label
|
||||
className={classNames({ 'p-error': !contractFormData.files || isEmpty(contractFormData.files) })}>
|
||||
{__('Files', 'gepafin')}*
|
||||
</label>
|
||||
<FileUpload
|
||||
ref={contractFormFilesRef}
|
||||
name="files[]"
|
||||
multiple
|
||||
accept={mimeTypes.map(o => o.code).join(',')}
|
||||
maxFileSize={defaultMaxFileSize}
|
||||
auto={false}
|
||||
customUpload={true}
|
||||
className={classNames({ 'p-invalid': !contractFormData.files || isEmpty(contractFormData.files) })}
|
||||
onSelect={(e) => {
|
||||
updateContractFormData(e.files, 'files');
|
||||
}}
|
||||
onRemove={(e) => {
|
||||
const updatedFiles = contractFormFilesRef.current.getFiles();
|
||||
updateContractFormData(updatedFiles, 'files');
|
||||
}}
|
||||
headerTemplate={(options) => {
|
||||
const { chooseButton } = options;
|
||||
return (
|
||||
<div className="p-fileupload-buttonbar" data-pc-section="buttonbar">
|
||||
{chooseButton}
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
chooseOptions={{
|
||||
label: __('Aggiungi i file', 'gepafin'),
|
||||
icon: 'pi pi-plus'
|
||||
}}
|
||||
itemTemplate={(file, props) => {
|
||||
return (
|
||||
<div className="p-fileupload-row" data-pc-section="file">
|
||||
<div data-pc-section="details" style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: '10px',
|
||||
textAlign: 'left'
|
||||
}}>
|
||||
<div className="p-fileupload-filename" data-pc-section="filename">
|
||||
{file.name}
|
||||
</div>
|
||||
<span
|
||||
data-pc-section="filesize">{getFormatedFileSizeText(file.size)}</span>
|
||||
</div>
|
||||
<div data-pc-section="actions">
|
||||
<Button
|
||||
type="button"
|
||||
icon="pi pi-times"
|
||||
className="p-button-rounded p-button-danger p-button-text"
|
||||
onClick={() => props.onRemove()}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
emptyTemplate={<p className="m-0">{__('Trascina i file qua')}</p>}
|
||||
/>
|
||||
</div>
|
||||
</Dialog>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -110,7 +110,9 @@ const DashboardPreInstructor = () => {
|
||||
|
||||
<div className="appPageSection">
|
||||
<h2>{__('Coda di lavoro', 'gepafin')}</h2>
|
||||
<DomandeTablePreInstructorAsync statuses={['OPEN', 'SOCCORSO']} userId={userData.id}/>
|
||||
<DomandeTablePreInstructorAsync
|
||||
statuses={['OPEN', 'SOCCORSO', 'AWAITING_CONTRACT', 'CONTRACT_SIGNED']}
|
||||
userId={userData.id}/>
|
||||
</div>
|
||||
|
||||
<div className="appPage__spacer"></div>
|
||||
|
||||
@@ -15,6 +15,7 @@ import { storeGet, storeSet, useStoreValue } from '../../store';
|
||||
import ApplicationEvaluationService from '../../service/application-evaluation-service';
|
||||
import AmendmentsService from '../../service/amendments-service';
|
||||
import AppointmentService from '../../service/appointment-service';
|
||||
import ApplicationContractService from '../../service/application-contract-service';
|
||||
|
||||
// tools
|
||||
import set404FromErrorResponse from '../../helpers/set404FromErrorResponse';
|
||||
@@ -99,6 +100,12 @@ const DomandaEditInstructorManager = () => {
|
||||
duration: 0,
|
||||
amount: 0
|
||||
});
|
||||
const [isVisibleContractForm, setIsVisibleContractForm] = useState(false);
|
||||
const [contractFormData, setContractFormData] = useState({
|
||||
subject: '',
|
||||
text: ''
|
||||
});
|
||||
const contractFormFilesRef = useRef(null);
|
||||
const [formData, setFormData] = useState([]);
|
||||
const [formId, setFormId] = useState(0);
|
||||
const [formInitialData, setFormInitialData] = useState(null);
|
||||
@@ -1001,6 +1008,102 @@ const DomandaEditInstructorManager = () => {
|
||||
setData(newData);
|
||||
}, [data]);
|
||||
|
||||
const openSendContractForm = () => {
|
||||
setIsVisibleContractForm(true);
|
||||
}
|
||||
|
||||
const headerContractDialog = () => {
|
||||
return <span>{__('Invia il contratto', 'gepafin')}</span>;
|
||||
}
|
||||
|
||||
const hideContractDialog = () => {
|
||||
setIsVisibleContractForm(false);
|
||||
setContractFormData({
|
||||
subject: '',
|
||||
text: ''
|
||||
});
|
||||
}
|
||||
|
||||
const footerContractDialog = useCallback(() => {
|
||||
let isDisabled = !contractFormData.subject || isEmpty(contractFormData.subject)
|
||||
|| !contractFormData.text || isEmpty(contractFormData.text)
|
||||
|| !contractFormData.files || isEmpty(contractFormData.files) || isAsyncRequest;
|
||||
|
||||
return <div>
|
||||
<Button type="button" label={__('Annulla', 'gepafin')} onClick={hideContractDialog} outlined/>
|
||||
<Button
|
||||
type="button"
|
||||
disabled={isDisabled}
|
||||
label={__('Invia', 'gepafin')} onClick={doSendContract}/>
|
||||
</div>
|
||||
}, [contractFormData]);
|
||||
|
||||
const updateContractFormData = (value, path) => {
|
||||
const newData = wrap(contractFormData).set(path.split('.'), value).value();
|
||||
setContractFormData(newData);
|
||||
};
|
||||
|
||||
const doSendContract = useCallback(() => {
|
||||
if (
|
||||
contractFormData.subject && !isEmpty(contractFormData.subject)
|
||||
&& contractFormData.text && !isEmpty(contractFormData.text)
|
||||
&& contractFormData.files && !isEmpty(contractFormData.files)
|
||||
) {
|
||||
const formDataToSend = new FormData();
|
||||
const contractFormDataTemp = {
|
||||
...contractFormData
|
||||
};
|
||||
delete contractFormDataTemp.files;
|
||||
const jsonBlob = new Blob([JSON.stringify(contractFormDataTemp)], {
|
||||
type: 'application/json'
|
||||
});
|
||||
formDataToSend.append('applicationContractRequest', jsonBlob);
|
||||
|
||||
if (contractFormData.files && contractFormData.files.length > 0) {
|
||||
contractFormData.files.forEach((file) => {
|
||||
formDataToSend.append('contractDocuments', file);
|
||||
});
|
||||
}
|
||||
|
||||
storeSet('setAsyncRequest');
|
||||
|
||||
ApplicationContractService.uploadApplicationContract(
|
||||
data.applicationId,
|
||||
formDataToSend,
|
||||
getUploadApplicationContractCallback,
|
||||
errGetUploadApplicationContractCallback
|
||||
);
|
||||
}
|
||||
}, [contractFormData]);
|
||||
|
||||
const getUploadApplicationContractCallback = (data) => {
|
||||
if (data.status === 'SUCCESS') {
|
||||
//setData(getFormattedData(data.data));
|
||||
if (toast.current && data.message) {
|
||||
toast.current.show({
|
||||
severity: 'success',
|
||||
summary: '',
|
||||
detail: data.message
|
||||
});
|
||||
}
|
||||
}
|
||||
hideContractDialog();
|
||||
storeSet('unsetAsyncRequest');
|
||||
}
|
||||
|
||||
const errGetUploadApplicationContractCallback = (data) => {
|
||||
if (toast.current && data.message) {
|
||||
toast.current.show({
|
||||
severity: data.status === 'SUCCESS' ? 'info' : 'error',
|
||||
summary: '',
|
||||
detail: data.message
|
||||
});
|
||||
}
|
||||
hideContractDialog();
|
||||
set404FromErrorResponse(data);
|
||||
storeSet('unsetAsyncRequest');
|
||||
}
|
||||
|
||||
const actionBtns = () => {
|
||||
return <div className="appPageSection__actions">
|
||||
{(['SOCCORSO', 'CLOSE', 'EVALUATION', 'NDG', 'APPOINTMENT', 'ADMISSIBLE',
|
||||
@@ -1136,6 +1239,13 @@ const DomandaEditInstructorManager = () => {
|
||||
onClick={initiateRejecting}
|
||||
label={__('Respingi domanda', 'gepafin')}
|
||||
icon="pi pi-times" iconPos="right"/> : null}
|
||||
{APP_HUB_ID !== 't7jh5wfg9QXylNaTZkPoE' && data.applicationStatus === 'APPROVED'
|
||||
? <Button
|
||||
type="button"
|
||||
disabled={!data.id}
|
||||
onClick={openSendContractForm}
|
||||
label={__('Invia il contratto', 'gepafin')}
|
||||
/> : null}
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -1330,6 +1440,48 @@ const DomandaEditInstructorManager = () => {
|
||||
|
||||
{data.evaluationVersion === 'V2'
|
||||
? <div className="appPageSection">
|
||||
<h3>{__('Contratto', 'gepafin')}</h3>
|
||||
{data.contract && data.contract?.beneficiaryDocuments && !isEmpty(data.contract?.beneficiaryDocuments)
|
||||
? <ol className="appPageSection__list">
|
||||
{data.contract?.beneficiaryDocuments.map(o => <li key={o.id} className="appPageSection__listItem">
|
||||
<div className="appPageSection__listItemRow">
|
||||
<div>{renderHtmlContent(o.name)}</div>
|
||||
<div className="appPageSection__iconActions">
|
||||
<Button icon="pi pi-eye" rounded
|
||||
onClick={() => {
|
||||
window.open(o.fileDetail[0].filePath, '_blank').focus()
|
||||
}}
|
||||
outlined severity="info"
|
||||
aria-label={__('Mostra', 'gepafin')}/>
|
||||
<ArchiveDocument
|
||||
ndg={data.ndg}
|
||||
applicationId={id}
|
||||
fileDescr={renderHtmlContent(o.name)}
|
||||
fileId={o.id}
|
||||
updateFn={(attachId) => {
|
||||
setData((prev) => {
|
||||
const newDocuments = data.contract.beneficiaryDocuments
|
||||
.map(ob => {
|
||||
return ob.id === o.id
|
||||
? {...o, documentAttachmentId: attachId}
|
||||
: o;
|
||||
});
|
||||
return {
|
||||
...prev,
|
||||
contract: {
|
||||
...prev.contract,
|
||||
beneficiaryDocuments: newDocuments
|
||||
}
|
||||
}
|
||||
});
|
||||
}}
|
||||
isSignedDocument={true}
|
||||
docAttachmentId={o.documentAttachmentId}/>
|
||||
</div>
|
||||
</div>
|
||||
</li>)}
|
||||
</ol>
|
||||
: <p>{__('Nessun documento firmato', 'gepafin')}</p>}
|
||||
<h2>{__('Domanda PDF firmato', 'gepafin')}</h2>
|
||||
{data.signedDocument && !isEmpty(data.signedDocument)
|
||||
? <ol className="appPageSection__list">
|
||||
@@ -1345,7 +1497,10 @@ const DomandaEditInstructorManager = () => {
|
||||
updateFn={(attachId) => {
|
||||
setData((prev) => ({
|
||||
...prev,
|
||||
documentAttachmentId: attachId
|
||||
signedDocument: {
|
||||
...prev.signedDocument,
|
||||
documentAttachmentId: attachId
|
||||
}
|
||||
}));
|
||||
}}
|
||||
isSignedDocument={true}
|
||||
@@ -1467,6 +1622,48 @@ const DomandaEditInstructorManager = () => {
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h3>{__('Contratto', 'gepafin')}</h3>
|
||||
{data.contract && data.contract?.beneficiaryDocuments && !isEmpty(data.contract?.beneficiaryDocuments)
|
||||
? <ol className="appPageSection__list">
|
||||
{data.contract?.beneficiaryDocuments.map(o => <li key={o.id} className="appPageSection__listItem">
|
||||
<div className="appPageSection__listItemRow">
|
||||
<div>{renderHtmlContent(o.name)}</div>
|
||||
<div className="appPageSection__iconActions">
|
||||
<Button icon="pi pi-eye" rounded
|
||||
onClick={() => {
|
||||
window.open(o.fileDetail[0].filePath, '_blank').focus()
|
||||
}}
|
||||
outlined severity="info"
|
||||
aria-label={__('Mostra', 'gepafin')}/>
|
||||
<ArchiveDocument
|
||||
ndg={data.ndg}
|
||||
applicationId={id}
|
||||
fileDescr={renderHtmlContent(o.name)}
|
||||
fileId={o.id}
|
||||
updateFn={(attachId) => {
|
||||
setData((prev) => {
|
||||
const newDocuments = data.contract.beneficiaryDocuments
|
||||
.map(ob => {
|
||||
return ob.id === o.id
|
||||
? {...o, documentAttachmentId: attachId}
|
||||
: o;
|
||||
});
|
||||
return {
|
||||
...prev,
|
||||
contract: {
|
||||
...prev.contract,
|
||||
beneficiaryDocuments: newDocuments
|
||||
}
|
||||
}
|
||||
});
|
||||
}}
|
||||
isSignedDocument={true}
|
||||
docAttachmentId={o.documentAttachmentId}/>
|
||||
</div>
|
||||
</div>
|
||||
</li>)}
|
||||
</ol>
|
||||
: <p>{__('Nessun documento firmato', 'gepafin')}</p>}
|
||||
<h3>{__('Domanda PDF firmato', 'gepafin')}</h3>
|
||||
{data.signedDocument && !isEmpty(data.signedDocument)
|
||||
? <ol className="appPageSection__list">
|
||||
@@ -1474,6 +1671,12 @@ const DomandaEditInstructorManager = () => {
|
||||
<div className="appPageSection__listItemRow">
|
||||
<div>{renderHtmlContent(data.signedDocument.fileName)}</div>
|
||||
<div className="appPageSection__iconActions">
|
||||
<Button icon="pi pi-eye" rounded
|
||||
onClick={() => {
|
||||
window.open(data.signedDocument.filePath, '_blank').focus()
|
||||
}}
|
||||
outlined severity="info"
|
||||
aria-label={__('Mostra', 'gepafin')}/>
|
||||
<ArchiveDocument
|
||||
ndg={data.ndg}
|
||||
applicationId={id}
|
||||
@@ -1482,7 +1685,10 @@ const DomandaEditInstructorManager = () => {
|
||||
updateFn={(attachId) => {
|
||||
setData((prev) => ({
|
||||
...prev,
|
||||
documentAttachmentId: attachId
|
||||
signedDocument: {
|
||||
...prev.signedDocument,
|
||||
documentAttachmentId: attachId
|
||||
}
|
||||
}));
|
||||
}}
|
||||
isSignedDocument={true}
|
||||
@@ -1825,6 +2031,102 @@ const DomandaEditInstructorManager = () => {
|
||||
</div>
|
||||
</Dialog>
|
||||
|
||||
<Dialog
|
||||
visible={isVisibleContractForm}
|
||||
modal
|
||||
header={headerContractDialog}
|
||||
footer={footerContractDialog}
|
||||
style={{ maxWidth: '600px', width: '100%' }}
|
||||
onHide={hideContractDialog}>
|
||||
<div className="appForm__field">
|
||||
<label
|
||||
className={classNames({ 'p-error': !contractFormData.subject || isEmpty(contractFormData.subject) })}>
|
||||
{__('Oggetto', 'gepafin')}*
|
||||
</label>
|
||||
<InputText
|
||||
value={contractFormData.subject}
|
||||
invalid={isEmpty(contractFormData.subject)}
|
||||
onChange={(e) => updateContractFormData(e.target.value, 'subject')}/>
|
||||
</div>
|
||||
<div className="appForm__field">
|
||||
<label
|
||||
className={classNames({ 'p-error': !contractFormData.text || isEmpty(contractFormData.text) })}>
|
||||
{__('Testo', 'gepafin')}*
|
||||
</label>
|
||||
<div translate="no">
|
||||
<Editor
|
||||
value={contractFormData.text}
|
||||
readOnly={loading}
|
||||
placeholder={__('Digita qui il messagio', 'gepafin')}
|
||||
headerTemplate={header}
|
||||
onTextChange={(e) => updateContractFormData(e.htmlValue, 'text')}
|
||||
style={{ height: 80 * 3, width: '100%' }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="appForm__field">
|
||||
<label
|
||||
className={classNames({ 'p-error': !contractFormData.files || isEmpty(contractFormData.files) })}>
|
||||
{__('Files', 'gepafin')}*
|
||||
</label>
|
||||
<FileUpload
|
||||
ref={contractFormFilesRef}
|
||||
name="files[]"
|
||||
multiple
|
||||
accept={mimeTypes.map(o => o.code).join(',')}
|
||||
maxFileSize={defaultMaxFileSize}
|
||||
auto={false}
|
||||
customUpload={true}
|
||||
className={classNames({ 'p-invalid': !contractFormData.files || isEmpty(contractFormData.files) })}
|
||||
onSelect={(e) => {
|
||||
updateContractFormData(e.files, 'files');
|
||||
}}
|
||||
onRemove={(e) => {
|
||||
const updatedFiles = contractFormFilesRef.current.getFiles();
|
||||
updateContractFormData(updatedFiles, 'files');
|
||||
}}
|
||||
headerTemplate={(options) => {
|
||||
const { chooseButton } = options;
|
||||
return (
|
||||
<div className="p-fileupload-buttonbar" data-pc-section="buttonbar">
|
||||
{chooseButton}
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
chooseOptions={{
|
||||
label: __('Aggiungi i file', 'gepafin'),
|
||||
icon: 'pi pi-plus'
|
||||
}}
|
||||
itemTemplate={(file, props) => {
|
||||
return (
|
||||
<div className="p-fileupload-row" data-pc-section="file">
|
||||
<div data-pc-section="details" style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: '10px',
|
||||
textAlign: 'left'
|
||||
}}>
|
||||
<div className="p-fileupload-filename" data-pc-section="filename">
|
||||
{file.name}
|
||||
</div>
|
||||
<span
|
||||
data-pc-section="filesize">{getFormatedFileSizeText(file.size)}</span>
|
||||
</div>
|
||||
<div data-pc-section="actions">
|
||||
<Button
|
||||
type="button"
|
||||
icon="pi pi-times"
|
||||
className="p-button-rounded p-button-danger p-button-text"
|
||||
onClick={() => props.onRemove()}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
emptyTemplate={<p className="m-0">{__('Trascina i file qua')}</p>}
|
||||
/>
|
||||
</div>
|
||||
</Dialog>
|
||||
</div>
|
||||
: <>
|
||||
<Skeleton width="20%" height="1rem" className="mb-2"></Skeleton>
|
||||
|
||||
@@ -15,6 +15,7 @@ import { storeGet, storeSet, useStoreValue } from '../../store';
|
||||
import ApplicationEvaluationService from '../../service/application-evaluation-service';
|
||||
import AmendmentsService from '../../service/amendments-service';
|
||||
import AppointmentService from '../../service/appointment-service';
|
||||
import ApplicationContractService from '../../service/application-contract-service';
|
||||
|
||||
// tools
|
||||
import set404FromErrorResponse from '../../helpers/set404FromErrorResponse';
|
||||
@@ -99,6 +100,12 @@ const DomandaEditPreInstructor = () => {
|
||||
duration: 0,
|
||||
amount: 0
|
||||
});
|
||||
const [isVisibleContractForm, setIsVisibleContractForm] = useState(false);
|
||||
const [contractFormData, setContractFormData] = useState({
|
||||
subject: '',
|
||||
text: ''
|
||||
});
|
||||
const contractFormFilesRef = useRef(null);
|
||||
const [formData, setFormData] = useState([]);
|
||||
const [formId, setFormId] = useState(0);
|
||||
const [formInitialData, setFormInitialData] = useState(null);
|
||||
@@ -1001,6 +1008,102 @@ const DomandaEditPreInstructor = () => {
|
||||
setData(newData);
|
||||
}, [data]);
|
||||
|
||||
const openSendContractForm = () => {
|
||||
setIsVisibleContractForm(true);
|
||||
}
|
||||
|
||||
const headerContractDialog = () => {
|
||||
return <span>{__('Invia il contratto', 'gepafin')}</span>;
|
||||
}
|
||||
|
||||
const hideContractDialog = () => {
|
||||
setIsVisibleContractForm(false);
|
||||
setContractFormData({
|
||||
subject: '',
|
||||
text: ''
|
||||
});
|
||||
}
|
||||
|
||||
const footerContractDialog = useCallback(() => {
|
||||
let isDisabled = !contractFormData.subject || isEmpty(contractFormData.subject)
|
||||
|| !contractFormData.text || isEmpty(contractFormData.text)
|
||||
|| !contractFormData.files || isEmpty(contractFormData.files) || isAsyncRequest;
|
||||
|
||||
return <div>
|
||||
<Button type="button" label={__('Annulla', 'gepafin')} onClick={hideContractDialog} outlined/>
|
||||
<Button
|
||||
type="button"
|
||||
disabled={isDisabled}
|
||||
label={__('Invia', 'gepafin')} onClick={doSendContract}/>
|
||||
</div>
|
||||
}, [contractFormData]);
|
||||
|
||||
const updateContractFormData = (value, path) => {
|
||||
const newData = wrap(contractFormData).set(path.split('.'), value).value();
|
||||
setContractFormData(newData);
|
||||
};
|
||||
|
||||
const doSendContract = useCallback(() => {
|
||||
if (
|
||||
contractFormData.subject && !isEmpty(contractFormData.subject)
|
||||
&& contractFormData.text && !isEmpty(contractFormData.text)
|
||||
&& contractFormData.files && !isEmpty(contractFormData.files)
|
||||
) {
|
||||
const formDataToSend = new FormData();
|
||||
const contractFormDataTemp = {
|
||||
...contractFormData
|
||||
};
|
||||
delete contractFormDataTemp.files;
|
||||
const jsonBlob = new Blob([JSON.stringify(contractFormDataTemp)], {
|
||||
type: 'application/json'
|
||||
});
|
||||
formDataToSend.append('applicationContractRequest', jsonBlob);
|
||||
|
||||
if (contractFormData.files && contractFormData.files.length > 0) {
|
||||
contractFormData.files.forEach((file) => {
|
||||
formDataToSend.append('contractDocuments', file);
|
||||
});
|
||||
}
|
||||
|
||||
storeSet('setAsyncRequest');
|
||||
|
||||
ApplicationContractService.uploadApplicationContract(
|
||||
data.applicationId,
|
||||
formDataToSend,
|
||||
getUploadApplicationContractCallback,
|
||||
errGetUploadApplicationContractCallback
|
||||
);
|
||||
}
|
||||
}, [contractFormData]);
|
||||
|
||||
const getUploadApplicationContractCallback = (data) => {
|
||||
if (data.status === 'SUCCESS') {
|
||||
//setData(getFormattedData(data.data));
|
||||
if (toast.current && data.message) {
|
||||
toast.current.show({
|
||||
severity: 'success',
|
||||
summary: '',
|
||||
detail: data.message
|
||||
});
|
||||
}
|
||||
}
|
||||
hideContractDialog();
|
||||
storeSet('unsetAsyncRequest');
|
||||
}
|
||||
|
||||
const errGetUploadApplicationContractCallback = (data) => {
|
||||
if (toast.current && data.message) {
|
||||
toast.current.show({
|
||||
severity: data.status === 'SUCCESS' ? 'info' : 'error',
|
||||
summary: '',
|
||||
detail: data.message
|
||||
});
|
||||
}
|
||||
hideContractDialog();
|
||||
set404FromErrorResponse(data);
|
||||
storeSet('unsetAsyncRequest');
|
||||
}
|
||||
|
||||
const actionBtns = () => {
|
||||
return <div className="appPageSection__actions">
|
||||
{(['SOCCORSO', 'CLOSE', 'EVALUATION', 'NDG', 'APPOINTMENT', 'ADMISSIBLE',
|
||||
@@ -1136,6 +1239,13 @@ const DomandaEditPreInstructor = () => {
|
||||
onClick={initiateRejecting}
|
||||
label={__('Respingi domanda', 'gepafin')}
|
||||
icon="pi pi-times" iconPos="right"/> : null}
|
||||
{APP_HUB_ID !== 't7jh5wfg9QXylNaTZkPoE' && data.applicationStatus === 'APPROVED'
|
||||
? <Button
|
||||
type="button"
|
||||
disabled={!data.id}
|
||||
onClick={openSendContractForm}
|
||||
label={__('Invia il contratto', 'gepafin')}
|
||||
/> : null}
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -1330,6 +1440,48 @@ const DomandaEditPreInstructor = () => {
|
||||
|
||||
{data.evaluationVersion === 'V2'
|
||||
? <div className="appPageSection">
|
||||
<h3>{__('Contratto', 'gepafin')}</h3>
|
||||
{data.contract && data.contract?.beneficiaryDocuments && !isEmpty(data.contract?.beneficiaryDocuments)
|
||||
? <ol className="appPageSection__list">
|
||||
{data.contract?.beneficiaryDocuments.map(o => <li key={o.id} className="appPageSection__listItem">
|
||||
<div className="appPageSection__listItemRow">
|
||||
<div>{renderHtmlContent(o.name)}</div>
|
||||
<div className="appPageSection__iconActions">
|
||||
<Button icon="pi pi-eye" rounded
|
||||
onClick={() => {
|
||||
window.open(o.fileDetail[0].filePath, '_blank').focus()
|
||||
}}
|
||||
outlined severity="info"
|
||||
aria-label={__('Mostra', 'gepafin')}/>
|
||||
<ArchiveDocument
|
||||
ndg={data.ndg}
|
||||
applicationId={id}
|
||||
fileDescr={renderHtmlContent(o.name)}
|
||||
fileId={o.id}
|
||||
updateFn={(attachId) => {
|
||||
setData((prev) => {
|
||||
const newDocuments = data.contract.beneficiaryDocuments
|
||||
.map(ob => {
|
||||
return ob.id === o.id
|
||||
? {...o, documentAttachmentId: attachId}
|
||||
: o;
|
||||
});
|
||||
return {
|
||||
...prev,
|
||||
contract: {
|
||||
...prev.contract,
|
||||
beneficiaryDocuments: newDocuments
|
||||
}
|
||||
}
|
||||
});
|
||||
}}
|
||||
isSignedDocument={true}
|
||||
docAttachmentId={o.documentAttachmentId}/>
|
||||
</div>
|
||||
</div>
|
||||
</li>)}
|
||||
</ol>
|
||||
: <p>{__('Nessun documento firmato', 'gepafin')}</p>}
|
||||
<h2>{__('Domanda PDF firmato', 'gepafin')}</h2>
|
||||
{data.signedDocument && !isEmpty(data.signedDocument)
|
||||
? <ol className="appPageSection__list">
|
||||
@@ -1345,7 +1497,10 @@ const DomandaEditPreInstructor = () => {
|
||||
updateFn={(attachId) => {
|
||||
setData((prev) => ({
|
||||
...prev,
|
||||
documentAttachmentId: attachId
|
||||
signedDocument: {
|
||||
...prev.signedDocument,
|
||||
documentAttachmentId: attachId
|
||||
}
|
||||
}));
|
||||
}}
|
||||
isSignedDocument={true}
|
||||
@@ -1467,6 +1622,48 @@ const DomandaEditPreInstructor = () => {
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h3>{__('Contratto', 'gepafin')}</h3>
|
||||
{data.contract && data.contract?.beneficiaryDocuments && !isEmpty(data.contract?.beneficiaryDocuments)
|
||||
? <ol className="appPageSection__list">
|
||||
{data.contract?.beneficiaryDocuments.map(o => <li key={o.id} className="appPageSection__listItem">
|
||||
<div className="appPageSection__listItemRow">
|
||||
<div>{renderHtmlContent(o.name)}</div>
|
||||
<div className="appPageSection__iconActions">
|
||||
<Button icon="pi pi-eye" rounded
|
||||
onClick={() => {
|
||||
window.open(o.fileDetail[0].filePath, '_blank').focus()
|
||||
}}
|
||||
outlined severity="info"
|
||||
aria-label={__('Mostra', 'gepafin')}/>
|
||||
<ArchiveDocument
|
||||
ndg={data.ndg}
|
||||
applicationId={id}
|
||||
fileDescr={renderHtmlContent(o.name)}
|
||||
fileId={o.id}
|
||||
updateFn={(attachId) => {
|
||||
setData((prev) => {
|
||||
const newDocuments = data.contract.beneficiaryDocuments
|
||||
.map(ob => {
|
||||
return ob.id === o.id
|
||||
? {...o, documentAttachmentId: attachId}
|
||||
: o;
|
||||
});
|
||||
return {
|
||||
...prev,
|
||||
contract: {
|
||||
...prev.contract,
|
||||
beneficiaryDocuments: newDocuments
|
||||
}
|
||||
}
|
||||
});
|
||||
}}
|
||||
isSignedDocument={true}
|
||||
docAttachmentId={o.documentAttachmentId}/>
|
||||
</div>
|
||||
</div>
|
||||
</li>)}
|
||||
</ol>
|
||||
: <p>{__('Nessun documento firmato', 'gepafin')}</p>}
|
||||
<h3>{__('Domanda PDF firmato', 'gepafin')}</h3>
|
||||
{data.signedDocument && !isEmpty(data.signedDocument)
|
||||
? <ol className="appPageSection__list">
|
||||
@@ -1474,6 +1671,12 @@ const DomandaEditPreInstructor = () => {
|
||||
<div className="appPageSection__listItemRow">
|
||||
<div>{renderHtmlContent(data.signedDocument.fileName)}</div>
|
||||
<div className="appPageSection__iconActions">
|
||||
<Button icon="pi pi-eye" rounded
|
||||
onClick={() => {
|
||||
window.open(data.signedDocument.filePath, '_blank').focus()
|
||||
}}
|
||||
outlined severity="info"
|
||||
aria-label={__('Mostra', 'gepafin')}/>
|
||||
<ArchiveDocument
|
||||
ndg={data.ndg}
|
||||
applicationId={id}
|
||||
@@ -1482,7 +1685,10 @@ const DomandaEditPreInstructor = () => {
|
||||
updateFn={(attachId) => {
|
||||
setData((prev) => ({
|
||||
...prev,
|
||||
documentAttachmentId: attachId
|
||||
signedDocument: {
|
||||
...prev.signedDocument,
|
||||
documentAttachmentId: attachId
|
||||
}
|
||||
}));
|
||||
}}
|
||||
isSignedDocument={true}
|
||||
@@ -1825,6 +2031,102 @@ const DomandaEditPreInstructor = () => {
|
||||
</div>
|
||||
</Dialog>
|
||||
|
||||
<Dialog
|
||||
visible={isVisibleContractForm}
|
||||
modal
|
||||
header={headerContractDialog}
|
||||
footer={footerContractDialog}
|
||||
style={{ maxWidth: '600px', width: '100%' }}
|
||||
onHide={hideContractDialog}>
|
||||
<div className="appForm__field">
|
||||
<label
|
||||
className={classNames({ 'p-error': !contractFormData.subject || isEmpty(contractFormData.subject) })}>
|
||||
{__('Oggetto', 'gepafin')}*
|
||||
</label>
|
||||
<InputText
|
||||
value={contractFormData.subject}
|
||||
invalid={isEmpty(contractFormData.subject)}
|
||||
onChange={(e) => updateContractFormData(e.target.value, 'subject')}/>
|
||||
</div>
|
||||
<div className="appForm__field">
|
||||
<label
|
||||
className={classNames({ 'p-error': !contractFormData.text || isEmpty(contractFormData.text) })}>
|
||||
{__('Testo', 'gepafin')}*
|
||||
</label>
|
||||
<div translate="no">
|
||||
<Editor
|
||||
value={contractFormData.text}
|
||||
readOnly={loading}
|
||||
placeholder={__('Digita qui il messagio', 'gepafin')}
|
||||
headerTemplate={header}
|
||||
onTextChange={(e) => updateContractFormData(e.htmlValue, 'text')}
|
||||
style={{ height: 80 * 3, width: '100%' }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="appForm__field">
|
||||
<label
|
||||
className={classNames({ 'p-error': !contractFormData.files || isEmpty(contractFormData.files) })}>
|
||||
{__('Files', 'gepafin')}*
|
||||
</label>
|
||||
<FileUpload
|
||||
ref={contractFormFilesRef}
|
||||
name="files[]"
|
||||
multiple
|
||||
accept={mimeTypes.map(o => o.code).join(',')}
|
||||
maxFileSize={defaultMaxFileSize}
|
||||
auto={false}
|
||||
customUpload={true}
|
||||
className={classNames({ 'p-invalid': !contractFormData.files || isEmpty(contractFormData.files) })}
|
||||
onSelect={(e) => {
|
||||
updateContractFormData(e.files, 'files');
|
||||
}}
|
||||
onRemove={(e) => {
|
||||
const updatedFiles = contractFormFilesRef.current.getFiles();
|
||||
updateContractFormData(updatedFiles, 'files');
|
||||
}}
|
||||
headerTemplate={(options) => {
|
||||
const { chooseButton } = options;
|
||||
return (
|
||||
<div className="p-fileupload-buttonbar" data-pc-section="buttonbar">
|
||||
{chooseButton}
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
chooseOptions={{
|
||||
label: __('Aggiungi i file', 'gepafin'),
|
||||
icon: 'pi pi-plus'
|
||||
}}
|
||||
itemTemplate={(file, props) => {
|
||||
return (
|
||||
<div className="p-fileupload-row" data-pc-section="file">
|
||||
<div data-pc-section="details" style={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: '10px',
|
||||
textAlign: 'left'
|
||||
}}>
|
||||
<div className="p-fileupload-filename" data-pc-section="filename">
|
||||
{file.name}
|
||||
</div>
|
||||
<span
|
||||
data-pc-section="filesize">{getFormatedFileSizeText(file.size)}</span>
|
||||
</div>
|
||||
<div data-pc-section="actions">
|
||||
<Button
|
||||
type="button"
|
||||
icon="pi pi-times"
|
||||
className="p-button-rounded p-button-danger p-button-text"
|
||||
onClick={() => props.onRemove()}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
emptyTemplate={<p className="m-0">{__('Trascina i file qua')}</p>}
|
||||
/>
|
||||
</div>
|
||||
</Dialog>
|
||||
</div>
|
||||
: <>
|
||||
<Skeleton width="20%" height="1rem" className="mb-2"></Skeleton>
|
||||
|
||||
@@ -15,7 +15,10 @@ const DomandeArchive = () => {
|
||||
|
||||
<div className="appPageSection">
|
||||
<h2>{__('Domande completate', 'gepafin')}</h2>
|
||||
<DomandeTablePreInstructorAsync statuses={['CLOSE']} applicationStatuses={['APPROVED', 'REJECTED', 'TECHNICAL_EVALUATION_REJECTED']} userId={0}/>
|
||||
<DomandeTablePreInstructorAsync
|
||||
statuses={['CLOSE', 'AWAITING_CONTRACT', 'CONTRACT_SIGNED']}
|
||||
applicationStatuses={['APPROVED', 'REJECTED', 'TECHNICAL_EVALUATION_REJECTED', 'AWAITING_CONTRACT', 'CONTRACT_SIGNED']}
|
||||
userId={0}/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -20,7 +20,10 @@ const DomandeArchivePreInstructor = () => {
|
||||
|
||||
<div className="appPageSection">
|
||||
<h2>{__('Domande completate', 'gepafin')}</h2>
|
||||
<DomandeTablePreInstructorAsync statuses={['CLOSE']} applicationStatuses={['APPROVED', 'REJECTED', 'TECHNICAL_EVALUATION_REJECTED']} userId={userData.id}/>
|
||||
<DomandeTablePreInstructorAsync
|
||||
statuses={['CLOSE', 'AWAITING_CONTRACT', 'CONTRACT_SIGNED']}
|
||||
applicationStatuses={['APPROVED', 'REJECTED', 'TECHNICAL_EVALUATION_REJECTED', 'AWAITING_CONTRACT', 'CONTRACT_SIGNED']}
|
||||
userId={userData.id}/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user