Merge pull request #60 from Kitzanos/master-sync/17-10-2025
Master sync/17 10 2025
This commit is contained in:
6
.idea/copilot.data.migration.agent.xml
generated
Normal file
6
.idea/copilot.data.migration.agent.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="AgentMigrationStateService">
|
||||||
|
<option name="migrationStatus" value="COMPLETED" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
6
.idea/copilot.data.migration.ask.xml
generated
Normal file
6
.idea/copilot.data.migration.ask.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="AskMigrationStateService">
|
||||||
|
<option name="migrationStatus" value="COMPLETED" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
6
.idea/copilot.data.migration.ask2agent.xml
generated
Normal file
6
.idea/copilot.data.migration.ask2agent.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="Ask2AgentMigrationStateService">
|
||||||
|
<option name="migrationStatus" value="COMPLETED" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
6
.idea/copilot.data.migration.edit.xml
generated
Normal file
6
.idea/copilot.data.migration.edit.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="EditMigrationStateService">
|
||||||
|
<option name="migrationStatus" value="COMPLETED" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
@@ -270,3 +270,39 @@ export const resendEmailLabelsByType = {
|
|||||||
APPLICATION_ADMISSIBLE: 'Invia email (ammisibile)',
|
APPLICATION_ADMISSIBLE: 'Invia email (ammisibile)',
|
||||||
APPLICATION_REJECTED: 'Invia email (respinto)'
|
APPLICATION_REJECTED: 'Invia email (respinto)'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const rejectionReasons = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
label: 'Documentazione incompleta',
|
||||||
|
text: 'la stessa è stata sottoposta ad istruttoria di ammissibilità con esito negativo.',
|
||||||
|
subject: 'Esito negativo istruttoria di ammissibilità'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
label: 'Altri motivi',
|
||||||
|
text: 'la stessa è stata esclusa dalla graduatoria definitiva',
|
||||||
|
subject: 'Esclusione dalla graduatoria definitiva.'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
export const amendmentRequestedDocs = {
|
||||||
|
NESSUNA_GARANZIA: [
|
||||||
|
'Lettera di accettazione firmata'
|
||||||
|
],
|
||||||
|
GARANZIA_MCC: [
|
||||||
|
'Lettera di accettazione firmata',
|
||||||
|
'Modulo di domanda della agevolazione (ex allegato 4)'
|
||||||
|
],
|
||||||
|
MCC_START_UP: [
|
||||||
|
'Lettera di accettazione firmata',
|
||||||
|
'Modulo di domanda della agevolazione (ex allegato 4)',
|
||||||
|
'Modello di valutazione bilanci previsionali',
|
||||||
|
'Modello valutazione start up'
|
||||||
|
],
|
||||||
|
ALTRE_GARANZIE: [
|
||||||
|
'Lettera di accettazione firmata',
|
||||||
|
'Modello privacy',
|
||||||
|
'Autocertificazione e altri eventuali in zip/p7m'
|
||||||
|
],
|
||||||
|
}
|
||||||
@@ -75,7 +75,7 @@ const getBandoLabel = (status) => {
|
|||||||
return __('Respinto', 'gepafin');
|
return __('Respinto', 'gepafin');
|
||||||
|
|
||||||
case 'TECHNICAL_EVALUATION_REJECTED':
|
case 'TECHNICAL_EVALUATION_REJECTED':
|
||||||
return __('Respinto', 'gepafin');
|
return __('Respinto Tec-Fin', 'gepafin');
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return '';
|
return '';
|
||||||
|
|||||||
@@ -72,6 +72,9 @@ const getBandoSeverity = (status) => {
|
|||||||
case 'REJECTED':
|
case 'REJECTED':
|
||||||
return 'danger';
|
return 'danger';
|
||||||
|
|
||||||
|
case 'TECHNICAL_EVALUATION_REJECTED':
|
||||||
|
return 'danger';
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return 'info';
|
return 'info';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,9 @@ import SoccorsoResendEmails from '../../../SoccorsoEditPreInstructor/components/
|
|||||||
|
|
||||||
const APP_HUB_ID = process.env.REACT_APP_HUB_ID;
|
const APP_HUB_ID = process.env.REACT_APP_HUB_ID;
|
||||||
|
|
||||||
const DomandeTablePreInstructorAsync = ({ userId = null, statuses = [] }) => {
|
const DomandeTablePreInstructorAsync = ({ userId = null, statuses = [],
|
||||||
|
applicationStatuses = ['EVALUATION', 'SOCCORSO', 'NDG', 'APPOINTMENT', 'ADMISSIBLE',
|
||||||
|
'AWAITING_TECHNICAL_EVALUATION', 'TECHNICAL_EVALUATION']}) => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const userData = useStoreValue('userData');
|
const userData = useStoreValue('userData');
|
||||||
const [localAsyncRequest, setLocalAsyncRequest] = useState(false);
|
const [localAsyncRequest, setLocalAsyncRequest] = useState(false);
|
||||||
@@ -106,14 +108,14 @@ const DomandeTablePreInstructorAsync = ({ userId = null, statuses = [] }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const statusFilterTemplate = (options) => {
|
const statusFilterTemplate = (options) => {
|
||||||
return <Dropdown value={options.value} options={statuses}
|
return <Dropdown value={options.value} options={applicationStatuses}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
options.filterCallback(e.value, options.index)
|
options.filterCallback(e.value, options.index)
|
||||||
const filters = { ...lazyState.filters };
|
const filters = { ...lazyState.filters };
|
||||||
if (e.value) {
|
if (e.value) {
|
||||||
filters['status'] = { value: e.value, matchMode: 'equals' };
|
filters['applicationStatus'] = { value: e.value, matchMode: 'equals' };
|
||||||
} else {
|
} else {
|
||||||
delete filters['status'];
|
delete filters['applicationStatus'];
|
||||||
}
|
}
|
||||||
setLazyState({ ...lazyState, filters, first: 0 });
|
setLazyState({ ...lazyState, filters, first: 0 });
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ import BlockingOverlay from '../../components/BlockingOverlay';
|
|||||||
import { classNames } from 'primereact/utils';
|
import { classNames } from 'primereact/utils';
|
||||||
import { InputTextarea } from 'primereact/inputtextarea';
|
import { InputTextarea } from 'primereact/inputtextarea';
|
||||||
import { InputText } from 'primereact/inputtext';
|
import { InputText } from 'primereact/inputtext';
|
||||||
|
import { Dropdown } from 'primereact/dropdown';
|
||||||
import ListOfFiles from '../DomandaEditPreInstructor/components/ListOfFiles';
|
import ListOfFiles from '../DomandaEditPreInstructor/components/ListOfFiles';
|
||||||
import RepeaterFields from '../DomandaEditPreInstructor/components/RepeaterFields';
|
import RepeaterFields from '../DomandaEditPreInstructor/components/RepeaterFields';
|
||||||
import ApplicationInfo from '../DomandaEditPreInstructor/components/ApplicationInfo';
|
import ApplicationInfo from '../DomandaEditPreInstructor/components/ApplicationInfo';
|
||||||
@@ -56,6 +57,9 @@ import FormField from '../../components/FormField';
|
|||||||
import SoccorsoResendEmails from '../SoccorsoEditPreInstructor/components/SoccorsoResendEmails';
|
import SoccorsoResendEmails from '../SoccorsoEditPreInstructor/components/SoccorsoResendEmails';
|
||||||
import EvaluationReAdmit from '../DomandaEditPreInstructor/components/EvaluationReAdmit';
|
import EvaluationReAdmit from '../DomandaEditPreInstructor/components/EvaluationReAdmit';
|
||||||
import { SplitButton } from 'primereact/splitbutton';
|
import { SplitButton } from 'primereact/splitbutton';
|
||||||
|
import { FileUpload } from 'primereact/fileupload';
|
||||||
|
import { defaultMaxFileSize, mimeTypes, rejectionReasons } from '../../configData';
|
||||||
|
import getFormatedFileSizeText from '../../helpers/getFormatedFileSizeText';
|
||||||
|
|
||||||
const APP_EVALUATION_FLOW_ID = process.env.REACT_APP_EVALUATION_FLOW_ID;
|
const APP_EVALUATION_FLOW_ID = process.env.REACT_APP_EVALUATION_FLOW_ID;
|
||||||
const APP_HUB_ID = process.env.REACT_APP_HUB_ID;
|
const APP_HUB_ID = process.env.REACT_APP_HUB_ID;
|
||||||
@@ -75,8 +79,10 @@ const DomandaEditInstructorManager = () => {
|
|||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [isVisibleCompleteDialog, setIsVisibleCompleteDialog] = useState(false);
|
const [isVisibleCompleteDialog, setIsVisibleCompleteDialog] = useState(false);
|
||||||
const [operationType, setOperationType] = useState('');
|
const [operationType, setOperationType] = useState('');
|
||||||
const [motivation, setMotivation] = useState('');
|
const [finalDialogData, setFinalDialogData] = useState({
|
||||||
const [amountAccepted, setAmountAccepted] = useState(0);
|
motivation: ''
|
||||||
|
});
|
||||||
|
const finalDialogFilesRef = useRef(null);
|
||||||
const [isVisibleAppointmentDialog, setIsVisibleAppointmentDialog] = useState(false);
|
const [isVisibleAppointmentDialog, setIsVisibleAppointmentDialog] = useState(false);
|
||||||
const [isVisiblePreTecEvalDialog, setIsVisiblePreTecEvalDialog] = useState(false);
|
const [isVisiblePreTecEvalDialog, setIsVisiblePreTecEvalDialog] = useState(false);
|
||||||
const [preTecEvalData, setPreTecEvalData] = useState({
|
const [preTecEvalData, setPreTecEvalData] = useState({
|
||||||
@@ -219,7 +225,7 @@ const DomandaEditInstructorManager = () => {
|
|||||||
const getCallback = (resp) => {
|
const getCallback = (resp) => {
|
||||||
if (resp.status === 'SUCCESS') {
|
if (resp.status === 'SUCCESS') {
|
||||||
setData(getFormattedData(resp.data));
|
setData(getFormattedData(resp.data));
|
||||||
setMotivation(resp.data.motivation);
|
setFinalDialogData((prev) => ({...prev, motivation: resp.data.motivation}));
|
||||||
updateFlagsForSoccorso(resp.data);
|
updateFlagsForSoccorso(resp.data);
|
||||||
|
|
||||||
if (resp.data.evaluationVersion === 'V2') {
|
if (resp.data.evaluationVersion === 'V2') {
|
||||||
@@ -372,9 +378,15 @@ const DomandaEditInstructorManager = () => {
|
|||||||
...cfgModifier
|
...cfgModifier
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const formDataToSend = new FormData();
|
||||||
|
const jsonBlob = new Blob([JSON.stringify(submitData)], {
|
||||||
|
type: 'application/json'
|
||||||
|
});
|
||||||
|
formDataToSend.append('evaluationRequest', jsonBlob);
|
||||||
|
|
||||||
ApplicationEvaluationService.updateEvaluation(
|
ApplicationEvaluationService.updateEvaluation(
|
||||||
data.assignedApplicationId,
|
data.assignedApplicationId,
|
||||||
submitData,
|
formDataToSend,
|
||||||
(data) => updateCallback(data, afterUpdateCallback),
|
(data) => updateCallback(data, afterUpdateCallback),
|
||||||
errUpdateCallback
|
errUpdateCallback
|
||||||
);
|
);
|
||||||
@@ -393,10 +405,16 @@ const DomandaEditInstructorManager = () => {
|
|||||||
...cfgModifier
|
...cfgModifier
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const formDataToSend = new FormData();
|
||||||
|
const jsonBlob = new Blob([JSON.stringify(submitData)], {
|
||||||
|
type: 'application/json'
|
||||||
|
});
|
||||||
|
formDataToSend.append('applicationEvaluationFormRequestBean', jsonBlob);
|
||||||
|
|
||||||
ApplicationEvaluationService.updateEvaluationV2(
|
ApplicationEvaluationService.updateEvaluationV2(
|
||||||
data.assignedApplicationId,
|
data.assignedApplicationId,
|
||||||
formId,
|
formId,
|
||||||
submitData,
|
formDataToSend,
|
||||||
(data) => updateCallback(data, afterUpdateCallback),
|
(data) => updateCallback(data, afterUpdateCallback),
|
||||||
errUpdateCallback
|
errUpdateCallback
|
||||||
);
|
);
|
||||||
@@ -445,15 +463,21 @@ const DomandaEditInstructorManager = () => {
|
|||||||
checklist: klona(data.checklist),
|
checklist: klona(data.checklist),
|
||||||
files: klona(data.files),
|
files: klona(data.files),
|
||||||
note: data.note,
|
note: data.note,
|
||||||
motivation,
|
motivation: finalDialogData.motivation,
|
||||||
amountAccepted
|
amountAccepted: finalDialogData.amount
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const formDataToSend = new FormData();
|
||||||
|
const jsonBlob = new Blob([JSON.stringify(submitData)], {
|
||||||
|
type: 'application/json'
|
||||||
|
});
|
||||||
|
formDataToSend.append('evaluationRequest', jsonBlob);
|
||||||
|
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
setIsVisibleCompleteDialog(false);
|
setIsVisibleCompleteDialog(false);
|
||||||
ApplicationEvaluationService.updateEvaluation(
|
ApplicationEvaluationService.updateEvaluation(
|
||||||
data.assignedApplicationId,
|
data.assignedApplicationId,
|
||||||
submitData,
|
formDataToSend,
|
||||||
approveRejectCallback,
|
approveRejectCallback,
|
||||||
errApproveRejectCallback
|
errApproveRejectCallback
|
||||||
);
|
);
|
||||||
@@ -470,21 +494,27 @@ const DomandaEditInstructorManager = () => {
|
|||||||
)),
|
)),
|
||||||
amendmentDetails: klona(data.amendmentDetails),
|
amendmentDetails: klona(data.amendmentDetails),
|
||||||
note: data.note,
|
note: data.note,
|
||||||
motivation,
|
motivation: finalDialogData.motivation,
|
||||||
amountAccepted
|
amountAccepted: finalDialogData.amount
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const formDataToSend = new FormData();
|
||||||
|
const jsonBlob = new Blob([JSON.stringify(submitData)], {
|
||||||
|
type: 'application/json'
|
||||||
|
});
|
||||||
|
formDataToSend.append('applicationEvaluationFormRequestBean', jsonBlob);
|
||||||
|
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
setIsVisibleCompleteDialog(false);
|
setIsVisibleCompleteDialog(false);
|
||||||
ApplicationEvaluationService.updateEvaluationV2(
|
ApplicationEvaluationService.updateEvaluationV2(
|
||||||
data.assignedApplicationId,
|
data.assignedApplicationId,
|
||||||
formId,
|
formId,
|
||||||
submitData,
|
formDataToSend,
|
||||||
approveRejectCallback,
|
approveRejectCallback,
|
||||||
errApproveRejectCallback
|
errApproveRejectCallback
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}, [data, motivation]);
|
}, [data, finalDialogData]);
|
||||||
|
|
||||||
const doReject = useCallback((newStatus) => {
|
const doReject = useCallback((newStatus) => {
|
||||||
if (data.evaluationVersion === 'V1') {
|
if (data.evaluationVersion === 'V1') {
|
||||||
@@ -494,14 +524,28 @@ const DomandaEditInstructorManager = () => {
|
|||||||
checklist: klona(data.checklist),
|
checklist: klona(data.checklist),
|
||||||
files: klona(data.files),
|
files: klona(data.files),
|
||||||
note: data.note,
|
note: data.note,
|
||||||
motivation
|
motivation: finalDialogData.motivation,
|
||||||
|
rejectedReason: finalDialogData.reason,
|
||||||
|
rejectedReasonSubject: finalDialogData.subject
|
||||||
|
}
|
||||||
|
|
||||||
|
const formDataToSend = new FormData();
|
||||||
|
const jsonBlob = new Blob([JSON.stringify(submitData)], {
|
||||||
|
type: 'application/json'
|
||||||
|
});
|
||||||
|
formDataToSend.append('evaluationRequest', jsonBlob);
|
||||||
|
|
||||||
|
if (finalDialogData.files && finalDialogData.files.length > 0) {
|
||||||
|
finalDialogData.files.forEach((file) => {
|
||||||
|
formDataToSend.append('rejectedDocuments', file);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
setIsVisibleCompleteDialog(false);
|
setIsVisibleCompleteDialog(false);
|
||||||
ApplicationEvaluationService.updateEvaluation(
|
ApplicationEvaluationService.updateEvaluation(
|
||||||
data.assignedApplicationId,
|
data.assignedApplicationId,
|
||||||
submitData,
|
formDataToSend,
|
||||||
approveRejectCallback,
|
approveRejectCallback,
|
||||||
errApproveRejectCallback
|
errApproveRejectCallback
|
||||||
);
|
);
|
||||||
@@ -518,7 +562,21 @@ const DomandaEditInstructorManager = () => {
|
|||||||
)),
|
)),
|
||||||
amendmentDetails: klona(data.amendmentDetails),
|
amendmentDetails: klona(data.amendmentDetails),
|
||||||
note: data.note,
|
note: data.note,
|
||||||
motivation
|
motivation: finalDialogData.motivation,
|
||||||
|
rejectedReason: finalDialogData.reason,
|
||||||
|
rejectedReasonSubject: finalDialogData.subject
|
||||||
|
}
|
||||||
|
|
||||||
|
const formDataToSend = new FormData();
|
||||||
|
const jsonBlob = new Blob([JSON.stringify(submitData)], {
|
||||||
|
type: 'application/json'
|
||||||
|
});
|
||||||
|
formDataToSend.append('applicationEvaluationFormRequestBean', jsonBlob);
|
||||||
|
|
||||||
|
if (finalDialogData.files && finalDialogData.files.length > 0) {
|
||||||
|
finalDialogData.files.forEach((file) => {
|
||||||
|
formDataToSend.append('rejectedDocuments', file);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
@@ -526,12 +584,12 @@ const DomandaEditInstructorManager = () => {
|
|||||||
ApplicationEvaluationService.updateEvaluationV2(
|
ApplicationEvaluationService.updateEvaluationV2(
|
||||||
data.assignedApplicationId,
|
data.assignedApplicationId,
|
||||||
formId,
|
formId,
|
||||||
submitData,
|
formDataToSend,
|
||||||
approveRejectCallback,
|
approveRejectCallback,
|
||||||
errApproveRejectCallback
|
errApproveRejectCallback
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}, [data, motivation]);
|
}, [data, finalDialogData]);
|
||||||
|
|
||||||
const approveRejectCallback = (data) => {
|
const approveRejectCallback = (data) => {
|
||||||
if (data.status === 'SUCCESS') {
|
if (data.status === 'SUCCESS') {
|
||||||
@@ -653,7 +711,7 @@ const DomandaEditInstructorManager = () => {
|
|||||||
const hideCompleteDialog = () => {
|
const hideCompleteDialog = () => {
|
||||||
setIsVisibleCompleteDialog(false);
|
setIsVisibleCompleteDialog(false);
|
||||||
setOperationType('');
|
setOperationType('');
|
||||||
setMotivation('');
|
setFinalDialogData({});
|
||||||
}
|
}
|
||||||
|
|
||||||
const footerCompleteDialog = useCallback(() => {
|
const footerCompleteDialog = useCallback(() => {
|
||||||
@@ -662,11 +720,12 @@ const DomandaEditInstructorManager = () => {
|
|||||||
|
|
||||||
if (operationType === 'approve') {
|
if (operationType === 'approve') {
|
||||||
onSubmitAction = doApprove;
|
onSubmitAction = doApprove;
|
||||||
isDisabled = isDisabled || !amountAccepted || isEmpty(amountAccepted) || amountAccepted === 0;
|
isDisabled = isDisabled || !finalDialogData.amount || isEmpty(finalDialogData.amount) || finalDialogData.amount === 0;
|
||||||
} else if (operationType === 'tf_reject') {
|
} else if (operationType === 'tf_reject') {
|
||||||
onSubmitAction = () => doReject('TECHNICAL_EVALUATION_REJECTED');
|
onSubmitAction = () => doReject('TECHNICAL_EVALUATION_REJECTED');
|
||||||
} else {
|
} else {
|
||||||
onSubmitAction = () => doReject('REJECTED');
|
onSubmitAction = () => doReject('REJECTED');
|
||||||
|
isDisabled = isDisabled || !finalDialogData.reason || isEmpty(finalDialogData.reason) || !finalDialogData.motivation || isEmpty(finalDialogData.motivation)
|
||||||
}
|
}
|
||||||
|
|
||||||
return <div>
|
return <div>
|
||||||
@@ -676,7 +735,12 @@ const DomandaEditInstructorManager = () => {
|
|||||||
disabled={isDisabled}
|
disabled={isDisabled}
|
||||||
label={__('Invia', 'gepafin')} onClick={onSubmitAction}/>
|
label={__('Invia', 'gepafin')} onClick={onSubmitAction}/>
|
||||||
</div>
|
</div>
|
||||||
}, [amountAccepted, data, motivation]);
|
}, [finalDialogData, data]);
|
||||||
|
|
||||||
|
const updateFinalDialogData = (value, path) => {
|
||||||
|
const newData = wrap(finalDialogData).set(path.split('.'), value).value();
|
||||||
|
setFinalDialogData(newData);
|
||||||
|
};
|
||||||
|
|
||||||
const initiateApproving = () => {
|
const initiateApproving = () => {
|
||||||
setOperationType('approve');
|
setOperationType('approve');
|
||||||
@@ -944,8 +1008,8 @@ const DomandaEditInstructorManager = () => {
|
|||||||
&& APP_HUB_ID === 't7jh5wfg9QXylNaTZkPoE')
|
&& APP_HUB_ID === 't7jh5wfg9QXylNaTZkPoE')
|
||||||
? <Button
|
? <Button
|
||||||
type="button"
|
type="button"
|
||||||
disabled={!data.id || data.status === 'CLOSE'
|
disabled={!data.id || ['EXPIRED', 'CLOSE'].includes(data.status)
|
||||||
|| (data.applicationStatus === 'EVALUATION' && shouldDisableNewSoccorso())
|
|| (!['SOCCORSO', 'AWAITING_TECHNICAL_EVALUATION'].includes(data.applicationStatus) && shouldDisableNewSoccorso())
|
||||||
|| evaluationBlockedForUser(data)}
|
|| evaluationBlockedForUser(data)}
|
||||||
onClick={doNewSoccorso}
|
onClick={doNewSoccorso}
|
||||||
outlined
|
outlined
|
||||||
@@ -961,7 +1025,7 @@ const DomandaEditInstructorManager = () => {
|
|||||||
{data.id
|
{data.id
|
||||||
? <Button
|
? <Button
|
||||||
type="button"
|
type="button"
|
||||||
disabled={data.status === 'CLOSE' || evaluationBlockedForUser(data)}
|
disabled={['EXPIRED', 'CLOSE'].includes(data.status) || evaluationBlockedForUser(data)}
|
||||||
onClick={() => doSaveDraft()}
|
onClick={() => doSaveDraft()}
|
||||||
outlined
|
outlined
|
||||||
label={__('Salva bozza valutazione', 'gepafin')}
|
label={__('Salva bozza valutazione', 'gepafin')}
|
||||||
@@ -1089,12 +1153,24 @@ const DomandaEditInstructorManager = () => {
|
|||||||
setData(newData);
|
setData(newData);
|
||||||
}, [data]);
|
}, [data]);
|
||||||
|
|
||||||
|
const rejectionFiles = () => {
|
||||||
|
return data.rejectedDocument && !isEmpty(data.rejectedDocument) && ['REJECTED'].includes(data.applicationStatus)
|
||||||
|
? <ul>
|
||||||
|
{data.rejectedDocument.map(o => <li key={o.id}>
|
||||||
|
<a href={o.filePath}>{o.name}</a>
|
||||||
|
</li>)}
|
||||||
|
</ul> : null
|
||||||
|
}
|
||||||
|
|
||||||
const motivationMsg = () => {
|
const motivationMsg = () => {
|
||||||
return data.motivation && !isEmpty(data.motivation) && ['REJECTED', 'APPROVED'].includes(data.applicationStatus)
|
return data.motivation && !isEmpty(data.motivation) && ['REJECTED', 'APPROVED'].includes(data.applicationStatus)
|
||||||
? <div className="appPageSection__message info">
|
? <div className="appPageSection__message info">
|
||||||
<i className="pi pi-info-circle"></i>
|
<i className="pi pi-info-circle"></i>
|
||||||
<span className="summary">{__('Motivazione:', 'gepafin')}</span>
|
<span className="summary">{__('Motivazione:', 'gepafin')}</span>
|
||||||
<span>{renderHtmlContent(data.motivation)}</span>
|
<div style={{display: 'flex', flexDirection: 'column', gap: 10}}>
|
||||||
|
<span>{renderHtmlContent(data.motivation)}</span>
|
||||||
|
{rejectionFiles()}
|
||||||
|
</div>
|
||||||
</div> : null
|
</div> : null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1505,28 +1581,113 @@ const DomandaEditInstructorManager = () => {
|
|||||||
{operationType === 'approve'
|
{operationType === 'approve'
|
||||||
? <div className="appForm__field">
|
? <div className="appForm__field">
|
||||||
<label
|
<label
|
||||||
className={classNames({ 'p-error': !amountAccepted || isEmpty(amountAccepted) || amountAccepted === 0 })}>
|
className={classNames({ 'p-error': !finalDialogData.amount || isEmpty(finalDialogData.amount) || finalDialogData.amount === 0 })}>
|
||||||
{__('Importo approvato', 'gepafin')}
|
{__('Importo approvato', 'gepafin')}
|
||||||
</label>
|
</label>
|
||||||
<InputNumber
|
<InputNumber
|
||||||
value={amountAccepted}
|
value={finalDialogData.amount}
|
||||||
keyfilter="int"
|
keyfilter="int"
|
||||||
invalid={!amountAccepted || isEmpty(amountAccepted) || amountAccepted === 0}
|
invalid={!finalDialogData.amount || isEmpty(finalDialogData.amount) || finalDialogData.amount === 0}
|
||||||
onChange={(e) => setAmountAccepted(e.value)}/>
|
onChange={(e) => updateFinalDialogData(e.value, 'amount')}/>
|
||||||
|
</div> : null}
|
||||||
|
{operationType === 'reject' && APP_HUB_ID !== 't7jh5wfg9QXylNaTZkPoE'
|
||||||
|
? <div className="appForm__field">
|
||||||
|
<label className={classNames({ 'p-error': !finalDialogData.reason || isEmpty(finalDialogData.reason) })}>
|
||||||
|
{__('Oggetto', 'gepafin')}
|
||||||
|
</label>
|
||||||
|
<Dropdown
|
||||||
|
value={rejectionReasons.find(reason => reason.id === finalDialogData.reasonId) || null}
|
||||||
|
options={rejectionReasons}
|
||||||
|
optionLabel="label"
|
||||||
|
placeholder={__('Seleziona motivo', 'gepafin')}
|
||||||
|
onChange={(e) => {
|
||||||
|
setFinalDialogData(prev => ({
|
||||||
|
...prev,
|
||||||
|
reasonId: e.value.id,
|
||||||
|
reason: e.value.text,
|
||||||
|
subject: e.value.subject
|
||||||
|
}))
|
||||||
|
}}
|
||||||
|
style={{ marginBottom: '10px' }}
|
||||||
|
/>
|
||||||
|
<InputTextarea
|
||||||
|
name="reason"
|
||||||
|
value={finalDialogData.reason}
|
||||||
|
invalid={!finalDialogData.reason || isEmpty(finalDialogData.reason)}
|
||||||
|
onChange={(e) => updateFinalDialogData(e.target.value, 'reason')}
|
||||||
|
rows={3}
|
||||||
|
style={{ width: '100%' }}/>
|
||||||
</div> : null}
|
</div> : null}
|
||||||
<div className="appForm__field">
|
<div className="appForm__field">
|
||||||
<label>{__('Motivazione', 'gepafin')}</label>
|
<label className={classNames({ 'p-error': !finalDialogData.motivation || isEmpty(finalDialogData.motivation) })}>
|
||||||
|
{__('Motivazione', 'gepafin')}
|
||||||
|
</label>
|
||||||
<div translate="no">
|
<div translate="no">
|
||||||
<Editor
|
<Editor
|
||||||
value={motivation}
|
value={finalDialogData.motivation}
|
||||||
readOnly={loading}
|
readOnly={loading}
|
||||||
placeholder={__('Digita qui il messagio', 'gepafin')}
|
placeholder={__('Digita qui il messagio', 'gepafin')}
|
||||||
headerTemplate={header}
|
headerTemplate={header}
|
||||||
onTextChange={(e) => setMotivation(e.htmlValue)}
|
onTextChange={(e) => updateFinalDialogData(e.htmlValue, 'motivation')}
|
||||||
style={{ height: 80 * 3, width: '100%' }}
|
style={{ height: 80 * 3, width: '100%' }}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{operationType === 'reject' && APP_HUB_ID !== 't7jh5wfg9QXylNaTZkPoE'
|
||||||
|
? <div className="appForm__field">
|
||||||
|
<label>
|
||||||
|
{__('Files', 'gepafin')}
|
||||||
|
</label>
|
||||||
|
<FileUpload
|
||||||
|
ref={finalDialogFilesRef}
|
||||||
|
name="files[]"
|
||||||
|
multiple
|
||||||
|
accept={mimeTypes.map(o => o.code).join(',')}
|
||||||
|
maxFileSize={defaultMaxFileSize}
|
||||||
|
auto={false}
|
||||||
|
customUpload={true}
|
||||||
|
onSelect={(e) => {
|
||||||
|
updateFinalDialogData(e.files, 'files');
|
||||||
|
}}
|
||||||
|
onRemove={(e) => {
|
||||||
|
const updatedFiles = finalDialogFilesRef.current.getFiles();
|
||||||
|
updateFinalDialogData(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> : null}
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
|
||||||
<Dialog
|
<Dialog
|
||||||
|
|||||||
@@ -68,6 +68,10 @@ const ApplicationInfo = ({ data }) => {
|
|||||||
<span>{__('Importo richiesto', 'gepafin')}</span>
|
<span>{__('Importo richiesto', 'gepafin')}</span>
|
||||||
<span>{getNumberWithCurrency(data.amountRequested)}</span>
|
<span>{getNumberWithCurrency(data.amountRequested)}</span>
|
||||||
</p>
|
</p>
|
||||||
|
<p className="appPageSection__pMeta">
|
||||||
|
<span>{__('Importo deliberato', 'gepafin')}</span>
|
||||||
|
<span>{getNumberWithCurrency(data.amountAccepted)}</span>
|
||||||
|
</p>
|
||||||
<p className="appPageSection__pMeta">
|
<p className="appPageSection__pMeta">
|
||||||
<span>{__('Scadenza Valutazione', 'gepafin')}</span>
|
<span>{__('Scadenza Valutazione', 'gepafin')}</span>
|
||||||
<span>{getDateFromISOstring(data.evaluationEndDate)}</span>
|
<span>{getDateFromISOstring(data.evaluationEndDate)}</span>
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ import BlockingOverlay from '../../components/BlockingOverlay';
|
|||||||
import { classNames } from 'primereact/utils';
|
import { classNames } from 'primereact/utils';
|
||||||
import { InputTextarea } from 'primereact/inputtextarea';
|
import { InputTextarea } from 'primereact/inputtextarea';
|
||||||
import { InputText } from 'primereact/inputtext';
|
import { InputText } from 'primereact/inputtext';
|
||||||
|
import { Dropdown } from 'primereact/dropdown';
|
||||||
import ListOfFiles from './components/ListOfFiles';
|
import ListOfFiles from './components/ListOfFiles';
|
||||||
import RepeaterFields from './components/RepeaterFields';
|
import RepeaterFields from './components/RepeaterFields';
|
||||||
import ApplicationInfo from './components/ApplicationInfo';
|
import ApplicationInfo from './components/ApplicationInfo';
|
||||||
@@ -56,6 +57,9 @@ import FormField from '../../components/FormField';
|
|||||||
import SoccorsoResendEmails from '../SoccorsoEditPreInstructor/components/SoccorsoResendEmails';
|
import SoccorsoResendEmails from '../SoccorsoEditPreInstructor/components/SoccorsoResendEmails';
|
||||||
import EvaluationReAdmit from './components/EvaluationReAdmit';
|
import EvaluationReAdmit from './components/EvaluationReAdmit';
|
||||||
import { SplitButton } from 'primereact/splitbutton';
|
import { SplitButton } from 'primereact/splitbutton';
|
||||||
|
import { FileUpload } from 'primereact/fileupload';
|
||||||
|
import { defaultMaxFileSize, mimeTypes, rejectionReasons } from '../../configData';
|
||||||
|
import getFormatedFileSizeText from '../../helpers/getFormatedFileSizeText';
|
||||||
|
|
||||||
const APP_EVALUATION_FLOW_ID = process.env.REACT_APP_EVALUATION_FLOW_ID;
|
const APP_EVALUATION_FLOW_ID = process.env.REACT_APP_EVALUATION_FLOW_ID;
|
||||||
const APP_HUB_ID = process.env.REACT_APP_HUB_ID;
|
const APP_HUB_ID = process.env.REACT_APP_HUB_ID;
|
||||||
@@ -75,8 +79,10 @@ const DomandaEditPreInstructor = () => {
|
|||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [isVisibleCompleteDialog, setIsVisibleCompleteDialog] = useState(false);
|
const [isVisibleCompleteDialog, setIsVisibleCompleteDialog] = useState(false);
|
||||||
const [operationType, setOperationType] = useState('');
|
const [operationType, setOperationType] = useState('');
|
||||||
const [motivation, setMotivation] = useState('');
|
const [finalDialogData, setFinalDialogData] = useState({
|
||||||
const [amountAccepted, setAmountAccepted] = useState(0);
|
motivation: ''
|
||||||
|
});
|
||||||
|
const finalDialogFilesRef = useRef(null);
|
||||||
const [isVisibleAppointmentDialog, setIsVisibleAppointmentDialog] = useState(false);
|
const [isVisibleAppointmentDialog, setIsVisibleAppointmentDialog] = useState(false);
|
||||||
const [isVisiblePreTecEvalDialog, setIsVisiblePreTecEvalDialog] = useState(false);
|
const [isVisiblePreTecEvalDialog, setIsVisiblePreTecEvalDialog] = useState(false);
|
||||||
const [preTecEvalData, setPreTecEvalData] = useState({
|
const [preTecEvalData, setPreTecEvalData] = useState({
|
||||||
@@ -219,7 +225,7 @@ const DomandaEditPreInstructor = () => {
|
|||||||
const getCallback = (resp) => {
|
const getCallback = (resp) => {
|
||||||
if (resp.status === 'SUCCESS') {
|
if (resp.status === 'SUCCESS') {
|
||||||
setData(getFormattedData(resp.data));
|
setData(getFormattedData(resp.data));
|
||||||
setMotivation(resp.data.motivation);
|
setFinalDialogData((prev) => ({...prev, motivation: resp.data.motivation}));
|
||||||
updateFlagsForSoccorso(resp.data);
|
updateFlagsForSoccorso(resp.data);
|
||||||
|
|
||||||
if (resp.data.evaluationVersion === 'V2') {
|
if (resp.data.evaluationVersion === 'V2') {
|
||||||
@@ -372,9 +378,15 @@ const DomandaEditPreInstructor = () => {
|
|||||||
...cfgModifier
|
...cfgModifier
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const formDataToSend = new FormData();
|
||||||
|
const jsonBlob = new Blob([JSON.stringify(submitData)], {
|
||||||
|
type: 'application/json'
|
||||||
|
});
|
||||||
|
formDataToSend.append('evaluationRequest', jsonBlob);
|
||||||
|
|
||||||
ApplicationEvaluationService.updateEvaluation(
|
ApplicationEvaluationService.updateEvaluation(
|
||||||
data.assignedApplicationId,
|
data.assignedApplicationId,
|
||||||
submitData,
|
formDataToSend,
|
||||||
(data) => updateCallback(data, afterUpdateCallback),
|
(data) => updateCallback(data, afterUpdateCallback),
|
||||||
errUpdateCallback
|
errUpdateCallback
|
||||||
);
|
);
|
||||||
@@ -393,10 +405,16 @@ const DomandaEditPreInstructor = () => {
|
|||||||
...cfgModifier
|
...cfgModifier
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const formDataToSend = new FormData();
|
||||||
|
const jsonBlob = new Blob([JSON.stringify(submitData)], {
|
||||||
|
type: 'application/json'
|
||||||
|
});
|
||||||
|
formDataToSend.append('applicationEvaluationFormRequestBean', jsonBlob);
|
||||||
|
|
||||||
ApplicationEvaluationService.updateEvaluationV2(
|
ApplicationEvaluationService.updateEvaluationV2(
|
||||||
data.assignedApplicationId,
|
data.assignedApplicationId,
|
||||||
formId,
|
formId,
|
||||||
submitData,
|
formDataToSend,
|
||||||
(data) => updateCallback(data, afterUpdateCallback),
|
(data) => updateCallback(data, afterUpdateCallback),
|
||||||
errUpdateCallback
|
errUpdateCallback
|
||||||
);
|
);
|
||||||
@@ -445,15 +463,21 @@ const DomandaEditPreInstructor = () => {
|
|||||||
checklist: klona(data.checklist),
|
checklist: klona(data.checklist),
|
||||||
files: klona(data.files),
|
files: klona(data.files),
|
||||||
note: data.note,
|
note: data.note,
|
||||||
motivation,
|
motivation: finalDialogData.motivation,
|
||||||
amountAccepted
|
amountAccepted: finalDialogData.amount
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const formDataToSend = new FormData();
|
||||||
|
const jsonBlob = new Blob([JSON.stringify(submitData)], {
|
||||||
|
type: 'application/json'
|
||||||
|
});
|
||||||
|
formDataToSend.append('evaluationRequest', jsonBlob);
|
||||||
|
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
setIsVisibleCompleteDialog(false);
|
setIsVisibleCompleteDialog(false);
|
||||||
ApplicationEvaluationService.updateEvaluation(
|
ApplicationEvaluationService.updateEvaluation(
|
||||||
data.assignedApplicationId,
|
data.assignedApplicationId,
|
||||||
submitData,
|
formDataToSend,
|
||||||
approveRejectCallback,
|
approveRejectCallback,
|
||||||
errApproveRejectCallback
|
errApproveRejectCallback
|
||||||
);
|
);
|
||||||
@@ -470,21 +494,27 @@ const DomandaEditPreInstructor = () => {
|
|||||||
)),
|
)),
|
||||||
amendmentDetails: klona(data.amendmentDetails),
|
amendmentDetails: klona(data.amendmentDetails),
|
||||||
note: data.note,
|
note: data.note,
|
||||||
motivation,
|
motivation: finalDialogData.motivation,
|
||||||
amountAccepted
|
amountAccepted: finalDialogData.amount
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const formDataToSend = new FormData();
|
||||||
|
const jsonBlob = new Blob([JSON.stringify(submitData)], {
|
||||||
|
type: 'application/json'
|
||||||
|
});
|
||||||
|
formDataToSend.append('applicationEvaluationFormRequestBean', jsonBlob);
|
||||||
|
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
setIsVisibleCompleteDialog(false);
|
setIsVisibleCompleteDialog(false);
|
||||||
ApplicationEvaluationService.updateEvaluationV2(
|
ApplicationEvaluationService.updateEvaluationV2(
|
||||||
data.assignedApplicationId,
|
data.assignedApplicationId,
|
||||||
formId,
|
formId,
|
||||||
submitData,
|
formDataToSend,
|
||||||
approveRejectCallback,
|
approveRejectCallback,
|
||||||
errApproveRejectCallback
|
errApproveRejectCallback
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}, [data, motivation]);
|
}, [data, finalDialogData]);
|
||||||
|
|
||||||
const doReject = useCallback((newStatus) => {
|
const doReject = useCallback((newStatus) => {
|
||||||
if (data.evaluationVersion === 'V1') {
|
if (data.evaluationVersion === 'V1') {
|
||||||
@@ -494,14 +524,28 @@ const DomandaEditPreInstructor = () => {
|
|||||||
checklist: klona(data.checklist),
|
checklist: klona(data.checklist),
|
||||||
files: klona(data.files),
|
files: klona(data.files),
|
||||||
note: data.note,
|
note: data.note,
|
||||||
motivation
|
motivation: finalDialogData.motivation,
|
||||||
|
rejectedReason: finalDialogData.reason,
|
||||||
|
rejectedReasonSubject: finalDialogData.subject
|
||||||
|
}
|
||||||
|
|
||||||
|
const formDataToSend = new FormData();
|
||||||
|
const jsonBlob = new Blob([JSON.stringify(submitData)], {
|
||||||
|
type: 'application/json'
|
||||||
|
});
|
||||||
|
formDataToSend.append('evaluationRequest', jsonBlob);
|
||||||
|
|
||||||
|
if (finalDialogData.files && finalDialogData.files.length > 0) {
|
||||||
|
finalDialogData.files.forEach((file) => {
|
||||||
|
formDataToSend.append('rejectedDocuments', file);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
setIsVisibleCompleteDialog(false);
|
setIsVisibleCompleteDialog(false);
|
||||||
ApplicationEvaluationService.updateEvaluation(
|
ApplicationEvaluationService.updateEvaluation(
|
||||||
data.assignedApplicationId,
|
data.assignedApplicationId,
|
||||||
submitData,
|
formDataToSend,
|
||||||
approveRejectCallback,
|
approveRejectCallback,
|
||||||
errApproveRejectCallback
|
errApproveRejectCallback
|
||||||
);
|
);
|
||||||
@@ -518,7 +562,21 @@ const DomandaEditPreInstructor = () => {
|
|||||||
)),
|
)),
|
||||||
amendmentDetails: klona(data.amendmentDetails),
|
amendmentDetails: klona(data.amendmentDetails),
|
||||||
note: data.note,
|
note: data.note,
|
||||||
motivation
|
motivation: finalDialogData.motivation,
|
||||||
|
rejectedReason: finalDialogData.reason,
|
||||||
|
rejectedReasonSubject: finalDialogData.subject
|
||||||
|
}
|
||||||
|
|
||||||
|
const formDataToSend = new FormData();
|
||||||
|
const jsonBlob = new Blob([JSON.stringify(submitData)], {
|
||||||
|
type: 'application/json'
|
||||||
|
});
|
||||||
|
formDataToSend.append('applicationEvaluationFormRequestBean', jsonBlob);
|
||||||
|
|
||||||
|
if (finalDialogData.files && finalDialogData.files.length > 0) {
|
||||||
|
finalDialogData.files.forEach((file) => {
|
||||||
|
formDataToSend.append('rejectedDocuments', file);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
@@ -526,12 +584,12 @@ const DomandaEditPreInstructor = () => {
|
|||||||
ApplicationEvaluationService.updateEvaluationV2(
|
ApplicationEvaluationService.updateEvaluationV2(
|
||||||
data.assignedApplicationId,
|
data.assignedApplicationId,
|
||||||
formId,
|
formId,
|
||||||
submitData,
|
formDataToSend,
|
||||||
approveRejectCallback,
|
approveRejectCallback,
|
||||||
errApproveRejectCallback
|
errApproveRejectCallback
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}, [data, motivation]);
|
}, [data, finalDialogData]);
|
||||||
|
|
||||||
const approveRejectCallback = (data) => {
|
const approveRejectCallback = (data) => {
|
||||||
if (data.status === 'SUCCESS') {
|
if (data.status === 'SUCCESS') {
|
||||||
@@ -653,7 +711,7 @@ const DomandaEditPreInstructor = () => {
|
|||||||
const hideCompleteDialog = () => {
|
const hideCompleteDialog = () => {
|
||||||
setIsVisibleCompleteDialog(false);
|
setIsVisibleCompleteDialog(false);
|
||||||
setOperationType('');
|
setOperationType('');
|
||||||
setMotivation('');
|
setFinalDialogData({});
|
||||||
}
|
}
|
||||||
|
|
||||||
const footerCompleteDialog = useCallback(() => {
|
const footerCompleteDialog = useCallback(() => {
|
||||||
@@ -662,11 +720,12 @@ const DomandaEditPreInstructor = () => {
|
|||||||
|
|
||||||
if (operationType === 'approve') {
|
if (operationType === 'approve') {
|
||||||
onSubmitAction = doApprove;
|
onSubmitAction = doApprove;
|
||||||
isDisabled = isDisabled || !amountAccepted || isEmpty(amountAccepted) || amountAccepted === 0;
|
isDisabled = isDisabled || !finalDialogData.amount || isEmpty(finalDialogData.amount) || finalDialogData.amount === 0;
|
||||||
} else if (operationType === 'tf_reject') {
|
} else if (operationType === 'tf_reject') {
|
||||||
onSubmitAction = () => doReject('TECHNICAL_EVALUATION_REJECTED');
|
onSubmitAction = () => doReject('TECHNICAL_EVALUATION_REJECTED');
|
||||||
} else {
|
} else {
|
||||||
onSubmitAction = () => doReject('REJECTED');
|
onSubmitAction = () => doReject('REJECTED');
|
||||||
|
isDisabled = isDisabled || !finalDialogData.reason || isEmpty(finalDialogData.reason) || !finalDialogData.motivation || isEmpty(finalDialogData.motivation)
|
||||||
}
|
}
|
||||||
|
|
||||||
return <div>
|
return <div>
|
||||||
@@ -676,7 +735,12 @@ const DomandaEditPreInstructor = () => {
|
|||||||
disabled={isDisabled}
|
disabled={isDisabled}
|
||||||
label={__('Invia', 'gepafin')} onClick={onSubmitAction}/>
|
label={__('Invia', 'gepafin')} onClick={onSubmitAction}/>
|
||||||
</div>
|
</div>
|
||||||
}, [amountAccepted, data, motivation]);
|
}, [finalDialogData, data]);
|
||||||
|
|
||||||
|
const updateFinalDialogData = (value, path) => {
|
||||||
|
const newData = wrap(finalDialogData).set(path.split('.'), value).value();
|
||||||
|
setFinalDialogData(newData);
|
||||||
|
};
|
||||||
|
|
||||||
const initiateApproving = () => {
|
const initiateApproving = () => {
|
||||||
setOperationType('approve');
|
setOperationType('approve');
|
||||||
@@ -944,8 +1008,8 @@ const DomandaEditPreInstructor = () => {
|
|||||||
&& APP_HUB_ID === 't7jh5wfg9QXylNaTZkPoE')
|
&& APP_HUB_ID === 't7jh5wfg9QXylNaTZkPoE')
|
||||||
? <Button
|
? <Button
|
||||||
type="button"
|
type="button"
|
||||||
disabled={!data.id || data.status === 'CLOSE'
|
disabled={!data.id || ['EXPIRED', 'CLOSE'].includes(data.status)
|
||||||
|| (data.applicationStatus === 'EVALUATION' && shouldDisableNewSoccorso())
|
|| (!['SOCCORSO', 'AWAITING_TECHNICAL_EVALUATION'].includes(data.applicationStatus) && shouldDisableNewSoccorso())
|
||||||
|| evaluationBlockedForUser(data)}
|
|| evaluationBlockedForUser(data)}
|
||||||
onClick={doNewSoccorso}
|
onClick={doNewSoccorso}
|
||||||
outlined
|
outlined
|
||||||
@@ -961,7 +1025,7 @@ const DomandaEditPreInstructor = () => {
|
|||||||
{data.id
|
{data.id
|
||||||
? <Button
|
? <Button
|
||||||
type="button"
|
type="button"
|
||||||
disabled={data.status === 'CLOSE' || evaluationBlockedForUser(data)}
|
disabled={['EXPIRED', 'CLOSE'].includes(data.status) || evaluationBlockedForUser(data)}
|
||||||
onClick={() => doSaveDraft()}
|
onClick={() => doSaveDraft()}
|
||||||
outlined
|
outlined
|
||||||
label={__('Salva bozza valutazione', 'gepafin')}
|
label={__('Salva bozza valutazione', 'gepafin')}
|
||||||
@@ -1089,12 +1153,24 @@ const DomandaEditPreInstructor = () => {
|
|||||||
setData(newData);
|
setData(newData);
|
||||||
}, [data]);
|
}, [data]);
|
||||||
|
|
||||||
|
const rejectionFiles = () => {
|
||||||
|
return data.rejectedDocument && !isEmpty(data.rejectedDocument) && ['REJECTED'].includes(data.applicationStatus)
|
||||||
|
? <ul>
|
||||||
|
{data.rejectedDocument.map(o => <li key={o.id}>
|
||||||
|
<a href={o.filePath}>{o.name}</a>
|
||||||
|
</li>)}
|
||||||
|
</ul> : null
|
||||||
|
}
|
||||||
|
|
||||||
const motivationMsg = () => {
|
const motivationMsg = () => {
|
||||||
return data.motivation && !isEmpty(data.motivation) && ['REJECTED', 'APPROVED'].includes(data.applicationStatus)
|
return data.motivation && !isEmpty(data.motivation) && ['REJECTED', 'APPROVED'].includes(data.applicationStatus)
|
||||||
? <div className="appPageSection__message info">
|
? <div className="appPageSection__message info">
|
||||||
<i className="pi pi-info-circle"></i>
|
<i className="pi pi-info-circle"></i>
|
||||||
<span className="summary">{__('Motivazione:', 'gepafin')}</span>
|
<span className="summary">{__('Motivazione:', 'gepafin')}</span>
|
||||||
<span>{renderHtmlContent(data.motivation)}</span>
|
<div style={{display: 'flex', flexDirection: 'column', gap: 10}}>
|
||||||
|
<span>{renderHtmlContent(data.motivation)}</span>
|
||||||
|
{rejectionFiles()}
|
||||||
|
</div>
|
||||||
</div> : null
|
</div> : null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1505,28 +1581,113 @@ const DomandaEditPreInstructor = () => {
|
|||||||
{operationType === 'approve'
|
{operationType === 'approve'
|
||||||
? <div className="appForm__field">
|
? <div className="appForm__field">
|
||||||
<label
|
<label
|
||||||
className={classNames({ 'p-error': !amountAccepted || isEmpty(amountAccepted) || amountAccepted === 0 })}>
|
className={classNames({ 'p-error': !finalDialogData.amount || isEmpty(finalDialogData.amount) || finalDialogData.amount === 0 })}>
|
||||||
{__('Importo approvato', 'gepafin')}
|
{__('Importo approvato', 'gepafin')}
|
||||||
</label>
|
</label>
|
||||||
<InputNumber
|
<InputNumber
|
||||||
value={amountAccepted}
|
value={finalDialogData.amount}
|
||||||
keyfilter="int"
|
keyfilter="int"
|
||||||
invalid={!amountAccepted || isEmpty(amountAccepted) || amountAccepted === 0}
|
invalid={!finalDialogData.amount || isEmpty(finalDialogData.amount) || finalDialogData.amount === 0}
|
||||||
onChange={(e) => setAmountAccepted(e.value)}/>
|
onChange={(e) => updateFinalDialogData(e.value, 'amount')}/>
|
||||||
|
</div> : null}
|
||||||
|
{operationType === 'reject' && APP_HUB_ID !== 't7jh5wfg9QXylNaTZkPoE'
|
||||||
|
? <div className="appForm__field">
|
||||||
|
<label className={classNames({ 'p-error': !finalDialogData.reason || isEmpty(finalDialogData.reason) })}>
|
||||||
|
{__('Oggetto', 'gepafin')}
|
||||||
|
</label>
|
||||||
|
<Dropdown
|
||||||
|
value={rejectionReasons.find(reason => reason.id === finalDialogData.reasonId) || null}
|
||||||
|
options={rejectionReasons}
|
||||||
|
optionLabel="label"
|
||||||
|
placeholder={__('Seleziona motivo', 'gepafin')}
|
||||||
|
onChange={(e) => {
|
||||||
|
setFinalDialogData(prev => ({
|
||||||
|
...prev,
|
||||||
|
reasonId: e.value.id,
|
||||||
|
reason: e.value.text,
|
||||||
|
subject: e.value.subject
|
||||||
|
}))
|
||||||
|
}}
|
||||||
|
style={{ marginBottom: '10px' }}
|
||||||
|
/>
|
||||||
|
<InputTextarea
|
||||||
|
name="reason"
|
||||||
|
value={finalDialogData.reason}
|
||||||
|
invalid={!finalDialogData.reason || isEmpty(finalDialogData.reason)}
|
||||||
|
onChange={(e) => updateFinalDialogData(e.target.value, 'reason')}
|
||||||
|
rows={3}
|
||||||
|
style={{ width: '100%' }}/>
|
||||||
</div> : null}
|
</div> : null}
|
||||||
<div className="appForm__field">
|
<div className="appForm__field">
|
||||||
<label>{__('Motivazione', 'gepafin')}</label>
|
<label className={classNames({ 'p-error': !finalDialogData.motivation || isEmpty(finalDialogData.motivation) })}>
|
||||||
|
{__('Motivazione', 'gepafin')}
|
||||||
|
</label>
|
||||||
<div translate="no">
|
<div translate="no">
|
||||||
<Editor
|
<Editor
|
||||||
value={motivation}
|
value={finalDialogData.motivation}
|
||||||
readOnly={loading}
|
readOnly={loading}
|
||||||
placeholder={__('Digita qui il messagio', 'gepafin')}
|
placeholder={__('Digita qui il messagio', 'gepafin')}
|
||||||
headerTemplate={header}
|
headerTemplate={header}
|
||||||
onTextChange={(e) => setMotivation(e.htmlValue)}
|
onTextChange={(e) => updateFinalDialogData(e.htmlValue, 'motivation')}
|
||||||
style={{ height: 80 * 3, width: '100%' }}
|
style={{ height: 80 * 3, width: '100%' }}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{operationType === 'reject' && APP_HUB_ID !== 't7jh5wfg9QXylNaTZkPoE'
|
||||||
|
? <div className="appForm__field">
|
||||||
|
<label>
|
||||||
|
{__('Files', 'gepafin')}
|
||||||
|
</label>
|
||||||
|
<FileUpload
|
||||||
|
ref={finalDialogFilesRef}
|
||||||
|
name="files[]"
|
||||||
|
multiple
|
||||||
|
accept={mimeTypes.map(o => o.code).join(',')}
|
||||||
|
maxFileSize={defaultMaxFileSize}
|
||||||
|
auto={false}
|
||||||
|
customUpload={true}
|
||||||
|
onSelect={(e) => {
|
||||||
|
updateFinalDialogData(e.files, 'files');
|
||||||
|
}}
|
||||||
|
onRemove={(e) => {
|
||||||
|
const updatedFiles = finalDialogFilesRef.current.getFiles();
|
||||||
|
updateFinalDialogData(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> : null}
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
|
||||||
<Dialog
|
<Dialog
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ const DomandeArchive = () => {
|
|||||||
|
|
||||||
<div className="appPageSection">
|
<div className="appPageSection">
|
||||||
<h2>{__('Domande completate', 'gepafin')}</h2>
|
<h2>{__('Domande completate', 'gepafin')}</h2>
|
||||||
<DomandeTablePreInstructorAsync statuses={['CLOSE']} userId={0}/>
|
<DomandeTablePreInstructorAsync statuses={['CLOSE']} applicationStatuses={['APPROVED', 'REJECTED', 'TECHNICAL_EVALUATION_REJECTED']} userId={0}/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ const DomandeArchivePreInstructor = () => {
|
|||||||
|
|
||||||
<div className="appPageSection">
|
<div className="appPageSection">
|
||||||
<h2>{__('Domande completate', 'gepafin')}</h2>
|
<h2>{__('Domande completate', 'gepafin')}</h2>
|
||||||
<DomandeTablePreInstructorAsync statuses={['CLOSE']} userId={userData.id}/>
|
<DomandeTablePreInstructorAsync statuses={['CLOSE']} applicationStatuses={['APPROVED', 'REJECTED', 'TECHNICAL_EVALUATION_REJECTED']} userId={userData.id}/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import AmendmentsService from '../../service/amendments-service';
|
|||||||
|
|
||||||
// tools
|
// tools
|
||||||
import set404FromErrorResponse from '../../helpers/set404FromErrorResponse';
|
import set404FromErrorResponse from '../../helpers/set404FromErrorResponse';
|
||||||
|
import getFormatedFileSizeText from '../../helpers/getFormatedFileSizeText';
|
||||||
|
|
||||||
// components
|
// components
|
||||||
import { Skeleton } from 'primereact/skeleton';
|
import { Skeleton } from 'primereact/skeleton';
|
||||||
@@ -24,6 +25,8 @@ import { Toast } from 'primereact/toast';
|
|||||||
import { InputSwitch } from 'primereact/inputswitch';
|
import { InputSwitch } from 'primereact/inputswitch';
|
||||||
import ApplicationEvaluationService from '../../service/application-evaluation-service';
|
import ApplicationEvaluationService from '../../service/application-evaluation-service';
|
||||||
import { Dialog } from 'primereact/dialog';
|
import { Dialog } from 'primereact/dialog';
|
||||||
|
import { FileUpload } from 'primereact/fileupload';
|
||||||
|
import { defaultMaxFileSize, mimeTypes } from '../../configData';
|
||||||
|
|
||||||
const SoccorsoAddInstructorManager = () => {
|
const SoccorsoAddInstructorManager = () => {
|
||||||
const isAsyncRequest = useStoreValue('isAsyncRequest');
|
const isAsyncRequest = useStoreValue('isAsyncRequest');
|
||||||
@@ -32,8 +35,9 @@ const SoccorsoAddInstructorManager = () => {
|
|||||||
const [data, setData] = useState({});
|
const [data, setData] = useState({});
|
||||||
const [evaluationId, setEvaluationId] = useState(0);
|
const [evaluationId, setEvaluationId] = useState(0);
|
||||||
const [formData, setFormData] = useState({});
|
const [formData, setFormData] = useState({});
|
||||||
const [isVisibleConfirmDialog, setIsVisibleConfirmDialog] = useState(false)
|
const [isVisibleConfirmDialog, setIsVisibleConfirmDialog] = useState(false);
|
||||||
const toast = useRef(null);
|
const toast = useRef(null);
|
||||||
|
const ammendmentFilesRef = useRef(null);
|
||||||
|
|
||||||
const goToEvaluationPage = () => {
|
const goToEvaluationPage = () => {
|
||||||
navigate(`/mie-domande/${id}`);
|
navigate(`/mie-domande/${id}`);
|
||||||
@@ -120,8 +124,24 @@ const SoccorsoAddInstructorManager = () => {
|
|||||||
|
|
||||||
const doCreate = () => {
|
const doCreate = () => {
|
||||||
storeSet('setAsyncRequest');
|
storeSet('setAsyncRequest');
|
||||||
|
const updatedFormData = { ...formData };
|
||||||
|
delete updatedFormData.files;
|
||||||
|
delete updatedFormData.formFields;
|
||||||
|
|
||||||
AmendmentsService.createSoccorso(formData, createCallback, errCreateCallback, [
|
const formDataToSend = new FormData();
|
||||||
|
|
||||||
|
const jsonBlob = new Blob([JSON.stringify(updatedFormData)], {
|
||||||
|
type: 'application/json'
|
||||||
|
});
|
||||||
|
formDataToSend.append('applicationAmendmentRequest', jsonBlob);
|
||||||
|
|
||||||
|
if (formData.files && formData.files.length > 0) {
|
||||||
|
formData.files.forEach((file) => {
|
||||||
|
formDataToSend.append('files', file);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
AmendmentsService.createSoccorso(formDataToSend, createCallback, errCreateCallback, [
|
||||||
['applicationEvaluationId', evaluationId]
|
['applicationEvaluationId', evaluationId]
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@@ -222,7 +242,7 @@ const SoccorsoAddInstructorManager = () => {
|
|||||||
<div className="appPageSection columns">
|
<div className="appPageSection columns">
|
||||||
<div>
|
<div>
|
||||||
<h3>{__('Pec/Email', 'gepafin')}</h3>
|
<h3>{__('Pec/Email', 'gepafin')}</h3>
|
||||||
<div style={{ marginBottom: '30px' }} translate="no">
|
<div style={{marginBottom: '30px'}} translate="no">
|
||||||
<Editor
|
<Editor
|
||||||
value={formData.note}
|
value={formData.note}
|
||||||
placeholder={__('Digita qui il messagio', 'gepafin')}
|
placeholder={__('Digita qui il messagio', 'gepafin')}
|
||||||
@@ -235,8 +255,65 @@ const SoccorsoAddInstructorManager = () => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div style={{marginBottom: '30px'}}>
|
||||||
|
<div className="appForm__field">
|
||||||
|
<label>
|
||||||
|
{__('Allegati PEC', 'gepafin')}
|
||||||
|
</label>
|
||||||
|
<FileUpload
|
||||||
|
ref={ammendmentFilesRef}
|
||||||
|
name="files[]"
|
||||||
|
multiple
|
||||||
|
accept={mimeTypes.map(o => o.code).join(',')}
|
||||||
|
maxFileSize={defaultMaxFileSize}
|
||||||
|
auto={false}
|
||||||
|
customUpload={true}
|
||||||
|
onSelect={(e) => {
|
||||||
|
updateEvaluationValue(e.files, 'files');
|
||||||
|
}}
|
||||||
|
onRemove={(e) => {
|
||||||
|
const updatedFiles = ammendmentFilesRef.current.getFiles();
|
||||||
|
updateEvaluationValue(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>
|
||||||
|
</div>
|
||||||
|
|
||||||
<h3>{__('Tempo per la Risposta (giorni)', 'gepafin')}</h3>
|
<h3>{__('Tempo per la Risposta (giorni)', 'gepafin')}</h3>
|
||||||
<div style={{ marginBottom: '30px' }}>
|
<div style={{marginBottom: '30px'}}>
|
||||||
<InputNumber
|
<InputNumber
|
||||||
keyfilter="int"
|
keyfilter="int"
|
||||||
value={formData.responseDays}
|
value={formData.responseDays}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import AmendmentsService from '../../service/amendments-service';
|
|||||||
|
|
||||||
// tools
|
// tools
|
||||||
import set404FromErrorResponse from '../../helpers/set404FromErrorResponse';
|
import set404FromErrorResponse from '../../helpers/set404FromErrorResponse';
|
||||||
|
import getFormatedFileSizeText from '../../helpers/getFormatedFileSizeText';
|
||||||
|
|
||||||
// components
|
// components
|
||||||
import { Skeleton } from 'primereact/skeleton';
|
import { Skeleton } from 'primereact/skeleton';
|
||||||
@@ -24,6 +25,8 @@ import { Toast } from 'primereact/toast';
|
|||||||
import { InputSwitch } from 'primereact/inputswitch';
|
import { InputSwitch } from 'primereact/inputswitch';
|
||||||
import ApplicationEvaluationService from '../../service/application-evaluation-service';
|
import ApplicationEvaluationService from '../../service/application-evaluation-service';
|
||||||
import { Dialog } from 'primereact/dialog';
|
import { Dialog } from 'primereact/dialog';
|
||||||
|
import { FileUpload } from 'primereact/fileupload';
|
||||||
|
import { defaultMaxFileSize, mimeTypes } from '../../configData';
|
||||||
|
|
||||||
const SoccorsoAddPreInstructor = () => {
|
const SoccorsoAddPreInstructor = () => {
|
||||||
const isAsyncRequest = useStoreValue('isAsyncRequest');
|
const isAsyncRequest = useStoreValue('isAsyncRequest');
|
||||||
@@ -34,6 +37,7 @@ const SoccorsoAddPreInstructor = () => {
|
|||||||
const [formData, setFormData] = useState({});
|
const [formData, setFormData] = useState({});
|
||||||
const [isVisibleConfirmDialog, setIsVisibleConfirmDialog] = useState(false);
|
const [isVisibleConfirmDialog, setIsVisibleConfirmDialog] = useState(false);
|
||||||
const toast = useRef(null);
|
const toast = useRef(null);
|
||||||
|
const ammendmentFilesRef = useRef(null);
|
||||||
|
|
||||||
const goToEvaluationPage = () => {
|
const goToEvaluationPage = () => {
|
||||||
navigate(`/domande/${id}`);
|
navigate(`/domande/${id}`);
|
||||||
@@ -120,8 +124,24 @@ const SoccorsoAddPreInstructor = () => {
|
|||||||
|
|
||||||
const doCreate = () => {
|
const doCreate = () => {
|
||||||
storeSet('setAsyncRequest');
|
storeSet('setAsyncRequest');
|
||||||
|
const updatedFormData = { ...formData };
|
||||||
|
delete updatedFormData.files;
|
||||||
|
delete updatedFormData.formFields;
|
||||||
|
|
||||||
AmendmentsService.createSoccorso(formData, createCallback, errCreateCallback, [
|
const formDataToSend = new FormData();
|
||||||
|
|
||||||
|
const jsonBlob = new Blob([JSON.stringify(updatedFormData)], {
|
||||||
|
type: 'application/json'
|
||||||
|
});
|
||||||
|
formDataToSend.append('applicationAmendmentRequest', jsonBlob);
|
||||||
|
|
||||||
|
if (formData.files && formData.files.length > 0) {
|
||||||
|
formData.files.forEach((file) => {
|
||||||
|
formDataToSend.append('files', file);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
AmendmentsService.createSoccorso(formDataToSend, createCallback, errCreateCallback, [
|
||||||
['applicationEvaluationId', evaluationId]
|
['applicationEvaluationId', evaluationId]
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@@ -235,6 +255,63 @@ const SoccorsoAddPreInstructor = () => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div style={{marginBottom: '30px'}}>
|
||||||
|
<div className="appForm__field">
|
||||||
|
<label>
|
||||||
|
{__('Allegati PEC', 'gepafin')}
|
||||||
|
</label>
|
||||||
|
<FileUpload
|
||||||
|
ref={ammendmentFilesRef}
|
||||||
|
name="files[]"
|
||||||
|
multiple
|
||||||
|
accept={mimeTypes.map(o => o.code).join(',')}
|
||||||
|
maxFileSize={defaultMaxFileSize}
|
||||||
|
auto={false}
|
||||||
|
customUpload={true}
|
||||||
|
onSelect={(e) => {
|
||||||
|
updateEvaluationValue(e.files, 'files');
|
||||||
|
}}
|
||||||
|
onRemove={(e) => {
|
||||||
|
const updatedFiles = ammendmentFilesRef.current.getFiles();
|
||||||
|
updateEvaluationValue(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>
|
||||||
|
</div>
|
||||||
|
|
||||||
<h3>{__('Tempo per la Risposta (giorni)', 'gepafin')}</h3>
|
<h3>{__('Tempo per la Risposta (giorni)', 'gepafin')}</h3>
|
||||||
<div style={{marginBottom: '30px'}}>
|
<div style={{marginBottom: '30px'}}>
|
||||||
<InputNumber
|
<InputNumber
|
||||||
@@ -297,7 +374,7 @@ const SoccorsoAddPreInstructor = () => {
|
|||||||
<div className="appPageSection__message warning">
|
<div className="appPageSection__message warning">
|
||||||
<i className="pi pi-exclamation-triangle"></i>
|
<i className="pi pi-exclamation-triangle"></i>
|
||||||
<span className="summary">{__('Attenzione', 'gepafin')}</span>
|
<span className="summary">{__('Attenzione', 'gepafin')}</span>
|
||||||
<span>{__("L'invio della richiesta di integrazione sospenderà il termine di valutazione della domanda.", 'gepafin')}</span>
|
<span>{__('L\'invio della richiesta di integrazione sospenderà il termine di valutazione della domanda.', 'gepafin')}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="appPageSection__hr">
|
<div className="appPageSection__hr">
|
||||||
|
|||||||
@@ -338,6 +338,16 @@ const SoccorsoEditBeneficiario = () => {
|
|||||||
<SoccorsoComunications amendmentId={data.id} soccorsoStatus={data.status}/>
|
<SoccorsoComunications amendmentId={data.id} soccorsoStatus={data.status}/>
|
||||||
</div> : null}
|
</div> : null}
|
||||||
|
|
||||||
|
{data.id && data.amendmentInitialDocument && is(Array, data.amendmentInitialDocument)
|
||||||
|
? <div className="appPageSection">
|
||||||
|
<h3>{__('Documenti da PEC', 'gepafin')}</h3>
|
||||||
|
<ol className="appPageSection__list">
|
||||||
|
{data.amendmentInitialDocument.map((o, i) => <li key={o.fieldId}>
|
||||||
|
<a href={o.filePath} target="_blank" rel="noreferrer">{o.name}</a>
|
||||||
|
</li>)}
|
||||||
|
</ol>
|
||||||
|
</div> : null}
|
||||||
|
|
||||||
{data.id
|
{data.id
|
||||||
? <div className="appPageSection">
|
? <div className="appPageSection">
|
||||||
<h3>{__('Documenti richiesti', 'gepafin')}</h3>
|
<h3>{__('Documenti richiesti', 'gepafin')}</h3>
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import { InputNumber } from 'primereact/inputnumber';
|
|||||||
import SoccorsoComunications from '../SoccorsoEditPreInstructor/components/SoccorsoComunications';
|
import SoccorsoComunications from '../SoccorsoEditPreInstructor/components/SoccorsoComunications';
|
||||||
import SoccorsoResendEmails from '../SoccorsoEditPreInstructor/components/SoccorsoResendEmails';
|
import SoccorsoResendEmails from '../SoccorsoEditPreInstructor/components/SoccorsoResendEmails';
|
||||||
|
|
||||||
|
import { amendmentRequestedDocs } from '../../configData';
|
||||||
|
|
||||||
const SoccorsoEditInstructorManager = () => {
|
const SoccorsoEditInstructorManager = () => {
|
||||||
const isAsyncRequest = useStoreValue('isAsyncRequest');
|
const isAsyncRequest = useStoreValue('isAsyncRequest');
|
||||||
@@ -422,16 +423,33 @@ const SoccorsoEditInstructorManager = () => {
|
|||||||
<div
|
<div
|
||||||
className="appPageSection__emailTemplate">{getEmailTemplateForSoccorso(data.emailTemplate, data.note)}</div>
|
className="appPageSection__emailTemplate">{getEmailTemplateForSoccorso(data.emailTemplate, data.note)}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="appPageSection">
|
|
||||||
<h3>{__('Documenti richiesti', 'gepafin')}</h3>
|
{data.amendmentInitialDocument && is(Array, data.amendmentInitialDocument)
|
||||||
<ol className="appPageSection__list">
|
? <div className="appPageSection">
|
||||||
{data.formFields
|
<h3>{__('Documenti da PEC', 'gepafin')}</h3>
|
||||||
? data.formFields.map((o, i) => <li key={o.fieldId}
|
<ol className="appPageSection__list">
|
||||||
style={{ flexDirection: 'row' }}>
|
{data.amendmentInitialDocument.map((o, i) => <li key={o.fieldId}>
|
||||||
|
<a href={o.filePath} target="_blank" rel="noreferrer">{o.name}</a>
|
||||||
|
</li>)}
|
||||||
|
</ol>
|
||||||
|
</div> : null}
|
||||||
|
|
||||||
|
{(data.formFields && !isEmpty(data.formFields)) || (data.amendmentType === 'SPECIAL' && !isNil(data.amendmentDocumentType)
|
||||||
|
&& amendmentRequestedDocs[data.amendmentDocumentType])
|
||||||
|
? <div className="appPageSection">
|
||||||
|
<h3>{__('Documenti richiesti', 'gepafin')}</h3>
|
||||||
|
<ol className="appPageSection__list">
|
||||||
|
{data.formFields && !isEmpty(data.formFields)
|
||||||
|
? data.formFields.map((o, i) => <li key={o.fieldId}
|
||||||
|
style={{ flexDirection: 'row' }}>
|
||||||
<span>{o.label}</span>
|
<span>{o.label}</span>
|
||||||
</li>) : null}
|
</li>) : null}
|
||||||
</ol>
|
{amendmentRequestedDocs[data.amendmentDocumentType].map((v) => <li key={v}
|
||||||
</div>
|
style={{ flexDirection: 'row' }}>
|
||||||
|
<span>{v}</span>
|
||||||
|
</li>)}
|
||||||
|
</ol>
|
||||||
|
</div> : null}
|
||||||
|
|
||||||
<div className="appPageSection">
|
<div className="appPageSection">
|
||||||
<h2>{__('Comunicazioni', 'gepafin')}</h2>
|
<h2>{__('Comunicazioni', 'gepafin')}</h2>
|
||||||
|
|||||||
@@ -7,9 +7,10 @@ import { wrap } from 'object-path-immutable';
|
|||||||
import getDateFromISOstring from '../../../../helpers/getDateFromISOstring';
|
import getDateFromISOstring from '../../../../helpers/getDateFromISOstring';
|
||||||
import set404FromErrorResponse from '../../../../helpers/set404FromErrorResponse';
|
import set404FromErrorResponse from '../../../../helpers/set404FromErrorResponse';
|
||||||
import uniqid from '../../../../helpers/uniqid';
|
import uniqid from '../../../../helpers/uniqid';
|
||||||
|
import getFormatedFileSizeText from '../../../../helpers/getFormatedFileSizeText';
|
||||||
|
|
||||||
// store
|
// store
|
||||||
import { storeGet } from '../../../../store';
|
import { storeGet, useStoreValue } from '../../../../store';
|
||||||
|
|
||||||
// api
|
// api
|
||||||
import CommunicationService from '../../../../service/communication-service';
|
import CommunicationService from '../../../../service/communication-service';
|
||||||
@@ -18,16 +19,21 @@ import CommunicationService from '../../../../service/communication-service';
|
|||||||
import { Button } from 'primereact/button';
|
import { Button } from 'primereact/button';
|
||||||
import { classNames } from 'primereact/utils';
|
import { classNames } from 'primereact/utils';
|
||||||
import { InputText } from 'primereact/inputtext';
|
import { InputText } from 'primereact/inputtext';
|
||||||
import { InputTextarea } from 'primereact/inputtextarea';
|
|
||||||
import { Dialog } from 'primereact/dialog';
|
import { Dialog } from 'primereact/dialog';
|
||||||
import { Toast } from 'primereact/toast';
|
import { Toast } from 'primereact/toast';
|
||||||
|
import { FileUpload } from 'primereact/fileupload';
|
||||||
|
import { defaultMaxFileSize, mimeTypes } from '../../../../configData';
|
||||||
|
import { Editor } from 'primereact/editor';
|
||||||
|
import renderHtmlContent from '../../../../helpers/renderHtmlContent';
|
||||||
|
|
||||||
const SoccorsoComunications = ({ amendmentId, soccorsoStatus }) => {
|
const SoccorsoComunications = ({amendmentId, soccorsoStatus}) => {
|
||||||
const [comms, setComms] = useState([]);
|
const [comms, setComms] = useState([]);
|
||||||
const [isVisibleNewCommDialog, setIsVisibleNewCommDialog] = useState(false);
|
const [isVisibleNewCommDialog, setIsVisibleNewCommDialog] = useState(false);
|
||||||
const [newCommData, setNewCommData] = useState({});
|
const [newCommData, setNewCommData] = useState({});
|
||||||
const [isLoadingCommunication, setIsLoadingCommunication] = useState(false);
|
const [isLoadingCommunication, setIsLoadingCommunication] = useState(false);
|
||||||
const toast = useRef(null);
|
const toast = useRef(null);
|
||||||
|
const commDialogFilesRef = useRef(null);
|
||||||
|
const role = useStoreValue('getRole');
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (amendmentId && amendmentId !== 0) {
|
if (amendmentId && amendmentId !== 0) {
|
||||||
@@ -38,10 +44,10 @@ const SoccorsoComunications = ({ amendmentId, soccorsoStatus }) => {
|
|||||||
|
|
||||||
const getCommsCallback = (data) => {
|
const getCommsCallback = (data) => {
|
||||||
if (data.status === 'SUCCESS') {
|
if (data.status === 'SUCCESS') {
|
||||||
setComms(data.data.commentsList.map(o => getFormattedCommsData(o)));
|
setComms(data.data.map(o => getFormattedCommsData(o)));
|
||||||
}
|
}
|
||||||
setIsLoadingCommunication(false);
|
setIsLoadingCommunication(false);
|
||||||
}
|
};
|
||||||
|
|
||||||
const errGetCommsCallback = (data) => {
|
const errGetCommsCallback = (data) => {
|
||||||
if (toast.current && data.message) {
|
if (toast.current && data.message) {
|
||||||
@@ -52,7 +58,7 @@ const SoccorsoComunications = ({ amendmentId, soccorsoStatus }) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
setIsLoadingCommunication(false);
|
setIsLoadingCommunication(false);
|
||||||
}
|
};
|
||||||
|
|
||||||
const getFormattedCommsData = (data) => {
|
const getFormattedCommsData = (data) => {
|
||||||
data.id = isNil(data.id) ? uniqid('id') : data.id;
|
data.id = isNil(data.id) ? uniqid('id') : data.id;
|
||||||
@@ -63,8 +69,8 @@ const SoccorsoComunications = ({ amendmentId, soccorsoStatus }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const headerNewComDialog = () => {
|
const headerNewComDialog = () => {
|
||||||
return <span>{__('Aggiungi comunicazione', 'gepafin')}</span>
|
return <span>{__('Aggiungi comunicazione', 'gepafin')}</span>;
|
||||||
}
|
};
|
||||||
|
|
||||||
const hideNewComDialog = () => {
|
const hideNewComDialog = () => {
|
||||||
setIsVisibleNewCommDialog(false);
|
setIsVisibleNewCommDialog(false);
|
||||||
@@ -72,7 +78,7 @@ const SoccorsoComunications = ({ amendmentId, soccorsoStatus }) => {
|
|||||||
title: '',
|
title: '',
|
||||||
comment: ''
|
comment: ''
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
const footerNewComDialog = () => {
|
const footerNewComDialog = () => {
|
||||||
return <div>
|
return <div>
|
||||||
@@ -81,8 +87,8 @@ const SoccorsoComunications = ({ amendmentId, soccorsoStatus }) => {
|
|||||||
type="button"
|
type="button"
|
||||||
disabled={isLoadingCommunication || isEmpty(newCommData.title) || isEmpty(newCommData.comment)}
|
disabled={isLoadingCommunication || isEmpty(newCommData.title) || isEmpty(newCommData.comment)}
|
||||||
label={__('Invia', 'gepafin')} onClick={createCommunication}/>
|
label={__('Invia', 'gepafin')} onClick={createCommunication}/>
|
||||||
</div>
|
</div>;
|
||||||
}
|
};
|
||||||
|
|
||||||
const openNewCommDialog = () => {
|
const openNewCommDialog = () => {
|
||||||
setIsVisibleNewCommDialog(true);
|
setIsVisibleNewCommDialog(true);
|
||||||
@@ -90,17 +96,32 @@ const SoccorsoComunications = ({ amendmentId, soccorsoStatus }) => {
|
|||||||
title: '',
|
title: '',
|
||||||
comment: ''
|
comment: ''
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
const updateNewCommData = (value, path) => {
|
const updateNewCommData = (value, path) => {
|
||||||
const newData = wrap(newCommData).set(path.split('.'), value).value();
|
const newData = wrap(newCommData).set(path.split('.'), value).value();
|
||||||
setNewCommData(newData);
|
setNewCommData(newData);
|
||||||
}
|
};
|
||||||
|
|
||||||
const createCommunication = () => {
|
const createCommunication = () => {
|
||||||
setIsLoadingCommunication(true);
|
setIsLoadingCommunication(true);
|
||||||
CommunicationService.createCommunication(amendmentId, newCommData, createCommunicationCallback, errCreateCommunicationCallback);
|
const updatedFormData = { ...newCommData };
|
||||||
}
|
delete updatedFormData.files;
|
||||||
|
const formDataToSend = new FormData();
|
||||||
|
|
||||||
|
const jsonBlob = new Blob([JSON.stringify(updatedFormData)], {
|
||||||
|
type: 'application/json'
|
||||||
|
});
|
||||||
|
formDataToSend.append('communicationRequestBean', jsonBlob);
|
||||||
|
|
||||||
|
if (newCommData.files && newCommData.files.length > 0) {
|
||||||
|
newCommData.files.forEach((file) => {
|
||||||
|
formDataToSend.append('files', file);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
CommunicationService.createCommunication(amendmentId, formDataToSend, createCommunicationCallback, errCreateCommunicationCallback);
|
||||||
|
};
|
||||||
|
|
||||||
const createCommunicationCallback = (data) => {
|
const createCommunicationCallback = (data) => {
|
||||||
if (data.status === 'SUCCESS') {
|
if (data.status === 'SUCCESS') {
|
||||||
@@ -111,11 +132,11 @@ const SoccorsoComunications = ({ amendmentId, soccorsoStatus }) => {
|
|||||||
detail: data.message
|
detail: data.message
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
setComms([...comms, getFormattedCommsData(data.data)])
|
setComms([...comms, getFormattedCommsData(data.data)]);
|
||||||
setIsVisibleNewCommDialog(false);
|
setIsVisibleNewCommDialog(false);
|
||||||
}
|
}
|
||||||
setIsLoadingCommunication(false);
|
setIsLoadingCommunication(false);
|
||||||
}
|
};
|
||||||
|
|
||||||
const errCreateCommunicationCallback = (data) => {
|
const errCreateCommunicationCallback = (data) => {
|
||||||
if (toast.current && data.message) {
|
if (toast.current && data.message) {
|
||||||
@@ -127,29 +148,49 @@ const SoccorsoComunications = ({ amendmentId, soccorsoStatus }) => {
|
|||||||
}
|
}
|
||||||
set404FromErrorResponse(data);
|
set404FromErrorResponse(data);
|
||||||
setIsLoadingCommunication(false);
|
setIsLoadingCommunication(false);
|
||||||
}
|
};
|
||||||
|
|
||||||
const displayCommIcon = (comm) => {
|
const displayCommIcon = (comm) => {
|
||||||
const userData = storeGet('userData');
|
const userData = storeGet('userData');
|
||||||
return userData.id === comm.senderUserId
|
return userData.id === comm.senderUserId
|
||||||
? <i className="pi pi-upload"></i>
|
? <i className="pi pi-upload"></i>
|
||||||
: <i className="pi pi-download"></i>;
|
: <i className="pi pi-download"></i>;
|
||||||
}
|
};
|
||||||
|
|
||||||
const getCommRowClass = (comm) => {
|
const getCommRowClass = (comm) => {
|
||||||
const userData = storeGet('userData');
|
const userData = storeGet('userData');
|
||||||
return userData.id === comm.senderUserId ? 'outgoing' : 'incoming';
|
return userData.id === comm.senderUserId ? 'outgoing' : 'incoming';
|
||||||
}
|
};
|
||||||
|
|
||||||
|
const renderHeader = () => {
|
||||||
|
return (
|
||||||
|
<span className="ql-formats">
|
||||||
|
<button className="ql-bold" aria-label="Bold"></button>
|
||||||
|
<button className="ql-italic" aria-label="Italic"></button>
|
||||||
|
<button className="ql-underline" aria-label="Underline"></button>
|
||||||
|
<button className="ql-link" aria-label="Link"></button>
|
||||||
|
<button className="ql-list" value="ordered"></button>
|
||||||
|
<button className="ql-header" value="2"></button>
|
||||||
|
<button className="ql-header" value="3"></button>
|
||||||
|
<button className="ql-blockquote"></button>
|
||||||
|
<button className="ql-list" value="bullet"></button>
|
||||||
|
<button className="ql-indent" value="-1"></button>
|
||||||
|
<button className="ql-indent" value="+1"></button>
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const header = renderHeader();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Toast ref={toast}/>
|
<Toast ref={toast}/>
|
||||||
<table className="myTable">
|
<table className="myTable">
|
||||||
<thead className="myThead">
|
<thead className="myThead">
|
||||||
<tr>
|
<tr>
|
||||||
<th style={{ width: 50 }}></th>
|
<th style={{width: 50}}></th>
|
||||||
<th style={{ width: 250 }}>{__('Data', 'gepafin')}</th>
|
<th style={{width: 250}}>{__('Data', 'gepafin')}</th>
|
||||||
<th style={{ width: '100%' }}>{__('Comunicazione', 'gepafin')}</th>
|
<th style={{width: '100%'}}>{__('Comunicazione', 'gepafin')}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody className="myTbody">
|
<tbody className="myTbody">
|
||||||
@@ -163,7 +204,10 @@ const SoccorsoComunications = ({ amendmentId, soccorsoStatus }) => {
|
|||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<h3>{o.title}</h3>
|
<h3>{o.title}</h3>
|
||||||
<p>{o.comment}</p>
|
{renderHtmlContent(o.comment)}
|
||||||
|
{o.documents && !isEmpty(o.documents)
|
||||||
|
? <div>{o.documents.map((doc) => <a href={doc.filePath} target="_blank" rel="noreferrer">{doc.name}</a>)}</div>
|
||||||
|
: null }
|
||||||
</td>
|
</td>
|
||||||
</tr>)
|
</tr>)
|
||||||
: <tr>
|
: <tr>
|
||||||
@@ -175,7 +219,7 @@ const SoccorsoComunications = ({ amendmentId, soccorsoStatus }) => {
|
|||||||
</table>
|
</table>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
style={{ marginTop: 30 }}
|
style={{marginTop: 30}}
|
||||||
onClick={openNewCommDialog}
|
onClick={openNewCommDialog}
|
||||||
disabled={soccorsoStatus === 'CLOSE'}
|
disabled={soccorsoStatus === 'CLOSE'}
|
||||||
type="button"
|
type="button"
|
||||||
@@ -187,11 +231,11 @@ const SoccorsoComunications = ({ amendmentId, soccorsoStatus }) => {
|
|||||||
modal
|
modal
|
||||||
header={headerNewComDialog}
|
header={headerNewComDialog}
|
||||||
footer={footerNewComDialog}
|
footer={footerNewComDialog}
|
||||||
style={{ maxWidth: '600px', width: '100%' }}
|
style={{maxWidth: '600px', width: '100%'}}
|
||||||
onHide={hideNewComDialog}>
|
onHide={hideNewComDialog}>
|
||||||
<div className="appForm__field">
|
<div className="appForm__field">
|
||||||
<label
|
<label
|
||||||
className={classNames({ 'p-error': isEmpty(newCommData.title) })}>
|
className={classNames({'p-error': !newCommData.title || isEmpty(newCommData.title)})}>
|
||||||
{__('Titolo', 'gepafin')}*
|
{__('Titolo', 'gepafin')}*
|
||||||
</label>
|
</label>
|
||||||
<InputText value={newCommData.title}
|
<InputText value={newCommData.title}
|
||||||
@@ -200,19 +244,76 @@ const SoccorsoComunications = ({ amendmentId, soccorsoStatus }) => {
|
|||||||
onChange={(e) => updateNewCommData(e.target.value, 'title')}/>
|
onChange={(e) => updateNewCommData(e.target.value, 'title')}/>
|
||||||
|
|
||||||
<label
|
<label
|
||||||
className={classNames({ 'p-error': isEmpty(newCommData.comment) })}>
|
className={classNames({'p-error': !newCommData.comment || isEmpty(newCommData.comment)})}>
|
||||||
{__('Contenuto', 'gepafin')}*
|
{__('Contenuto', 'gepafin')}*
|
||||||
</label>
|
</label>
|
||||||
<InputTextarea
|
<Editor
|
||||||
value={newCommData.comment}
|
value={newCommData.comment}
|
||||||
disabled={soccorsoStatus === 'CLOSE'}
|
placeholder={__('Digita qui il messagio', 'gepafin')}
|
||||||
rows={5} cols={30}
|
readOnly={soccorsoStatus === 'CLOSE'}
|
||||||
invalid={isEmpty(newCommData.comment)}
|
headerTemplate={header}
|
||||||
onChange={(e) => updateNewCommData(e.target.value, 'comment')}/>
|
onTextChange={(e) => updateNewCommData(e.htmlValue, 'comment')}
|
||||||
|
style={{ height: 80 * 3, width: '100%' }}
|
||||||
|
/>
|
||||||
|
{!['ROLE_CONFIDI', 'ROLE_BENEFICIARY'].includes(role)
|
||||||
|
? <div className="appForm__field">
|
||||||
|
<label>
|
||||||
|
{__('Files', 'gepafin')}
|
||||||
|
</label>
|
||||||
|
<FileUpload
|
||||||
|
ref={commDialogFilesRef}
|
||||||
|
name="files[]"
|
||||||
|
multiple
|
||||||
|
accept={mimeTypes.map(o => o.code).join(',')}
|
||||||
|
maxFileSize={defaultMaxFileSize}
|
||||||
|
auto={false}
|
||||||
|
customUpload={true}
|
||||||
|
onSelect={(e) => {
|
||||||
|
updateNewCommData(e.files, 'files');
|
||||||
|
}}
|
||||||
|
onRemove={(e) => {
|
||||||
|
const updatedFiles = commDialogFilesRef.current.getFiles();
|
||||||
|
updateNewCommData(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> : null}
|
||||||
</div>
|
</div>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
</>
|
</>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export default SoccorsoComunications;
|
export default SoccorsoComunications;
|
||||||
@@ -30,6 +30,7 @@ import { InputNumber } from 'primereact/inputnumber';
|
|||||||
import SoccorsoComunications from './components/SoccorsoComunications';
|
import SoccorsoComunications from './components/SoccorsoComunications';
|
||||||
import SoccorsoResendEmails from './components/SoccorsoResendEmails';
|
import SoccorsoResendEmails from './components/SoccorsoResendEmails';
|
||||||
|
|
||||||
|
import { amendmentRequestedDocs } from '../../configData';
|
||||||
|
|
||||||
const SoccorsoEditPreInstructor = () => {
|
const SoccorsoEditPreInstructor = () => {
|
||||||
const isAsyncRequest = useStoreValue('isAsyncRequest');
|
const isAsyncRequest = useStoreValue('isAsyncRequest');
|
||||||
@@ -422,16 +423,33 @@ const SoccorsoEditPreInstructor = () => {
|
|||||||
<div
|
<div
|
||||||
className="appPageSection__emailTemplate">{getEmailTemplateForSoccorso(data.emailTemplate, data.note)}</div>
|
className="appPageSection__emailTemplate">{getEmailTemplateForSoccorso(data.emailTemplate, data.note)}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="appPageSection">
|
|
||||||
<h3>{__('Documenti richiesti', 'gepafin')}</h3>
|
{data.amendmentInitialDocument && is(Array, data.amendmentInitialDocument)
|
||||||
<ol className="appPageSection__list">
|
? <div className="appPageSection">
|
||||||
{data.formFields
|
<h3>{__('Documenti da PEC', 'gepafin')}</h3>
|
||||||
? data.formFields.map((o, i) => <li key={o.fieldId}
|
<ol className="appPageSection__list">
|
||||||
style={{ flexDirection: 'row' }}>
|
{data.amendmentInitialDocument.map((o, i) => <li key={o.fieldId}>
|
||||||
|
<a href={o.filePath} target="_blank" rel="noreferrer">{o.name}</a>
|
||||||
|
</li>)}
|
||||||
|
</ol>
|
||||||
|
</div> : null}
|
||||||
|
|
||||||
|
{(data.formFields && !isEmpty(data.formFields)) || (data.amendmentType === 'SPECIAL' && !isNil(data.amendmentDocumentType)
|
||||||
|
&& amendmentRequestedDocs[data.amendmentDocumentType])
|
||||||
|
? <div className="appPageSection">
|
||||||
|
<h3>{__('Documenti richiesti', 'gepafin')}</h3>
|
||||||
|
<ol className="appPageSection__list">
|
||||||
|
{data.formFields && !isEmpty(data.formFields)
|
||||||
|
? data.formFields.map((o, i) => <li key={o.fieldId}
|
||||||
|
style={{ flexDirection: 'row' }}>
|
||||||
<span>{o.label}</span>
|
<span>{o.label}</span>
|
||||||
</li>) : null}
|
</li>) : null}
|
||||||
</ol>
|
{amendmentRequestedDocs[data.amendmentDocumentType].map((v) => <li key={v}
|
||||||
</div>
|
style={{ flexDirection: 'row' }}>
|
||||||
|
<span>{v}</span>
|
||||||
|
</li>)}
|
||||||
|
</ol>
|
||||||
|
</div> : null}
|
||||||
|
|
||||||
<div className="appPageSection">
|
<div className="appPageSection">
|
||||||
<h2>{__('Comunicazioni', 'gepafin')}</h2>
|
<h2>{__('Comunicazioni', 'gepafin')}</h2>
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ export default class AmendmentsService {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static createSoccorso = (body, callback, errCallback, queryParams) => {
|
static createSoccorso = (body, callback, errCallback, queryParams) => {
|
||||||
NetworkService.post(`${API_BASE_URL}/amendments`, body, callback, errCallback, queryParams);
|
NetworkService.postMultiPart(`${API_BASE_URL}/amendments`, body, callback, errCallback, queryParams);
|
||||||
};
|
};
|
||||||
|
|
||||||
static updateSoccorso = (id, body, callback, errCallback, queryParams) => {
|
static updateSoccorso = (id, body, callback, errCallback, queryParams) => {
|
||||||
|
|||||||
@@ -17,11 +17,11 @@ export default class ApplicationEvaluationService {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static updateEvaluation = (assignedApplicationId, body, callback, errCallback, queryParams) => {
|
static updateEvaluation = (assignedApplicationId, body, callback, errCallback, queryParams) => {
|
||||||
NetworkService.put(`${API_BASE_URL}/applicationEvaluation/${assignedApplicationId}`, body, callback, errCallback, queryParams);
|
NetworkService.putMultiPart(`${API_BASE_URL}/applicationEvaluation/${assignedApplicationId}`, body, callback, errCallback, queryParams);
|
||||||
};
|
};
|
||||||
|
|
||||||
static updateEvaluationV2 = (assignedApplicationId, formId, body, callback, errCallback, queryParams = []) => {
|
static updateEvaluationV2 = (assignedApplicationId, formId, body, callback, errCallback, queryParams = []) => {
|
||||||
NetworkService.put(`${API_BASE_URL}/applicationEvaluation/v2/assignedApplication/${assignedApplicationId}`, body, callback, errCallback, [
|
NetworkService.putMultiPart(`${API_BASE_URL}/applicationEvaluation/v2/assignedApplication/${assignedApplicationId}`, body, callback, errCallback, [
|
||||||
['evaluationFormId', formId]
|
['evaluationFormId', formId]
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,6 +9,6 @@ export default class CommunicationService {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static createCommunication = (id, body, callback, errCallback, queryParams) => {
|
static createCommunication = (id, body, callback, errCallback, queryParams) => {
|
||||||
NetworkService.post(`${API_BASE_URL}/communication/${id}`, body, callback, errCallback, queryParams);
|
NetworkService.postMultiPart(`${API_BASE_URL}/communication/${id}`, body, callback, errCallback, queryParams);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,7 +84,6 @@ export class NetworkService {
|
|||||||
method: 'POST',
|
method: 'POST',
|
||||||
mode: 'cors',
|
mode: 'cors',
|
||||||
headers: {
|
headers: {
|
||||||
//'Content-Type': 'multipart/form-data',
|
|
||||||
'Authorization': 'Bearer ' + storeGet('getToken'),
|
'Authorization': 'Bearer ' + storeGet('getToken'),
|
||||||
},
|
},
|
||||||
body: body
|
body: body
|
||||||
@@ -235,6 +234,49 @@ export class NetworkService {
|
|||||||
.catch(err => errorCallback(err));
|
.catch(err => errorCallback(err));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static putMultiPart = (url, body, callback, errorCallback, queryParams = null) => {
|
||||||
|
if (queryParams) {
|
||||||
|
url += '?'
|
||||||
|
|
||||||
|
for (let i = 0; i < queryParams.length; i++) {
|
||||||
|
if (queryParams[i] && this.isNotBlank(queryParams[i][0]) && this.isNotBlank(queryParams[i][1])) {
|
||||||
|
let param = queryParams[i][0] + '=' + queryParams[i][1]
|
||||||
|
|
||||||
|
if (i !== queryParams.length - 1)
|
||||||
|
param += '&'
|
||||||
|
|
||||||
|
url += param;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (url.charAt(url.length) === '&')
|
||||||
|
url = url.substring(0, url.length - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch(url, {
|
||||||
|
method: 'PUT',
|
||||||
|
mode: 'cors',
|
||||||
|
headers: {
|
||||||
|
'Authorization': 'Bearer ' + storeGet('getToken'),
|
||||||
|
},
|
||||||
|
body: body
|
||||||
|
})
|
||||||
|
.then(async response => {
|
||||||
|
let status = response.status;
|
||||||
|
this.logApiError(url, status);
|
||||||
|
return { response: await response.json(), status: status }
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
if (data.status >= 400 && data.status <= 599) {
|
||||||
|
errorCallback(data.response)
|
||||||
|
this.logApiError(url, data.status, data.response);
|
||||||
|
} else {
|
||||||
|
callback(data.response)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(err => errorCallback(err));
|
||||||
|
};
|
||||||
|
|
||||||
static isNotBlank(value) {
|
static isNotBlank(value) {
|
||||||
return value !== null && value !== undefined && value !== ''
|
return value !== null && value !== undefined && value !== ''
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user