- added files field to evaluation rejection, ammendment creation and ammendment communication modal windows;
- fixed issue with filtering applications in dashboard for pre instructor;
This commit is contained in:
@@ -54,6 +54,8 @@ const DomandeTablePreInstructorAsync = ({ userId = null, statuses = [] }) => {
|
||||
assignedUserName: { value: null, matchMode: 'equals' }
|
||||
}
|
||||
});
|
||||
const applicationStatuses = ['EVALUATION', 'SOCCORSO', 'NDG', 'APPOINTMENT', 'ADMISSIBLE',
|
||||
'AWAITING_TECHNICAL_EVALUATION', 'TECHNICAL_EVALUATION'];
|
||||
|
||||
const getPaginationQuery = useCallback(() => getQueryParamsForPaginatedEndpoint(lazyState, statuses, 'applicationId'), [lazyState]);
|
||||
|
||||
@@ -106,14 +108,14 @@ const DomandeTablePreInstructorAsync = ({ userId = null, statuses = [] }) => {
|
||||
};
|
||||
|
||||
const statusFilterTemplate = (options) => {
|
||||
return <Dropdown value={options.value} options={statuses}
|
||||
return <Dropdown value={options.value} options={applicationStatuses}
|
||||
onChange={(e) => {
|
||||
options.filterCallback(e.value, options.index)
|
||||
const filters = { ...lazyState.filters };
|
||||
if (e.value) {
|
||||
filters['status'] = { value: e.value, matchMode: 'equals' };
|
||||
filters['applicationStatus'] = { value: e.value, matchMode: 'equals' };
|
||||
} else {
|
||||
delete filters['status'];
|
||||
delete filters['applicationStatus'];
|
||||
}
|
||||
setLazyState({ ...lazyState, filters, first: 0 });
|
||||
}}
|
||||
|
||||
@@ -56,6 +56,9 @@ import FormField from '../../components/FormField';
|
||||
import SoccorsoResendEmails from '../SoccorsoEditPreInstructor/components/SoccorsoResendEmails';
|
||||
import EvaluationReAdmit from '../DomandaEditPreInstructor/components/EvaluationReAdmit';
|
||||
import { SplitButton } from 'primereact/splitbutton';
|
||||
import { FileUpload } from 'primereact/fileupload';
|
||||
import { defaultMaxFileSize, mimeTypes } from '../../configData';
|
||||
import getFormatedFileSizeText from '../../helpers/getFormatedFileSizeText';
|
||||
|
||||
const APP_EVALUATION_FLOW_ID = process.env.REACT_APP_EVALUATION_FLOW_ID;
|
||||
const APP_HUB_ID = process.env.REACT_APP_HUB_ID;
|
||||
@@ -75,8 +78,10 @@ const DomandaEditInstructorManager = () => {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [isVisibleCompleteDialog, setIsVisibleCompleteDialog] = useState(false);
|
||||
const [operationType, setOperationType] = useState('');
|
||||
const [motivation, setMotivation] = useState('');
|
||||
const [amountAccepted, setAmountAccepted] = useState(0);
|
||||
const [finalDialogData, setFinalDialogData] = useState({
|
||||
motivation: ''
|
||||
});
|
||||
const finalDialogFilesRef = useRef(null);
|
||||
const [isVisibleAppointmentDialog, setIsVisibleAppointmentDialog] = useState(false);
|
||||
const [isVisiblePreTecEvalDialog, setIsVisiblePreTecEvalDialog] = useState(false);
|
||||
const [preTecEvalData, setPreTecEvalData] = useState({
|
||||
@@ -219,7 +224,7 @@ const DomandaEditInstructorManager = () => {
|
||||
const getCallback = (resp) => {
|
||||
if (resp.status === 'SUCCESS') {
|
||||
setData(getFormattedData(resp.data));
|
||||
setMotivation(resp.data.motivation);
|
||||
setFinalDialogData((prev) => ({...prev, motivation: resp.data.motivation}));
|
||||
updateFlagsForSoccorso(resp.data);
|
||||
|
||||
if (resp.data.evaluationVersion === 'V2') {
|
||||
@@ -445,8 +450,8 @@ const DomandaEditInstructorManager = () => {
|
||||
checklist: klona(data.checklist),
|
||||
files: klona(data.files),
|
||||
note: data.note,
|
||||
motivation,
|
||||
amountAccepted
|
||||
motivation: finalDialogData.motivation,
|
||||
amountAccepted: finalDialogData.amount
|
||||
}
|
||||
|
||||
setLoading(true);
|
||||
@@ -470,8 +475,8 @@ const DomandaEditInstructorManager = () => {
|
||||
)),
|
||||
amendmentDetails: klona(data.amendmentDetails),
|
||||
note: data.note,
|
||||
motivation,
|
||||
amountAccepted
|
||||
motivation: finalDialogData.motivation,
|
||||
amountAccepted: finalDialogData.amount
|
||||
}
|
||||
|
||||
setLoading(true);
|
||||
@@ -484,7 +489,7 @@ const DomandaEditInstructorManager = () => {
|
||||
errApproveRejectCallback
|
||||
);
|
||||
}
|
||||
}, [data, motivation]);
|
||||
}, [data, finalDialogData]);
|
||||
|
||||
const doReject = useCallback((newStatus) => {
|
||||
if (data.evaluationVersion === 'V1') {
|
||||
@@ -494,7 +499,7 @@ const DomandaEditInstructorManager = () => {
|
||||
checklist: klona(data.checklist),
|
||||
files: klona(data.files),
|
||||
note: data.note,
|
||||
motivation
|
||||
motivation: finalDialogData.motivation
|
||||
}
|
||||
|
||||
setLoading(true);
|
||||
@@ -518,7 +523,7 @@ const DomandaEditInstructorManager = () => {
|
||||
)),
|
||||
amendmentDetails: klona(data.amendmentDetails),
|
||||
note: data.note,
|
||||
motivation
|
||||
motivation: finalDialogData.motivation
|
||||
}
|
||||
|
||||
setLoading(true);
|
||||
@@ -531,7 +536,7 @@ const DomandaEditInstructorManager = () => {
|
||||
errApproveRejectCallback
|
||||
);
|
||||
}
|
||||
}, [data, motivation]);
|
||||
}, [data, finalDialogData]);
|
||||
|
||||
const approveRejectCallback = (data) => {
|
||||
if (data.status === 'SUCCESS') {
|
||||
@@ -653,7 +658,7 @@ const DomandaEditInstructorManager = () => {
|
||||
const hideCompleteDialog = () => {
|
||||
setIsVisibleCompleteDialog(false);
|
||||
setOperationType('');
|
||||
setMotivation('');
|
||||
setFinalDialogData({});
|
||||
}
|
||||
|
||||
const footerCompleteDialog = useCallback(() => {
|
||||
@@ -662,11 +667,12 @@ const DomandaEditInstructorManager = () => {
|
||||
|
||||
if (operationType === 'approve') {
|
||||
onSubmitAction = doApprove;
|
||||
isDisabled = isDisabled || !amountAccepted || isEmpty(amountAccepted) || amountAccepted === 0;
|
||||
isDisabled = isDisabled || !finalDialogData.amount || isEmpty(finalDialogData.amount) || finalDialogData.amount === 0;
|
||||
} else if (operationType === 'tf_reject') {
|
||||
onSubmitAction = () => doReject('TECHNICAL_EVALUATION_REJECTED');
|
||||
} else {
|
||||
onSubmitAction = () => doReject('REJECTED');
|
||||
isDisabled = isDisabled || !finalDialogData.subject || isEmpty(finalDialogData.subject) || !finalDialogData.motivation || isEmpty(finalDialogData.motivation)
|
||||
}
|
||||
|
||||
return <div>
|
||||
@@ -676,7 +682,12 @@ const DomandaEditInstructorManager = () => {
|
||||
disabled={isDisabled}
|
||||
label={__('Invia', 'gepafin')} onClick={onSubmitAction}/>
|
||||
</div>
|
||||
}, [amountAccepted, data, motivation]);
|
||||
}, [finalDialogData, data]);
|
||||
|
||||
const updateFinalDialogData = (value, path) => {
|
||||
const newData = wrap(finalDialogData).set(path.split('.'), value).value();
|
||||
setFinalDialogData(newData);
|
||||
};
|
||||
|
||||
const initiateApproving = () => {
|
||||
setOperationType('approve');
|
||||
@@ -945,7 +956,7 @@ const DomandaEditInstructorManager = () => {
|
||||
? <Button
|
||||
type="button"
|
||||
disabled={!data.id || data.status === 'CLOSE'
|
||||
|| (data.applicationStatus === 'EVALUATION' && shouldDisableNewSoccorso())
|
||||
|| (data.applicationStatus !== 'SOCCORSO' && shouldDisableNewSoccorso())
|
||||
|| evaluationBlockedForUser(data)}
|
||||
onClick={doNewSoccorso}
|
||||
outlined
|
||||
@@ -1505,28 +1516,95 @@ const DomandaEditInstructorManager = () => {
|
||||
{operationType === 'approve'
|
||||
? <div className="appForm__field">
|
||||
<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')}
|
||||
</label>
|
||||
<InputNumber
|
||||
value={amountAccepted}
|
||||
value={finalDialogData.amount}
|
||||
keyfilter="int"
|
||||
invalid={!amountAccepted || isEmpty(amountAccepted) || amountAccepted === 0}
|
||||
onChange={(e) => setAmountAccepted(e.value)}/>
|
||||
invalid={!finalDialogData.amount || isEmpty(finalDialogData.amount) || finalDialogData.amount === 0}
|
||||
onChange={(e) => updateFinalDialogData(e.value, 'amount')}/>
|
||||
</div> : null}
|
||||
{operationType === 'reject'
|
||||
? <div className="appForm__field">
|
||||
<label className={classNames({ 'p-error': !finalDialogData.subject || isEmpty(finalDialogData.subject) })}>
|
||||
{__('Soggetto', 'gepafin')}
|
||||
</label>
|
||||
<InputText
|
||||
value={finalDialogData.subject}
|
||||
invalid={!finalDialogData.subject || isEmpty(finalDialogData.subject)}
|
||||
onChange={(e) => updateFinalDialogData(e.target.value, 'subject')}/>
|
||||
</div> : null}
|
||||
<div className="appForm__field">
|
||||
<label>{__('Motivazione', 'gepafin')}</label>
|
||||
<label className={classNames({ 'p-error': !finalDialogData.motivation || isEmpty(finalDialogData.motivation) })}>
|
||||
{__('Motivazione', 'gepafin')}
|
||||
</label>
|
||||
<div translate="no">
|
||||
<Editor
|
||||
value={motivation}
|
||||
value={finalDialogData.motivation}
|
||||
readOnly={loading}
|
||||
placeholder={__('Digita qui il messagio', 'gepafin')}
|
||||
headerTemplate={header}
|
||||
onTextChange={(e) => setMotivation(e.htmlValue)}
|
||||
onTextChange={(e) => updateFinalDialogData(e.htmlValue, 'motivation')}
|
||||
style={{ height: 80 * 3, width: '100%' }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{operationType === 'reject'
|
||||
? <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
|
||||
|
||||
@@ -56,6 +56,9 @@ import FormField from '../../components/FormField';
|
||||
import SoccorsoResendEmails from '../SoccorsoEditPreInstructor/components/SoccorsoResendEmails';
|
||||
import EvaluationReAdmit from './components/EvaluationReAdmit';
|
||||
import { SplitButton } from 'primereact/splitbutton';
|
||||
import { FileUpload } from 'primereact/fileupload';
|
||||
import { defaultMaxFileSize, mimeTypes } from '../../configData';
|
||||
import getFormatedFileSizeText from '../../helpers/getFormatedFileSizeText';
|
||||
|
||||
const APP_EVALUATION_FLOW_ID = process.env.REACT_APP_EVALUATION_FLOW_ID;
|
||||
const APP_HUB_ID = process.env.REACT_APP_HUB_ID;
|
||||
@@ -75,8 +78,10 @@ const DomandaEditPreInstructor = () => {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [isVisibleCompleteDialog, setIsVisibleCompleteDialog] = useState(false);
|
||||
const [operationType, setOperationType] = useState('');
|
||||
const [motivation, setMotivation] = useState('');
|
||||
const [amountAccepted, setAmountAccepted] = useState(0);
|
||||
const [finalDialogData, setFinalDialogData] = useState({
|
||||
motivation: ''
|
||||
});
|
||||
const finalDialogFilesRef = useRef(null);
|
||||
const [isVisibleAppointmentDialog, setIsVisibleAppointmentDialog] = useState(false);
|
||||
const [isVisiblePreTecEvalDialog, setIsVisiblePreTecEvalDialog] = useState(false);
|
||||
const [preTecEvalData, setPreTecEvalData] = useState({
|
||||
@@ -219,7 +224,7 @@ const DomandaEditPreInstructor = () => {
|
||||
const getCallback = (resp) => {
|
||||
if (resp.status === 'SUCCESS') {
|
||||
setData(getFormattedData(resp.data));
|
||||
setMotivation(resp.data.motivation);
|
||||
setFinalDialogData((prev) => ({...prev, motivation: resp.data.motivation}));
|
||||
updateFlagsForSoccorso(resp.data);
|
||||
|
||||
if (resp.data.evaluationVersion === 'V2') {
|
||||
@@ -445,8 +450,8 @@ const DomandaEditPreInstructor = () => {
|
||||
checklist: klona(data.checklist),
|
||||
files: klona(data.files),
|
||||
note: data.note,
|
||||
motivation,
|
||||
amountAccepted
|
||||
motivation: finalDialogData.motivation,
|
||||
amountAccepted: finalDialogData.amount
|
||||
}
|
||||
|
||||
setLoading(true);
|
||||
@@ -470,8 +475,8 @@ const DomandaEditPreInstructor = () => {
|
||||
)),
|
||||
amendmentDetails: klona(data.amendmentDetails),
|
||||
note: data.note,
|
||||
motivation,
|
||||
amountAccepted
|
||||
motivation: finalDialogData.motivation,
|
||||
amountAccepted: finalDialogData.amount
|
||||
}
|
||||
|
||||
setLoading(true);
|
||||
@@ -484,7 +489,7 @@ const DomandaEditPreInstructor = () => {
|
||||
errApproveRejectCallback
|
||||
);
|
||||
}
|
||||
}, [data, motivation]);
|
||||
}, [data, finalDialogData]);
|
||||
|
||||
const doReject = useCallback((newStatus) => {
|
||||
if (data.evaluationVersion === 'V1') {
|
||||
@@ -494,7 +499,7 @@ const DomandaEditPreInstructor = () => {
|
||||
checklist: klona(data.checklist),
|
||||
files: klona(data.files),
|
||||
note: data.note,
|
||||
motivation
|
||||
motivation: finalDialogData.motivation
|
||||
}
|
||||
|
||||
setLoading(true);
|
||||
@@ -518,7 +523,7 @@ const DomandaEditPreInstructor = () => {
|
||||
)),
|
||||
amendmentDetails: klona(data.amendmentDetails),
|
||||
note: data.note,
|
||||
motivation
|
||||
motivation: finalDialogData.motivation
|
||||
}
|
||||
|
||||
setLoading(true);
|
||||
@@ -531,7 +536,7 @@ const DomandaEditPreInstructor = () => {
|
||||
errApproveRejectCallback
|
||||
);
|
||||
}
|
||||
}, [data, motivation]);
|
||||
}, [data, finalDialogData]);
|
||||
|
||||
const approveRejectCallback = (data) => {
|
||||
if (data.status === 'SUCCESS') {
|
||||
@@ -653,7 +658,7 @@ const DomandaEditPreInstructor = () => {
|
||||
const hideCompleteDialog = () => {
|
||||
setIsVisibleCompleteDialog(false);
|
||||
setOperationType('');
|
||||
setMotivation('');
|
||||
setFinalDialogData({});
|
||||
}
|
||||
|
||||
const footerCompleteDialog = useCallback(() => {
|
||||
@@ -662,11 +667,12 @@ const DomandaEditPreInstructor = () => {
|
||||
|
||||
if (operationType === 'approve') {
|
||||
onSubmitAction = doApprove;
|
||||
isDisabled = isDisabled || !amountAccepted || isEmpty(amountAccepted) || amountAccepted === 0;
|
||||
isDisabled = isDisabled || !finalDialogData.amount || isEmpty(finalDialogData.amount) || finalDialogData.amount === 0;
|
||||
} else if (operationType === 'tf_reject') {
|
||||
onSubmitAction = () => doReject('TECHNICAL_EVALUATION_REJECTED');
|
||||
} else {
|
||||
onSubmitAction = () => doReject('REJECTED');
|
||||
isDisabled = isDisabled || !finalDialogData.subject || isEmpty(finalDialogData.subject) || !finalDialogData.motivation || isEmpty(finalDialogData.motivation)
|
||||
}
|
||||
|
||||
return <div>
|
||||
@@ -676,7 +682,12 @@ const DomandaEditPreInstructor = () => {
|
||||
disabled={isDisabled}
|
||||
label={__('Invia', 'gepafin')} onClick={onSubmitAction}/>
|
||||
</div>
|
||||
}, [amountAccepted, data, motivation]);
|
||||
}, [finalDialogData, data]);
|
||||
|
||||
const updateFinalDialogData = (value, path) => {
|
||||
const newData = wrap(finalDialogData).set(path.split('.'), value).value();
|
||||
setFinalDialogData(newData);
|
||||
};
|
||||
|
||||
const initiateApproving = () => {
|
||||
setOperationType('approve');
|
||||
@@ -945,7 +956,7 @@ const DomandaEditPreInstructor = () => {
|
||||
? <Button
|
||||
type="button"
|
||||
disabled={!data.id || data.status === 'CLOSE'
|
||||
|| (data.applicationStatus === 'EVALUATION' && shouldDisableNewSoccorso())
|
||||
|| (data.applicationStatus !== 'SOCCORSO' && shouldDisableNewSoccorso())
|
||||
|| evaluationBlockedForUser(data)}
|
||||
onClick={doNewSoccorso}
|
||||
outlined
|
||||
@@ -1505,28 +1516,95 @@ const DomandaEditPreInstructor = () => {
|
||||
{operationType === 'approve'
|
||||
? <div className="appForm__field">
|
||||
<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')}
|
||||
</label>
|
||||
<InputNumber
|
||||
value={amountAccepted}
|
||||
value={finalDialogData.amount}
|
||||
keyfilter="int"
|
||||
invalid={!amountAccepted || isEmpty(amountAccepted) || amountAccepted === 0}
|
||||
onChange={(e) => setAmountAccepted(e.value)}/>
|
||||
invalid={!finalDialogData.amount || isEmpty(finalDialogData.amount) || finalDialogData.amount === 0}
|
||||
onChange={(e) => updateFinalDialogData(e.value, 'amount')}/>
|
||||
</div> : null}
|
||||
{operationType === 'reject'
|
||||
? <div className="appForm__field">
|
||||
<label className={classNames({ 'p-error': !finalDialogData.subject || isEmpty(finalDialogData.subject) })}>
|
||||
{__('Soggetto', 'gepafin')}
|
||||
</label>
|
||||
<InputText
|
||||
value={finalDialogData.subject}
|
||||
invalid={!finalDialogData.subject || isEmpty(finalDialogData.subject)}
|
||||
onChange={(e) => updateFinalDialogData(e.target.value, 'subject')}/>
|
||||
</div> : null}
|
||||
<div className="appForm__field">
|
||||
<label>{__('Motivazione', 'gepafin')}</label>
|
||||
<label className={classNames({ 'p-error': !finalDialogData.motivation || isEmpty(finalDialogData.motivation) })}>
|
||||
{__('Motivazione', 'gepafin')}
|
||||
</label>
|
||||
<div translate="no">
|
||||
<Editor
|
||||
value={motivation}
|
||||
value={finalDialogData.motivation}
|
||||
readOnly={loading}
|
||||
placeholder={__('Digita qui il messagio', 'gepafin')}
|
||||
headerTemplate={header}
|
||||
onTextChange={(e) => setMotivation(e.htmlValue)}
|
||||
onTextChange={(e) => updateFinalDialogData(e.htmlValue, 'motivation')}
|
||||
style={{ height: 80 * 3, width: '100%' }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{operationType === 'reject'
|
||||
? <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
|
||||
|
||||
@@ -12,6 +12,7 @@ import AmendmentsService from '../../service/amendments-service';
|
||||
|
||||
// tools
|
||||
import set404FromErrorResponse from '../../helpers/set404FromErrorResponse';
|
||||
import getFormatedFileSizeText from '../../helpers/getFormatedFileSizeText';
|
||||
|
||||
// components
|
||||
import { Skeleton } from 'primereact/skeleton';
|
||||
@@ -24,6 +25,8 @@ import { Toast } from 'primereact/toast';
|
||||
import { InputSwitch } from 'primereact/inputswitch';
|
||||
import ApplicationEvaluationService from '../../service/application-evaluation-service';
|
||||
import { Dialog } from 'primereact/dialog';
|
||||
import { FileUpload } from 'primereact/fileupload';
|
||||
import { defaultMaxFileSize, mimeTypes } from '../../configData';
|
||||
|
||||
const SoccorsoAddInstructorManager = () => {
|
||||
const isAsyncRequest = useStoreValue('isAsyncRequest');
|
||||
@@ -32,8 +35,9 @@ const SoccorsoAddInstructorManager = () => {
|
||||
const [data, setData] = useState({});
|
||||
const [evaluationId, setEvaluationId] = useState(0);
|
||||
const [formData, setFormData] = useState({});
|
||||
const [isVisibleConfirmDialog, setIsVisibleConfirmDialog] = useState(false)
|
||||
const [isVisibleConfirmDialog, setIsVisibleConfirmDialog] = useState(false);
|
||||
const toast = useRef(null);
|
||||
const ammendmentFilesRef = useRef(null);
|
||||
|
||||
const goToEvaluationPage = () => {
|
||||
navigate(`/mie-domande/${id}`);
|
||||
@@ -222,7 +226,7 @@ const SoccorsoAddInstructorManager = () => {
|
||||
<div className="appPageSection columns">
|
||||
<div>
|
||||
<h3>{__('Pec/Email', 'gepafin')}</h3>
|
||||
<div style={{ marginBottom: '30px' }} translate="no">
|
||||
<div style={{marginBottom: '30px'}} translate="no">
|
||||
<Editor
|
||||
value={formData.note}
|
||||
placeholder={__('Digita qui il messagio', 'gepafin')}
|
||||
@@ -235,8 +239,65 @@ const SoccorsoAddInstructorManager = () => {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div style={{marginBottom: '30px'}}>
|
||||
<div className="appForm__field">
|
||||
<label>
|
||||
{__('Files', '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>
|
||||
<div style={{ marginBottom: '30px' }}>
|
||||
<div style={{marginBottom: '30px'}}>
|
||||
<InputNumber
|
||||
keyfilter="int"
|
||||
value={formData.responseDays}
|
||||
|
||||
@@ -12,6 +12,7 @@ import AmendmentsService from '../../service/amendments-service';
|
||||
|
||||
// tools
|
||||
import set404FromErrorResponse from '../../helpers/set404FromErrorResponse';
|
||||
import getFormatedFileSizeText from '../../helpers/getFormatedFileSizeText';
|
||||
|
||||
// components
|
||||
import { Skeleton } from 'primereact/skeleton';
|
||||
@@ -24,6 +25,8 @@ import { Toast } from 'primereact/toast';
|
||||
import { InputSwitch } from 'primereact/inputswitch';
|
||||
import ApplicationEvaluationService from '../../service/application-evaluation-service';
|
||||
import { Dialog } from 'primereact/dialog';
|
||||
import { FileUpload } from 'primereact/fileupload';
|
||||
import { defaultMaxFileSize, mimeTypes } from '../../configData';
|
||||
|
||||
const SoccorsoAddPreInstructor = () => {
|
||||
const isAsyncRequest = useStoreValue('isAsyncRequest');
|
||||
@@ -34,6 +37,7 @@ const SoccorsoAddPreInstructor = () => {
|
||||
const [formData, setFormData] = useState({});
|
||||
const [isVisibleConfirmDialog, setIsVisibleConfirmDialog] = useState(false);
|
||||
const toast = useRef(null);
|
||||
const ammendmentFilesRef = useRef(null);
|
||||
|
||||
const goToEvaluationPage = () => {
|
||||
navigate(`/domande/${id}`);
|
||||
@@ -235,6 +239,63 @@ const SoccorsoAddPreInstructor = () => {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div style={{marginBottom: '30px'}}>
|
||||
<div className="appForm__field">
|
||||
<label>
|
||||
{__('Files', '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>
|
||||
<div style={{marginBottom: '30px'}}>
|
||||
<InputNumber
|
||||
@@ -297,7 +358,7 @@ const SoccorsoAddPreInstructor = () => {
|
||||
<div className="appPageSection__message warning">
|
||||
<i className="pi pi-exclamation-triangle"></i>
|
||||
<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 className="appPageSection__hr">
|
||||
|
||||
@@ -9,7 +9,7 @@ import set404FromErrorResponse from '../../../../helpers/set404FromErrorResponse
|
||||
import uniqid from '../../../../helpers/uniqid';
|
||||
|
||||
// store
|
||||
import { storeGet } from '../../../../store';
|
||||
import { storeGet, useStoreValue } from '../../../../store';
|
||||
|
||||
// api
|
||||
import CommunicationService from '../../../../service/communication-service';
|
||||
@@ -21,13 +21,18 @@ import { InputText } from 'primereact/inputtext';
|
||||
import { InputTextarea } from 'primereact/inputtextarea';
|
||||
import { Dialog } from 'primereact/dialog';
|
||||
import { Toast } from 'primereact/toast';
|
||||
import { FileUpload } from 'primereact/fileupload';
|
||||
import { defaultMaxFileSize, mimeTypes } from '../../../../configData';
|
||||
import getFormatedFileSizeText from '../../../../helpers/getFormatedFileSizeText';
|
||||
|
||||
const SoccorsoComunications = ({ amendmentId, soccorsoStatus }) => {
|
||||
const SoccorsoComunications = ({amendmentId, soccorsoStatus}) => {
|
||||
const [comms, setComms] = useState([]);
|
||||
const [isVisibleNewCommDialog, setIsVisibleNewCommDialog] = useState(false);
|
||||
const [newCommData, setNewCommData] = useState({});
|
||||
const [isLoadingCommunication, setIsLoadingCommunication] = useState(false);
|
||||
const toast = useRef(null);
|
||||
const commDialogFilesRef = useRef(null);
|
||||
const role = useStoreValue('getRole');
|
||||
|
||||
useEffect(() => {
|
||||
if (amendmentId && amendmentId !== 0) {
|
||||
@@ -41,7 +46,7 @@ const SoccorsoComunications = ({ amendmentId, soccorsoStatus }) => {
|
||||
setComms(data.data.commentsList.map(o => getFormattedCommsData(o)));
|
||||
}
|
||||
setIsLoadingCommunication(false);
|
||||
}
|
||||
};
|
||||
|
||||
const errGetCommsCallback = (data) => {
|
||||
if (toast.current && data.message) {
|
||||
@@ -52,8 +57,8 @@ const SoccorsoComunications = ({ amendmentId, soccorsoStatus }) => {
|
||||
});
|
||||
}
|
||||
setIsLoadingCommunication(false);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
const getFormattedCommsData = (data) => {
|
||||
data.id = isNil(data.id) ? uniqid('id') : data.id;
|
||||
data.commentedDate = is(String, data.commentedDate) ? new Date(data.commentedDate) : (data.commentedDate ? data.commentedDate : '');
|
||||
@@ -63,8 +68,8 @@ const SoccorsoComunications = ({ amendmentId, soccorsoStatus }) => {
|
||||
};
|
||||
|
||||
const headerNewComDialog = () => {
|
||||
return <span>{__('Aggiungi comunicazione', 'gepafin')}</span>
|
||||
}
|
||||
return <span>{__('Aggiungi comunicazione', 'gepafin')}</span>;
|
||||
};
|
||||
|
||||
const hideNewComDialog = () => {
|
||||
setIsVisibleNewCommDialog(false);
|
||||
@@ -72,7 +77,7 @@ const SoccorsoComunications = ({ amendmentId, soccorsoStatus }) => {
|
||||
title: '',
|
||||
comment: ''
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const footerNewComDialog = () => {
|
||||
return <div>
|
||||
@@ -81,8 +86,8 @@ const SoccorsoComunications = ({ amendmentId, soccorsoStatus }) => {
|
||||
type="button"
|
||||
disabled={isLoadingCommunication || isEmpty(newCommData.title) || isEmpty(newCommData.comment)}
|
||||
label={__('Invia', 'gepafin')} onClick={createCommunication}/>
|
||||
</div>
|
||||
}
|
||||
</div>;
|
||||
};
|
||||
|
||||
const openNewCommDialog = () => {
|
||||
setIsVisibleNewCommDialog(true);
|
||||
@@ -90,17 +95,17 @@ const SoccorsoComunications = ({ amendmentId, soccorsoStatus }) => {
|
||||
title: '',
|
||||
comment: ''
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const updateNewCommData = (value, path) => {
|
||||
const newData = wrap(newCommData).set(path.split('.'), value).value();
|
||||
setNewCommData(newData);
|
||||
}
|
||||
};
|
||||
|
||||
const createCommunication = () => {
|
||||
setIsLoadingCommunication(true);
|
||||
CommunicationService.createCommunication(amendmentId, newCommData, createCommunicationCallback, errCreateCommunicationCallback);
|
||||
}
|
||||
};
|
||||
|
||||
const createCommunicationCallback = (data) => {
|
||||
if (data.status === 'SUCCESS') {
|
||||
@@ -111,11 +116,11 @@ const SoccorsoComunications = ({ amendmentId, soccorsoStatus }) => {
|
||||
detail: data.message
|
||||
});
|
||||
}
|
||||
setComms([...comms, getFormattedCommsData(data.data)])
|
||||
setComms([...comms, getFormattedCommsData(data.data)]);
|
||||
setIsVisibleNewCommDialog(false);
|
||||
}
|
||||
setIsLoadingCommunication(false);
|
||||
}
|
||||
};
|
||||
|
||||
const errCreateCommunicationCallback = (data) => {
|
||||
if (toast.current && data.message) {
|
||||
@@ -127,29 +132,29 @@ const SoccorsoComunications = ({ amendmentId, soccorsoStatus }) => {
|
||||
}
|
||||
set404FromErrorResponse(data);
|
||||
setIsLoadingCommunication(false);
|
||||
}
|
||||
};
|
||||
|
||||
const displayCommIcon = (comm) => {
|
||||
const userData = storeGet('userData');
|
||||
return userData.id === comm.senderUserId
|
||||
? <i className="pi pi-upload"></i>
|
||||
: <i className="pi pi-download"></i>;
|
||||
}
|
||||
};
|
||||
|
||||
const getCommRowClass = (comm) => {
|
||||
const userData = storeGet('userData');
|
||||
return userData.id === comm.senderUserId ? 'outgoing' : 'incoming';
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Toast ref={toast}/>
|
||||
<Toast ref={toast}/>
|
||||
<table className="myTable">
|
||||
<thead className="myThead">
|
||||
<tr>
|
||||
<th style={{ width: 50 }}></th>
|
||||
<th style={{ width: 250 }}>{__('Data', 'gepafin')}</th>
|
||||
<th style={{ width: '100%' }}>{__('Comunicazione', 'gepafin')}</th>
|
||||
<th style={{width: 50}}></th>
|
||||
<th style={{width: 250}}>{__('Data', 'gepafin')}</th>
|
||||
<th style={{width: '100%'}}>{__('Comunicazione', 'gepafin')}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="myTbody">
|
||||
@@ -175,7 +180,7 @@ const SoccorsoComunications = ({ amendmentId, soccorsoStatus }) => {
|
||||
</table>
|
||||
|
||||
<Button
|
||||
style={{ marginTop: 30 }}
|
||||
style={{marginTop: 30}}
|
||||
onClick={openNewCommDialog}
|
||||
disabled={soccorsoStatus === 'CLOSE'}
|
||||
type="button"
|
||||
@@ -187,11 +192,11 @@ const SoccorsoComunications = ({ amendmentId, soccorsoStatus }) => {
|
||||
modal
|
||||
header={headerNewComDialog}
|
||||
footer={footerNewComDialog}
|
||||
style={{ maxWidth: '600px', width: '100%' }}
|
||||
style={{maxWidth: '600px', width: '100%'}}
|
||||
onHide={hideNewComDialog}>
|
||||
<div className="appForm__field">
|
||||
<label
|
||||
className={classNames({ 'p-error': isEmpty(newCommData.title) })}>
|
||||
className={classNames({'p-error': isEmpty(newCommData.title)})}>
|
||||
{__('Titolo', 'gepafin')}*
|
||||
</label>
|
||||
<InputText value={newCommData.title}
|
||||
@@ -200,7 +205,7 @@ const SoccorsoComunications = ({ amendmentId, soccorsoStatus }) => {
|
||||
onChange={(e) => updateNewCommData(e.target.value, 'title')}/>
|
||||
|
||||
<label
|
||||
className={classNames({ 'p-error': isEmpty(newCommData.comment) })}>
|
||||
className={classNames({'p-error': isEmpty(newCommData.comment)})}>
|
||||
{__('Contenuto', 'gepafin')}*
|
||||
</label>
|
||||
<InputTextarea
|
||||
@@ -209,10 +214,65 @@ const SoccorsoComunications = ({ amendmentId, soccorsoStatus }) => {
|
||||
rows={5} cols={30}
|
||||
invalid={isEmpty(newCommData.comment)}
|
||||
onChange={(e) => updateNewCommData(e.target.value, 'comment')}/>
|
||||
{!['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>
|
||||
</Dialog>
|
||||
</>
|
||||
)
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export default SoccorsoComunications;
|
||||
Reference in New Issue
Block a user