From 99dabb607fff1ec3097d94382739be3c830ce6bc Mon Sep 17 00:00:00 2001 From: Vitalii Kiiko Date: Thu, 30 Jan 2025 15:56:34 +0100 Subject: [PATCH 01/10] - added step 3 and evaluation form creation for call; --- .../components/BandoEditFormStep1/index.js | 20 ++- .../components/BandoEditFormStep2/index.js | 16 +- .../components/BandoEditFormStep3/index.js | 147 ++++++++++++++++++ src/pages/BandoEdit/index.js | 62 +++++--- src/pages/BandoFormsEdit/index.js | 6 +- src/service/bando-service.js | 4 + src/service/evaluation-forms-service.js | 26 ++++ 7 files changed, 252 insertions(+), 29 deletions(-) create mode 100644 src/pages/BandoEdit/components/BandoEditFormStep3/index.js create mode 100644 src/service/evaluation-forms-service.js diff --git a/src/pages/BandoEdit/components/BandoEditFormStep1/index.js b/src/pages/BandoEdit/components/BandoEditFormStep1/index.js index 04c7680..5c106ae 100644 --- a/src/pages/BandoEdit/components/BandoEditFormStep1/index.js +++ b/src/pages/BandoEdit/components/BandoEditFormStep1/index.js @@ -27,6 +27,7 @@ import { storeSet } from '../../../../store'; import set404FromErrorResponse from '../../../../helpers/set404FromErrorResponse'; import getTimeParsedFromString from '../../../../helpers/getTimeParsedFromString'; import formatDateString from '../../../../helpers/formatDateString'; +import EvaluationFormsService from '../../../../service/evaluation-forms-service'; const BandoEditFormStep1 = forwardRef(function ({ initialData, setInitialData, getFormErrors, status }, ref) { const navigate = useNavigate(); @@ -115,7 +116,12 @@ const BandoEditFormStep1 = forwardRef(function ({ initialData, setInitialData, g } const values = getValues(); if (!values.id && data.data.id) { - navigate(`/bandi/${data.data.id}`); + storeSet.main.setAsyncRequest(); + const sampleFormData = { + label: `Evaluation form for call #${data.data.id}`, + content: [] + } + EvaluationFormsService.createFormForCall(data.data.id, sampleFormData, createFormCallback, errCreateFormCallback) } else { setFormInitialData(data.data); setInitialData(data.data); @@ -135,6 +141,18 @@ const BandoEditFormStep1 = forwardRef(function ({ initialData, setInitialData, g storeSet.main.unsetAsyncRequest(); } + const createFormCallback = (resp) => { + if (resp.status === 'SUCCESS') { + navigate(`/bandi/${resp.data.callId}`); + } + storeSet.main.unsetAsyncRequest(); + } + + const errCreateFormCallback = (resp) => { + set404FromErrorResponse(resp); + storeSet.main.unsetAsyncRequest(); + } + const openPreview = () => { navigate(`/bandi/${values.id}/preview`); } diff --git a/src/pages/BandoEdit/components/BandoEditFormStep2/index.js b/src/pages/BandoEdit/components/BandoEditFormStep2/index.js index 7bae164..c649a6c 100644 --- a/src/pages/BandoEdit/components/BandoEditFormStep2/index.js +++ b/src/pages/BandoEdit/components/BandoEditFormStep2/index.js @@ -94,7 +94,11 @@ const BandoEditFormStep2 = forwardRef(function ({ initialData, setInitialData, g delete formData.endDate; storeSet.main.setAsyncRequest(); - BandoService.updateBandoStep2(formData.id, formData, createCallback, errCreateCallback); + if (values.evaluationVersion === 'V1') { + BandoService.updateBandoStep2(formData.id, formData, createCallback, errCreateCallback); + } else if (values.evaluationVersion === 'V2') { + BandoService.updateBandoStep2V2(formData.id, formData, createCallback, errCreateCallback); + } } const createCallback = (data) => { @@ -221,7 +225,8 @@ const BandoEditFormStep2 = forwardRef(function ({ initialData, setInitialData, g return (
- isEmpty(o.value) || isEmpty(o.score)).length === 0 || __('Non lasciare il valore vuoto', 'gepafin') } - }}/> + }}/> : null} - isEmpty(o.value)).length === 0 || __('Non lasciare il valore vuoto', 'gepafin') } }} - /> + /> : null}
diff --git a/src/pages/BandoEdit/components/BandoEditFormStep3/index.js b/src/pages/BandoEdit/components/BandoEditFormStep3/index.js new file mode 100644 index 0000000..0843da9 --- /dev/null +++ b/src/pages/BandoEdit/components/BandoEditFormStep3/index.js @@ -0,0 +1,147 @@ +import React, { forwardRef, useEffect, useRef, useState } from 'react'; +import { __ } from '@wordpress/i18n'; +import { useNavigate, useParams } from 'react-router-dom'; +import { klona } from 'klona'; +import { DndProvider } from 'react-dnd'; +import { HTML5Backend } from 'react-dnd-html5-backend'; + +// api +import EvaluationFormsService from '../../../../service/evaluation-forms-service'; +import FormsService from '../../../../service/forms-service'; + +// store +import { storeGet, storeSet } from '../../../../store'; + +// tools +import set404FromErrorResponse from '../../../../helpers/set404FromErrorResponse'; + +// components +import BandoEditFormActions from '../BandoEditFormActions'; +import { Toast } from 'primereact/toast'; +import FormBuilder from '../../../BandoFormsEdit/components/FormBuilder'; +import { elementItems } from '../../../../tempData'; + + +const BandoEditFormStep3 = forwardRef(function () { + const navigate = useNavigate(); + const { id } = useParams(); + const [formName, setFormName] = useState(''); + const [bandoStatus, setBandoStatus] = useState(''); + const toast = useRef(null); + + const getBandoId = () => { + const parsed = parseInt(id) + return !isNaN(parsed) ? parsed : 0; + } + + const onSaveDraft = () => { + const content = storeGet.main.formElements(); + const formId = storeGet.main.formId(); + const formData = { + label: formName, + content + } + + storeSet.main.setAsyncRequest(); + EvaluationFormsService.updateForm(formId, formData, updateFormCallback, errUpdateFormCallback) + } + + const updateFormCallback = (resp) => { + if (resp.status === 'SUCCESS') { + setBandoStatus(resp.data.callStatus); + if (toast.current) { + toast.current.show({ + severity: 'success', + summary: '', + detail: __('Il bando è stato aggiornato correttamente!', 'gepafin') + }); + } + } + storeSet.main.unsetAsyncRequest(); + } + + const errUpdateFormCallback = (resp) => { + set404FromErrorResponse(resp); + storeSet.main.unsetAsyncRequest(); + } + + const openPreview = () => { + const bandoId = getBandoId(); + navigate(`/bandi/${bandoId}/preview`); + } + + const openPreviewEvaluation = () => { + const bandoId = getBandoId(); + navigate(`/bandi/${bandoId}/preview-evaluation`); + } + + const getElementItemsCallback = (data) => { + if (data.status === 'SUCCESS') { + storeSet.main.elementItems(elementItems.sort((a, b) => a.sortOrder - b.sortOrder)); + //storeSet.main.elementItems(data.data.sort((a, b) => a.sortOrder - b.sortOrder)); + } + storeSet.main.unsetAsyncRequest(); + } + + const errGetElementItemsCallbacks = (data) => { + storeSet.main.unsetAsyncRequest(); + } + + const getFormCallback = (resp) => { + if (resp.status === 'SUCCESS') { + storeSet.main.formId(resp.data.id); + storeSet.main.formLabel(resp.data.label); + setFormName(resp.data.label); + setBandoStatus(resp.data.callStatus); + const elements = klona(resp.data.content); + storeSet.main.formElements(elements); + } + storeSet.main.unsetAsyncRequest(); + } + + const errGetFormCallback = (resp) => { + set404FromErrorResponse(resp); + storeSet.main.unsetAsyncRequest(); + } + + useEffect(() => { + storeSet.main.setAsyncRequest(); + EvaluationFormsService.getFormForCall(id, getFormCallback, errGetFormCallback) + }, [id]); + + useEffect(() => { + storeSet.main.setAsyncRequest(); + FormsService.getElementItems(getElementItemsCallback, errGetElementItemsCallbacks); + + return () => { + storeSet.main.formId(0); + storeSet.main.formElements([]); + } + }, []); + + return ( +
+
+ + + +
+ +
+ +
+ {__('Azioni', 'gepafin')} +
+ + + +
+ ) +}) + +export default BandoEditFormStep3; \ No newline at end of file diff --git a/src/pages/BandoEdit/index.js b/src/pages/BandoEdit/index.js index f9b0951..275fd61 100644 --- a/src/pages/BandoEdit/index.js +++ b/src/pages/BandoEdit/index.js @@ -23,6 +23,7 @@ import { Messages } from 'primereact/messages'; import FormsService from '../../service/forms-service'; import BlockingOverlay from '../../components/BlockingOverlay'; import { Toast } from 'primereact/toast'; +import BandoEditFormStep3 from './components/BandoEditFormStep3'; const BandoEdit = () => { const isAsyncRequest = useStore().main.isAsyncRequest(); @@ -35,28 +36,45 @@ const BandoEdit = () => { const bandoMsgs = useRef(null); const toast = useRef(null); - const stepItems = [ - { - label: __('Testi', 'gepafin'), - command: () => { - if (activeStep === 0) { - return false + const stepItems = (evalProcessVer) => { + let steps = [ + { + label: __('Testi', 'gepafin'), + command: () => { + if (activeStep === 0) { + return false + } + bandoMsgs.current.clear(); + goToStep(0); } - bandoMsgs.current.clear(); - goToStep(0); - } - }, - { - label: __('Gestione', 'gepafin'), - command: () => { - if (activeStep === 1) { - return false + }, + { + label: __('Gestione', 'gepafin'), + command: () => { + if (activeStep === 1) { + return false + } + bandoMsgs.current.clear(); + goToStep(1); } - bandoMsgs.current.clear(); - goToStep(1); } + ]; + + if (evalProcessVer === 'V2') { + steps.push({ + label: __('Valutazione', 'gepafin'), + command: () => { + if (activeStep === 2) { + return false + } + bandoMsgs.current.clear(); + goToStep(2); + } + }) } - ]; + + return steps; + } const goToStep = (step) => { setActiveStep(step); @@ -238,7 +256,8 @@ const BandoEdit = () => { if (bandoId === 0) { setData({ - status: null + status: null, + evaluationVersion: 'V2' }); storeSet.main.unsetAsyncRequest(); @@ -274,7 +293,7 @@ const BandoEdit = () => { {!isEmpty(data) ? : null} @@ -293,6 +312,9 @@ const BandoEdit = () => { {activeStep === 1 ? : null} + {activeStep === 2 && data.evaluationVersion === 'V2' + ? + : null}

{__('Crea o modifica il Form compilabile dal Beneficiario', 'gepafin')}

diff --git a/src/pages/BandoFormsEdit/index.js b/src/pages/BandoFormsEdit/index.js index e26a69a..bf85ac9 100644 --- a/src/pages/BandoFormsEdit/index.js +++ b/src/pages/BandoFormsEdit/index.js @@ -110,7 +110,6 @@ const BandoFormsEdit = () => { const formCreateCallback = (data, shouldRedirect) => { if (data.status === 'SUCCESS') { - storeSet.main.unsetAsyncRequest(); const bandoId = getBandoId(); if (shouldRedirect) { navigate(`/bandi/${bandoId}/forms/${data.data.id}/preview`); @@ -127,6 +126,7 @@ const BandoFormsEdit = () => { }); } } + storeSet.main.unsetAsyncRequest(); } const errFormCreateCallback = (data) => { @@ -221,7 +221,7 @@ const BandoFormsEdit = () => { storeSet.main.unsetAsyncRequest(); } - const errGetElementItemsCallbacks = (data) => { + const errGetElementItemsCallback = (data) => { storeSet.main.unsetAsyncRequest(); } @@ -261,7 +261,7 @@ const BandoFormsEdit = () => { const bandoFormId = !isNaN(parsedFormId) ? parsedFormId : 0; storeSet.main.setAsyncRequest(); - FormsService.getElementItems(getElementItemsCallback, errGetElementItemsCallbacks); + FormsService.getElementItems(getElementItemsCallback, errGetElementItemsCallback); if (bandoFormId) { storeSet.main.setAsyncRequest(); diff --git a/src/service/bando-service.js b/src/service/bando-service.js index 5f616fb..3a38a80 100644 --- a/src/service/bando-service.js +++ b/src/service/bando-service.js @@ -32,6 +32,10 @@ export default class BandoService { NetworkService.put(`${API_BASE_URL}/call/step2/${id}`, body, callback, errCallback); }; + static updateBandoStep2V2 = (id, body, callback, errCallback) => { + NetworkService.put(`${API_BASE_URL}/call/step2-v2/${id}`, body, callback, errCallback); + }; + static updateBandoStatus = (id, callback, errCallback, queryParams) => { NetworkService.put(`${API_BASE_URL}/call/${id}/status`, {}, callback, errCallback, queryParams); }; diff --git a/src/service/evaluation-forms-service.js b/src/service/evaluation-forms-service.js new file mode 100644 index 0000000..dc5d048 --- /dev/null +++ b/src/service/evaluation-forms-service.js @@ -0,0 +1,26 @@ +import { NetworkService } from './network-service'; + +const API_BASE_URL = process.env.REACT_APP_API_EXECUTION_ADDRESS; + +export default class EvaluationFormsService { + + static getFormForCall = (id, callback, errCallback) => { + NetworkService.get(`${API_BASE_URL}/evaluationForm/call/${id}`, callback, errCallback); + }; + + static createFormForCall = (id, body, callback, errCallback) => { + NetworkService.post(`${API_BASE_URL}/evaluationForm/call/${id}`, body, callback, errCallback); + }; + + static updateForm = (id, body, callback, errCallback, queryParams) => { + NetworkService.put(`${API_BASE_URL}/evaluationForm/${id}`, body, callback, errCallback, queryParams); + }; + + static getFormById = (id, callback, errCallback) => { + NetworkService.get(`${API_BASE_URL}/evaluationForm/${id}`, callback, errCallback); + }; + + static deleteForm = (id, callback, errCallback) => { + NetworkService.delete(`${API_BASE_URL}/evaluationForm/${id}`, {}, callback, errCallback); + }; +} From eff571f0549ee77f752bd14438db8f3889b686ad Mon Sep 17 00:00:00 2001 From: Vitalii Kiiko Date: Fri, 31 Jan 2025 17:24:39 +0100 Subject: [PATCH 02/10] - saving progress; --- src/assets/scss/components/formBuilder.scss | 6 +++++- .../components/Table/RenderTable/index.js | 2 +- src/components/FormField/components/Table/index.js | 11 ++++++----- src/helpers/isDateTimeInFuture.js | 10 ++++++++++ .../components/AllBandiAccordion/index.js | 14 ++++++++++---- src/pages/BandoApplication/index.js | 5 ++++- .../ElementSettingCriteriaTableColumns/index.js | 4 ++-- .../components/ElementSettingTableColumns/index.js | 4 ++-- 8 files changed, 40 insertions(+), 16 deletions(-) create mode 100644 src/helpers/isDateTimeInFuture.js diff --git a/src/assets/scss/components/formBuilder.scss b/src/assets/scss/components/formBuilder.scss index db9b8ad..2b82558 100644 --- a/src/assets/scss/components/formBuilder.scss +++ b/src/assets/scss/components/formBuilder.scss @@ -241,9 +241,13 @@ .formElementSettings__repeaterItem { display: grid; - grid-template-columns: 4.5fr 2.4fr 1fr 1.4fr 0.7fr; + grid-template-columns: 1fr; gap: 12px; + &.tableRow { + grid-template-columns: 4.5fr 2.4fr 1fr 1.4fr 0.7fr; + } + > div { display: flex; align-items: center; diff --git a/src/components/FormField/components/Table/RenderTable/index.js b/src/components/FormField/components/Table/RenderTable/index.js index c925bcd..f376913 100644 --- a/src/components/FormField/components/Table/RenderTable/index.js +++ b/src/components/FormField/components/Table/RenderTable/index.js @@ -7,7 +7,7 @@ import { isEmpty } from 'ramda'; import DefaultCell from './components/DefaultCell'; import LastRowCell from './components/LastRowCell'; -const RenderTable = ({ rowsData, columnsCfg, lastRowCfg, setRowsFn, disabled }) => { +const RenderTable = ({ rowsData = [], columnsCfg, lastRowCfg, setRowsFn, disabled }) => { const table = useReactTable({ data: rowsData, columns: columnsCfg, diff --git a/src/components/FormField/components/Table/index.js b/src/components/FormField/components/Table/index.js index 02d33be..62d71de 100644 --- a/src/components/FormField/components/Table/index.js +++ b/src/components/FormField/components/Table/index.js @@ -122,13 +122,13 @@ const Table = ({ useEffect(() => { const stateFieldData = pathOr([], ['stateFieldData'], tableColumns); - const obj = stateFieldData + /*const obj = stateFieldData .reduce((acc, cur) => { acc[cur.name] = '' return acc; - }, {}); - let rowsData = pathOr([obj], ['rowsData'], tableColumns); - rowsData = isEmpty(rowsData) ? [obj] : rowsData; + }, {});*/ + let rowsData = pathOr([], ['rowsData'], tableColumns); + //rowsData = isEmpty(rowsData) ? [obj] : rowsData; setColumnsCfg(stateFieldData); setRowsCfg(rowsData); @@ -169,7 +169,8 @@ const Table = ({ {label}{config.required || config.isRequired || (config.validate && config.validate.nonEmptyTables) ? * : null} - {rows ? { + const [hours, minutes, seconds = 0] = timeStr.split(':').map(Number); + const dateTime = new Date(dateStr); + dateTime.setHours(hours, minutes, seconds); + const now = new Date(); + + return dateTime > now; +} + +export default isDateTimeInFuture; \ No newline at end of file diff --git a/src/pages/BandiBeneficiario/components/AllBandiAccordion/index.js b/src/pages/BandiBeneficiario/components/AllBandiAccordion/index.js index 057deea..8218845 100644 --- a/src/pages/BandiBeneficiario/components/AllBandiAccordion/index.js +++ b/src/pages/BandiBeneficiario/components/AllBandiAccordion/index.js @@ -1,5 +1,5 @@ import React, { useState, useEffect} from 'react'; -import { __ } from '@wordpress/i18n'; +import { __, sprintf } from '@wordpress/i18n'; import { is, uniq, isNil, isEmpty } from 'ramda'; import { wrap } from 'object-path-immutable'; import { useNavigate } from 'react-router-dom'; @@ -30,6 +30,8 @@ import { Button } from 'primereact/button'; // i18n import translationStrings from '../../../../translationStringsForComponents'; import isDateTimeInPast from '../../../../helpers/isDateTimeInPast'; +import isDateTimeInFuture from '../../../../helpers/isDateTimeInFuture'; +import { Badge } from 'primereact/badge'; const REACT_APP_HUB_ID = process.env.REACT_APP_HUB_ID; @@ -182,18 +184,22 @@ const AllBandiAccordion = ({ showOnlyPreferred = false }) => { const rowExpansionTemplate = (data) => { const isCallExpired = isDateTimeInPast(data.dates[1], data.endTime); + const isCallScheduled = isDateTimeInFuture(data.dates[0], data.startTime); + return (
{renderHtmlContent(data.descriptionShort)}

{__('Scadenza', 'gepafin')}: {getDateFromISOstring(data.dates[1])}

- {!isCallExpired && !isEmpty(chosenCompanyId) && chosenCompanyId !== 0 && (!data.confidi + {!isCallExpired && !isCallScheduled && !isEmpty(chosenCompanyId) && chosenCompanyId !== 0 && (!data.confidi || (data.confidi && data.id === 6 && REACT_APP_HUB_ID === 'p4lk3bcx1RStqTaIVVbXs')) ? : null} {isCallExpired - ?

{__('È scaduto', 'gepafin')}

: null} - {isCallExpired || (!isEmpty(chosenCompanyId) && chosenCompanyId !== 0 && data.confidi + ?

: null} + {isCallScheduled + ?

: null} + {isCallExpired || isCallScheduled || (!isEmpty(chosenCompanyId) && chosenCompanyId !== 0 && data.confidi && (data.id !== 6 || (data.id === 6 && REACT_APP_HUB_ID !== 'p4lk3bcx1RStqTaIVVbXs'))) ?
: { const errGetStats = () => {} + const getDoubleStats = (data) => { + if (data.status === 'SUCCESS') { + console.log(data.data); + } + } + + const errGetDoubleStats = () => {} + const getStatValue = (key, fallback = '') => { return pathOr(fallback, [key], mainStats); } useEffect(() => { DashboardService.getEvaluationsStats(getStats, errGetStats); + DashboardService.getInstructorAmendmentsStats(getDoubleStats, errGetDoubleStats); }, []); return( diff --git a/src/pages/DashboardPreInstructor/index.js b/src/pages/DashboardPreInstructor/index.js index cbd94a5..9e67e92 100644 --- a/src/pages/DashboardPreInstructor/index.js +++ b/src/pages/DashboardPreInstructor/index.js @@ -31,12 +31,12 @@ const DashboardPreInstructor = () => { const errGetStats = () => {} - const getStatValue = (key, fallback = '') => { - return pathOr(fallback, [key], mainStats); + const getStatValue = (keys = [], fallback = '') => { + return pathOr(fallback, keys, mainStats); } useEffect(() => { - DashboardService.getEvaluationsStats(getStats, errGetStats); + DashboardService.getInstructorAmendmentsStats(getStats, errGetStats); }, []); return( @@ -49,49 +49,57 @@ const DashboardPreInstructor = () => {

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

-
-
- {__('Totale domande', 'gepafin')} - +
+ {__('Domande da valutare', 'gepafin')} + + {/*
+ + {getStatValue(['assignedApplication', 'additionalApplicationPercentage'], 0)}% + {__('da ieri', 'gepafin')} +
*/}
-
- {__('In soccorso', 'gepafin')} - + {__('Domande valutate', 'gepafin')} + + {/*
+ + {getStatValue(['evaluatedApplication', 'dailyAverage'], 0)} + {__('media giornaliera', 'gepafin')} +
*/}
-
- {__('In valutazione', 'gepafin')} - -
-
- {__('Completate', 'gepafin')} - -
-
- {__('Tempo medio di valutazione', 'gepafin')} - + {__('Tempo medio valutazione', 'gepafin')} + + {/*
+ + {getStatValue(['averageEvaluationDays', 'timeDifferenceFromAverage'], 0)} + {__('rispetto alla media', 'gepafin')} +
*/}
-
- {__('Domande in scadenza (48h)', 'gepafin')} - + {__('Soccorsi istruttori in corso', 'gepafin')} + + locales="it-IT"/> + {/*
+ + {getStatValue(['amendmentInProgress', 'expiringToday'], 0)} + {__('in scadenza oggi', 'gepafin')} +
*/}
diff --git a/src/pages/DomandaEditInstructorManager/index.js b/src/pages/DomandaEditInstructorManager/index.js index c273bf2..0c0b095 100644 --- a/src/pages/DomandaEditInstructorManager/index.js +++ b/src/pages/DomandaEditInstructorManager/index.js @@ -37,6 +37,8 @@ import DownloadSignedApplication from '../DomandaEditPreInstructor/components/Do import ListOfFiles from '../DomandaEditPreInstructor/components/ListOfFiles'; import RepeaterFields from '../DomandaEditPreInstructor/components/RepeaterFields'; import getDateTimeFromISOstring from '../../helpers/getDateTimeFromISOstring'; +import ApplicationInfo from '../DomandaEditPreInstructor/components/ApplicationInfo'; +import ApplicationDownloadFiles from '../DomandaEditPreInstructor/components/ApplicationDownloadFiles'; const APP_EVALUATION_FLOW_ID = process.env.REACT_APP_EVALUATION_FLOW_ID; const APP_HUB_ID = process.env.REACT_APP_HUB_ID; @@ -553,67 +555,9 @@ const DomandaEditInstructorManager = () => { {!isAsyncRequest && !isEmpty(data) ?
-
-

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

-

- {__('Protocollo', 'gepafin')} - {data.protocolNumber} -

- {APP_HUB_ID !== 't7jh5wfg9QXylNaTZkPoE' - ?

- {__('NDG', 'gepafin')} - {data.ndg} -

: null} - {APP_HUB_ID !== 't7jh5wfg9QXylNaTZkPoE' - ?

- {__('Appuntamento', 'gepafin')} - {data.appointmentId} -

: null} -

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

-

- {__('Referente Aziendale', 'gepafin')} - {data.beneficiary} -

-

- {__('Azienda Beneficiaria', 'gepafin')} - {data.companyName} -

-

- {__('Data ricezione', 'gepafin')} - {getDateTimeFromISOstring(data.submissionDate)} -

-

- {__('Data assegnazione', 'gepafin')} - {getDateTimeFromISOstring(data.assignedAt)} -

-

- {__('Aassegnato a', 'gepafin')} - {data.assignedUserName} -

-

- {__('Scadenza Valutazione', 'gepafin')} - {getDateFromISOstring(data.evaluationEndDate)} -

-

- {__('Stato', 'gepafin')} - {getBandoLabel(data.applicationStatus)} -

-
+ -
-

{__('Scarica documenti della domanda', 'gepafin')}

-
- - - -
-
+

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

@@ -628,56 +572,73 @@ const DomandaEditInstructorManager = () => { sourceName="evaluation"/>
-
-

{__('Checklist Valutazione', 'gepafin')}

-
-
-

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

-
-
- {data.checklist.map((o, i) =>
- updateEvaluationValue( - e.checked, - ['checklist', i, 'valid'] - )} - checked={o.valid}> - -
)} + {data.evaluationVersion === 'V2' + ?
+

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

+ {!isEmpty(data.files) + ? shouldDisableField(name) || evaluationShouldBeBlocked(data)} + name="files" + ndg={data.ndg} + applicationId={id}/> + :

{__('Nessun documento allegato', 'gepafin')}

} +
+ : null} + + {data.evaluationVersion === 'V1' + ?
+

{__('Checklist Valutazione', 'gepafin')}

+
+
+

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

+
+
+ {data.checklist.map((o, i) =>
+ updateEvaluationValue( + e.checked, + ['checklist', i, 'valid'] + )} + checked={o.valid}> + +
)} +
+
+ +

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

+
+ updateEvaluationValue( + e.htmlValue, + ['note'] + )} + style={{ height: 80 * 3, width: '100%' }} + />
- -

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

- updateEvaluationValue( - e.htmlValue, - ['note'] - )} - style={{ height: 80 * 3, width: '100%' }} - /> +

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

+ {!isEmpty(data.files) + ? shouldDisableField(name) || evaluationShouldBeBlocked(data)} + name="files" + ndg={data.ndg} + applicationId={id}/> + :

{__('Nessun documento allegato', 'gepafin')}

}
-
-

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

- {!isEmpty(data.files) - ? shouldDisableField(name) || evaluationShouldBeBlocked(data)} - name="files" - ndg={data.ndg} - applicationId={id}/> - :

{__('Nessun documento allegato', 'gepafin')}

} -
-
+ : null} {!isEmpty(data.amendmentDetails) ?
@@ -691,84 +652,86 @@ const DomandaEditInstructorManager = () => { applicationId={id}/>
: null} -
-

{__('Punteggi di valutazione', 'gepafin')}

- {data.criteria - ? - - - - - - - - - {data.criteria.map((o, i) => - - + + )} + + + + + + + + + + + +
{__('Parametro', 'gepafin')}{__('Punteggio', 'gepafin')}{__('Stato', 'gepafin')}
{o.label} -
- updateEvaluationValue( - e.value, - ['criteria', i, 'score'], - o.criteria - )}/> - + {data.evaluationVersion === 'V1' + ?
+

{__('Punteggi di valutazione', 'gepafin')}

+ {data.criteria + ? + + + + + + + + + {data.criteria.map((o, i) => + + - - )} - - - - - - - - - - - -
{__('Parametro', 'gepafin')}{__('Punteggio', 'gepafin')}{__('Stato', 'gepafin')}
{o.label} +
+ updateEvaluationValue( + e.value, + ['criteria', i, 'score'], + o.criteria + )}/> + / {o.maxScore} -
-
-
- {!isEmpty(o.criteriaMappedFields) - ?
-
{__('Punteggio:', 'gepafin')}{sum(data.criteria.map(o => o.score))} - {isAdmissible - ? : null} - {!isAdmissible - ? : null} -
{sprintf(__('Punteggio minimo per l\'ammissione: %d'), data.minScore)}
: null} -
+
+
+
+ {!isEmpty(o.criteriaMappedFields) + ?
+
{__('Punteggio:', 'gepafin')}{sum(data.criteria.map(o => o.score))} + {isAdmissible + ? : null} + {!isAdmissible + ? : null} +
{sprintf(__('Punteggio minimo per l\'ammissione: %d'), data.minScore)}
: null} +
+ : null}
@@ -832,7 +795,8 @@ const DomandaEditInstructorManager = () => {
diff --git a/src/pages/SoccorsoIstruttorioPreInstructor/index.js b/src/pages/SoccorsoIstruttorioPreInstructor/index.js index fd1cc4d..b0959b7 100644 --- a/src/pages/SoccorsoIstruttorioPreInstructor/index.js +++ b/src/pages/SoccorsoIstruttorioPreInstructor/index.js @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react'; +import React, { useEffect, useState, useCallback } from 'react'; import { __ } from '@wordpress/i18n'; import { pathOr } from 'ramda'; import NumberFlow from '@number-flow/react'; @@ -22,9 +22,9 @@ const SoccorsoIstruttorioPreInstructor = () => { const errGetStats = () => {} - const getStatValue = (key, fallback = '') => { + const getStatValue = useCallback((key, fallback = '') => { return pathOr(fallback, [key], mainStats); - } + }, [mainStats]); useEffect(() => { DashboardService.getAmendmentsStats(getStats, errGetStats); diff --git a/src/service/application-evaluation-service.js b/src/service/application-evaluation-service.js index 048cb46..cc20ea6 100644 --- a/src/service/application-evaluation-service.js +++ b/src/service/application-evaluation-service.js @@ -8,7 +8,21 @@ export default class ApplicationEvaluationService { NetworkService.get(`${API_BASE_URL}/applicationEvaluation/application`, callback, errCallback, queryParams); }; + static getEvaluationV2ByApplId = (callback, errCallback, queryParams) => { + NetworkService.get(`${API_BASE_URL}/applicationEvaluation/v2`, callback, errCallback, queryParams); + }; + + static getEvaluationVersionByApplId = (id, callback, errCallback, queryParams) => { + NetworkService.get(`${API_BASE_URL}/applicationEvaluation/application/${id}/version`, callback, errCallback, queryParams); + }; + static updateEvaluation = (assignedApplicationId, body, callback, errCallback, queryParams) => { NetworkService.put(`${API_BASE_URL}/applicationEvaluation/${assignedApplicationId}`, body, callback, errCallback, queryParams); }; + + static updateEvaluationV2 = (assignedApplicationId, formId, body, callback, errCallback, queryParams = []) => { + NetworkService.put(`${API_BASE_URL}/applicationEvaluation/v2/assignedApplication/${assignedApplicationId}`, body, callback, errCallback, [ + ['evaluationFormId', formId] + ]); + }; } diff --git a/src/service/dashboard-service.js b/src/service/dashboard-service.js index 093db59..bf30675 100644 --- a/src/service/dashboard-service.js +++ b/src/service/dashboard-service.js @@ -23,4 +23,8 @@ export default class DashboardService { static getBeneficiaryStatsForCompany = (id, callback, errCallback) => { NetworkService.get(`${API_BASE_URL}/dashboard/beneficiary/company/${id}`, callback, errCallback); }; + + static getInstructorAmendmentsStats = (callback, errCallback) => { + NetworkService.get(`${API_BASE_URL}/dashboard/instructor/amendment`, callback, errCallback); + }; } From 3588f527875186d38f012bbdb623918daac9d11f Mon Sep 17 00:00:00 2001 From: Vitalii Kiiko Date: Fri, 7 Feb 2025 14:28:57 +0100 Subject: [PATCH 04/10] - completed page for instructor manager; - update API related to profile updating; - fixed displaying stats for instructor manager; - added checklist items based validation; --- src/pages/DashboardInstructorManager/index.js | 9 -- src/pages/DashboardPreInstructor/index.js | 4 +- .../DomandaEditInstructorManager/index.js | 117 +++++++++++------- src/pages/Profile/index.js | 3 +- src/pages/ProfileBeneficiario/index.js | 2 +- src/service/dashboard-service.js | 4 +- src/service/user-service.js | 4 + 7 files changed, 85 insertions(+), 58 deletions(-) diff --git a/src/pages/DashboardInstructorManager/index.js b/src/pages/DashboardInstructorManager/index.js index 8822037..2ee8a13 100644 --- a/src/pages/DashboardInstructorManager/index.js +++ b/src/pages/DashboardInstructorManager/index.js @@ -27,21 +27,12 @@ const DashboardInstructorManager = () => { const errGetStats = () => {} - const getDoubleStats = (data) => { - if (data.status === 'SUCCESS') { - console.log(data.data); - } - } - - const errGetDoubleStats = () => {} - const getStatValue = (key, fallback = '') => { return pathOr(fallback, [key], mainStats); } useEffect(() => { DashboardService.getEvaluationsStats(getStats, errGetStats); - DashboardService.getInstructorAmendmentsStats(getDoubleStats, errGetDoubleStats); }, []); return( diff --git a/src/pages/DashboardPreInstructor/index.js b/src/pages/DashboardPreInstructor/index.js index 9e67e92..ed54aeb 100644 --- a/src/pages/DashboardPreInstructor/index.js +++ b/src/pages/DashboardPreInstructor/index.js @@ -36,7 +36,9 @@ const DashboardPreInstructor = () => { } useEffect(() => { - DashboardService.getInstructorAmendmentsStats(getStats, errGetStats); + DashboardService.getInstructorAmendmentsStats(getStats, errGetStats, [ + ['userId', userData.id] + ]); }, []); return( diff --git a/src/pages/DomandaEditInstructorManager/index.js b/src/pages/DomandaEditInstructorManager/index.js index f9d4409..c47351e 100644 --- a/src/pages/DomandaEditInstructorManager/index.js +++ b/src/pages/DomandaEditInstructorManager/index.js @@ -4,6 +4,9 @@ import { useNavigate, useParams } from 'react-router-dom'; import { is, isEmpty, isNil, sum, pathOr, head, pluck } from 'ramda'; import { klona } from 'klona'; import { wrap } from 'object-path-immutable'; +import { evaluate } from 'mathjs'; +import equal from 'fast-deep-equal'; +import { useForm } from 'react-hook-form'; // store import { storeGet, storeSet, useStore } from '../../store'; @@ -15,31 +18,6 @@ import AppointmentService from '../../service/appointment-service'; // tools import set404FromErrorResponse from '../../helpers/set404FromErrorResponse'; -import getBandoLabel from '../../helpers/getBandoLabel'; -import getDateFromISOstring from '../../helpers/getDateFromISOstring'; - -// components -import { Skeleton } from 'primereact/skeleton'; -import { Button } from 'primereact/button'; -import { Tag } from 'primereact/tag'; -import { Checkbox } from 'primereact/checkbox'; -import { Editor } from 'primereact/editor'; -import { InputNumber } from 'primereact/inputnumber'; -import { Toast } from 'primereact/toast'; -import { Dialog } from 'primereact/dialog'; -import HelpIcon from '../../icons/HelpIcon'; -import { classNames } from 'primereact/utils'; -import { InputTextarea } from 'primereact/inputtextarea'; -import { InputText } from 'primereact/inputtext'; -import DownloadApplicationArchive from '../DomandaEditPreInstructor/components/DownloadApplicationArchive'; -import DownloadCompanyDelegation from '../DomandaEditPreInstructor/components/DownloadCompanyDelegation'; -import DownloadSignedApplication from '../DomandaEditPreInstructor/components/DownloadSignedApplication'; -import ListOfFiles from '../DomandaEditPreInstructor/components/ListOfFiles'; -import RepeaterFields from '../DomandaEditPreInstructor/components/RepeaterFields'; -import getDateTimeFromISOstring from '../../helpers/getDateTimeFromISOstring'; -import ApplicationInfo from '../DomandaEditPreInstructor/components/ApplicationInfo'; -import ApplicationDownloadFiles from '../DomandaEditPreInstructor/components/ApplicationDownloadFiles'; -import { useForm } from 'react-hook-form'; import { isCAP, isCodiceFiscale, @@ -54,9 +32,25 @@ import formatDateString from '../../helpers/formatDateString'; import getTokens from '../../helpers/getTokens'; import parseCommaDecimal from '../../helpers/parseCommaDecimal'; import renderWithDataVars from '../../helpers/renderWithDataVars'; -import { evaluate } from 'mathjs'; -import equal from 'fast-deep-equal'; import renderHtmlContent from '../../helpers/renderHtmlContent'; + +// components +import { Skeleton } from 'primereact/skeleton'; +import { Button } from 'primereact/button'; +import { Tag } from 'primereact/tag'; +import { Checkbox } from 'primereact/checkbox'; +import { Editor } from 'primereact/editor'; +import { InputNumber } from 'primereact/inputnumber'; +import { Toast } from 'primereact/toast'; +import { Dialog } from 'primereact/dialog'; +import HelpIcon from '../../icons/HelpIcon'; +import { classNames } from 'primereact/utils'; +import { InputTextarea } from 'primereact/inputtextarea'; +import { InputText } from 'primereact/inputtext'; +import ListOfFiles from '../DomandaEditPreInstructor/components/ListOfFiles'; +import RepeaterFields from '../DomandaEditPreInstructor/components/RepeaterFields'; +import ApplicationInfo from '../DomandaEditPreInstructor/components/ApplicationInfo'; +import ApplicationDownloadFiles from '../DomandaEditPreInstructor/components/ApplicationDownloadFiles'; import FormField from '../../components/FormField'; const APP_EVALUATION_FLOW_ID = process.env.REACT_APP_EVALUATION_FLOW_ID; @@ -126,7 +120,7 @@ const DomandaEditInstructorManager = () => { navigate('/mie-domande'); } - const updateFlagsForSoccorso = (data) => { + const updateFlagsForSoccorso = useCallback((data) => { let nonRatedFilesLength = 0; if (data.files) { @@ -145,14 +139,28 @@ const DomandaEditInstructorManager = () => { setAllFilesRated(nonRatedFilesLength === 0); - if (data.checklist) { - const checkedChecklistItems = data.checklist - .map(el => el.valid) - .filter(v => v); - setAtLeastOneChecked(checkedChecklistItems.length > 0); - setAllChecksChecked(checkedChecklistItems.length === data.checklist.length) + if (data.evaluationVersion === 'V1') { + if (data.checklist) { + const checkedChecklistItems = data.checklist + .map(el => el.valid) + .filter(v => v); + setAtLeastOneChecked(checkedChecklistItems.length > 0); + setAllChecksChecked(checkedChecklistItems.length === data.checklist.length) + } + } else if (data.evaluationVersion === 'V2') { + const minChecks = data.numberOfCheck; + const formFieldsChecklist = formData + .filter(o => head(o.settings.filter(s => s.name === 'isChecklistItem' && s.value))) + .map(o => o.id); + + if (formFieldsChecklist.length >= minChecks) { + const valuesTotal = formFieldsChecklist.map(v => formValues[v]); + const valuesFirst = valuesTotal.toSpliced(minChecks); + setAtLeastOneChecked(valuesTotal.filter(v => v === true).length === valuesTotal.length); + setAllChecksChecked(valuesFirst.filter(v => v === true).length === valuesFirst.length) + } } - } + }, [formValues]); const doNewSoccorso = () => { if (connectedSoccorsoId !== 0) { @@ -191,24 +199,43 @@ const DomandaEditInstructorManager = () => { storeSet.main.unsetAsyncRequest(); } - const getCallback = (data) => { - if (data.status === 'SUCCESS') { - setData(getFormattedData(data.data)); - setMotivation(data.data.motivation); - updateFlagsForSoccorso(data.data); + const getCallback = (resp) => { + if (resp.status === 'SUCCESS') { + setData(getFormattedData(resp.data)); + setMotivation(resp.data.motivation); + updateFlagsForSoccorso(resp.data); + setFormData(resp.data.applicationEvaluationFormResponse.content); + setFormId(resp.data.applicationEvaluationFormResponse.id); + let formDataInitial = {}; + + if (resp.data.applicationEvaluationFormResponse.formFields) { + const submitData = resp.data.applicationEvaluationFormResponse.formFields.map((o) => ({ + fieldId: o.fieldId, + fieldValue: o.fieldValue + })); + formDataInitial = submitData.reduce((acc, cur) => { + if (cur.fieldValue) { + acc[cur.fieldId] = cur.fieldValue; + } + return acc; + }, formDataInitial); + } + + reset(); + setFormInitialData(formDataInitial); } storeSet.main.unsetAsyncRequest(); } - const errGetCallback = (data) => { - if (toast.current && data.message) { + const errGetCallback = (resp) => { + if (toast.current && resp.message) { toast.current.show({ severity: 'error', summary: '', - detail: data.message + detail: resp.message }); } - set404FromErrorResponse(data); + set404FromErrorResponse(resp); storeSet.main.unsetAsyncRequest(); } @@ -834,6 +861,8 @@ const DomandaEditInstructorManager = () => { if (!isEmpty(updatedFormValues) && !equal(updatedFormValues, formValues)) { reset(updatedFormValues); } + + updateFlagsForSoccorso(data); }, [formValues]); useEffect(() => { diff --git a/src/pages/Profile/index.js b/src/pages/Profile/index.js index d7b3474..3b2d5b7 100644 --- a/src/pages/Profile/index.js +++ b/src/pages/Profile/index.js @@ -36,7 +36,7 @@ const Profile = () => { const onSubmit = (formData) => { storeSet.main.setAsyncRequest(); - UserService.updateUser(userData.id, formData, updateCallback, updateError); + UserService.updateUserSelf(userData.id, formData, updateCallback, updateError); }; const updateCallback = (data) => { @@ -109,6 +109,7 @@ const Profile = () => { { const onSubmit = (formData) => { storeSet.main.setAsyncRequest(); - UserService.updateUser(userData.id, formData, updateCallback, updateError); + UserService.updateUserSelf(userData.id, formData, updateCallback, updateError); }; const updateCallback = (data) => { diff --git a/src/service/dashboard-service.js b/src/service/dashboard-service.js index bf30675..5ad2f03 100644 --- a/src/service/dashboard-service.js +++ b/src/service/dashboard-service.js @@ -24,7 +24,7 @@ export default class DashboardService { NetworkService.get(`${API_BASE_URL}/dashboard/beneficiary/company/${id}`, callback, errCallback); }; - static getInstructorAmendmentsStats = (callback, errCallback) => { - NetworkService.get(`${API_BASE_URL}/dashboard/instructor/amendment`, callback, errCallback); + static getInstructorAmendmentsStats = (callback, errCallback, queryParams) => { + NetworkService.get(`${API_BASE_URL}/dashboard/instructor/amendment`, callback, errCallback, queryParams); }; } diff --git a/src/service/user-service.js b/src/service/user-service.js index e98fd89..1906903 100644 --- a/src/service/user-service.js +++ b/src/service/user-service.js @@ -16,6 +16,10 @@ export default class UserService { NetworkService.put(`${API_BASE_URL}/user/${id}`, body, callback, errCallback); }; + static updateUserSelf = (id, body, callback, errCallback) => { + NetworkService.put(`${API_BASE_URL}/user/${id}/update-details`, body, callback, errCallback); + }; + static createUser = (body, callback, errCallback) => { NetworkService.post(`${API_BASE_URL}/user`, body, callback, errCallback); }; From 948d511189393b3c564a357ca6a49f197277e83a Mon Sep 17 00:00:00 2001 From: Vitalii Kiiko Date: Fri, 7 Feb 2025 14:45:39 +0100 Subject: [PATCH 05/10] - updated page of evaluation editing for instructor; --- .../components/LastRowCell/index.js | 4 +- src/pages/DomandaEditPreInstructor/index.js | 69 ++++++++++++------- 2 files changed, 46 insertions(+), 27 deletions(-) diff --git a/src/components/FormField/components/CriteriaTable/RenderTable/components/LastRowCell/index.js b/src/components/FormField/components/CriteriaTable/RenderTable/components/LastRowCell/index.js index cd0d954..73d987c 100644 --- a/src/components/FormField/components/CriteriaTable/RenderTable/components/LastRowCell/index.js +++ b/src/components/FormField/components/CriteriaTable/RenderTable/components/LastRowCell/index.js @@ -1,4 +1,4 @@ -import { head, isNil, pathOr } from 'ramda'; +import { head, is, isNil, pathOr } from 'ramda'; import getNumberFormatted from '../../../../../../../helpers/getNumberFormatted'; const LastRowCell = ({columnId, lastRowCfg, columnMeta = {}, tableValue = []}) => { @@ -9,7 +9,7 @@ const LastRowCell = ({columnId, lastRowCfg, columnMeta = {}, tableValue = []}) = cellValue = pathOr(0, ['total'], tableValue); } - return {getNumberFormatted(cellValue)}; + return {is(Number, cellValue) ? getNumberFormatted(cellValue) : cellValue}; }; export default LastRowCell; \ No newline at end of file diff --git a/src/pages/DomandaEditPreInstructor/index.js b/src/pages/DomandaEditPreInstructor/index.js index 3860f56..64b4546 100644 --- a/src/pages/DomandaEditPreInstructor/index.js +++ b/src/pages/DomandaEditPreInstructor/index.js @@ -121,7 +121,7 @@ const DomandaEditPreInstructor = () => { navigate('/domande'); } - const updateFlagsForSoccorso = (data) => { + const updateFlagsForSoccorso = useCallback((data) => { let nonRatedFilesLength = 0; if (data.files) { @@ -140,14 +140,28 @@ const DomandaEditPreInstructor = () => { setAllFilesRated(nonRatedFilesLength === 0); - if (data.checklist) { - const checkedChecklistItems = data.checklist - .map(el => el.valid) - .filter(v => v); - setAtLeastOneChecked(checkedChecklistItems.length > 0); - setAllChecksChecked(checkedChecklistItems.length === data.checklist.length) + if (data.evaluationVersion === 'V1') { + if (data.checklist) { + const checkedChecklistItems = data.checklist + .map(el => el.valid) + .filter(v => v); + setAtLeastOneChecked(checkedChecklistItems.length > 0); + setAllChecksChecked(checkedChecklistItems.length === data.checklist.length) + } + } else if (data.evaluationVersion === 'V2') { + const minChecks = data.numberOfCheck; + const formFieldsChecklist = formData + .filter(o => head(o.settings.filter(s => s.name === 'isChecklistItem' && s.value))) + .map(o => o.id); + + if (formFieldsChecklist.length >= minChecks) { + const valuesTotal = formFieldsChecklist.map(v => formValues[v]); + const valuesFirst = valuesTotal.toSpliced(minChecks); + setAtLeastOneChecked(valuesTotal.filter(v => v === true).length === valuesTotal.length); + setAllChecksChecked(valuesFirst.filter(v => v === true).length === valuesFirst.length) + } } - } + }, [formValues]); const doNewSoccorso = () => { if (connectedSoccorsoId !== 0) { @@ -191,25 +205,28 @@ const DomandaEditPreInstructor = () => { setData(getFormattedData(resp.data)); setMotivation(resp.data.motivation); updateFlagsForSoccorso(resp.data); - setFormData(resp.data.applicationEvaluationFormResponse.content); - setFormId(resp.data.applicationEvaluationFormResponse.id); - let formDataInitial = {}; - if (resp.data.applicationEvaluationFormResponse.formFields) { - const submitData = resp.data.applicationEvaluationFormResponse.formFields.map((o) => ({ - fieldId: o.fieldId, - fieldValue: o.fieldValue - })); - formDataInitial = submitData.reduce((acc, cur) => { - if (cur.fieldValue) { - acc[cur.fieldId] = cur.fieldValue; - } - return acc; - }, formDataInitial); + if (resp.data.evaluationVersion === 'V2') { + setFormData(resp.data.applicationEvaluationFormResponse.content); + setFormId(resp.data.applicationEvaluationFormResponse.id); + let formDataInitial = {}; + + if (resp.data.applicationEvaluationFormResponse.formFields) { + const submitData = resp.data.applicationEvaluationFormResponse.formFields.map((o) => ({ + fieldId: o.fieldId, + fieldValue: o.fieldValue + })); + formDataInitial = submitData.reduce((acc, cur) => { + if (cur.fieldValue) { + acc[cur.fieldId] = cur.fieldValue; + } + return acc; + }, formDataInitial); + } + + reset(); + setFormInitialData(formDataInitial); } - - reset(); - setFormInitialData(formDataInitial); } storeSet.main.unsetAsyncRequest(); } @@ -848,6 +865,8 @@ const DomandaEditPreInstructor = () => { if (!isEmpty(updatedFormValues) && !equal(updatedFormValues, formValues)) { reset(updatedFormValues); } + + updateFlagsForSoccorso(data); }, [formValues]); useEffect(() => { From bed271448acbebc91dd696668fe1aac7d9817173 Mon Sep 17 00:00:00 2001 From: Vitalii Kiiko Date: Mon, 10 Feb 2025 10:10:09 +0100 Subject: [PATCH 06/10] - updates; --- .../BandoFormsEdit/components/BuilderElement/index.js | 8 +++++++- .../components/BuilderElementSettings/index.js | 4 ++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/pages/BandoFormsEdit/components/BuilderElement/index.js b/src/pages/BandoFormsEdit/components/BuilderElement/index.js index 2cfffa6..78353bc 100644 --- a/src/pages/BandoFormsEdit/components/BuilderElement/index.js +++ b/src/pages/BandoFormsEdit/components/BuilderElement/index.js @@ -108,9 +108,15 @@ const BuilderElement = ({ id, name, label, index, bandoStatus }) => { if (duplicatedElement) { const copyElement = klona(duplicatedElement); + copyElement.settings = copyElement.settings.map((o) => { + if (o.name === 'label') { + o.value = `Copy - ${o.value}` + } + return o; + }) copyElement.id = uniqid(); const originalIndex = elements.map(o => o.id).indexOf(id); - const newElements = [...elements].toSpliced(originalIndex, 0, copyElement); + const newElements = [...elements].toSpliced(originalIndex + 1, 0, copyElement); storeSet.main.formElements(newElements); } }, [elements]); diff --git a/src/pages/BandoFormsEdit/components/BuilderElementSettings/index.js b/src/pages/BandoFormsEdit/components/BuilderElementSettings/index.js index 92fec6f..d7fc321 100644 --- a/src/pages/BandoFormsEdit/components/BuilderElementSettings/index.js +++ b/src/pages/BandoFormsEdit/components/BuilderElementSettings/index.js @@ -124,7 +124,7 @@ const BuilderElementSettings = ({ closeSettingsFn, callStatus, context }) => { } settings = settings.filter(o => context === 'call' - ? !['isRequestedAmount', 'isDelegation'].includes(o.name) + ? !['isRequestedAmount', 'isDelegation', ''].includes(o.name) : !['isChecklistItem'].includes(o.name)); if (chosen) { @@ -157,7 +157,7 @@ const BuilderElementSettings = ({ closeSettingsFn, callStatus, context }) => { changeFn={onChange} updateDataFn={onUpdateOptions}/>) : null} - {!isNil(dynamicDataOptions[activeElementData.name]) + {!isNil(dynamicDataOptions[activeElementData.name]) && context === 'application' ?
Date: Mon, 10 Feb 2025 10:27:16 +0100 Subject: [PATCH 07/10] - filtered builder elements based on context; --- src/pages/BandoFormsEdit/index.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pages/BandoFormsEdit/index.js b/src/pages/BandoFormsEdit/index.js index fb8fe06..9fdfbe9 100644 --- a/src/pages/BandoFormsEdit/index.js +++ b/src/pages/BandoFormsEdit/index.js @@ -216,7 +216,9 @@ const BandoFormsEdit = () => { const getElementItemsCallback = (data) => { if (data.status === 'SUCCESS') { //storeSet.main.elementItems(elementItems.sort((a, b) => a.sortOrder - b.sortOrder)); - storeSet.main.elementItems(data.data.sort((a, b) => a.sortOrder - b.sortOrder)); + storeSet.main.elementItems(data.data + .filter(o => o.id !== 22) + .sort((a, b) => a.sortOrder - b.sortOrder)); } storeSet.main.unsetAsyncRequest(); } From 7fa06b5b8ce6be8ccb4b2d0785321d509a77dfe8 Mon Sep 17 00:00:00 2001 From: Vitalii Kiiko Date: Mon, 10 Feb 2025 14:35:51 +0100 Subject: [PATCH 08/10] - saving progress; --- src/assets/scss/components/formBuilder.scss | 4 + .../scss/components/statsBigBadges.scss | 44 +++++ src/components/ChartDomandePerStato/index.js | 79 ++++++++ .../components/AppSidebar/index.js | 6 +- .../components/BandoEditFormStep3/index.js | 2 + .../components/BuilderElement/index.js | 23 ++- src/pages/BandoFormsEdit/index.js | 4 +- .../PreInstructorSoccorsiTable/index.js | 178 ++++++++++++++++++ src/pages/StatsBeneficiary/index.js | 107 +++++++++++ src/routes.js | 7 + src/service/dashboard-service.js | 3 + src/store/initial.js | 1 + 12 files changed, 447 insertions(+), 11 deletions(-) create mode 100644 src/components/ChartDomandePerStato/index.js create mode 100644 src/pages/StatsBeneficiary/components/PreInstructorSoccorsiTable/index.js create mode 100644 src/pages/StatsBeneficiary/index.js diff --git a/src/assets/scss/components/formBuilder.scss b/src/assets/scss/components/formBuilder.scss index 3ed9564..00db384 100644 --- a/src/assets/scss/components/formBuilder.scss +++ b/src/assets/scss/components/formBuilder.scss @@ -57,6 +57,10 @@ cursor: pointer; } + /*&.selected { + border-color: var(--menuitem-active-background); + }*/ + .meta { display: flex; flex-direction: column; diff --git a/src/assets/scss/components/statsBigBadges.scss b/src/assets/scss/components/statsBigBadges.scss index 8bde805..6c08cb7 100644 --- a/src/assets/scss/components/statsBigBadges.scss +++ b/src/assets/scss/components/statsBigBadges.scss @@ -112,6 +112,50 @@ } } +.statsBigBadges__gridItemDoubleStatsBeneficiary { + display: flex; + flex-direction: column; + padding: 16px; + border-radius: 6px; + border: 1px solid #858585; + background: #cecece; + align-items: center; + gap: 32px; + + span { + color: #FFF; + font-size: 18px; + font-style: normal; + font-weight: 600; + line-height: normal; + text-align: center; + } + + > span:first-of-type { + min-height: 50px; + } + + &:nth-of-type(1) { + border: 1px solid var(--yellow-500); + background: var(--card-full-background-color-2); + } + + &:nth-of-type(2) { + border: 1px solid var(--yellow-500); + background: var(--card-full-background-color-4); + } + + &:nth-of-type(3) { + border: 1px solid var(--yellow-500); + background: var(--card-full-background-color-3); + } + + &:nth-of-type(4) { + border: 1px solid var(--yellow-500); + background: var(--card-full-background-color-1); + } +} + .statsBigBadges__grid { .statsBigBadges__gridItem { &:nth-of-type(1) { diff --git a/src/components/ChartDomandePerStato/index.js b/src/components/ChartDomandePerStato/index.js new file mode 100644 index 0000000..efbc744 --- /dev/null +++ b/src/components/ChartDomandePerStato/index.js @@ -0,0 +1,79 @@ +import React, { useEffect, useState } from 'react'; +import { __ } from '@wordpress/i18n'; +import { Tooltip, ResponsiveContainer, Cell, Pie, PieChart } from 'recharts'; +import { isEmpty } from 'ramda'; +import getBandoLabel from '../../helpers/getBandoLabel'; + +// components + + +const ChartDomandePerStato = ({ title, data = [] }) => { + const COLORS = ['#0088FE', '#00C49F', '#FFBB28', '#FF8042', '#8884d8', '#82ca9d']; + const [chartData, setChartData] = useState({}); + + const CustomTooltip = ({ active, payload }) => { + if (active && payload && payload.length) { + return ( +
+

{getBandoLabel(payload[0].name)}

+

+ {payload[0].name}: {payload[0].value} +

+
+ ); + } + return null; + }; + + useEffect(() => { + const grouped = data.reduce((acc, cur) => { + if (cur.status === 'APPROVED') { + acc.approved.value = cur.numberOfApplication; + } else if (cur.status === 'REJECTED') { + acc.rejected.value = cur.numberOfApplication; + } else { + acc.inProgress.value += cur.numberOfApplication; + } + return acc; + }, { + inProgress: {value: 0, label: 'In corso'}, + approved: {value: 0, label: 'Approvato'}, + rejected: {value: 0, label: 'Respinto'} + }); + setChartData(grouped) + }, [data]); + + console.log('chartData', chartData) + + return (
+ {title ? {title} : null} + {chartData && !isEmpty(chartData) + ?
+ + + `${(percent * 100).toFixed(0)}%`} + outerRadius={120} + fill="#8884d8" + dataKey="value" + nameKey="label" + > + {Object.values(chartData).map((entry, index) => ( + + ))} + + } /> + + +
: null} +
) +} + +export default ChartDomandePerStato; \ 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 aa25929..c449022 100644 --- a/src/layouts/DefaultLayout/components/AppSidebar/index.js +++ b/src/layouts/DefaultLayout/components/AppSidebar/index.js @@ -132,11 +132,11 @@ const AppSidebar = () => { enable: false }, { - label: __('Report e Analisi', 'gepafin'), + label: __('Statistiche', 'gepafin'), icon: 'pi pi-chart-bar', - //href: '/stats', + href: '/stats', id: 15, - enable: false + enable: intersection(permissions, ['APPLY_CALLS']).length }, { label: __('Log di Sistema', 'gepafin'), diff --git a/src/pages/BandoEdit/components/BandoEditFormStep3/index.js b/src/pages/BandoEdit/components/BandoEditFormStep3/index.js index 4f7fd1e..b67b93f 100644 --- a/src/pages/BandoEdit/components/BandoEditFormStep3/index.js +++ b/src/pages/BandoEdit/components/BandoEditFormStep3/index.js @@ -116,6 +116,8 @@ const BandoEditFormStep3 = forwardRef(function () { return () => { storeSet.main.formId(0); storeSet.main.formElements([]); + storeSet.main.activeElement(''); + storeSet.main.selectedElement(''); } }, []); diff --git a/src/pages/BandoFormsEdit/components/BuilderElement/index.js b/src/pages/BandoFormsEdit/components/BuilderElement/index.js index 78353bc..d0acc67 100644 --- a/src/pages/BandoFormsEdit/components/BuilderElement/index.js +++ b/src/pages/BandoFormsEdit/components/BuilderElement/index.js @@ -18,6 +18,7 @@ import BuilderElementProperLabel from '../BuilderElementProperLabel'; const BuilderElement = ({ id, name, label, index, bandoStatus }) => { const draggingElementId = useStore().main.draggingElementId(); + const selectedElement = useStore().main.selectedElement(); const ref = useRef(null); const elements = useStore().main.formElements(); const element = head(elements.filter(o => o.id === id)); @@ -99,11 +100,15 @@ const BuilderElement = ({ id, name, label, index, bandoStatus }) => { storeSet.main.moveElement(dragIndex, hoverIndex, item); } - const openSettings = (id) => { + const openSettings = () => { storeSet.main.activeElement(id); } - const duplicateElement = useCallback((id) => { + const selectElement = () => { + storeSet.main.selectedElement(id); + } + + const duplicateElement = useCallback(() => { const duplicatedElement = head(elements.filter(o => o.id === id)); if (duplicatedElement) { @@ -121,7 +126,7 @@ const BuilderElement = ({ id, name, label, index, bandoStatus }) => { } }, [elements]); - const remove = (id) => { + const remove = () => { storeSet.main.removeElement(id); } @@ -158,7 +163,11 @@ const BuilderElement = ({ id, name, label, index, bandoStatus }) => { ?
{__('lascia qui', 'gepafin')}
- :
+ :
@@ -174,9 +183,9 @@ const BuilderElement = ({ id, name, label, index, bandoStatus }) => {
-
) diff --git a/src/pages/BandoFormsEdit/index.js b/src/pages/BandoFormsEdit/index.js index 9fdfbe9..e739c89 100644 --- a/src/pages/BandoFormsEdit/index.js +++ b/src/pages/BandoFormsEdit/index.js @@ -223,7 +223,7 @@ const BandoFormsEdit = () => { storeSet.main.unsetAsyncRequest(); } - const errGetElementItemsCallback = (data) => { + const errGetElementItemsCallback = () => { storeSet.main.unsetAsyncRequest(); } @@ -278,6 +278,8 @@ const BandoFormsEdit = () => { storeSet.main.formLabel(''); storeSet.main.formElements([]); storeSet.main.bandoCriteria([]); + storeSet.main.activeElement(''); + storeSet.main.selectedElement(''); } }, [id, formId]); diff --git a/src/pages/StatsBeneficiary/components/PreInstructorSoccorsiTable/index.js b/src/pages/StatsBeneficiary/components/PreInstructorSoccorsiTable/index.js new file mode 100644 index 0000000..b74acd6 --- /dev/null +++ b/src/pages/StatsBeneficiary/components/PreInstructorSoccorsiTable/index.js @@ -0,0 +1,178 @@ +import React, { useState, useEffect} from 'react'; +import { __ } from '@wordpress/i18n'; +import { is, isNil, uniq } from 'ramda'; +import { Link } from 'react-router-dom'; + +// api +import AmendmentsService from '../../../../service/amendments-service'; + +// tools +import getBandoLabel from '../../../../helpers/getBandoLabel'; +import getBandoSeverity from '../../../../helpers/getBandoSeverity'; + +// components +import { FilterMatchMode, FilterOperator } from 'primereact/api'; +import { DataTable } from 'primereact/datatable'; +import { Column } from 'primereact/column'; +import { Button } from 'primereact/button'; +import { Calendar } from 'primereact/calendar'; +import ProperBandoLabel from '../../../../components/ProperBandoLabel'; +import { Dropdown } from 'primereact/dropdown'; +import { Tag } from 'primereact/tag'; + +import translationStrings from '../../../../translationStringsForComponents'; + + +const PreInstructorSoccorsiTable = ({ userId = null }) => { + const [items, setItems] = useState(null); + const [filters, setFilters] = useState(null); + const [localAsyncRequest, setLocalAsyncRequest] = useState(false); + const [statuses, setStatuses] = useState([]); + + useEffect(() => { + if (!isNil(userId)) { + setLocalAsyncRequest(true); + + if (userId === 0) { + AmendmentsService.getSoccorsi(getCallback, errGetCallbacks); + } else { + AmendmentsService.getSoccorsi(getCallback, errGetCallbacks, [ + ['userId', userId] + ]); + } + } + }, [userId]); + + const getCallback = (data) => { + if (data.status === 'SUCCESS') { + setItems(getFormattedData(data.data)); + setStatuses(uniq(data.data.map(o => o.status))) + initFilters(); + } + setLocalAsyncRequest(false); + } + + const errGetCallbacks = (data) => { + setLocalAsyncRequest(false); + } + + const getFormattedData = (data) => { + return data.map((d) => { + d.startDate = is(String, d.startDate) ? new Date(d.startDate) : (d.startDate ? d.startDate : ''); + d.evaluationEndDate = is(String, d.evaluationEndDate) ? new Date(d.evaluationEndDate) : (d.evaluationEndDate ? d.evaluationEndDate : ''); + return d; + }); + }; + + const formatDate = (value) => { + return value.toLocaleDateString('it-IT', { + day: '2-digit', + month: '2-digit', + year: 'numeric' + }); + }; + + const clearFilter = () => { + initFilters(); + }; + + const initFilters = () => { + setFilters({ + global: { value: null, matchMode: FilterMatchMode.CONTAINS }, + callName: { + operator: FilterOperator.AND, + constraints: [{ value: null, matchMode: FilterMatchMode.STARTS_WITH }] + }, + companyName: { + operator: FilterOperator.AND, + constraints: [{ value: null, matchMode: FilterMatchMode.STARTS_WITH }] + }, + startDate: { + operator: FilterOperator.AND, + constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }] + }, + evaluationEndDate: { + operator: FilterOperator.AND, + constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }] + } + }); + }; + + const renderHeader = () => { + return ( +
+
+ ); + }; + + const dateStartBodyTemplate = (rowData) => { + return formatDate(rowData.startDate); + }; + + const dateExpirationBodyTemplate = (rowData) => { + return rowData.evaluationEndDate ? formatDate(rowData.evaluationEndDate) : ''; + }; + + const dateFilterTemplate = (options) => { + return options.filterCallback(e.value, options.index)} dateFormat="mm/dd/yy" placeholder="mm/dd/yyyy" mask="99/99/9999" />; + }; + + const statusBodyTemplate = (rowData) => { + return ; + }; + + const statusFilterTemplate = (options) => { + return options.filterCallback(e.value, options.index)} itemTemplate={statusItemTemplate} placeholder={translationStrings.selectOneLabel} className="p-column-filter" showClear />; + }; + + const statusItemTemplate = (option) => { + return ; + }; + + const actionsBodyTemplate = (rowData) => { + return +
diff --git a/src/pages/DomandeInstructorManager/index.js b/src/pages/DomandeInstructorManager/index.js index 35957b5..31ee817 100644 --- a/src/pages/DomandeInstructorManager/index.js +++ b/src/pages/DomandeInstructorManager/index.js @@ -1,6 +1,6 @@ import React, { useEffect, useRef, useState } from 'react'; import { __ } from '@wordpress/i18n'; -import { isEmpty, pathOr } from 'ramda'; +import { isEmpty } from 'ramda'; // store import { storeSet } from '../../store'; diff --git a/src/pages/StatsBeneficiary/components/BeneficiarioUltimeDomandeTable/index.js b/src/pages/StatsBeneficiary/components/BeneficiarioUltimeDomandeTable/index.js new file mode 100644 index 0000000..31c7ec9 --- /dev/null +++ b/src/pages/StatsBeneficiary/components/BeneficiarioUltimeDomandeTable/index.js @@ -0,0 +1,146 @@ +import React, { useState, useEffect } from 'react'; +import { __ } from '@wordpress/i18n'; +import { is, isEmpty, uniq } from 'ramda'; + +// store +import { useStore } from '../../../../store'; + +// api +import ApplicationService from '../../../../service/application-service'; + +// tools +import getNumberWithCurrency from '../../../../helpers/getNumberWithCurrency'; + +// components +import { FilterMatchMode, FilterOperator } from 'primereact/api'; +import { DataTable } from 'primereact/datatable'; +import { Column } from 'primereact/column'; +import ProperBandoLabel from '../../../../components/ProperBandoLabel'; +import translationStrings from '../../../../translationStringsForComponents'; + + +const BeneficiarioUltimeDomandeTable = () => { + const chosenCompanyId = useStore().main.chosenCompanyId(); + const [items, setItems] = useState(null); + // eslint-disable-next-line + const [filters, setFilters] = useState(null); + const [localAsyncRequest, setLocalAsyncRequest] = useState(false); + // eslint-disable-next-line + const [statuses, setStatuses] = useState([]); + const perPage = 5; + + const getPaginationQuery = (status = 'DRAFT', curPage = 1) => { + return { + "globalFilters": { + //"year": 0, + "page": curPage, + //"search": "", + "limit": perPage, + }, + //"daysRange": 0, + "status": status + } + } + + useEffect(() => { + if (!isEmpty(chosenCompanyId) && chosenCompanyId !== 0 && !localAsyncRequest) { + const bodyParams = getPaginationQuery( + ['SOCCORSO', 'APPROVED', 'REJECTED', 'EVALUATION', 'SUBMIT'], + 1 + ); + + setLocalAsyncRequest(true); + ApplicationService.getApplicationsPaginated(bodyParams, getApplCallback, errGetApplCallback, [ + ['companyId', chosenCompanyId], + ['statuses', ['SOCCORSO', 'APPROVED', 'REJECTED', 'EVALUATION', 'SUBMIT']] // 'NDG', 'ADMISSIBLE', 'APPOINTMENT' + ]); + } + }, [chosenCompanyId]); + + const getApplCallback = (resp) => { + if (resp.status === 'SUCCESS') { + if (resp.data && is(Array, resp.data.body)) { + setItems(getFormattedBandiData(resp.data.body)); + setStatuses(uniq(items.map(o => o.status))) + initFilters(); + } + } + setLocalAsyncRequest(false); + } + + const errGetApplCallback = () => { + setLocalAsyncRequest(false); + } + + const getFormattedBandiData = (data) => { + return [...(data || [])].map((d) => { + d.callEndDate = new Date(d.callEndDate); + d.modifiedDate = new Date(d.modifiedDate); + d.submissionDate = new Date(d.submissionDate); + + return d; + }); + }; + + const formatDate = (value) => { + return value.toLocaleDateString('it-IT', { + year: 'numeric' + }); + }; + + const initFilters = () => { + setFilters({ + global: { value: null, matchMode: FilterMatchMode.CONTAINS }, + callTitle: { + operator: FilterOperator.AND, + constraints: [{ value: null, matchMode: FilterMatchMode.STARTS_WITH }] + }, + companyName: { + operator: FilterOperator.AND, + constraints: [{ value: null, matchMode: FilterMatchMode.STARTS_WITH }] + }, + modifiedDate: { + operator: FilterOperator.AND, + constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }] + }, + callEndDate: { + operator: FilterOperator.AND, + constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }] + } + }); + }; + + const dateSubmissionBodyTemplate = (rowData) => { + return formatDate(rowData.submissionDate); + }; + + const importoBodyTemplate = (rowData) => { + return getNumberWithCurrency(rowData.amountRequested); + }; + + const statusBodyTemplate = (rowData) => { + return ; + }; + + return ( +
+ + + + + + +
+ ) +} + +export default BeneficiarioUltimeDomandeTable; diff --git a/src/pages/StatsBeneficiary/components/PreInstructorSoccorsiTable/index.js b/src/pages/StatsBeneficiary/components/PreInstructorSoccorsiTable/index.js deleted file mode 100644 index b74acd6..0000000 --- a/src/pages/StatsBeneficiary/components/PreInstructorSoccorsiTable/index.js +++ /dev/null @@ -1,178 +0,0 @@ -import React, { useState, useEffect} from 'react'; -import { __ } from '@wordpress/i18n'; -import { is, isNil, uniq } from 'ramda'; -import { Link } from 'react-router-dom'; - -// api -import AmendmentsService from '../../../../service/amendments-service'; - -// tools -import getBandoLabel from '../../../../helpers/getBandoLabel'; -import getBandoSeverity from '../../../../helpers/getBandoSeverity'; - -// components -import { FilterMatchMode, FilterOperator } from 'primereact/api'; -import { DataTable } from 'primereact/datatable'; -import { Column } from 'primereact/column'; -import { Button } from 'primereact/button'; -import { Calendar } from 'primereact/calendar'; -import ProperBandoLabel from '../../../../components/ProperBandoLabel'; -import { Dropdown } from 'primereact/dropdown'; -import { Tag } from 'primereact/tag'; - -import translationStrings from '../../../../translationStringsForComponents'; - - -const PreInstructorSoccorsiTable = ({ userId = null }) => { - const [items, setItems] = useState(null); - const [filters, setFilters] = useState(null); - const [localAsyncRequest, setLocalAsyncRequest] = useState(false); - const [statuses, setStatuses] = useState([]); - - useEffect(() => { - if (!isNil(userId)) { - setLocalAsyncRequest(true); - - if (userId === 0) { - AmendmentsService.getSoccorsi(getCallback, errGetCallbacks); - } else { - AmendmentsService.getSoccorsi(getCallback, errGetCallbacks, [ - ['userId', userId] - ]); - } - } - }, [userId]); - - const getCallback = (data) => { - if (data.status === 'SUCCESS') { - setItems(getFormattedData(data.data)); - setStatuses(uniq(data.data.map(o => o.status))) - initFilters(); - } - setLocalAsyncRequest(false); - } - - const errGetCallbacks = (data) => { - setLocalAsyncRequest(false); - } - - const getFormattedData = (data) => { - return data.map((d) => { - d.startDate = is(String, d.startDate) ? new Date(d.startDate) : (d.startDate ? d.startDate : ''); - d.evaluationEndDate = is(String, d.evaluationEndDate) ? new Date(d.evaluationEndDate) : (d.evaluationEndDate ? d.evaluationEndDate : ''); - return d; - }); - }; - - const formatDate = (value) => { - return value.toLocaleDateString('it-IT', { - day: '2-digit', - month: '2-digit', - year: 'numeric' - }); - }; - - const clearFilter = () => { - initFilters(); - }; - - const initFilters = () => { - setFilters({ - global: { value: null, matchMode: FilterMatchMode.CONTAINS }, - callName: { - operator: FilterOperator.AND, - constraints: [{ value: null, matchMode: FilterMatchMode.STARTS_WITH }] - }, - companyName: { - operator: FilterOperator.AND, - constraints: [{ value: null, matchMode: FilterMatchMode.STARTS_WITH }] - }, - startDate: { - operator: FilterOperator.AND, - constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }] - }, - evaluationEndDate: { - operator: FilterOperator.AND, - constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }] - } - }); - }; - - const renderHeader = () => { - return ( -
-
- ); - }; - - const dateStartBodyTemplate = (rowData) => { - return formatDate(rowData.startDate); - }; - - const dateExpirationBodyTemplate = (rowData) => { - return rowData.evaluationEndDate ? formatDate(rowData.evaluationEndDate) : ''; - }; - - const dateFilterTemplate = (options) => { - return options.filterCallback(e.value, options.index)} dateFormat="mm/dd/yy" placeholder="mm/dd/yyyy" mask="99/99/9999" />; - }; - - const statusBodyTemplate = (rowData) => { - return ; - }; - - const statusFilterTemplate = (options) => { - return options.filterCallback(e.value, options.index)} itemTemplate={statusItemTemplate} placeholder={translationStrings.selectOneLabel} className="p-column-filter" showClear />; - }; - - const statusItemTemplate = (option) => { - return ; - }; - - const actionsBodyTemplate = (rowData) => { - return -
@@ -92,14 +90,21 @@ console.log(chartStats) ?

{__('Statistiche di sistema', 'gepafin')}

- {/**/} +
: null} + +
+ +
+

{__('Ultime richieste di finanziamento', 'gepafin')}

+ +
) } diff --git a/src/service/application-service.js b/src/service/application-service.js index ae59a84..961ee34 100644 --- a/src/service/application-service.js +++ b/src/service/application-service.js @@ -8,6 +8,10 @@ export default class ApplicationService { NetworkService.get(`${API_BASE_URL}/application`, callback, errCallback, queryParams); }; + static getApplicationsPaginated = (body, callback, errCallback, queryParams) => { + NetworkService.post(`${API_BASE_URL}/application/pagination`, body, callback, errCallback, queryParams); + }; + static getApplication = (id, callback, errCallback) => { NetworkService.get(`${API_BASE_URL}/application/${id}`, callback, errCallback); }; From 8e16e1993795f2ac35eef9ee3a678102590376d7 Mon Sep 17 00:00:00 2001 From: Vitalii Kiiko Date: Wed, 12 Feb 2025 10:52:54 +0100 Subject: [PATCH 10/10] - updated condition for multi application for the same company and beneficiary; --- src/helpers/getBandoLabel.js | 3 ++ src/helpers/getBandoSeverity.js | 3 ++ src/pages/BandoViewBeneficiario/index.js | 11 ++++-- .../DomandaEditInstructorManager/index.js | 37 ++++++++++--------- 4 files changed, 33 insertions(+), 21 deletions(-) diff --git a/src/helpers/getBandoLabel.js b/src/helpers/getBandoLabel.js index 1816a42..7cbf3bf 100644 --- a/src/helpers/getBandoLabel.js +++ b/src/helpers/getBandoLabel.js @@ -59,6 +59,9 @@ const getBandoLabel = (status) => { case 'CLOSE': return __('Chiuso', 'gepafin'); + case 'REJECTED': + return __('Respinto', 'gepafin'); + default: return ''; } diff --git a/src/helpers/getBandoSeverity.js b/src/helpers/getBandoSeverity.js index d6c4dbf..03b8704 100644 --- a/src/helpers/getBandoSeverity.js +++ b/src/helpers/getBandoSeverity.js @@ -57,6 +57,9 @@ const getBandoSeverity = (status) => { case 'CLOSE': return 'closed'; + case 'REJECTED': + return 'danger'; + default: return 'info'; } diff --git a/src/pages/BandoViewBeneficiario/index.js b/src/pages/BandoViewBeneficiario/index.js index f6bea38..ab99cb8 100644 --- a/src/pages/BandoViewBeneficiario/index.js +++ b/src/pages/BandoViewBeneficiario/index.js @@ -1,7 +1,7 @@ import React, { useState, useEffect, useRef } from 'react'; import { __ } from '@wordpress/i18n'; import { useNavigate, useParams } from 'react-router-dom'; -import { is, isEmpty, isNil } from 'ramda'; +import { head, is, isEmpty, isNil } from 'ramda'; import 'quill/dist/quill.core.css'; // store @@ -12,11 +12,13 @@ import getNumberWithCurrency from '../../helpers/getNumberWithCurrency'; import getDateFromISOstring from '../../helpers/getDateFromISOstring'; import set404FromErrorResponse from '../../helpers/set404FromErrorResponse'; import renderHtmlContent from '../../helpers/renderHtmlContent'; +import isDateTimeInPast from '../../helpers/isDateTimeInPast'; // api import BandoService from '../../service/bando-service'; import FaqItemService from '../../service/faq-item-service'; import ApplicationService from '../../service/application-service'; +import PreferredBandoService from '../../service/preferred-bando-service'; // components import { Skeleton } from 'primereact/skeleton'; @@ -28,8 +30,6 @@ import { Message } from 'primereact/message'; import { Toast } from 'primereact/toast'; import { Editor } from 'primereact/editor'; import { Dialog } from 'primereact/dialog'; -import PreferredBandoService from '../../service/preferred-bando-service'; -import isDateTimeInPast from '../../helpers/isDateTimeInPast'; const REACT_APP_HUB_ID = process.env.REACT_APP_HUB_ID; @@ -244,7 +244,10 @@ const BandoViewBeneficiario = () => { const getApplCallback = (data) => { if (data.status === 'SUCCESS') { if (data.data.length) { - setApplicationObj(data.data[0]); + const nonRejectedAppl = head(data.data.filter(o => !['REJECTED'].includes(o.status))); + if (nonRejectedAppl) { + setApplicationObj(nonRejectedAppl); + } } } storeSet.main.unsetAsyncRequest(); diff --git a/src/pages/DomandaEditInstructorManager/index.js b/src/pages/DomandaEditInstructorManager/index.js index c47351e..a85efde 100644 --- a/src/pages/DomandaEditInstructorManager/index.js +++ b/src/pages/DomandaEditInstructorManager/index.js @@ -204,25 +204,28 @@ const DomandaEditInstructorManager = () => { setData(getFormattedData(resp.data)); setMotivation(resp.data.motivation); updateFlagsForSoccorso(resp.data); - setFormData(resp.data.applicationEvaluationFormResponse.content); - setFormId(resp.data.applicationEvaluationFormResponse.id); - let formDataInitial = {}; - if (resp.data.applicationEvaluationFormResponse.formFields) { - const submitData = resp.data.applicationEvaluationFormResponse.formFields.map((o) => ({ - fieldId: o.fieldId, - fieldValue: o.fieldValue - })); - formDataInitial = submitData.reduce((acc, cur) => { - if (cur.fieldValue) { - acc[cur.fieldId] = cur.fieldValue; - } - return acc; - }, formDataInitial); + if (resp.data.evaluationVersion === 'V2') { + setFormData(resp.data.applicationEvaluationFormResponse.content); + setFormId(resp.data.applicationEvaluationFormResponse.id); + let formDataInitial = {}; + + if (resp.data.applicationEvaluationFormResponse.formFields) { + const submitData = resp.data.applicationEvaluationFormResponse.formFields.map((o) => ({ + fieldId: o.fieldId, + fieldValue: o.fieldValue + })); + formDataInitial = submitData.reduce((acc, cur) => { + if (cur.fieldValue) { + acc[cur.fieldId] = cur.fieldValue; + } + return acc; + }, formDataInitial); + } + + reset(); + setFormInitialData(formDataInitial); } - - reset(); - setFormInitialData(formDataInitial); } storeSet.main.unsetAsyncRequest(); }