- saving progress;
This commit is contained in:
@@ -26,6 +26,9 @@ const getBandoLabel = (status) => {
|
|||||||
case 'AWAIT':
|
case 'AWAIT':
|
||||||
return __('In attesa', 'gepafin');
|
return __('In attesa', 'gepafin');
|
||||||
|
|
||||||
|
case 'OPEN':
|
||||||
|
return __('Aperto', 'gepafin');
|
||||||
|
|
||||||
case 'ASSIGNED':
|
case 'ASSIGNED':
|
||||||
return __('Assegnato', 'gepafin');
|
return __('Assegnato', 'gepafin');
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,9 @@ const getBandoSeverity = (status) => {
|
|||||||
case 'AWAIT':
|
case 'AWAIT':
|
||||||
return 'warning';
|
return 'warning';
|
||||||
|
|
||||||
|
case 'OPEN':
|
||||||
|
return 'warning';
|
||||||
|
|
||||||
case 'ASSIGNED':
|
case 'ASSIGNED':
|
||||||
return 'warning';
|
return 'warning';
|
||||||
|
|
||||||
|
|||||||
20
src/icons/HelpIcon/index.js
Normal file
20
src/icons/HelpIcon/index.js
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
const HelpIcon = () => {
|
||||||
|
return <svg width="15" height="14" viewBox="0 0 15 14" fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g clipPath="url(#clip0_1665_1656)">
|
||||||
|
<path
|
||||||
|
d="M7.50129 14C6.53308 14 5.62302 13.8163 4.7711 13.4488C3.91919 13.0814 3.17818 12.5827 2.54805 11.9529C1.91793 11.323 1.41903 10.5823 1.05134 9.73074C0.683781 8.87919 0.5 7.96938 0.5 7.00129C0.5 6.03308 0.683719 5.12302 1.05116 4.2711C1.4186 3.41919 1.91725 2.67818 2.54713 2.04805C3.17701 1.41793 3.91772 0.919026 4.76926 0.551342C5.62081 0.183781 6.53062 0 7.49871 0C8.46692 0 9.37698 0.183719 10.2289 0.551158C11.0808 0.918596 11.8218 1.41725 12.4519 2.04713C13.0821 2.67701 13.581 3.41772 13.9487 4.26926C14.3162 5.12081 14.5 6.03062 14.5 6.99871C14.5 7.96692 14.3163 8.87698 13.9488 9.72889C13.5814 10.5808 13.0827 11.3218 12.4529 11.9519C11.823 12.5821 11.0823 13.081 10.2307 13.4487C9.37919 13.8162 8.46938 14 7.50129 14ZM5.36316 12.4895L6.44576 10.0238C5.98585 9.86147 5.58888 9.60977 5.25484 9.26874C4.92081 8.92758 4.66598 8.52747 4.49037 8.06842L1.99634 9.1C2.28359 9.88596 2.72195 10.5737 3.31142 11.1632C3.90089 11.7526 4.58481 12.1947 5.36316 12.4895ZM4.49037 5.93158C4.65665 5.47253 4.90816 5.07555 5.24489 4.74066C5.58163 4.40576 5.97719 4.15567 6.43158 3.99037L5.4 1.49634C4.60937 1.79587 3.91932 2.24037 3.32984 2.82984C2.74037 3.41932 2.29587 4.10937 1.99634 4.9L4.49037 5.93158ZM7.49834 9.09724C8.08045 9.09724 8.57579 8.8935 8.98437 8.48603C9.39295 8.07855 9.59724 7.58376 9.59724 7.00166C9.59724 6.41955 9.3935 5.92421 8.98603 5.51563C8.57855 5.10705 8.08376 4.90276 7.50166 4.90276C6.91955 4.90276 6.42421 5.1065 6.01563 5.51397C5.60705 5.92145 5.40276 6.41624 5.40276 6.99834C5.40276 7.58045 5.6065 8.07579 6.01397 8.48437C6.42145 8.89295 6.91624 9.09724 7.49834 9.09724ZM9.63684 12.4895C10.4105 12.1947 11.089 11.7557 11.6724 11.1724C12.2557 10.589 12.6947 9.91053 12.9895 9.13684L10.5238 8.05424C10.368 8.50862 10.1209 8.90302 9.78274 9.23742C9.44453 9.57182 9.05203 9.82923 8.60526 10.0096L9.63684 12.4895ZM10.5096 5.89474L12.9895 4.86316C12.6947 4.08947 12.2557 3.41096 11.6724 2.82763C11.089 2.2443 10.4105 1.80526 9.63684 1.51053L8.60526 4.01303C9.04258 4.18299 9.4242 4.43051 9.75013 4.75558C10.0761 5.08053 10.3292 5.46025 10.5096 5.89474Z"
|
||||||
|
fill="currentColor"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<clipPath id="clip0_1665_1656">
|
||||||
|
<rect width="14" height="14" fill="white"
|
||||||
|
transform="translate(0.5)"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
}
|
||||||
|
|
||||||
|
export default HelpIcon;
|
||||||
@@ -1,12 +1,13 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { __ } from '@wordpress/i18n';
|
import { __ } from '@wordpress/i18n';
|
||||||
import { intersection } from 'ramda';
|
import { intersection, is } from 'ramda';
|
||||||
|
|
||||||
// store
|
// store
|
||||||
import { useStore } from '../../../../store';
|
import { useStore } from '../../../../store';
|
||||||
|
|
||||||
// components
|
// components
|
||||||
import { NavLink } from 'react-router-dom';
|
import { NavLink } from 'react-router-dom';
|
||||||
|
import HelpIcon from '../../../../icons/HelpIcon';
|
||||||
|
|
||||||
const AppSidebar = () => {
|
const AppSidebar = () => {
|
||||||
const permissions = useStore().main.getPermissions();
|
const permissions = useStore().main.getPermissions();
|
||||||
@@ -54,32 +55,39 @@ const AppSidebar = () => {
|
|||||||
id: 6,
|
id: 6,
|
||||||
enable: intersection(permissions, ['EVALUATE_APPLICATIONS']).length
|
enable: intersection(permissions, ['EVALUATE_APPLICATIONS']).length
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: __('Soccorso Istruttorio', 'gepafin'),
|
||||||
|
icon: <HelpIcon/>,
|
||||||
|
href: '/soccorso-istruttorio',
|
||||||
|
id: 7,
|
||||||
|
enable: intersection(permissions, ['EVALUATE_APPLICATIONS']).length
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: __('Gestione Utenti', 'gepafin'),
|
label: __('Gestione Utenti', 'gepafin'),
|
||||||
icon: 'pi pi-users',
|
icon: 'pi pi-users',
|
||||||
href: '/utenti',
|
href: '/utenti',
|
||||||
id: 7,
|
id: 8,
|
||||||
enable: intersection(permissions, ['VIEW_USERS', 'MANAGE_USERS']).length
|
enable: intersection(permissions, ['VIEW_USERS', 'MANAGE_USERS']).length
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: __('Configurazione', 'gepafin'),
|
label: __('Configurazione', 'gepafin'),
|
||||||
icon: 'pi pi-cog',
|
icon: 'pi pi-cog',
|
||||||
//href: '/configurazione',
|
//href: '/configurazione',
|
||||||
id: 8,
|
id: 9,
|
||||||
enable: false
|
enable: false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: __('Report e Analisi', 'gepafin'),
|
label: __('Report e Analisi', 'gepafin'),
|
||||||
icon: 'pi pi-chart-bar',
|
icon: 'pi pi-chart-bar',
|
||||||
//href: '/stats',
|
//href: '/stats',
|
||||||
id: 9,
|
id: 10,
|
||||||
enable: false
|
enable: false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: __('Log di Sistema', 'gepafin'),
|
label: __('Log di Sistema', 'gepafin'),
|
||||||
icon: 'pi pi-receipt',
|
icon: 'pi pi-receipt',
|
||||||
clickFn: () => {},
|
clickFn: () => {},
|
||||||
id: 10,
|
id: 11,
|
||||||
enable: false
|
enable: false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -91,11 +99,15 @@ const AppSidebar = () => {
|
|||||||
.map(o => <li key={o.id}>
|
.map(o => <li key={o.id}>
|
||||||
{o.href
|
{o.href
|
||||||
? <NavLink to={o.href}>
|
? <NavLink to={o.href}>
|
||||||
<i className={o.icon}></i>
|
{is(String, o.icon)
|
||||||
|
? <i className={o.icon}></i>
|
||||||
|
: o.icon}
|
||||||
<span>{o.label}</span>
|
<span>{o.label}</span>
|
||||||
</NavLink>
|
</NavLink>
|
||||||
: <button onClick={() => {}}>
|
: <button onClick={() => {}}>
|
||||||
<i className={o.icon}></i>
|
{is(String, o.icon)
|
||||||
|
? <i className={o.icon}></i>
|
||||||
|
: o.icon}
|
||||||
<span>{o.label}</span>
|
<span>{o.label}</span>
|
||||||
</button>}
|
</button>}
|
||||||
</li>)}
|
</li>)}
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect, useRef } from 'react';
|
||||||
import { __ } from '@wordpress/i18n';
|
import { __ } from '@wordpress/i18n';
|
||||||
import { useParams, useNavigate } from 'react-router-dom';
|
import { useParams, useNavigate } from 'react-router-dom';
|
||||||
import { is, isEmpty, isNil } from 'ramda';
|
import { isEmpty } from 'ramda';
|
||||||
import { classNames } from 'primereact/utils';
|
import { classNames } from 'primereact/utils';
|
||||||
|
import { klona } from 'klona';
|
||||||
|
|
||||||
// components
|
// components
|
||||||
import { Button } from 'primereact/button';
|
import { Button } from 'primereact/button';
|
||||||
@@ -15,6 +16,8 @@ import FormsService from '../../service/forms-service';
|
|||||||
import { storeSet } from '../../store';
|
import { storeSet } from '../../store';
|
||||||
import set404FromErrorResponse from '../../helpers/set404FromErrorResponse';
|
import set404FromErrorResponse from '../../helpers/set404FromErrorResponse';
|
||||||
import BandoService from '../../service/bando-service';
|
import BandoService from '../../service/bando-service';
|
||||||
|
import uniqid from '../../helpers/uniqid';
|
||||||
|
import { Toast } from 'primereact/toast';
|
||||||
|
|
||||||
const BandoForms = () => {
|
const BandoForms = () => {
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
@@ -22,8 +25,10 @@ const BandoForms = () => {
|
|||||||
const [templates, setTemplates] = useState(null);
|
const [templates, setTemplates] = useState(null);
|
||||||
const [selectedTemplate, setSelectedTemplate] = useState(null);
|
const [selectedTemplate, setSelectedTemplate] = useState(null);
|
||||||
const [selectedForm, setSelectedForm] = useState(null);
|
const [selectedForm, setSelectedForm] = useState(null);
|
||||||
|
const [selectedForDuplicateForm, setSelectedForDuplicateForm] = useState(null);
|
||||||
const [forms, setForms] = useState([]);
|
const [forms, setForms] = useState([]);
|
||||||
const [bandoStatus, setBandoStatus] = useState('');
|
const [bandoStatus, setBandoStatus] = useState('');
|
||||||
|
const toast = useRef(null);
|
||||||
|
|
||||||
const doCreateNewForm = () => {
|
const doCreateNewForm = () => {
|
||||||
navigate(`/bandi/${id}/forms/new`);
|
navigate(`/bandi/${id}/forms/new`);
|
||||||
@@ -43,10 +48,73 @@ const BandoForms = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const goToEditFormFromTemplate = () => {
|
const doDuplicateForm = () => {
|
||||||
console.log('goToEditFormFromTemplate', selectedTemplate)
|
const selectedFormArr = forms.filter(o => o.value === selectedForDuplicateForm);
|
||||||
//navigate(`/bandi/${id}`);
|
|
||||||
|
if (!isEmpty(selectedFormArr)) {
|
||||||
|
storeSet.main.setAsyncRequest();
|
||||||
|
FormsService.getFormById(selectedForDuplicateForm, getFormCallback, errGetFormCallbacks);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getFormCallback = (data) => {
|
||||||
|
if (data.status === 'SUCCESS') {
|
||||||
|
const newLabel = `${data.data.label} (copy)`;
|
||||||
|
|
||||||
|
const formData = {
|
||||||
|
label: newLabel,
|
||||||
|
content: data.data.content.map(o => ({
|
||||||
|
...o,
|
||||||
|
id: uniqid()
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
FormsService.createFormForCall(
|
||||||
|
id,
|
||||||
|
formData,
|
||||||
|
formCreateCallback,
|
||||||
|
errFormCreateCallback
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const errGetFormCallbacks = (data) => {
|
||||||
|
set404FromErrorResponse(data);
|
||||||
|
storeSet.main.unsetAsyncRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
const formCreateCallback = (data) => {
|
||||||
|
if (data.status === 'SUCCESS') {
|
||||||
|
storeSet.main.unsetAsyncRequest();
|
||||||
|
|
||||||
|
if (toast.current) {
|
||||||
|
toast.current.show({
|
||||||
|
severity: 'success',
|
||||||
|
summary: '',
|
||||||
|
detail: __('Il form è stato aggiornato corretamente!', 'gepafin')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
navigate(`/bandi/${id}/forms/${data.data.id}`);
|
||||||
|
}, 1000)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const errFormCreateCallback = (data) => {
|
||||||
|
storeSet.main.unsetAsyncRequest();
|
||||||
|
if (toast.current) {
|
||||||
|
toast.current.show({
|
||||||
|
severity: 'error',
|
||||||
|
summary: '',
|
||||||
|
detail: data.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*const goToEditFormFromTemplate = () => {
|
||||||
|
console.log('goToEditFormFromTemplate', selectedTemplate)
|
||||||
|
}*/
|
||||||
|
|
||||||
const getCallback = (data) => {
|
const getCallback = (data) => {
|
||||||
if (data.status === 'SUCCESS') {
|
if (data.status === 'SUCCESS') {
|
||||||
@@ -62,7 +130,7 @@ const BandoForms = () => {
|
|||||||
|
|
||||||
const getFormsCallback = (data) => {
|
const getFormsCallback = (data) => {
|
||||||
if (data.status === 'SUCCESS') {
|
if (data.status === 'SUCCESS') {
|
||||||
const forms = data.data.map(o => ({label: o.label, value: o.id}))
|
const forms = data.data.map(o => ({ label: o.label, value: o.id }))
|
||||||
setForms(forms);
|
setForms(forms);
|
||||||
}
|
}
|
||||||
storeSet.main.unsetAsyncRequest();
|
storeSet.main.unsetAsyncRequest();
|
||||||
@@ -78,7 +146,7 @@ const BandoForms = () => {
|
|||||||
const bandoId = !isNaN(parsed) ? parsed : 0;
|
const bandoId = !isNaN(parsed) ? parsed : 0;
|
||||||
|
|
||||||
setTemplates([
|
setTemplates([
|
||||||
{label: "Form template", value: 11}
|
{ label: 'Form template', value: 11 }
|
||||||
])
|
])
|
||||||
|
|
||||||
storeSet.main.setAsyncRequest();
|
storeSet.main.setAsyncRequest();
|
||||||
@@ -96,6 +164,7 @@ const BandoForms = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="appPage__spacer"></div>
|
<div className="appPage__spacer"></div>
|
||||||
|
<Toast ref={toast} />
|
||||||
|
|
||||||
<div className="appPage__content">
|
<div className="appPage__content">
|
||||||
|
|
||||||
@@ -124,16 +193,32 @@ const BandoForms = () => {
|
|||||||
<div className="appPageSection__withBorder">
|
<div className="appPageSection__withBorder">
|
||||||
<h2>{__('Crea un nuovo Form da Zero', 'gepafin')}</h2>
|
<h2>{__('Crea un nuovo Form da Zero', 'gepafin')}</h2>
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<p>{__('Inizia con un form completamente vuoto e personalizzabil', 'gepafin')}</p>
|
<p>{__('Inizia con un form completamente vuoto e personalizzabile', 'gepafin')}</p>
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
disabled={'PUBLISH' === bandoStatus}
|
disabled={'PUBLISH' === bandoStatus}
|
||||||
onClick={doCreateNewForm}
|
onClick={doCreateNewForm}
|
||||||
label={__('Crea form', 'gepafin')}/>
|
label={__('Crea form', 'gepafin')}/>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="row">
|
||||||
|
<p>{__('Duplica il form creato in precedenza', 'gepafin')}</p>
|
||||||
|
<Dropdown
|
||||||
|
id="form"
|
||||||
|
disabled={isEmpty(forms)}
|
||||||
|
value={selectedForDuplicateForm}
|
||||||
|
onChange={(e) => setSelectedForDuplicateForm(e.value)}
|
||||||
|
options={forms}
|
||||||
|
optionLabel="label"
|
||||||
|
placeholder={__('Seleziona form', 'gepafin')}/>
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
disabled={'PUBLISH' === bandoStatus || isEmpty(forms)}
|
||||||
|
onClick={doDuplicateForm}
|
||||||
|
label={__('Duplicare', 'gepafin')}/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={classNames(["appPageSection__withBorder", (isEmpty(forms) ? 'disabled' : '')])}>
|
<div className={classNames(['appPageSection__withBorder', (isEmpty(forms) ? 'disabled' : '')])}>
|
||||||
<h2>{__('Modifica form esistente', 'gepafin')}</h2>
|
<h2>{__('Modifica form esistente', 'gepafin')}</h2>
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<p>{__('Continua a lavorare su un form precedentemente salvato', 'gepafin')}</p>
|
<p>{__('Continua a lavorare su un form precedentemente salvato', 'gepafin')}</p>
|
||||||
|
|||||||
@@ -50,7 +50,6 @@ const PreInstructorDomandeTable = () => {
|
|||||||
const getFormattedData = (data) => {
|
const getFormattedData = (data) => {
|
||||||
return data.map((d) => {
|
return data.map((d) => {
|
||||||
d.callEndDate = is(String, d.callEndDate) ? new Date(d.callEndDate) : (d.callEndDate ? d.callEndDate : '');
|
d.callEndDate = is(String, d.callEndDate) ? new Date(d.callEndDate) : (d.callEndDate ? d.callEndDate : '');
|
||||||
d.updatedDate = is(String, d.updatedDate) ? new Date(d.updatedDate) : (d.updatedDate ? d.updatedDate : '');
|
|
||||||
d.submissionDate = is(String, d.submissionDate) ? new Date(d.submissionDate) : (d.submissionDate ? d.submissionDate : '');
|
d.submissionDate = is(String, d.submissionDate) ? new Date(d.submissionDate) : (d.submissionDate ? d.submissionDate : '');
|
||||||
return d;
|
return d;
|
||||||
});
|
});
|
||||||
@@ -89,7 +88,7 @@ const PreInstructorDomandeTable = () => {
|
|||||||
operator: FilterOperator.AND,
|
operator: FilterOperator.AND,
|
||||||
constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }]
|
constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }]
|
||||||
},
|
},
|
||||||
updatedDate : {
|
callEndDate : {
|
||||||
operator: FilterOperator.AND,
|
operator: FilterOperator.AND,
|
||||||
constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }]
|
constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }]
|
||||||
}
|
}
|
||||||
@@ -114,8 +113,7 @@ const PreInstructorDomandeTable = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const dateEndBodyTemplate = (rowData) => {
|
const dateEndBodyTemplate = (rowData) => {
|
||||||
//return formatDate(rowData.callEndDate);
|
return formatDate(rowData.callEndDate);
|
||||||
return '';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const dateFilterTemplate = (options) => {
|
const dateFilterTemplate = (options) => {
|
||||||
@@ -156,7 +154,7 @@ const PreInstructorDomandeTable = () => {
|
|||||||
<Column field="callName" header={__('Bando', 'gepafin')}
|
<Column field="callName" header={__('Bando', 'gepafin')}
|
||||||
filter filterPlaceholder={__('Cerca', 'gepafin')}
|
filter filterPlaceholder={__('Cerca', 'gepafin')}
|
||||||
style={{ minWidth: '12rem' }}/>
|
style={{ minWidth: '12rem' }}/>
|
||||||
<Column header={__('Data Ricezione', 'gepafin')} filterField="modifiedDate" dataType="date"
|
<Column header={__('Data Ricezione', 'gepafin')} filterField="submissionDate" dataType="date"
|
||||||
style={{ minWidth: '10rem' }}
|
style={{ minWidth: '10rem' }}
|
||||||
body={dateAppliedBodyTemplate} filter filterElement={dateFilterTemplate}/>
|
body={dateAppliedBodyTemplate} filter filterElement={dateFilterTemplate}/>
|
||||||
<Column header={__('Scadenza', 'gepafin')} filterField="callEndDate" dataType="date"
|
<Column header={__('Scadenza', 'gepafin')} filterField="callEndDate" dataType="date"
|
||||||
|
|||||||
@@ -1,60 +1,69 @@
|
|||||||
import React, { useState, useEffect, useRef } from 'react';
|
import React, { useState, useEffect, useRef } from 'react';
|
||||||
import { __, sprintf } from '@wordpress/i18n';
|
import { __, sprintf } from '@wordpress/i18n';
|
||||||
import { useNavigate, useParams } from 'react-router-dom';
|
import { useNavigate, useParams } from 'react-router-dom';
|
||||||
import { is, isEmpty, isNil } from 'ramda';
|
import { is, isEmpty, isNil, sum, pathOr } from 'ramda';
|
||||||
|
import { klona } from 'klona';
|
||||||
|
import { wrap } from 'object-path-immutable';
|
||||||
|
|
||||||
// store
|
// store
|
||||||
import { storeSet, useStore } from '../../store';
|
import { storeSet, useStore } from '../../store';
|
||||||
|
|
||||||
|
// api
|
||||||
|
import ApplicationEvaluationService from '../../service/application-evaluation-service';
|
||||||
|
|
||||||
// tools
|
// tools
|
||||||
//import getNumberWithCurrency from '../../helpers/getNumberWithCurrency';
|
import set404FromErrorResponse from '../../helpers/set404FromErrorResponse';
|
||||||
//import getDateFromISOstring from '../../helpers/getDateFromISOstring';
|
import getBandoLabel from '../../helpers/getBandoLabel';
|
||||||
|
import getDateFromISOstring from '../../helpers/getDateFromISOstring';
|
||||||
|
|
||||||
// components
|
// components
|
||||||
import { Skeleton } from 'primereact/skeleton';
|
import { Skeleton } from 'primereact/skeleton';
|
||||||
import { Button } from 'primereact/button';
|
import { Button } from 'primereact/button';
|
||||||
import { Messages } from 'primereact/messages';
|
|
||||||
import { Tag } from 'primereact/tag';
|
import { Tag } from 'primereact/tag';
|
||||||
import { Checkbox } from 'primereact/checkbox';
|
import { Checkbox } from 'primereact/checkbox';
|
||||||
import { Editor } from 'primereact/editor';
|
import { Editor } from 'primereact/editor';
|
||||||
|
import { InputNumber } from 'primereact/inputnumber';
|
||||||
|
import BlockingOverlay from '../../components/BlockingOverlay';
|
||||||
|
import { Toast } from 'primereact/toast';
|
||||||
|
import HelpIcon from '../../icons/HelpIcon';
|
||||||
|
|
||||||
const DomandaEdit = () => {
|
const DomandaEditPreInstructor = () => {
|
||||||
const isAsyncRequest = useStore().main.isAsyncRequest();
|
const isAsyncRequest = useStore().main.isAsyncRequest();
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [data, setData] = useState({});
|
const [data, setData] = useState({});
|
||||||
const [message, setMessage] = useState('');
|
const [message, setMessage] = useState('');
|
||||||
const pageMsgs = useRef(null);
|
const [isAdmissible, setIsAdmissible] = useState(false);
|
||||||
|
const toast = useRef(null);
|
||||||
|
|
||||||
const goToEvaluationsPage = () => {
|
const goToEvaluationsPage = () => {
|
||||||
navigate('/domande');
|
navigate('/domande');
|
||||||
}
|
}
|
||||||
|
|
||||||
/*const getCallback = (data) => {
|
const getCallback = (data) => {
|
||||||
if (data.status === 'SUCCESS') {
|
if (data.status === 'SUCCESS') {
|
||||||
setData(getFormattedBandiData(data.data));
|
setData(getFormattedData(data.data));
|
||||||
}
|
}
|
||||||
storeSet.main.unsetAsyncRequest();
|
storeSet.main.unsetAsyncRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
const errGetCallback = (data) => {
|
const errGetCallback = (data) => {
|
||||||
if (pageMsgs.current && data.message) {
|
if (toast.current && data.message) {
|
||||||
pageMsgs.current.show([
|
toast.current.show({
|
||||||
{
|
severity: 'error',
|
||||||
sticky: true, severity: 'error', summary: '',
|
summary: '',
|
||||||
detail: data.message,
|
detail: data.message
|
||||||
closable: true
|
});
|
||||||
}
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
set404FromErrorResponse(data);
|
set404FromErrorResponse(data);
|
||||||
storeSet.main.unsetAsyncRequest();
|
storeSet.main.unsetAsyncRequest();
|
||||||
}*/
|
}
|
||||||
|
|
||||||
/*const getFormattedBandiData = (data) => {
|
const getFormattedData = (data) => {
|
||||||
data.dates = data.dates.map(v => is(String, v) ? new Date(v) : (v ? v : ''));
|
data.submissionDate = is(String, data.submissionDate) ? new Date(data.submissionDate) : (data.submissionDate ? data.submissionDate : '');
|
||||||
|
data.evaluationDate = is(String, data.evaluationDate) ? new Date(data.evaluationDate) : (data.evaluationDate ? data.evaluationDate : '');
|
||||||
return data;
|
return data;
|
||||||
};*/
|
};
|
||||||
|
|
||||||
const renderHeader = () => {
|
const renderHeader = () => {
|
||||||
return (
|
return (
|
||||||
@@ -76,58 +85,69 @@ const DomandaEdit = () => {
|
|||||||
|
|
||||||
const header = renderHeader();
|
const header = renderHeader();
|
||||||
|
|
||||||
|
const updateEvaluationValue = (value, path, maxValue) => {
|
||||||
|
let finalValue = value;
|
||||||
|
|
||||||
|
if (maxValue) {
|
||||||
|
finalValue = value > maxValue ? maxValue : value;
|
||||||
|
}
|
||||||
|
|
||||||
|
const newData = wrap(data).set(path.split('.'), finalValue).value();
|
||||||
|
setData(newData);
|
||||||
|
}
|
||||||
|
|
||||||
|
const doSaveDraft = () => {
|
||||||
|
const formData = {
|
||||||
|
criteria: klona(data.criteria),
|
||||||
|
checklist: klona(data.checklist),
|
||||||
|
files: klona(data.files),
|
||||||
|
note: data.note
|
||||||
|
}
|
||||||
|
ApplicationEvaluationService.updateEvaluation(id, formData, updateCallback, errUpdateCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateCallback = (data) => {
|
||||||
|
if (data.status === 'SUCCESS') {
|
||||||
|
if (toast.current) {
|
||||||
|
toast.current.show({
|
||||||
|
severity: 'success',
|
||||||
|
summary: '',
|
||||||
|
detail: data.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
storeSet.main.unsetAsyncRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
const errUpdateCallback = (data) => {
|
||||||
|
if (toast.current && data.message) {
|
||||||
|
toast.current.show({
|
||||||
|
severity: 'error',
|
||||||
|
summary: '',
|
||||||
|
detail: data.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
set404FromErrorResponse(data);
|
||||||
|
storeSet.main.unsetAsyncRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const maxScore = pathOr(0, ['minScore'], data);
|
||||||
|
const criteria = pathOr([], ['criteria'], data);
|
||||||
|
const scoreSum = sum(criteria.map(o => o.score));
|
||||||
|
|
||||||
|
setIsAdmissible(scoreSum !== 0 && scoreSum >= maxScore);
|
||||||
|
}, [data]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const parsed = parseInt(id)
|
const parsed = parseInt(id)
|
||||||
const entityId = !isNaN(parsed) ? parsed : 0;
|
const entityId = !isNaN(parsed) ? parsed : 0;
|
||||||
|
|
||||||
setData({
|
ApplicationEvaluationService.getEvaluationByApplId(getCallback, errGetCallback, [
|
||||||
id: 'DOM_2024_001',
|
['assignedApplicationId', entityId]
|
||||||
callTitle: 'Innovazione 2024',
|
]);
|
||||||
beneficiario: 'Azienda Alpha SRL',
|
|
||||||
createdAt: '2024-08-01',
|
|
||||||
scadenzaAt: '2024-08-05',
|
|
||||||
status: 'In Valutazione',
|
|
||||||
criteria: [
|
|
||||||
{ title: 'Innovatività del progetto', score: 25, id: 12 },
|
|
||||||
{ title: 'Innovatività del progetto2', score: 35, id: 13 },
|
|
||||||
{ title: 'Innovatività del progetto3', score: 15, id: 14 }
|
|
||||||
],
|
|
||||||
minScore: 60
|
|
||||||
});
|
|
||||||
|
|
||||||
//BandoService.getBando(entityId, getCallback, errGetCallback);
|
|
||||||
}, [id]);
|
}, [id]);
|
||||||
|
|
||||||
// TODO
|
|
||||||
const checklist = [
|
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
title: 'Requisiti di ammissibilità soddisfatti'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
title: 'Documentazione completa'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 3,
|
|
||||||
title: 'Obiettivi del progetto chiari e misurabili'
|
|
||||||
}
|
|
||||||
];
|
|
||||||
const documents = [
|
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
title: 'Doc 1'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
title: 'Bilancio ultimo esercizio Bilancio ultimo esercizio Bilancio ultimo esercizio'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 3,
|
|
||||||
title: 'Bilancio ultimo esercizio'
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="appPage">
|
<div className="appPage">
|
||||||
<div className="appPage__pageHeader">
|
<div className="appPage__pageHeader">
|
||||||
@@ -135,7 +155,8 @@ const DomandaEdit = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="appPage__spacer"></div>
|
<div className="appPage__spacer"></div>
|
||||||
<Messages ref={pageMsgs}/>
|
<Toast ref={toast}/>
|
||||||
|
<BlockingOverlay shouldDisplay={isAsyncRequest}/>
|
||||||
|
|
||||||
<div className="appPageSection__row">
|
<div className="appPageSection__row">
|
||||||
<Button
|
<Button
|
||||||
@@ -153,27 +174,27 @@ const DomandaEdit = () => {
|
|||||||
<div className="appPageSection__withBorder columns">
|
<div className="appPageSection__withBorder columns">
|
||||||
<p className="appPageSection__pMeta">
|
<p className="appPageSection__pMeta">
|
||||||
<span>{__('ID domanda', 'gepafin')}</span>
|
<span>{__('ID domanda', 'gepafin')}</span>
|
||||||
<span>{data.id}</span>
|
<span>{data.applicationId}</span>
|
||||||
</p>
|
</p>
|
||||||
<p className="appPageSection__pMeta">
|
<p className="appPageSection__pMeta">
|
||||||
<span>{__('Bando', 'gepafin')}</span>
|
<span>{__('Bando', 'gepafin')}</span>
|
||||||
<span>{data.callTitle}</span>
|
<span>{data.callName}</span>
|
||||||
</p>
|
</p>
|
||||||
<p className="appPageSection__pMeta">
|
<p className="appPageSection__pMeta">
|
||||||
<span>{__('Beneficiario', 'gepafin')}</span>
|
<span>{__('Beneficiario', 'gepafin')}</span>
|
||||||
<span>{data.beneficiario}</span>
|
<span>{data.beneficiary}</span>
|
||||||
</p>
|
</p>
|
||||||
<p className="appPageSection__pMeta">
|
<p className="appPageSection__pMeta">
|
||||||
<span>{__('Data ricezione', 'gepafin')}</span>
|
<span>{__('Data ricezione', 'gepafin')}</span>
|
||||||
<span>{data.createdAt}</span>
|
<span>{getDateFromISOstring(data.submissionDate)}</span>
|
||||||
</p>
|
</p>
|
||||||
<p className="appPageSection__pMeta">
|
<p className="appPageSection__pMeta">
|
||||||
<span>{__('Scadenza Valutazione', 'gepafin')}</span>
|
<span>{__('Scadenza Valutazione', 'gepafin')}</span>
|
||||||
<span>{data.scadenzaAt}</span>
|
<span>{getDateFromISOstring(data.callEndDate)}</span>
|
||||||
</p>
|
</p>
|
||||||
<p className="appPageSection__pMeta">
|
<p className="appPageSection__pMeta">
|
||||||
<span>{__('Stato', 'gepafin')}</span>
|
<span>{__('Stato', 'gepafin')}</span>
|
||||||
<span>{data.status}</span>
|
<span>{getBandoLabel(data.applicationStatus)}</span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -184,29 +205,63 @@ const DomandaEdit = () => {
|
|||||||
<thead className="myThead">
|
<thead className="myThead">
|
||||||
<tr>
|
<tr>
|
||||||
<th>{__('Parametro', 'gepafin')}</th>
|
<th>{__('Parametro', 'gepafin')}</th>
|
||||||
<th>{__('Punteggio', 'gepafin')}</th>
|
<th style={{ width: 200 }}>{__('Punteggio', 'gepafin')}</th>
|
||||||
<th>{__('Stato', 'gepafin')}</th>
|
<th style={{ width: 220 }}>{__('Stato', 'gepafin')}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody className="myTbody">
|
<tbody className="myTbody">
|
||||||
{data.criteria.map(o => <tr key={o.id}>
|
{data.criteria.map((o, i) => <tr key={o.id}>
|
||||||
<td>{o.title}</td>
|
<td>{o.label}</td>
|
||||||
<td>{o.score}</td>
|
<td>
|
||||||
|
<div className="p-inputgroup">
|
||||||
|
<InputNumber
|
||||||
|
placeholder={__('Punteggio', 'gepafin')}
|
||||||
|
keyfilter="int"
|
||||||
|
value={o.score}
|
||||||
|
max={o.maxScore}
|
||||||
|
onChange={(e) => updateEvaluationValue(
|
||||||
|
e.value,
|
||||||
|
`criteria.${i}.score`,
|
||||||
|
o.maxScore
|
||||||
|
)}/>
|
||||||
|
<span className="p-inputgroup-addon">
|
||||||
|
/ {o.maxScore}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div className="appPageSection__iconActions">
|
<div className="appPageSection__iconActions">
|
||||||
<Button icon="pi pi-eye" rounded outlined severity="info"
|
{!isEmpty(o.criteriaMappedFields)
|
||||||
aria-label={__('Mostra', 'gepafin')}/>
|
? <Button icon="pi pi-eye" rounded outlined severity="info"
|
||||||
|
aria-label={__('Mostra', 'gepafin')}/> : null}
|
||||||
<Button icon="pi pi-thumbs-up" rounded outlined
|
<Button icon="pi pi-thumbs-up" rounded outlined
|
||||||
|
severity={!isNil(o.valid) && o.valid ? 'success' : 'secondary'}
|
||||||
|
onClick={() => updateEvaluationValue(
|
||||||
|
true,
|
||||||
|
`criteria.${i}.valid`
|
||||||
|
)}
|
||||||
aria-label={__('Su', 'gepafin')}/>
|
aria-label={__('Su', 'gepafin')}/>
|
||||||
<Button icon="pi pi-thumbs-down" rounded outlined
|
<Button icon="pi pi-thumbs-down" rounded outlined
|
||||||
|
severity={!isNil(o.valid) && !o.valid ? 'danger' : 'secondary'}
|
||||||
|
onClick={() => updateEvaluationValue(
|
||||||
|
false,
|
||||||
|
`criteria.${i}.valid`
|
||||||
|
)}
|
||||||
aria-label={__('Giu', 'gepafin')}/>
|
aria-label={__('Giu', 'gepafin')}/>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>)}
|
</tr>)}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{__('Punteggio:', 'gepafin')}</td>
|
<td>{__('Punteggio:', 'gepafin')}</td>
|
||||||
<td>{68}</td>
|
<td>{sum(data.criteria.map(o => o.score))}</td>
|
||||||
<td><Tag icon="pi pi-check" severity="success" value={__('Ammissibile')}></Tag></td>
|
<td>
|
||||||
|
{isAdmissible
|
||||||
|
? <Tag icon="pi pi-check" severity="success"
|
||||||
|
value={__('Ammissibile')}></Tag> : null}
|
||||||
|
{!isAdmissible
|
||||||
|
? <Tag icon="pi pi-times" severity="warning"
|
||||||
|
value={__('Inammissibile')}></Tag> : null}
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
<tfoot className="myTfoot">
|
<tfoot className="myTfoot">
|
||||||
@@ -224,12 +279,15 @@ const DomandaEdit = () => {
|
|||||||
<h3>{__('Lista', 'gepafin')}</h3>
|
<h3>{__('Lista', 'gepafin')}</h3>
|
||||||
<div className="appPageSection__withBorder grey">
|
<div className="appPageSection__withBorder grey">
|
||||||
<div className="appPageSection__checklist">
|
<div className="appPageSection__checklist">
|
||||||
{checklist.map(o => <div key={o.id}>
|
{data.checklist.map((o, i) => <div key={o.id}>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
inputId={`checklist_${o.id}`}
|
inputId={`checklist_${o.id}`}
|
||||||
onChange={(e) => console.log(e.checked)}
|
onChange={(e) => updateEvaluationValue(
|
||||||
checked={false}></Checkbox>
|
e.checked,
|
||||||
<label htmlFor={`checklist_${o.id}`}>{o.title}</label>
|
`checklist.${i}.valid`
|
||||||
|
)}
|
||||||
|
checked={o.valid}></Checkbox>
|
||||||
|
<label htmlFor={`checklist_${o.id}`}>{o.label}</label>
|
||||||
</div>)}
|
</div>)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -237,10 +295,13 @@ const DomandaEdit = () => {
|
|||||||
<h3>{__('Note', 'gepafin')}</h3>
|
<h3>{__('Note', 'gepafin')}</h3>
|
||||||
<div>
|
<div>
|
||||||
<Editor
|
<Editor
|
||||||
value={message}
|
value={data.note}
|
||||||
placeholder={__('Digita qui il messagio', 'gepafin')}
|
placeholder={__('Digita qui il messagio', 'gepafin')}
|
||||||
headerTemplate={header}
|
headerTemplate={header}
|
||||||
onTextChange={(e) => setMessage(e.htmlValue)}
|
onTextChange={(e) => updateEvaluationValue(
|
||||||
|
e.htmlValue,
|
||||||
|
'note'
|
||||||
|
)}
|
||||||
style={{ height: 80 * 3, width: '100%' }}
|
style={{ height: 80 * 3, width: '100%' }}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -248,14 +309,27 @@ const DomandaEdit = () => {
|
|||||||
<div>
|
<div>
|
||||||
<h3>{__('Documenti allegati', 'gepafin')}</h3>
|
<h3>{__('Documenti allegati', 'gepafin')}</h3>
|
||||||
<ol className="appPageSection__list">
|
<ol className="appPageSection__list">
|
||||||
{documents.map(o => <li key={o.id}>
|
{data.files.map((o, i) => <li key={o.id}>
|
||||||
<span>{o.title}</span>
|
<span>{o.label}</span>
|
||||||
<div className="appPageSection__iconActions">
|
<div className="appPageSection__iconActions">
|
||||||
<Button icon="pi pi-eye" rounded outlined severity="info"
|
{o.fileDetail.length === 1
|
||||||
aria-label={__('Mostra', 'gepafin')}/>
|
? <Button icon="pi pi-eye" rounded
|
||||||
|
onClick={() => window.open(o.fileDetail[0].filePath, '_blank').focus()}
|
||||||
|
outlined severity="info"
|
||||||
|
aria-label={__('Mostra', 'gepafin')}/> : null}
|
||||||
<Button icon="pi pi-thumbs-up" rounded outlined
|
<Button icon="pi pi-thumbs-up" rounded outlined
|
||||||
|
severity={!isNil(o.valid) && o.valid ? 'success' : 'secondary'}
|
||||||
|
onClick={() => updateEvaluationValue(
|
||||||
|
true,
|
||||||
|
`files.${i}.valid`
|
||||||
|
)}
|
||||||
aria-label={__('Su', 'gepafin')}/>
|
aria-label={__('Su', 'gepafin')}/>
|
||||||
<Button icon="pi pi-thumbs-down" rounded outlined
|
<Button icon="pi pi-thumbs-down" rounded outlined
|
||||||
|
severity={!isNil(o.valid) && !o.valid ? 'danger' : 'secondary'}
|
||||||
|
onClick={() => updateEvaluationValue(
|
||||||
|
false,
|
||||||
|
`files.${i}.valid`
|
||||||
|
)}
|
||||||
aria-label={__('Giu', 'gepafin')}/>
|
aria-label={__('Giu', 'gepafin')}/>
|
||||||
</div>
|
</div>
|
||||||
</li>)}
|
</li>)}
|
||||||
@@ -278,30 +352,19 @@ const DomandaEdit = () => {
|
|||||||
label={<>
|
label={<>
|
||||||
{__('Richiedi Soccorso Istruttorio', 'gepafin')}
|
{__('Richiedi Soccorso Istruttorio', 'gepafin')}
|
||||||
<i style={{ marginLeft: 7 }}>
|
<i style={{ marginLeft: 7 }}>
|
||||||
<svg width="15" height="14" viewBox="0 0 15 14" fill="none"
|
<HelpIcon/>
|
||||||
xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<g clipPath="url(#clip0_1665_1656)">
|
|
||||||
<path
|
|
||||||
d="M7.50129 14C6.53308 14 5.62302 13.8163 4.7711 13.4488C3.91919 13.0814 3.17818 12.5827 2.54805 11.9529C1.91793 11.323 1.41903 10.5823 1.05134 9.73074C0.683781 8.87919 0.5 7.96938 0.5 7.00129C0.5 6.03308 0.683719 5.12302 1.05116 4.2711C1.4186 3.41919 1.91725 2.67818 2.54713 2.04805C3.17701 1.41793 3.91772 0.919026 4.76926 0.551342C5.62081 0.183781 6.53062 0 7.49871 0C8.46692 0 9.37698 0.183719 10.2289 0.551158C11.0808 0.918596 11.8218 1.41725 12.4519 2.04713C13.0821 2.67701 13.581 3.41772 13.9487 4.26926C14.3162 5.12081 14.5 6.03062 14.5 6.99871C14.5 7.96692 14.3163 8.87698 13.9488 9.72889C13.5814 10.5808 13.0827 11.3218 12.4529 11.9519C11.823 12.5821 11.0823 13.081 10.2307 13.4487C9.37919 13.8162 8.46938 14 7.50129 14ZM5.36316 12.4895L6.44576 10.0238C5.98585 9.86147 5.58888 9.60977 5.25484 9.26874C4.92081 8.92758 4.66598 8.52747 4.49037 8.06842L1.99634 9.1C2.28359 9.88596 2.72195 10.5737 3.31142 11.1632C3.90089 11.7526 4.58481 12.1947 5.36316 12.4895ZM4.49037 5.93158C4.65665 5.47253 4.90816 5.07555 5.24489 4.74066C5.58163 4.40576 5.97719 4.15567 6.43158 3.99037L5.4 1.49634C4.60937 1.79587 3.91932 2.24037 3.32984 2.82984C2.74037 3.41932 2.29587 4.10937 1.99634 4.9L4.49037 5.93158ZM7.49834 9.09724C8.08045 9.09724 8.57579 8.8935 8.98437 8.48603C9.39295 8.07855 9.59724 7.58376 9.59724 7.00166C9.59724 6.41955 9.3935 5.92421 8.98603 5.51563C8.57855 5.10705 8.08376 4.90276 7.50166 4.90276C6.91955 4.90276 6.42421 5.1065 6.01563 5.51397C5.60705 5.92145 5.40276 6.41624 5.40276 6.99834C5.40276 7.58045 5.6065 8.07579 6.01397 8.48437C6.42145 8.89295 6.91624 9.09724 7.49834 9.09724ZM9.63684 12.4895C10.4105 12.1947 11.089 11.7557 11.6724 11.1724C12.2557 10.589 12.6947 9.91053 12.9895 9.13684L10.5238 8.05424C10.368 8.50862 10.1209 8.90302 9.78274 9.23742C9.44453 9.57182 9.05203 9.82923 8.60526 10.0096L9.63684 12.4895ZM10.5096 5.89474L12.9895 4.86316C12.6947 4.08947 12.2557 3.41096 11.6724 2.82763C11.089 2.2443 10.4105 1.80526 9.63684 1.51053L8.60526 4.01303C9.04258 4.18299 9.4242 4.43051 9.75013 4.75558C10.0761 5.08053 10.3292 5.46025 10.5096 5.89474Z"
|
|
||||||
fill="#3B7C43"/>
|
|
||||||
</g>
|
|
||||||
<defs>
|
|
||||||
<clipPath id="clip0_1665_1656">
|
|
||||||
<rect width="14" height="14" fill="white"
|
|
||||||
transform="translate(0.5)"/>
|
|
||||||
</clipPath>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
||||||
</i>
|
</i>
|
||||||
</>}
|
</>}
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
|
onClick={doSaveDraft}
|
||||||
outlined
|
outlined
|
||||||
label={__('Salva Bozza Valutazione', 'gepafin')}
|
label={__('Salva Bozza Valutazione', 'gepafin')}
|
||||||
icon="pi pi-save" iconPos="right"/>
|
icon="pi pi-save" iconPos="right"/>
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
|
disabled={!isAdmissible}
|
||||||
label={__('Approva Domanda', 'gepafin')}
|
label={__('Approva Domanda', 'gepafin')}
|
||||||
icon="pi pi-check" iconPos="right"/>
|
icon="pi pi-check" iconPos="right"/>
|
||||||
<Button
|
<Button
|
||||||
@@ -327,4 +390,4 @@ const DomandaEdit = () => {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default DomandaEdit;
|
export default DomandaEditPreInstructor;
|
||||||
@@ -84,7 +84,7 @@ const AllDomandeTable = ({ openDialogFn }) => {
|
|||||||
operator: FilterOperator.AND,
|
operator: FilterOperator.AND,
|
||||||
constraints: [{ value: null, matchMode: FilterMatchMode.STARTS_WITH }]
|
constraints: [{ value: null, matchMode: FilterMatchMode.STARTS_WITH }]
|
||||||
},
|
},
|
||||||
appliedDate: {
|
submissionDate: {
|
||||||
operator: FilterOperator.AND,
|
operator: FilterOperator.AND,
|
||||||
constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }]
|
constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }]
|
||||||
},
|
},
|
||||||
@@ -152,7 +152,7 @@ const AllDomandeTable = ({ openDialogFn }) => {
|
|||||||
filter filterPlaceholder={__('Cerca', 'gepafin')}
|
filter filterPlaceholder={__('Cerca', 'gepafin')}
|
||||||
style={{ minWidth: '12rem' }}/>
|
style={{ minWidth: '12rem' }}/>
|
||||||
<Column header={__('Data Ricezione', 'gepafin')}
|
<Column header={__('Data Ricezione', 'gepafin')}
|
||||||
filterField="modifiedDate" dataType="date"
|
filterField="submissionDate" dataType="date"
|
||||||
style={{ minWidth: '10rem' }}
|
style={{ minWidth: '10rem' }}
|
||||||
body={dateAppliedBodyTemplate} filter filterElement={dateFilterTemplate}/>
|
body={dateAppliedBodyTemplate} filter filterElement={dateFilterTemplate}/>
|
||||||
<Column header={__('Scadenza', 'gepafin')}
|
<Column header={__('Scadenza', 'gepafin')}
|
||||||
|
|||||||
385
src/pages/SoccorsoEditPreInstructor/index.js
Normal file
385
src/pages/SoccorsoEditPreInstructor/index.js
Normal file
@@ -0,0 +1,385 @@
|
|||||||
|
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 { klona } from 'klona';
|
||||||
|
import { wrap } from 'object-path-immutable';
|
||||||
|
|
||||||
|
// store
|
||||||
|
import { storeSet, useStore } from '../../store';
|
||||||
|
|
||||||
|
// api
|
||||||
|
import ApplicationEvaluationService from '../../service/application-evaluation-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 BlockingOverlay from '../../components/BlockingOverlay';
|
||||||
|
import { Toast } from 'primereact/toast';
|
||||||
|
import HelpIcon from '../../icons/HelpIcon';
|
||||||
|
|
||||||
|
const SoccorsoEditPreInstructor = () => {
|
||||||
|
const isAsyncRequest = useStore().main.isAsyncRequest();
|
||||||
|
const { id, soccorsoId } = useParams();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const [data, setData] = useState({});
|
||||||
|
const toast = useRef(null);
|
||||||
|
|
||||||
|
const goToEvaluationPage = () => {
|
||||||
|
//navigate('/domande');
|
||||||
|
}
|
||||||
|
|
||||||
|
const getCallback = (data) => {
|
||||||
|
if (data.status === 'SUCCESS') {
|
||||||
|
setData(getFormattedData(data.data));
|
||||||
|
}
|
||||||
|
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 getFormattedData = (data) => {
|
||||||
|
data.submissionDate = is(String, data.submissionDate) ? new Date(data.submissionDate) : (data.submissionDate ? data.submissionDate : '');
|
||||||
|
data.evaluationDate = is(String, data.evaluationDate) ? new Date(data.evaluationDate) : (data.evaluationDate ? data.evaluationDate : '');
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderHeader = () => {
|
||||||
|
return (
|
||||||
|
<span className="ql-formats">
|
||||||
|
<button className="ql-bold" aria-label="Bold"></button>
|
||||||
|
<button className="ql-italic" aria-label="Italic"></button>
|
||||||
|
<button className="ql-underline" aria-label="Underline"></button>
|
||||||
|
<button className="ql-link" aria-label="Link"></button>
|
||||||
|
<button className="ql-list" value="ordered"></button>
|
||||||
|
<button className="ql-header" value="2"></button>
|
||||||
|
<button className="ql-header" value="3"></button>
|
||||||
|
<button className="ql-blockquote"></button>
|
||||||
|
<button className="ql-list" value="bullet"></button>
|
||||||
|
<button className="ql-indent" value="-1"></button>
|
||||||
|
<button className="ql-indent" value="+1"></button>
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const header = renderHeader();
|
||||||
|
|
||||||
|
const updateEvaluationValue = (value, path, maxValue) => {
|
||||||
|
let finalValue = value;
|
||||||
|
|
||||||
|
if (maxValue) {
|
||||||
|
finalValue = value > maxValue ? maxValue : value;
|
||||||
|
}
|
||||||
|
|
||||||
|
const newData = wrap(data).set(path.split('.'), finalValue).value();
|
||||||
|
setData(newData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*const doSaveDraft = () => {
|
||||||
|
const formData = {
|
||||||
|
criteria: klona(data.criteria),
|
||||||
|
checklist: klona(data.checklist),
|
||||||
|
files: klona(data.files),
|
||||||
|
note: data.note
|
||||||
|
}
|
||||||
|
ApplicationEvaluationService.updateEvaluation(id, formData, updateCallback, errUpdateCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateCallback = (data) => {
|
||||||
|
if (data.status === 'SUCCESS') {
|
||||||
|
if (toast.current) {
|
||||||
|
toast.current.show({
|
||||||
|
severity: 'success',
|
||||||
|
summary: '',
|
||||||
|
detail: data.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
storeSet.main.unsetAsyncRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
const errUpdateCallback = (data) => {
|
||||||
|
if (toast.current && data.message) {
|
||||||
|
toast.current.show({
|
||||||
|
severity: 'error',
|
||||||
|
summary: '',
|
||||||
|
detail: data.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
set404FromErrorResponse(data);
|
||||||
|
storeSet.main.unsetAsyncRequest();
|
||||||
|
}*/
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const parsed = parseInt(id)
|
||||||
|
const assignedCallId = !isNaN(parsed) ? parsed : 0;
|
||||||
|
const parsedSoccorsoId = parseInt(soccorsoId)
|
||||||
|
const soccorsoEntityId = !isNaN(parsedSoccorsoId) ? parsedSoccorsoId : 0;
|
||||||
|
|
||||||
|
ApplicationEvaluationService.getEvaluationByApplId(getCallback, errGetCallback, [
|
||||||
|
['assignedApplicationId', assignedCallId]
|
||||||
|
]);
|
||||||
|
}, [id, soccorsoId]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="appPage">
|
||||||
|
<div className="appPage__pageHeader">
|
||||||
|
<h1>{__('Soccorso Istruttorio - Dettagli', 'gepafin')}</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="appPage__spacer"></div>
|
||||||
|
<Toast ref={toast}/>
|
||||||
|
<BlockingOverlay shouldDisplay={isAsyncRequest}/>
|
||||||
|
|
||||||
|
<div className="appPageSection__row">
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
outlined
|
||||||
|
onClick={goToEvaluationPage}
|
||||||
|
label={__('Indietro', 'gepafin')}
|
||||||
|
icon="pi pi-arrow-left" iconPos="left"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="appPage__spacer"></div>
|
||||||
|
|
||||||
|
{!isAsyncRequest && !isEmpty(data)
|
||||||
|
? <div className="appPage__content">
|
||||||
|
<div className="appPageSection__withBorder columns">
|
||||||
|
<p className="appPageSection__pMeta">
|
||||||
|
<span>{__('ID domanda', 'gepafin')}</span>
|
||||||
|
<span>{data.applicationId}</span>
|
||||||
|
</p>
|
||||||
|
<p className="appPageSection__pMeta">
|
||||||
|
<span>{__('Bando', 'gepafin')}</span>
|
||||||
|
<span>{data.callName}</span>
|
||||||
|
</p>
|
||||||
|
<p className="appPageSection__pMeta">
|
||||||
|
<span>{__('Beneficiario', 'gepafin')}</span>
|
||||||
|
<span>{data.beneficiary}</span>
|
||||||
|
</p>
|
||||||
|
<p className="appPageSection__pMeta">
|
||||||
|
<span>{__('Data ricezione', 'gepafin')}</span>
|
||||||
|
<span>{getDateFromISOstring(data.submissionDate)}</span>
|
||||||
|
</p>
|
||||||
|
<p className="appPageSection__pMeta">
|
||||||
|
<span>{__('Scadenza Valutazione', 'gepafin')}</span>
|
||||||
|
<span>{getDateFromISOstring(data.callEndDate)}</span>
|
||||||
|
</p>
|
||||||
|
<p className="appPageSection__pMeta">
|
||||||
|
<span>{__('Stato', 'gepafin')}</span>
|
||||||
|
<span>{getBandoLabel(data.applicationStatus)}</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="appPageSection">
|
||||||
|
<h2>{__('Punteggi di valutazione', 'gepafin')}</h2>
|
||||||
|
{data.criteria
|
||||||
|
? <table className="myTable">
|
||||||
|
<thead className="myThead">
|
||||||
|
<tr>
|
||||||
|
<th>{__('Parametro', 'gepafin')}</th>
|
||||||
|
<th style={{ width: 200 }}>{__('Punteggio', 'gepafin')}</th>
|
||||||
|
<th style={{ width: 220 }}>{__('Stato', 'gepafin')}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody className="myTbody">
|
||||||
|
{data.criteria.map((o, i) => <tr key={o.id}>
|
||||||
|
<td>{o.label}</td>
|
||||||
|
<td>
|
||||||
|
<div className="p-inputgroup">
|
||||||
|
<InputNumber
|
||||||
|
placeholder={__('Punteggio', 'gepafin')}
|
||||||
|
keyfilter="int"
|
||||||
|
value={o.score}
|
||||||
|
max={o.maxScore}
|
||||||
|
onChange={(e) => updateEvaluationValue(
|
||||||
|
e.value,
|
||||||
|
`criteria.${i}.score`,
|
||||||
|
o.maxScore
|
||||||
|
)}/>
|
||||||
|
<span className="p-inputgroup-addon">
|
||||||
|
/ {o.maxScore}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div className="appPageSection__iconActions">
|
||||||
|
{!isEmpty(o.criteriaMappedFields)
|
||||||
|
? <Button icon="pi pi-eye" rounded outlined severity="info"
|
||||||
|
aria-label={__('Mostra', 'gepafin')}/> : null}
|
||||||
|
<Button icon="pi pi-thumbs-up" rounded outlined
|
||||||
|
severity={!isNil(o.valid) && o.valid ? 'success' : 'secondary'}
|
||||||
|
onClick={() => updateEvaluationValue(
|
||||||
|
true,
|
||||||
|
`criteria.${i}.valid`
|
||||||
|
)}
|
||||||
|
aria-label={__('Su', 'gepafin')}/>
|
||||||
|
<Button icon="pi pi-thumbs-down" rounded outlined
|
||||||
|
severity={!isNil(o.valid) && !o.valid ? 'danger' : 'secondary'}
|
||||||
|
onClick={() => updateEvaluationValue(
|
||||||
|
false,
|
||||||
|
`criteria.${i}.valid`
|
||||||
|
)}
|
||||||
|
aria-label={__('Giu', 'gepafin')}/>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>)}
|
||||||
|
<tr>
|
||||||
|
<td>{__('Punteggio:', 'gepafin')}</td>
|
||||||
|
<td>{sum(data.criteria.map(o => o.score))}</td>
|
||||||
|
<td>
|
||||||
|
{isAdmissible
|
||||||
|
? <Tag icon="pi pi-check" severity="success"
|
||||||
|
value={__('Ammissibile')}></Tag> : null}
|
||||||
|
{!isAdmissible
|
||||||
|
? <Tag icon="pi pi-times" severity="warning"
|
||||||
|
value={__('Inammissibile')}></Tag> : null}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
<tfoot className="myTfoot">
|
||||||
|
<tr>
|
||||||
|
<td colSpan="3">{sprintf(__('Punteggio minimo per l\'ammissione: %d'), data.minScore)}</td>
|
||||||
|
</tr>
|
||||||
|
</tfoot>
|
||||||
|
</table> : null}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="appPageSection">
|
||||||
|
<h2>{__('Checklist Valutazione', 'gepafin')}</h2>
|
||||||
|
<div className="appPageSection columns">
|
||||||
|
<div>
|
||||||
|
<h3>{__('Lista', 'gepafin')}</h3>
|
||||||
|
<div className="appPageSection__withBorder grey">
|
||||||
|
<div className="appPageSection__checklist">
|
||||||
|
{data.checklist.map((o, i) => <div key={o.id}>
|
||||||
|
<Checkbox
|
||||||
|
inputId={`checklist_${o.id}`}
|
||||||
|
onChange={(e) => updateEvaluationValue(
|
||||||
|
e.checked,
|
||||||
|
`checklist.${i}.valid`
|
||||||
|
)}
|
||||||
|
checked={o.valid}></Checkbox>
|
||||||
|
<label htmlFor={`checklist_${o.id}`}>{o.label}</label>
|
||||||
|
</div>)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3>{__('Note', 'gepafin')}</h3>
|
||||||
|
<div>
|
||||||
|
<Editor
|
||||||
|
value={data.note}
|
||||||
|
placeholder={__('Digita qui il messagio', 'gepafin')}
|
||||||
|
headerTemplate={header}
|
||||||
|
onTextChange={(e) => updateEvaluationValue(
|
||||||
|
e.htmlValue,
|
||||||
|
'note'
|
||||||
|
)}
|
||||||
|
style={{ height: 80 * 3, width: '100%' }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h3>{__('Documenti allegati', 'gepafin')}</h3>
|
||||||
|
<ol className="appPageSection__list">
|
||||||
|
{data.files.map((o, i) => <li key={o.id}>
|
||||||
|
<span>{o.label}</span>
|
||||||
|
<div className="appPageSection__iconActions">
|
||||||
|
{o.fileDetail.length === 1
|
||||||
|
? <Button icon="pi pi-eye" rounded
|
||||||
|
onClick={() => window.open(o.fileDetail[0].filePath, '_blank').focus()}
|
||||||
|
outlined severity="info"
|
||||||
|
aria-label={__('Mostra', 'gepafin')}/> : null}
|
||||||
|
<Button icon="pi pi-thumbs-up" rounded outlined
|
||||||
|
severity={!isNil(o.valid) && o.valid ? 'success' : 'secondary'}
|
||||||
|
onClick={() => updateEvaluationValue(
|
||||||
|
true,
|
||||||
|
`files.${i}.valid`
|
||||||
|
)}
|
||||||
|
aria-label={__('Su', 'gepafin')}/>
|
||||||
|
<Button icon="pi pi-thumbs-down" rounded outlined
|
||||||
|
severity={!isNil(o.valid) && !o.valid ? 'danger' : 'secondary'}
|
||||||
|
onClick={() => updateEvaluationValue(
|
||||||
|
false,
|
||||||
|
`files.${i}.valid`
|
||||||
|
)}
|
||||||
|
aria-label={__('Giu', 'gepafin')}/>
|
||||||
|
</div>
|
||||||
|
</li>)}
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="appPage__spacer"></div>
|
||||||
|
|
||||||
|
<div className="appPageSection__hr">
|
||||||
|
<span>{__('Azioni rapide', 'gepafin')}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="appPageSection">
|
||||||
|
<div className="appPageSection__actions">
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
outlined
|
||||||
|
label={<>
|
||||||
|
{__('Richiedi Soccorso Istruttorio', 'gepafin')}
|
||||||
|
<i style={{ marginLeft: 7 }}>
|
||||||
|
<HelpIcon/>
|
||||||
|
</i>
|
||||||
|
</>}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
onClick={doSaveDraft}
|
||||||
|
outlined
|
||||||
|
label={__('Salva Bozza Valutazione', 'gepafin')}
|
||||||
|
icon="pi pi-save" iconPos="right"/>
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
disabled={!isAdmissible}
|
||||||
|
label={__('Approva Domanda', 'gepafin')}
|
||||||
|
icon="pi pi-check" iconPos="right"/>
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
label={__('Respingi Domanda', 'gepafin')}
|
||||||
|
icon="pi pi-times" iconPos="right"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
: <>
|
||||||
|
<Skeleton width="20%" height="1rem" className="mb-2"></Skeleton>
|
||||||
|
<Skeleton width="100%" height="2rem" className="mb-8"></Skeleton>
|
||||||
|
<Skeleton width="20%" height="1rem" className="mb-2"></Skeleton>
|
||||||
|
<Skeleton width="100%" height="4rem" className="mb-8"></Skeleton>
|
||||||
|
<Skeleton width="20%" height="1rem" className="mb-2"></Skeleton>
|
||||||
|
<Skeleton width="100%" height="2rem" className="mb-8"></Skeleton>
|
||||||
|
<Skeleton width="20%" height="1rem" className="mb-2"></Skeleton>
|
||||||
|
<Skeleton width="100%" height="4rem"></Skeleton>
|
||||||
|
</>}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SoccorsoEditPreInstructor;
|
||||||
@@ -0,0 +1,171 @@
|
|||||||
|
import React, { useState, useEffect} from 'react';
|
||||||
|
import { __ } from '@wordpress/i18n';
|
||||||
|
import { is, uniq } from 'ramda';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
|
// store
|
||||||
|
//import { storeSet, storeGet } from '../../../../store';
|
||||||
|
|
||||||
|
// api
|
||||||
|
import ApplicationService from '../../../../service/application-service';
|
||||||
|
|
||||||
|
// components
|
||||||
|
import { FilterMatchMode, FilterOperator } from 'primereact/api';
|
||||||
|
import { DataTable } from 'primereact/datatable';
|
||||||
|
import { Column } from 'primereact/column';
|
||||||
|
import { InputText } from 'primereact/inputtext';
|
||||||
|
import { IconField } from 'primereact/iconfield';
|
||||||
|
import { InputIcon } from 'primereact/inputicon';
|
||||||
|
import { Button } from 'primereact/button';
|
||||||
|
import { Calendar } from 'primereact/calendar';
|
||||||
|
import ProperBandoLabel from '../../../../components/ProperBandoLabel';
|
||||||
|
|
||||||
|
|
||||||
|
const PreInstructorSoccorsiTable = ({ openDialogFn }) => {
|
||||||
|
const [items, setItems] = useState(null);
|
||||||
|
const [filters, setFilters] = useState(null);
|
||||||
|
const [localAsyncRequest, setLocalAsyncRequest] = useState(false);
|
||||||
|
const [globalFilterValue, setGlobalFilterValue] = useState('');
|
||||||
|
const [statuses, setStatuses] = useState([]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setLocalAsyncRequest(true);
|
||||||
|
ApplicationService.getApplications(getCallback, errGetCallbacks, [['status', 'SUBMIT']]);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
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.callEndDate = is(String, d.callEndDate) ? new Date(d.callEndDate) : (d.callEndDate ? d.callEndDate : '');
|
||||||
|
d.modifiedDate = is(String, d.modifiedDate) ? new Date(d.modifiedDate) : (d.modifiedDate ? d.modifiedDate : '');
|
||||||
|
d.submissionDate = is(String, d.submissionDate) ? new Date(d.submissionDate) : (d.submissionDate ? d.submissionDate : '');
|
||||||
|
return d;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const formatDate = (value) => {
|
||||||
|
return value.toLocaleDateString('it-IT', {
|
||||||
|
day: '2-digit',
|
||||||
|
month: '2-digit',
|
||||||
|
year: 'numeric'
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const clearFilter = () => {
|
||||||
|
initFilters();
|
||||||
|
};
|
||||||
|
|
||||||
|
const onGlobalFilterChange = (e) => {
|
||||||
|
const value = e.target.value;
|
||||||
|
let _filters = { ...filters };
|
||||||
|
|
||||||
|
_filters['global'].value = value;
|
||||||
|
|
||||||
|
setFilters(_filters);
|
||||||
|
setGlobalFilterValue(value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const initFilters = () => {
|
||||||
|
setFilters({
|
||||||
|
global: { value: null, matchMode: FilterMatchMode.CONTAINS },
|
||||||
|
callTitle: {
|
||||||
|
operator: FilterOperator.AND,
|
||||||
|
constraints: [{ value: null, matchMode: FilterMatchMode.STARTS_WITH }]
|
||||||
|
},
|
||||||
|
submissionDate: {
|
||||||
|
operator: FilterOperator.AND,
|
||||||
|
constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }]
|
||||||
|
},
|
||||||
|
callEndDate: {
|
||||||
|
operator: FilterOperator.AND,
|
||||||
|
constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
setGlobalFilterValue('');
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderHeader = () => {
|
||||||
|
return (
|
||||||
|
<div className="appTableHeader">
|
||||||
|
<Button type="button" icon="pi pi-filter-slash" label={__('Pulisci', 'gepafin')} outlined onClick={clearFilter} />
|
||||||
|
<IconField iconPosition="left">
|
||||||
|
<InputIcon className="pi pi-search" />
|
||||||
|
<InputText value={globalFilterValue} onChange={onGlobalFilterChange} placeholder={__('Cerca', 'gepafin')} />
|
||||||
|
</IconField>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const dateAppliedBodyTemplate = (rowData) => {
|
||||||
|
return formatDate(rowData.submissionDate);
|
||||||
|
};
|
||||||
|
|
||||||
|
const dateEndBodyTemplate = (rowData) => {
|
||||||
|
return formatDate(rowData.callEndDate);
|
||||||
|
};
|
||||||
|
|
||||||
|
const dateFilterTemplate = (options) => {
|
||||||
|
return <Calendar value={options.value} onChange={(e) => options.filterCallback(e.value, options.index)} dateFormat="mm/dd/yy" placeholder="mm/dd/yyyy" mask="99/99/9999" />;
|
||||||
|
};
|
||||||
|
|
||||||
|
const statusBodyTemplate = (rowData) => {
|
||||||
|
return <ProperBandoLabel status={rowData.status}/>;
|
||||||
|
};
|
||||||
|
|
||||||
|
const actionsBodyTemplate = (rowData) => {
|
||||||
|
return openDialogFn
|
||||||
|
? <Button severity="info"
|
||||||
|
onClick={() => openDialogFn(rowData.id)}
|
||||||
|
label={__('Assegnare', 'gepafin')}
|
||||||
|
icon="pi pi-pencil" size="small" iconPos="right" />
|
||||||
|
: <Link to={'/domande'}>
|
||||||
|
<Button severity="info" label={__('Gestire', 'gepafin')} size="small" />
|
||||||
|
</Link>
|
||||||
|
}
|
||||||
|
|
||||||
|
const header = renderHeader();
|
||||||
|
|
||||||
|
return(
|
||||||
|
<div className="appPageSection__table">
|
||||||
|
<DataTable value={items} paginator showGridlines rows={10} loading={localAsyncRequest} dataKey="id"
|
||||||
|
filters={filters}
|
||||||
|
globalFilterFields={['name', 'status']}
|
||||||
|
header={header}
|
||||||
|
emptyMessage={__('Nessun dato disponibile', 'gepafin')}
|
||||||
|
onFilter={(e) => setFilters(e.filters)}>
|
||||||
|
<Column field="id" header={__('ID domanda', 'gepafin')}
|
||||||
|
filter filterPlaceholder={__('Cerca', 'gepafin')}
|
||||||
|
style={{ minWidth: '12rem' }}/>
|
||||||
|
<Column field="callTitle" header={__('Bando', 'gepafin')}
|
||||||
|
filter filterPlaceholder={__('Cerca', 'gepafin')}
|
||||||
|
style={{ minWidth: '12rem' }}/>
|
||||||
|
<Column header={__('Data Ricezione', 'gepafin')}
|
||||||
|
filterField="submissionDate" dataType="date"
|
||||||
|
style={{ minWidth: '10rem' }}
|
||||||
|
body={dateAppliedBodyTemplate} filter filterElement={dateFilterTemplate}/>
|
||||||
|
<Column header={__('Scadenza', 'gepafin')}
|
||||||
|
filterField="callEndDate" dataType="date"
|
||||||
|
style={{ minWidth: '10rem' }}
|
||||||
|
body={dateEndBodyTemplate} filter filterElement={dateFilterTemplate}/>
|
||||||
|
<Column field="status" header={__('Stato', 'gepafin')}
|
||||||
|
style={{ width: '120px' }} body={statusBodyTemplate} />
|
||||||
|
<Column header={__('Azioni', 'gepafin')}
|
||||||
|
body={actionsBodyTemplate}/>
|
||||||
|
</DataTable>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PreInstructorSoccorsiTable;
|
||||||
23
src/pages/SoccorsoIstruttorioPreInstructor/index.js
Normal file
23
src/pages/SoccorsoIstruttorioPreInstructor/index.js
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { __ } from '@wordpress/i18n';
|
||||||
|
|
||||||
|
// components
|
||||||
|
import PreInstructorSoccorsiTable from './components/PreInstructorSoccorsiTable';
|
||||||
|
|
||||||
|
const SoccorsoIstruttorioPreInstructor = () => {
|
||||||
|
return(
|
||||||
|
<div className="appPage">
|
||||||
|
<div className="appPage__pageHeader">
|
||||||
|
<h1>{__('Soccorso Istruttorio', 'gepafin')}</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="appPage__spacer"></div>
|
||||||
|
|
||||||
|
<div className="appPageSection">
|
||||||
|
<PreInstructorSoccorsiTable/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SoccorsoIstruttorioPreInstructor;
|
||||||
@@ -29,7 +29,9 @@ import DashboardPreInstructor from './pages/DashboardPreInstructor';
|
|||||||
import ProfileBeneficiario from './pages/ProfileBeneficiario';
|
import ProfileBeneficiario from './pages/ProfileBeneficiario';
|
||||||
import Domande from './pages/Domande';
|
import Domande from './pages/Domande';
|
||||||
import DomandePreInstructor from './pages/DomandePreInstructor';
|
import DomandePreInstructor from './pages/DomandePreInstructor';
|
||||||
import DomandaEdit from './pages/DomandaEdit';
|
import DomandaEditPreInstructor from './pages/DomandaEditPreInstructor';
|
||||||
|
import SoccorsoIstruttorioPreInstructor from './pages/SoccorsoIstruttorioPreInstructor';
|
||||||
|
import SoccorsoEditPreInstructor from './pages/SoccorsoEditPreInstructor';
|
||||||
|
|
||||||
const routes = ({ role, chosenCompanyId }) => {
|
const routes = ({ role, chosenCompanyId }) => {
|
||||||
|
|
||||||
@@ -89,7 +91,22 @@ const routes = ({ role, chosenCompanyId }) => {
|
|||||||
<Route path="/domande/:id/" element={<DefaultLayout>
|
<Route path="/domande/:id/" element={<DefaultLayout>
|
||||||
{'ROLE_SUPER_ADMIN' === role ? <PageNotFound/> : null}
|
{'ROLE_SUPER_ADMIN' === role ? <PageNotFound/> : null}
|
||||||
{'ROLE_BENEFICIARY' === role ? <PageNotFound/> : null}
|
{'ROLE_BENEFICIARY' === role ? <PageNotFound/> : null}
|
||||||
{'ROLE_PRE_INSTRUCTOR' === role ? <DomandaEdit/> : null}
|
{'ROLE_PRE_INSTRUCTOR' === role ? <DomandaEditPreInstructor/> : null}
|
||||||
|
</DefaultLayout>}/>
|
||||||
|
<Route path="/domande/:id/soccorso/new" element={<DefaultLayout>
|
||||||
|
{'ROLE_SUPER_ADMIN' === role ? <PageNotFound/> : null}
|
||||||
|
{'ROLE_BENEFICIARY' === role ? <PageNotFound/> : null}
|
||||||
|
{'ROLE_PRE_INSTRUCTOR' === role ? <SoccorsoEditPreInstructor/> : null}
|
||||||
|
</DefaultLayout>}/>
|
||||||
|
<Route path="/soccorso-istruttorio/" element={<DefaultLayout>
|
||||||
|
{'ROLE_SUPER_ADMIN' === role ? <PageNotFound/> : null}
|
||||||
|
{'ROLE_BENEFICIARY' === role ? <PageNotFound/> : null}
|
||||||
|
{'ROLE_PRE_INSTRUCTOR' === role ? <SoccorsoIstruttorioPreInstructor/> : null}
|
||||||
|
</DefaultLayout>}/>
|
||||||
|
<Route path="/soccorso-istruttorio/:soccorsoId" element={<DefaultLayout>
|
||||||
|
{'ROLE_SUPER_ADMIN' === role ? <PageNotFound/> : null}
|
||||||
|
{'ROLE_BENEFICIARY' === role ? <PageNotFound/> : null}
|
||||||
|
{'ROLE_PRE_INSTRUCTOR' === role ? <SoccorsoEditPreInstructor/> : null}
|
||||||
</DefaultLayout>}/>
|
</DefaultLayout>}/>
|
||||||
<Route path="/imieibandi" element={<DefaultLayout>
|
<Route path="/imieibandi" element={<DefaultLayout>
|
||||||
{'ROLE_SUPER_ADMIN' === role ? <PageNotFound/> : null}
|
{'ROLE_SUPER_ADMIN' === role ? <PageNotFound/> : null}
|
||||||
|
|||||||
14
src/service/amendments-service.js
Normal file
14
src/service/amendments-service.js
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import { NetworkService } from './network-service';
|
||||||
|
|
||||||
|
const API_BASE_URL = process.env.REACT_APP_API_EXECUTION_ADDRESS;
|
||||||
|
|
||||||
|
export default class ApplicationEvaluationService {
|
||||||
|
|
||||||
|
static getEvaluationByApplId = (callback, errCallback, queryParams) => {
|
||||||
|
NetworkService.get(`${API_BASE_URL}/applicationEvaluation/application`, callback, errCallback, queryParams);
|
||||||
|
};
|
||||||
|
|
||||||
|
static updateEvaluation = (id, body, callback, errCallback, queryParams) => {
|
||||||
|
NetworkService.put(`${API_BASE_URL}/applicationEvaluation/${id}`, body, callback, errCallback, queryParams);
|
||||||
|
};
|
||||||
|
}
|
||||||
14
src/service/application-evaluation-service.js
Normal file
14
src/service/application-evaluation-service.js
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import { NetworkService } from './network-service';
|
||||||
|
|
||||||
|
const API_BASE_URL = process.env.REACT_APP_API_EXECUTION_ADDRESS;
|
||||||
|
|
||||||
|
export default class ApplicationEvaluationService {
|
||||||
|
|
||||||
|
static getEvaluationByApplId = (callback, errCallback, queryParams) => {
|
||||||
|
NetworkService.get(`${API_BASE_URL}/applicationEvaluation/application`, callback, errCallback, queryParams);
|
||||||
|
};
|
||||||
|
|
||||||
|
static updateEvaluation = (id, body, callback, errCallback, queryParams) => {
|
||||||
|
NetworkService.put(`${API_BASE_URL}/applicationEvaluation/${id}`, body, callback, errCallback, queryParams);
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user