diff --git a/src/assets/scss/components/appPage.scss b/src/assets/scss/components/appPage.scss index 5196065..1d1b66b 100644 --- a/src/assets/scss/components/appPage.scss +++ b/src/assets/scss/components/appPage.scss @@ -208,13 +208,18 @@ flex-direction: column; padding: 0; - li { + > li { padding: 15px; border-bottom: 1px solid var(--button-secondary-borderColor); display: flex; justify-content: space-between; align-items: center; + flex-direction: column; gap: 1rem; + + &.row { + flex-direction: row; + } } } @@ -237,7 +242,7 @@ .appPageSection__message { display: flex; align-items: center; - gap: 7px; + gap: 20px; background: rgba(255, 242, 226, 0.7); border-style: solid; border-width: 0 0 0 6px; diff --git a/src/assets/scss/components/evaluation.scss b/src/assets/scss/components/evaluation.scss new file mode 100644 index 0000000..d0e8997 --- /dev/null +++ b/src/assets/scss/components/evaluation.scss @@ -0,0 +1,18 @@ +.criterionRelatedData { + display: flex; + flex-direction: column; + gap: 15px; + max-height: 400px; + overflow-y: auto; + padding: 0 0 10px 0; + + > h3 { + margin: 0; + } +} + +.criterionRelatedData__item { + display: flex; + flex-direction: column; + gap: 7px; +} \ No newline at end of file diff --git a/src/assets/scss/theme.scss b/src/assets/scss/theme.scss index c65f3b9..2bd1bad 100644 --- a/src/assets/scss/theme.scss +++ b/src/assets/scss/theme.scss @@ -42,4 +42,5 @@ @import "./components/login.scss"; @import "./components/flowBuilder.scss"; @import "./components/error404.scss"; -@import "./components/myTable.scss"; \ No newline at end of file +@import "./components/myTable.scss"; +@import "./components/evaluation.scss"; \ No newline at end of file diff --git a/src/layouts/DefaultLayout/components/AppSidebar/index.js b/src/layouts/DefaultLayout/components/AppSidebar/index.js index e336bdb..5155f78 100644 --- a/src/layouts/DefaultLayout/components/AppSidebar/index.js +++ b/src/layouts/DefaultLayout/components/AppSidebar/index.js @@ -34,20 +34,20 @@ const AppSidebar = () => { id: 3, enable: intersection(permissions, ['APPLY_CALLS']).length }, - { - label: __('Gestione Domande', 'gepafin'), - icon: 'pi pi-file', - href: '/domande', - id: 4, - enable: intersection(permissions, ['VIEW_USERS', 'MANAGE_USERS']).length - }, { label: __('Bandi disponibili', 'gepafin'), icon: 'pi pi-bookmark', href: '/bandi', - id: 5, + id: 4, enable: intersection(permissions, ['VIEW_CALLS']).length }, + { + label: __('Gestione domande', 'gepafin'), + icon: 'pi pi-file', + href: '/domande', + id: 5, + enable: intersection(permissions, ['VIEW_USERS', 'MANAGE_USERS']).length + }, { label: __('Domande da valutare', 'gepafin'), icon: 'pi pi-calendar-clock', @@ -56,38 +56,45 @@ const AppSidebar = () => { enable: intersection(permissions, ['EVALUATE_APPLICATIONS']).length }, { - label: __('Soccorso Istruttorio', 'gepafin'), + label: __('Archivio domande', 'gepafin'), + icon: 'pi pi-file', + href: '/domande', + id: 7, + enable: intersection(permissions, ['APPLY_CALLS']).length + }, + { + label: __('Soccorso istruttorio', 'gepafin'), icon: , href: '/soccorso-istruttorio', - id: 7, + id: 8, enable: intersection(permissions, ['EVALUATE_APPLICATIONS']).length }, { - label: __('Gestione Utenti', 'gepafin'), + label: __('Gestione utenti', 'gepafin'), icon: 'pi pi-users', href: '/utenti', - id: 8, + id: 9, enable: intersection(permissions, ['VIEW_USERS', 'MANAGE_USERS']).length }, { label: __('Configurazione', 'gepafin'), icon: 'pi pi-cog', //href: '/configurazione', - id: 9, + id: 10, enable: false }, { label: __('Report e Analisi', 'gepafin'), icon: 'pi pi-chart-bar', //href: '/stats', - id: 10, + id: 11, enable: false }, { label: __('Log di Sistema', 'gepafin'), icon: 'pi pi-receipt', clickFn: () => {}, - id: 11, + id: 12, enable: false } ] diff --git a/src/pages/DashboardBeneficiario/components/MyLatestSubmissionsTable/index.js b/src/pages/DashboardBeneficiario/components/MyLatestSubmissionsTable/index.js index 060bf59..b67128e 100644 --- a/src/pages/DashboardBeneficiario/components/MyLatestSubmissionsTable/index.js +++ b/src/pages/DashboardBeneficiario/components/MyLatestSubmissionsTable/index.js @@ -36,7 +36,8 @@ const MyLatestSubmissionsTable = () => { useEffect(() => { setLocalAsyncRequest(true); ApplicationService.getApplications(getApplCallback, errGetApplCallback, [ - ['companyId', chosenCompanyId] + ['companyId', chosenCompanyId], + ['statuses', ['DRAFT', 'SUBMIT', 'AWAITING', 'READY', 'DISCARD']] ]) }, [chosenCompanyId]); diff --git a/src/pages/DashboardPreInstructor/components/PreInstructorDomandeTable/index.js b/src/pages/DashboardPreInstructor/components/PreInstructorDomandeTable/index.js index 84c5d93..1c3944d 100644 --- a/src/pages/DashboardPreInstructor/components/PreInstructorDomandeTable/index.js +++ b/src/pages/DashboardPreInstructor/components/PreInstructorDomandeTable/index.js @@ -31,7 +31,9 @@ const PreInstructorDomandeTable = () => { useEffect(() => { setLocalAsyncRequest(true); - AssignedApplicationService.getAssignedApplications(getCallback, errGetCallbacks, [['userId', userData.id]]); + AssignedApplicationService.getAssignedApplications(getCallback, errGetCallbacks, [ + ['userId', userData.id] + ]); }, []); const getCallback = (data) => { @@ -132,10 +134,6 @@ const PreInstructorDomandeTable = () => { const header = renderHeader(); - const createEvaluation = (id) => { - console.log('createEvaluation:', id) - } - return(
{ header={header} emptyMessage={__('Nessun dato disponibile', 'gepafin')} onFilter={(e) => setFilters(e.filters)}> - { + const isAsyncRequest = useStore().main.isAsyncRequest(); + const { id } = useParams(); + const navigate = useNavigate(); + const [data, setData] = useState({}); + const [comms, setComms] = useState([]); + const [isVisibleNewCommDialog, setIsVisibleNewCommDialog] = useState(false); + const [newCommData, setNewCommData] = useState({}); + const [isLoadingCommunication, setIsLoadingCommunication] = useState(false); + const [isVisibleExtendTimeDialog, setIsVisibleExtendTimeDialog] = useState(false); + const [extendedTime, setExtendedTime] = useState(3); + const [isLoadingExtendingTime, setIsLoadingExtendingTime] = useState(false); + const [isLoadingReminding, setIsLoadingReminding] = useState(false); + const toast = useRef(null); + const [formInitialData, setFormInitialData] = useState({}); + const { + control, + handleSubmit, + formState: { errors, isValid }, + setValue, + register, + trigger, + getValues, + clearErrors + } = useForm({ + defaultValues: useMemo(() => { + return formInitialData; + }, [formInitialData]), mode: 'onChange' + }); + + const goToArchivePage = () => { + navigate(`/domande`); + } + + const getCallback = (data) => { + if (data.status === 'SUCCESS') { + setData(getFormattedData(data.data)); + //CommunicationService.getCommsByAmendmentId(data.data.id, getCommsCallback, errGetCommsCallback); + } + //storeSet.main.unsetAsyncRequest(); + } + + const errGetCallback = (data) => { + if (toast.current && data.message) { + toast.current.show({ + severity: 'error', + summary: '', + detail: data.message + }); + } + set404FromErrorResponse(data); + storeSet.main.unsetAsyncRequest(); + } + + const getCommsCallback = (data) => { + if (data.status === 'SUCCESS') { + setComms(data.data.commentsList.map(o => getFormattedCommsData(o))); + } + storeSet.main.unsetAsyncRequest(); + } + + const errGetCommsCallback = (data) => { + if (toast.current && data.message) { + toast.current.show({ + severity: 'error', + summary: '', + detail: data.message + }); + } + set404FromErrorResponse(data); + storeSet.main.unsetAsyncRequest(); + } + + const getFormattedData = (data) => { + data.startDate = is(String, data.startDate) ? new Date(data.startDate) : (data.startDate ? data.startDate : ''); + data.expirationDate = is(String, data.expirationDate) ? new Date(data.expirationDate) : (data.expirationDate ? data.expirationDate : ''); + return data; + }; + + 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 : ''); + data.createdDate = is(String, data.createdDate) ? new Date(data.createdDate) : (data.createdDate ? data.createdDate : ''); + data.updatedDate = is(String, data.updatedDate) ? new Date(data.updatedDate) : (data.updatedDate ? data.updatedDate : ''); + return data; + }; + + const headerNewComDialog = () => { + return {__('Aggiungi comunicazione', 'gepafin')} + } + + const hideNewComDialog = () => { + setIsVisibleNewCommDialog(false); + setNewCommData({ + title: '', + comment: '' + }); + } + + const footerNewComDialog = () => { + return
+
+ } + + const openNewCommDialog = () => { + setIsVisibleNewCommDialog(true); + setNewCommData({ + title: '', + comment: '' + }); + } + + const updateNewCommData = (value, path) => { + const newData = wrap(newCommData).set(path.split('.'), value).value(); + setNewCommData(newData); + } + + const renderHeader = () => { + return ( + + + + + + + + + + + + + + ); + }; + + const header = renderHeader(); + + const updateNewAmendmentData = (value, path) => { + const newData = wrap(data).set(path.split('.'), value).value(); + setData(newData); + } + + const createCommunication = () => { + setIsLoadingCommunication(true); + const amendmentId = 0 + CommunicationService.createCommunication(amendmentId, newCommData, createCommunicationCallback, errCreateCommunicationCallback); + } + + const createCommunicationCallback = (data) => { + if (data.status === 'SUCCESS') { + if (toast.current) { + toast.current.show({ + severity: 'success', + summary: '', + detail: data.message + }); + } + setComms([...comms, getFormattedCommsData(data.data)]) + setIsVisibleNewCommDialog(false); + } + setIsLoadingCommunication(false); + } + + const errCreateCommunicationCallback = (data) => { + if (toast.current && data.message) { + toast.current.show({ + severity: 'error', + summary: '', + detail: data.message + }); + } + set404FromErrorResponse(data); + setIsLoadingCommunication(false); + } + + useEffect(() => { + const parsedId = parseInt(id); + const entityId = !isNaN(parsedId) ? parsedId : 0; + + AmendmentsService.getSoccorsoByApplId(entityId, getCallback, errGetCallback, [ + ['statuses', 'AWAITING'] + ]); + }, [id]); + + return ( +
+
+

{sprintf(__('Soccorso Istruttorio: richiesta integrazione documenti per domanda #%s', 'gepafin'), id)}

+
+ +
+ + + +
+
+ +
+ +
+
+

+ {__('ID domanda', 'gepafin')} + {data.applicationId} +

+

+ {__('Bando', 'gepafin')} + {data.callName} +

+

+ {__('Beneficiario', 'gepafin')} + {data.beneficiaryName} +

+

+ {__('Inizio', 'gepafin')} + {getDateFromISOstring(data.startDate)} +

+

+ {__('Scadenza', 'gepafin')} + {getDateFromISOstring(data.expirationDate)} +

+

+ {__('Stato', 'gepafin')} + {getBandoLabel(data.status)} +

+
+ +
+

{__('Dettagli Richiesta', 'gepafin')}

+
+
+

{__('Documenti Richiesti', 'gepafin')}

+
    + {data.formFields + ? data.formFields.map((o, i) =>
  1. + {o.label} +
  2. ) : null} +
+
+
+

{__('Note e spiegazioni', 'gepafin')}

+
+ {renderHtmlContent(data.note)} +
+
+ +
+
+ +
+

{__('Comunicazioni', 'gepafin')}

+ + + + + + + + + {!isNil(comms) && !isEmpty(comms) + ? comms.map((o, i) => + + + ) + : + + + } + +
{__('Data', 'gepafin')}{__('Comunicazione', 'gepafin')}
+ {getDateFromISOstring(o.commentedDate)} + +

{o.title}

+

{o.comment}

+
--
+ +
+ +
+ + {__('Attenzione', 'gepafin')} + {__('Inviare la documentazione richiesta completa delle integrazioni esclusivamente via PEC. In caso contarrio l’integrazione non può essere ritenuta valida.', 'gepafin')} +
+ +
+
+
+
+ + +
+ + +
+ + updateNewCommData(e.target.value, 'title')}/> + + + updateNewCommData(e.target.value, 'comment')}/> +
+
+
+ ) + +} + +export default DomandaBeneficiario; \ No newline at end of file diff --git a/src/pages/DomandaEditPreInstructor/index.js b/src/pages/DomandaEditPreInstructor/index.js index 26e9e35..9560664 100644 --- a/src/pages/DomandaEditPreInstructor/index.js +++ b/src/pages/DomandaEditPreInstructor/index.js @@ -1,7 +1,7 @@ import React, { useState, useEffect, useRef } from 'react'; import { __, sprintf } from '@wordpress/i18n'; import { useNavigate, useParams } from 'react-router-dom'; -import { is, isEmpty, isNil, sum, pathOr } from 'ramda'; +import { is, isEmpty, isNil, sum, pathOr, head } from 'ramda'; import { klona } from 'klona'; import { wrap } from 'object-path-immutable'; @@ -26,13 +26,16 @@ import { InputNumber } from 'primereact/inputnumber'; import BlockingOverlay from '../../components/BlockingOverlay'; import { Toast } from 'primereact/toast'; import HelpIcon from '../../icons/HelpIcon'; +import { Dialog } from 'primereact/dialog'; const DomandaEditPreInstructor = () => { const isAsyncRequest = useStore().main.isAsyncRequest(); const { id } = useParams(); const navigate = useNavigate(); const [data, setData] = useState({}); - const [message, setMessage] = useState(''); + const [isVisibleCriterionData, setIsVisibleCriterionData] = useState(0); + const [criterionDataTitle, setCriterionDataTitle] = useState(''); + const [criterionDataContent, setCriterionDataContent] = useState(''); const [isAdmissible, setIsAdmissible] = useState(false); const toast = useRef(null); @@ -107,7 +110,7 @@ const DomandaEditPreInstructor = () => { files: klona(data.files), note: data.note } - ApplicationEvaluationService.updateEvaluation(id, formData, updateCallback, errUpdateCallback); + ApplicationEvaluationService.updateEvaluation(data.assignedApplicationId, formData, updateCallback, errUpdateCallback); } const updateCallback = (data) => { @@ -135,6 +138,66 @@ const DomandaEditPreInstructor = () => { storeSet.main.unsetAsyncRequest(); } + const doApprove = () => { + const formData = { + status: 'APPROVED' + } + ApplicationEvaluationService.updateEvaluation(data.assignedApplicationId, formData, updateStatusCallback, errUpdateStatusCallback); + } + + const doReject = () => { + const formData = { + status: 'REJECTED' + } + ApplicationEvaluationService.updateEvaluation(data.assignedApplicationId, formData, updateStatusCallback, errUpdateStatusCallback); + } + + const updateStatusCallback = (data) => { + if (data.status === 'SUCCESS') { + if (toast.current) { + toast.current.show({ + severity: 'success', + summary: '', + detail: data.message + }); + } + } + storeSet.main.unsetAsyncRequest(); + } + + const errUpdateStatusCallback = (data) => { + if (toast.current && data.message) { + toast.current.show({ + severity: 'error', + summary: '', + detail: data.message + }); + } + set404FromErrorResponse(data); + storeSet.main.unsetAsyncRequest(); + } + + const displayCriterionData = (id) => { + const criterion = head(data.criteria.filter(o => o.id === id)); + console.log(id, criterion); + setCriterionDataTitle(criterion.label); + const content =
+

{__('I campi correlati')}

+ {criterion.criteriaMappedFields.map(o =>
+ {o.fieldLabel} + {o.fieldValue} +
)} +
; + setCriterionDataContent(content); + setIsVisibleCriterionData(id); + } + + const hideCriterionData = () => { + setIsVisibleCriterionData(0); + setCriterionDataTitle(''); + setCriterionDataContent(''); + } + useEffect(() => { const maxScore = pathOr(0, ['minScore'], data); const criteria = pathOr([], ['criteria'], data); @@ -236,7 +299,9 @@ const DomandaEditPreInstructor = () => {
{!isEmpty(o.criteriaMappedFields) - ?
+ {o.fileDetail.length > 1 + ? + : null} )} @@ -370,15 +466,25 @@ const DomandaEditPreInstructor = () => {