Merge pull request #5 from Kitzanos/master-sync/11-11-2024
Master sync/11 11 2024
This commit is contained in:
@@ -8,7 +8,8 @@
|
|||||||
"@date-fns/tz": "1.1.2",
|
"@date-fns/tz": "1.1.2",
|
||||||
"@emailjs/browser": "^4.4.1",
|
"@emailjs/browser": "^4.4.1",
|
||||||
"@emotion/styled": "11.13.0",
|
"@emotion/styled": "11.13.0",
|
||||||
"@tanstack/react-table": "8.20.5",
|
"@number-flow/react": "0.2.0",
|
||||||
|
"@tanstack/react-table": "^8.20.5",
|
||||||
"@wordpress/i18n": "5.8.0",
|
"@wordpress/i18n": "5.8.0",
|
||||||
"@wordpress/react-i18n": "4.8.0",
|
"@wordpress/react-i18n": "4.8.0",
|
||||||
"@xyflow/react": "12.3.1",
|
"@xyflow/react": "12.3.1",
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 24px;
|
gap: 24px;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
.appForm__field {
|
.appForm__field {
|
||||||
position: relative;
|
position: relative;
|
||||||
@@ -11,6 +12,11 @@
|
|||||||
padding: 5px 0;
|
padding: 5px 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
|
&.row {
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
label {
|
label {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
|
|||||||
@@ -88,6 +88,18 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
&.columns {
|
||||||
|
display: grid;
|
||||||
|
gap: 1rem;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
/*> div {
|
||||||
|
max-width: 50%;
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
color: var(--global-textColor);
|
color: var(--global-textColor);
|
||||||
@@ -98,11 +110,27 @@
|
|||||||
margin: 0 0 24px;
|
margin: 0 0 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
color: var(--global-textColor);
|
||||||
|
font-size: 16px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: normal;
|
||||||
|
margin: 0 0 16px;
|
||||||
|
}
|
||||||
|
|
||||||
.row {
|
.row {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 5px 0;
|
padding: 5px 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,6 +145,10 @@
|
|||||||
container-name: section_with_border;
|
container-name: section_with_border;
|
||||||
container-type: inline-size;
|
container-type: inline-size;
|
||||||
|
|
||||||
|
&.grey {
|
||||||
|
border-color: var(--table-border-color)
|
||||||
|
}
|
||||||
|
|
||||||
&.disabled {
|
&.disabled {
|
||||||
filter: grayscale(1);
|
filter: grayscale(1);
|
||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
@@ -149,14 +181,101 @@
|
|||||||
flex: 1 1 100%;
|
flex: 1 1 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
ul {
|
ul, ol {
|
||||||
padding-left: 1rem;
|
padding-left: 1rem;
|
||||||
|
|
||||||
|
li {
|
||||||
|
color: var(--global-textColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: var(--global-textColor);
|
||||||
|
text-decoration: underline;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
button {
|
button {
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.columns {
|
||||||
|
gap: 2em;
|
||||||
|
column-count: 2;
|
||||||
|
column-width: 4em;
|
||||||
|
display: block;
|
||||||
|
padding-bottom: 0;
|
||||||
|
|
||||||
|
.appPageSection__pMeta {
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.appPageSection__list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 0;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
> li {
|
||||||
|
padding: 15px;
|
||||||
|
border-bottom: 1px solid var(--button-secondary-borderColor);
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1rem;
|
||||||
|
|
||||||
|
&.row {
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.appPageSection__checklist {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1rem;
|
||||||
|
|
||||||
|
div {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.appPageSection__iconActions {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.appPageSection__message {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 20px;
|
||||||
|
background: rgba(255, 242, 226, 0.7);
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 0 0 0 6px;
|
||||||
|
padding: 1.25rem 1.75rem;
|
||||||
|
border-radius: 6px;
|
||||||
|
|
||||||
|
&.warning {
|
||||||
|
color: var(--message-warning-color);
|
||||||
|
border-color: var(--message-warning-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.info {
|
||||||
|
color: var(--message-info-color);
|
||||||
|
border-color: var(--message-info-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@container section_with_border (max-width: 600px) {
|
@container section_with_border (max-width: 600px) {
|
||||||
@@ -215,6 +334,10 @@
|
|||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
line-height: normal;
|
line-height: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
span:nth-of-type(2) {
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.appPageSection__table {
|
.appPageSection__table {
|
||||||
@@ -270,3 +393,11 @@
|
|||||||
background-color: var(--message-info-background);
|
background-color: var(--message-info-background);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (max-width: 700px) {
|
||||||
|
.appPageSection {
|
||||||
|
&.columns {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
41
src/assets/scss/components/evaluation.scss
Normal file
41
src/assets/scss/components/evaluation.scss
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
.criterionRelatedData {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 15px;
|
||||||
|
max-height: 400px;
|
||||||
|
overflow-y: auto;
|
||||||
|
padding: 0 0 10px 0;
|
||||||
|
|
||||||
|
> h3 {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.criterionRelatedData__item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 7px;
|
||||||
|
padding: 10px;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
font-size: 14px;
|
||||||
|
|
||||||
|
ul {
|
||||||
|
margin: 0;
|
||||||
|
padding-left: 15px;
|
||||||
|
|
||||||
|
li a {
|
||||||
|
text-decoration: underline;
|
||||||
|
color: var(--global-textColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
table, th, td {
|
||||||
|
border: 1px solid var(--table-border-color);
|
||||||
|
border-collapse: collapse;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
th, td {
|
||||||
|
padding: 3px;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,9 +12,19 @@ body {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
font-family: "Montserrat", sans-serif;
|
font-family: "Montserrat", sans-serif;
|
||||||
|
|
||||||
p, span:not(.p-button-label, .p-button-icon, .p-badge, .p-message-detail, .p-highlight, .p-inline-message-text),
|
/*p, span:not(.p-button-label, .p-button-icon, .p-badge, .p-message-detail, .p-message-summary, .p-highlight, .p-inline-message-text, .p-tag, .p-tag-icon),
|
||||||
input, label:not(.p-error), textarea, a, li, h1, h2, h3, h4, h5, h6, div:not(.p-inline-message, .p-toast-detail), th, td {
|
input:not(.p-checkbox-input),
|
||||||
|
label:not(.p-error), textarea, a, li, h1, h2, h3, h4, h5, h6, div:not(.p-inline-message, .p-toast-detail, .p-checkbox-box), th, td,
|
||||||
|
:not(svg, path, .p-button, .p-button > span, .statsBigBadges__gridItem > span, number-flow, .p-paginator-page, .p-badge) {
|
||||||
color: var(--global-textColor);
|
color: var(--global-textColor);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
h2, h3, p, label, .appPageSection__hr, li {
|
||||||
|
color: var(--global-textColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,6 +97,12 @@ img {
|
|||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
svg {
|
||||||
|
path {
|
||||||
|
fill: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
span {
|
span {
|
||||||
color: var(--menuitem-active-color);
|
color: var(--menuitem-active-color);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,16 +113,15 @@
|
|||||||
background-color: rgba(255,255,255,0.3)
|
background-color: rgba(255,255,255,0.3)
|
||||||
}
|
}
|
||||||
|
|
||||||
.p-inputgroup {
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.p-accordion-header-text, .p-accordion-content {
|
.p-accordion-header-text, .p-accordion-content {
|
||||||
p {
|
p {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.p-inputgroup.flex-1 {
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
.flex-1 {
|
.flex-1 {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
39
src/assets/scss/components/myTable.scss
Normal file
39
src/assets/scss/components/myTable.scss
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
.myTable {
|
||||||
|
border-spacing: 0px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.myThead {
|
||||||
|
th {
|
||||||
|
text-align: left;
|
||||||
|
padding: 1rem 1rem;
|
||||||
|
border: 1px solid #e5e7eb;
|
||||||
|
border-width: 0 0 1px 0;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #374151;
|
||||||
|
background: #f9fafb;
|
||||||
|
transition: box-shadow 0.2s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.myTbody {
|
||||||
|
td {
|
||||||
|
text-align: left;
|
||||||
|
border: 1px solid #e5e7eb;
|
||||||
|
border-width: 0 0 1px 0;
|
||||||
|
padding: 1rem 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.myTfoot {
|
||||||
|
td {
|
||||||
|
text-align: left;
|
||||||
|
padding: 1rem 1rem;
|
||||||
|
border: 1px solid #e5e7eb;
|
||||||
|
border-width: 0 0 1px 0;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #374151;
|
||||||
|
background: #f9fafb;
|
||||||
|
transition: box-shadow 0.2s;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,6 +18,7 @@
|
|||||||
--table-border-color: #B7B7B7B2;
|
--table-border-color: #B7B7B7B2;
|
||||||
--message-error-background: #ffdbdb;
|
--message-error-background: #ffdbdb;
|
||||||
--message-error-color: #C2504D;
|
--message-error-color: #C2504D;
|
||||||
|
--message-warning-color: #cc8925;
|
||||||
--message-info-background: rgba(183, 183, 183, 0.7);
|
--message-info-background: rgba(183, 183, 183, 0.7);
|
||||||
--message-info-color: #3B82F6;
|
--message-info-color: #3B82F6;
|
||||||
|
|
||||||
@@ -41,3 +42,5 @@
|
|||||||
@import "./components/login.scss";
|
@import "./components/login.scss";
|
||||||
@import "./components/flowBuilder.scss";
|
@import "./components/flowBuilder.scss";
|
||||||
@import "./components/error404.scss";
|
@import "./components/error404.scss";
|
||||||
|
@import "./components/myTable.scss";
|
||||||
|
@import "./components/evaluation.scss";
|
||||||
@@ -55,7 +55,7 @@ const TopBarProfileMenu = ({ menuLeftRef }) => {
|
|||||||
command: () => {
|
command: () => {
|
||||||
navigate('/profilo-aziendale')
|
navigate('/profilo-aziendale')
|
||||||
},
|
},
|
||||||
enable: !intersection(permissions, ['MANAGE_TENDERS']).length && companies.length > 0
|
enable: intersection(permissions, ['APPLY_CALLS']).length && companies.length > 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: __('Seleziona azienda', 'gepafin'),
|
label: __('Seleziona azienda', 'gepafin'),
|
||||||
@@ -67,7 +67,7 @@ const TopBarProfileMenu = ({ menuLeftRef }) => {
|
|||||||
command: () => {
|
command: () => {
|
||||||
navigate('/agguingi-azienda')
|
navigate('/agguingi-azienda')
|
||||||
},
|
},
|
||||||
enable: !intersection(permissions, ['MANAGE_TENDERS']).length
|
enable: intersection(permissions, ['APPLY_CALLS']).length
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
separator: true,
|
separator: true,
|
||||||
@@ -86,7 +86,7 @@ const TopBarProfileMenu = ({ menuLeftRef }) => {
|
|||||||
const switchCompany = (id) => {
|
const switchCompany = (id) => {
|
||||||
if (chosenCompanyId !== id) {
|
if (chosenCompanyId !== id) {
|
||||||
storeSet.main.chosenCompanyId(id);
|
storeSet.main.chosenCompanyId(id);
|
||||||
console.log('set company 2', id)
|
|
||||||
if (toast.current) {
|
if (toast.current) {
|
||||||
toast.current.show({
|
toast.current.show({
|
||||||
severity: 'success',
|
severity: 'success',
|
||||||
|
|||||||
@@ -2,17 +2,62 @@ import { useEffect } from 'react';
|
|||||||
import { __ } from '@wordpress/i18n';
|
import { __ } from '@wordpress/i18n';
|
||||||
import equal from 'fast-deep-equal';
|
import equal from 'fast-deep-equal';
|
||||||
//import { diff } from 'deep-object-diff';
|
//import { diff } from 'deep-object-diff';
|
||||||
|
import { klona } from 'klona';
|
||||||
|
import { TZDate } from '@date-fns/tz';
|
||||||
|
import { wrap } from 'object-path-immutable';
|
||||||
|
import { is, isNil } from 'ramda';
|
||||||
|
|
||||||
// store
|
// store
|
||||||
import { storeGet } from '../../store';
|
import { storeGet } from '../../store';
|
||||||
|
|
||||||
const UnsavedChangesDetector = ({ getValuesFn }) => {
|
const UnsavedChangesDetector = ({ getValuesFn }) => {
|
||||||
const warnIfUnsavedChanges = (event) => {
|
const warnIfUnsavedChanges = (event) => {
|
||||||
const formData = getValuesFn();
|
let formData = klona(getValuesFn());
|
||||||
|
formData.dates = [];
|
||||||
|
|
||||||
|
if (formData.startDate) {
|
||||||
|
let starDate;
|
||||||
|
|
||||||
|
if (is(String, formData.startDate)) {
|
||||||
|
starDate = formData.startDate;
|
||||||
|
} else {
|
||||||
|
const tzAwareDate = new TZDate(formData.startDate, 'Europe/Berlin');
|
||||||
|
starDate = tzAwareDate.toISOString().substring(0, 19);
|
||||||
|
}
|
||||||
|
|
||||||
|
formData = wrap(formData).insert(['dates'], starDate, 0).value();
|
||||||
|
}
|
||||||
|
if (formData.endDate) {
|
||||||
|
let endDate;
|
||||||
|
|
||||||
|
if (is(String, formData.endDate)) {
|
||||||
|
endDate = formData.endDate;
|
||||||
|
} else {
|
||||||
|
const tzAwareDate = new TZDate(formData.endDate, 'Europe/Berlin');
|
||||||
|
endDate = tzAwareDate.toISOString().substring(0, 19);
|
||||||
|
}
|
||||||
|
|
||||||
|
formData = wrap(formData).insert(['dates'], endDate, 1).value();
|
||||||
|
}
|
||||||
|
if (!isNil(formData.startTime)) {
|
||||||
|
if (!is(String, formData.startTime)) {
|
||||||
|
const tzAwareDate = new TZDate(formData.startTime, 'Europe/Berlin');
|
||||||
|
formData.startTime = tzAwareDate.toISOString().substring(11, 16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!isNil(formData.endTime)) {
|
||||||
|
if (!is(String, formData.endTime)) {
|
||||||
|
const tzAwareDate = new TZDate(formData.endTime, 'Europe/Berlin');
|
||||||
|
formData.endTime = tzAwareDate.toISOString().substring(11, 16);
|
||||||
|
}
|
||||||
|
}
|
||||||
const initial = storeGet.main.formInitialData();
|
const initial = storeGet.main.formInitialData();
|
||||||
|
|
||||||
const isEqual = equal(initial, formData);
|
const isEqual = equal(initial, formData);
|
||||||
// TODO
|
// TODO
|
||||||
//console.log('isEqual', isEqual, initial, formData, diff(initial, formData))
|
/*console.log('isEqual', isEqual,
|
||||||
|
initial, formData,
|
||||||
|
diff(initial, formData))*/
|
||||||
if (!isEqual) {
|
if (!isEqual) {
|
||||||
event.returnValue = __('You have unsaved changes. If you proceed, they will be lost.', 'gepafin');
|
event.returnValue = __('You have unsaved changes. If you proceed, they will be lost.', 'gepafin');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,9 @@ const getBandoLabel = (status) => {
|
|||||||
case 'READY':
|
case 'READY':
|
||||||
return __('Pronto', 'gepafin');
|
return __('Pronto', 'gepafin');
|
||||||
|
|
||||||
|
case 'SOCCORSO':
|
||||||
|
return __('Soccorso', 'gepafin');
|
||||||
|
|
||||||
case 'DRAFT':
|
case 'DRAFT':
|
||||||
return __('Bozza', 'gepafin');
|
return __('Bozza', 'gepafin');
|
||||||
|
|
||||||
@@ -38,6 +41,9 @@ const getBandoLabel = (status) => {
|
|||||||
case 'EXPIRED':
|
case 'EXPIRED':
|
||||||
return __('Scaduto', 'gepafin');
|
return __('Scaduto', 'gepafin');
|
||||||
|
|
||||||
|
case 'CLOSE':
|
||||||
|
return __('Chiuso', 'gepafin');
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,9 @@ const getBandoSeverity = (status) => {
|
|||||||
case 'READY':
|
case 'READY':
|
||||||
return 'info';
|
return 'info';
|
||||||
|
|
||||||
|
case 'SOCCORSO':
|
||||||
|
return 'warning';
|
||||||
|
|
||||||
case 'DRAFT':
|
case 'DRAFT':
|
||||||
return 'warning';
|
return 'warning';
|
||||||
|
|
||||||
@@ -36,6 +39,9 @@ const getBandoSeverity = (status) => {
|
|||||||
case 'EXPIRED':
|
case 'EXPIRED':
|
||||||
return 'closed';
|
return 'closed';
|
||||||
|
|
||||||
|
case 'CLOSE':
|
||||||
|
return 'closed';
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return 'info';
|
return 'info';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
import parse from 'html-react-parser';
|
import parse from 'html-react-parser';
|
||||||
import { isNil } from 'ramda';
|
import { isNil } from 'ramda';
|
||||||
|
import DOMPurify from 'dompurify';
|
||||||
|
|
||||||
const renderHtmlContent = (content = '') => !isNil(content) ? parse(content) : '';
|
const renderHtmlContent = (content = '') => {
|
||||||
|
const clean = DOMPurify.sanitize(content);
|
||||||
|
return !isNil(clean) ? parse(clean) : '';
|
||||||
|
}
|
||||||
|
|
||||||
export default renderHtmlContent;
|
export default renderHtmlContent;
|
||||||
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();
|
||||||
@@ -41,32 +42,59 @@ const AppSidebar = () => {
|
|||||||
enable: intersection(permissions, ['VIEW_CALLS']).length
|
enable: intersection(permissions, ['VIEW_CALLS']).length
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: __('Gestione Utenti', 'gepafin'),
|
label: __('Gestione domande', 'gepafin'),
|
||||||
|
icon: 'pi pi-file',
|
||||||
|
href: '/domande',
|
||||||
|
id: 5,
|
||||||
|
enable: intersection(permissions, ['VIEW_USERS', 'MANAGE_USERS']).length
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: __('Domande da valutare', 'gepafin'),
|
||||||
|
icon: 'pi pi-calendar-clock',
|
||||||
|
href: '/domande',
|
||||||
|
id: 6,
|
||||||
|
enable: intersection(permissions, ['EVALUATE_APPLICATIONS']).length
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: __('Archivio domande', 'gepafin'),
|
||||||
|
icon: 'pi pi-file',
|
||||||
|
href: '/domande',
|
||||||
|
id: 7,
|
||||||
|
enable: intersection(permissions, ['APPLY_CALLS']).length
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: __('Soccorso istruttorio', 'gepafin'),
|
||||||
|
icon: <HelpIcon/>,
|
||||||
|
href: '/soccorso-istruttorio',
|
||||||
|
id: 8,
|
||||||
|
enable: intersection(permissions, ['EVALUATE_APPLICATIONS']).length
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: __('Gestione utenti', 'gepafin'),
|
||||||
icon: 'pi pi-users',
|
icon: 'pi pi-users',
|
||||||
href: '/utenti',
|
href: '/utenti',
|
||||||
id: 5,
|
id: 9,
|
||||||
enable: false
|
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: 6,
|
id: 10,
|
||||||
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: 7,
|
id: 11,
|
||||||
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: 8,
|
id: 12,
|
||||||
enable: false
|
enable: false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -78,11 +106,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>)}
|
||||||
|
|||||||
@@ -27,9 +27,10 @@ const AppTopbar = () => {
|
|||||||
<i className="pi pi-bell p-overlay-badge topBar__icon">
|
<i className="pi pi-bell p-overlay-badge topBar__icon">
|
||||||
<Badge value="0"></Badge>
|
<Badge value="0"></Badge>
|
||||||
</i>
|
</i>
|
||||||
<i className="pi pi-envelope p-overlay-badge topBar__icon">
|
<i className="pi pi-envelope topBar__icon"></i>
|
||||||
|
{/*<i className="pi pi-envelope p-overlay-badge topBar__icon">
|
||||||
<Badge severity="danger"></Badge>
|
<Badge severity="danger"></Badge>
|
||||||
</i>
|
</i>*/}
|
||||||
<Button
|
<Button
|
||||||
className="topBar__profileBtn"
|
className="topBar__profileBtn"
|
||||||
outlined
|
outlined
|
||||||
@@ -40,7 +41,7 @@ const AppTopbar = () => {
|
|||||||
<TopBarProfileMenu menuLeftRef={menuLeft}/>
|
<TopBarProfileMenu menuLeftRef={menuLeft}/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
return(
|
return (
|
||||||
<Toolbar start={startContent} end={endContent} className="topBar"/>
|
<Toolbar start={startContent} end={endContent} className="topBar"/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,9 +2,6 @@ import React, { useState, useEffect} from 'react';
|
|||||||
import { __ } from '@wordpress/i18n';
|
import { __ } from '@wordpress/i18n';
|
||||||
import { is, uniq } from 'ramda';
|
import { is, uniq } from 'ramda';
|
||||||
|
|
||||||
// store
|
|
||||||
import { storeSet, storeGet } from '../../../../store';
|
|
||||||
|
|
||||||
// tools
|
// tools
|
||||||
import getBandoSeverity from '../../../../helpers/getBandoSeverity';
|
import getBandoSeverity from '../../../../helpers/getBandoSeverity';
|
||||||
import getBandoLabel from '../../../../helpers/getBandoLabel';
|
import getBandoLabel from '../../../../helpers/getBandoLabel';
|
||||||
@@ -31,12 +28,12 @@ import { Link } from 'react-router-dom';
|
|||||||
const AllBandiTable = () => {
|
const AllBandiTable = () => {
|
||||||
const [items, setItems] = useState(null);
|
const [items, setItems] = useState(null);
|
||||||
const [filters, setFilters] = useState(null);
|
const [filters, setFilters] = useState(null);
|
||||||
const [loading, setLoading] = useState(false);
|
const [localAsyncRequest, setLocalAsyncRequest] = useState(false);
|
||||||
const [globalFilterValue, setGlobalFilterValue] = useState('');
|
const [globalFilterValue, setGlobalFilterValue] = useState('');
|
||||||
const [statuses, setStatuses] = useState([]);
|
const [statuses, setStatuses] = useState([]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
storeSet.main.setAsyncRequest();
|
setLocalAsyncRequest(true);
|
||||||
BandoService.getBandi(getCallback, errGetCallbacks);
|
BandoService.getBandi(getCallback, errGetCallbacks);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
@@ -46,12 +43,11 @@ const AllBandiTable = () => {
|
|||||||
setStatuses(uniq(data.data.map(o => o.status)))
|
setStatuses(uniq(data.data.map(o => o.status)))
|
||||||
initFilters();
|
initFilters();
|
||||||
}
|
}
|
||||||
storeSet.main.unsetAsyncRequest();
|
setLocalAsyncRequest(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
const errGetCallbacks = (data) => {
|
const errGetCallbacks = (data) => {
|
||||||
console.log('errGetCallbacks', data)
|
setLocalAsyncRequest(false);
|
||||||
storeSet.main.unsetAsyncRequest();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const getFormattedBandiData = (data) => {
|
const getFormattedBandiData = (data) => {
|
||||||
@@ -98,9 +94,9 @@ const AllBandiTable = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const nameBodyTemplate = (rowData) => {
|
/*const nameBodyTemplate = (rowData) => {
|
||||||
return <span>{rowData.name}</span>
|
return <span>{rowData.name}</span>
|
||||||
}
|
}*/
|
||||||
|
|
||||||
const dateStartBodyTemplate = (rowData) => {
|
const dateStartBodyTemplate = (rowData) => {
|
||||||
return getDateFromISOstring(rowData.dates[0]);
|
return getDateFromISOstring(rowData.dates[0]);
|
||||||
@@ -136,7 +132,7 @@ const AllBandiTable = () => {
|
|||||||
|
|
||||||
return(
|
return(
|
||||||
<div className="appPageSection__table">
|
<div className="appPageSection__table">
|
||||||
<DataTable value={items} paginator showGridlines rows={10} loading={loading} dataKey="id"
|
<DataTable value={items} paginator showGridlines rows={10} loading={localAsyncRequest} dataKey="id"
|
||||||
filters={filters}
|
filters={filters}
|
||||||
globalFilterFields={['name', 'status']}
|
globalFilterFields={['name', 'status']}
|
||||||
header={header}
|
header={header}
|
||||||
@@ -144,15 +140,15 @@ const AllBandiTable = () => {
|
|||||||
onFilter={(e) => setFilters(e.filters)}>
|
onFilter={(e) => setFilters(e.filters)}>
|
||||||
<Column field="name" header={__('Nome Bando', 'gepafin')}
|
<Column field="name" header={__('Nome Bando', 'gepafin')}
|
||||||
filter filterPlaceholder={__('Cerca', 'gepafin')}
|
filter filterPlaceholder={__('Cerca', 'gepafin')}
|
||||||
style={{ minWidth: '12rem' }}/>
|
style={{ minWidth: '8rem' }}/>
|
||||||
<Column header={__('Data Pubblicazione', 'gepafin')} filterField="start_date" dataType="date"
|
<Column header={__('Data Pubblicazione', 'gepafin')} filterField="start_date" dataType="date"
|
||||||
style={{ minWidth: '10rem' }}
|
style={{ minWidth: '8rem' }}
|
||||||
body={dateStartBodyTemplate} filter filterElement={dateFilterTemplate}/>
|
body={dateStartBodyTemplate} filter filterElement={dateFilterTemplate}/>
|
||||||
<Column header={__('Data Scadenza', 'gepafin')} filterField="end_date" dataType="date"
|
<Column header={__('Data Scadenza', 'gepafin')} filterField="end_date" dataType="date"
|
||||||
style={{ minWidth: '10rem' }}
|
style={{ minWidth: '8rem' }}
|
||||||
body={dateEndBodyTemplate} filter filterElement={dateFilterTemplate}/>
|
body={dateEndBodyTemplate} filter filterElement={dateFilterTemplate}/>
|
||||||
<Column field="status" header={__('Stato', 'gepafin')} filterMenuStyle={{ width: '14rem' }}
|
<Column field="status" header={__('Stato', 'gepafin')} filterMenuStyle={{ width: '14rem' }}
|
||||||
style={{ width: '120px' }} body={statusBodyTemplate} filter
|
style={{ minWidth: '7rem' }} body={statusBodyTemplate} filter
|
||||||
filterElement={statusFilterTemplate}/>
|
filterElement={statusFilterTemplate}/>
|
||||||
<Column header={__('Azioni', 'gepafin')}
|
<Column header={__('Azioni', 'gepafin')}
|
||||||
body={actionsBodyTemplate}/>
|
body={actionsBodyTemplate}/>
|
||||||
|
|||||||
@@ -92,21 +92,21 @@ const AllBandiAccordion = () => {
|
|||||||
return <Tag value={getBandoLabel(option)} severity={getBandoSeverity(option)} />;
|
return <Tag value={getBandoLabel(option)} severity={getBandoSeverity(option)} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
const addToFavourites = () => {
|
/*const addToFavourites = () => {
|
||||||
console.log('addToFavourites');
|
console.log('addToFavourites');
|
||||||
}
|
}*/
|
||||||
|
|
||||||
const goToBandoPage = (id) => {
|
const goToBandoPage = (id) => {
|
||||||
navigate(`/bandi/${id}`)
|
navigate(`/bandi/${id}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const actionsBodyTemplate = (rowData) => {
|
/*const actionsBodyTemplate = (rowData) => {
|
||||||
return <div className="appPageSection__tableActions">
|
return <div className="appPageSection__tableActions">
|
||||||
<button type="button" className="appPageSection__addToFavourites" onClick={addToFavourites} disabled={true}>
|
<button type="button" className="appPageSection__addToFavourites" onClick={addToFavourites} disabled={true}>
|
||||||
<i className="pi pi-heart" style={{ fontSize: '1rem' }}></i>
|
<i className="pi pi-heart" style={{ fontSize: '1rem' }}></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
}
|
}*/
|
||||||
|
|
||||||
const rowExpansionTemplate = (data) => {
|
const rowExpansionTemplate = (data) => {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,20 +1,13 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { range } from 'ramda';
|
import { range } from 'ramda';
|
||||||
//import { __ } from '@wordpress/i18n';
|
import { __ } from '@wordpress/i18n';
|
||||||
|
|
||||||
// components
|
// components
|
||||||
import { Steps } from 'primereact/steps';
|
import { Steps } from 'primereact/steps';
|
||||||
|
|
||||||
const ApplicationSteps = ({ totalSteps = 0, activeStepIndex }) => {
|
const ApplicationSteps = ({ totalSteps = 0, activeStepIndex }) => {
|
||||||
const rangeArr = range(1, totalSteps + 1);
|
const rangeArr = range(1, totalSteps + 1);
|
||||||
const items = rangeArr.map(() => ({ label: 'Passo' }));
|
const items = rangeArr.map(() => ({ label: __('Passo', 'gepafin') }));
|
||||||
|
|
||||||
/*// TODO update to using Steps after primereact is updated
|
|
||||||
return(
|
|
||||||
0 !== totalSteps
|
|
||||||
? <span>{__('Passo', 'gepafin')}: {activeStepIndex + 1}</span>
|
|
||||||
: null
|
|
||||||
)*/
|
|
||||||
|
|
||||||
return(
|
return(
|
||||||
0 !== totalSteps
|
0 !== totalSteps
|
||||||
|
|||||||
@@ -326,10 +326,14 @@ const BandoApplication = () => {
|
|||||||
].includes(cur)) {
|
].includes(cur)) {
|
||||||
acc.user[cur] = userData[cur];
|
acc.user[cur] = userData[cur];
|
||||||
}
|
}
|
||||||
|
if (['dateOfBirth'].includes(cur)) {
|
||||||
|
acc.user[cur] = new Date(userData[cur]);
|
||||||
|
}
|
||||||
return acc;
|
return acc;
|
||||||
}, dynamicData);
|
}, dynamicData);
|
||||||
|
|
||||||
if (data.data.applicationFormResponse.content) {
|
if (data.data.applicationFormResponse.content) {
|
||||||
|
// eslint-disable-next-line array-callback-return
|
||||||
data.data.applicationFormResponse.content.map((o) => {
|
data.data.applicationFormResponse.content.map((o) => {
|
||||||
if (o.dynamicData && !isEmpty(o.dynamicData)) {
|
if (o.dynamicData && !isEmpty(o.dynamicData)) {
|
||||||
formDataInitial[o.id] = pathOr('', o.dynamicData.split('.'), dynamicData);
|
formDataInitial[o.id] = pathOr('', o.dynamicData.split('.'), dynamicData);
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { useForm } from 'react-hook-form';
|
|||||||
import { isEmpty, isNil, is } from 'ramda';
|
import { isEmpty, isNil, is } from 'ramda';
|
||||||
import { klona } from 'klona';
|
import { klona } from 'klona';
|
||||||
import { TZDate } from '@date-fns/tz';
|
import { TZDate } from '@date-fns/tz';
|
||||||
|
import { wrap } from 'object-path-immutable';
|
||||||
|
|
||||||
// components
|
// components
|
||||||
import FormField from '../../../../components/FormField';
|
import FormField from '../../../../components/FormField';
|
||||||
@@ -48,38 +49,36 @@ const BandoEditFormStep1 = forwardRef(function ({ initialData, getFormErrors, st
|
|||||||
const values = getValues();
|
const values = getValues();
|
||||||
const toast = useRef(null);
|
const toast = useRef(null);
|
||||||
|
|
||||||
const onSubmit = (formData) => {
|
const onSubmit = () => {};
|
||||||
/*if (!isNil(formData.dates) && formData.dates.length) {
|
|
||||||
formData.dates = formData.dates.map(v => {
|
|
||||||
if (is(String, v)) {
|
|
||||||
return v;
|
|
||||||
} else {
|
|
||||||
const tzAwareDate = new TZDate(v, 'Europe/Berlin');
|
|
||||||
return tzAwareDate.toISOString().substring(0, 19);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
storeSet.main.setAsyncRequest();
|
|
||||||
if (!formData.id) {
|
|
||||||
BandoService.createBando(formData, createCallback, errCreateCallback);
|
|
||||||
} else {
|
|
||||||
BandoService.updateBandoStep1(formData.id, formData, createCallback, errCreateCallback);
|
|
||||||
}*/
|
|
||||||
};
|
|
||||||
|
|
||||||
const onSaveDraft = () => {
|
const onSaveDraft = () => {
|
||||||
trigger();
|
trigger();
|
||||||
const formData = getValues();
|
let formData = klona(getValues());
|
||||||
if (!isNil(formData.dates) && formData.dates.length) {
|
formData.dates = [];
|
||||||
formData.dates = formData.dates.map(v => {
|
|
||||||
if (is(String, v)) {
|
if (formData.startDate) {
|
||||||
return v;
|
let starDate;
|
||||||
} else {
|
|
||||||
const tzAwareDate = new TZDate(v, 'Europe/Berlin');
|
if (is(String, formData.startDate)) {
|
||||||
return tzAwareDate.toISOString().substring(0, 19);
|
starDate = formData.startDate;
|
||||||
}
|
} else {
|
||||||
});
|
const tzAwareDate = new TZDate(formData.startDate, 'Europe/Berlin');
|
||||||
|
starDate = tzAwareDate.toISOString().substring(0, 19);
|
||||||
|
}
|
||||||
|
|
||||||
|
formData = wrap(formData).insert(['dates'], starDate, 0).value();
|
||||||
|
}
|
||||||
|
if (formData.endDate) {
|
||||||
|
let endDate;
|
||||||
|
|
||||||
|
if (is(String, formData.endDate)) {
|
||||||
|
endDate = formData.endDate;
|
||||||
|
} else {
|
||||||
|
const tzAwareDate = new TZDate(formData.endDate, 'Europe/Berlin');
|
||||||
|
endDate = tzAwareDate.toISOString().substring(0, 19);
|
||||||
|
}
|
||||||
|
|
||||||
|
formData = wrap(formData).insert(['dates'], endDate, 1).value();
|
||||||
}
|
}
|
||||||
if (!isNil(formData.startTime)) {
|
if (!isNil(formData.startTime)) {
|
||||||
if (!is(String, formData.startTime)) {
|
if (!is(String, formData.startTime)) {
|
||||||
@@ -95,6 +94,9 @@ const BandoEditFormStep1 = forwardRef(function ({ initialData, getFormErrors, st
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete formData.startDate;
|
||||||
|
delete formData.endDate;
|
||||||
|
|
||||||
storeSet.main.setAsyncRequest();
|
storeSet.main.setAsyncRequest();
|
||||||
if (!formData.id) {
|
if (!formData.id) {
|
||||||
BandoService.createBando(formData, createCallback, errCreateCallback);
|
BandoService.createBando(formData, createCallback, errCreateCallback);
|
||||||
@@ -106,11 +108,13 @@ const BandoEditFormStep1 = forwardRef(function ({ initialData, getFormErrors, st
|
|||||||
const createCallback = (data) => {
|
const createCallback = (data) => {
|
||||||
storeSet.main.unsetAsyncRequest();
|
storeSet.main.unsetAsyncRequest();
|
||||||
if (data.status === 'SUCCESS') {
|
if (data.status === 'SUCCESS') {
|
||||||
toast.current.show({
|
if (toast.current) {
|
||||||
severity: 'success',
|
toast.current.show({
|
||||||
summary: '',
|
severity: 'success',
|
||||||
detail: __('Il bando è stato aggiornato corretamente!', 'gepafin')
|
summary: '',
|
||||||
});
|
detail: __('Il bando è stato aggiornato corretamente!', 'gepafin')
|
||||||
|
});
|
||||||
|
}
|
||||||
const values = getValues();
|
const values = getValues();
|
||||||
if (!values.id && data.data.id) {
|
if (!values.id && data.data.id) {
|
||||||
navigate(`/bandi/${data.data.id}`);
|
navigate(`/bandi/${data.data.id}`);
|
||||||
@@ -121,6 +125,13 @@ const BandoEditFormStep1 = forwardRef(function ({ initialData, getFormErrors, st
|
|||||||
}
|
}
|
||||||
|
|
||||||
const errCreateCallback = (data) => {
|
const errCreateCallback = (data) => {
|
||||||
|
if (toast.current && data.message) {
|
||||||
|
toast.current.show({
|
||||||
|
severity: 'error',
|
||||||
|
summary: '',
|
||||||
|
detail: data.message
|
||||||
|
});
|
||||||
|
}
|
||||||
set404FromErrorResponse(data);
|
set404FromErrorResponse(data);
|
||||||
storeSet.main.unsetAsyncRequest();
|
storeSet.main.unsetAsyncRequest();
|
||||||
}
|
}
|
||||||
@@ -193,7 +204,12 @@ const BandoEditFormStep1 = forwardRef(function ({ initialData, getFormErrors, st
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const newFormData = klona(formInitialData);
|
const newFormData = klona(formInitialData);
|
||||||
if (!isNil(formInitialData.dates) && formInitialData.dates.length) {
|
if (!isNil(formInitialData.dates) && formInitialData.dates.length) {
|
||||||
newFormData.dates = formInitialData.dates.map(v => is(String, v) ? new Date(v) : (v ? v : ''));
|
if (newFormData.dates[0]) {
|
||||||
|
newFormData.startDate = is(String, newFormData.dates[0]) ? new Date(newFormData.dates[0]) : (newFormData.dates[0] ? newFormData.dates[0] : '');
|
||||||
|
}
|
||||||
|
if (newFormData.dates[1]) {
|
||||||
|
newFormData.endDate = is(String, newFormData.dates[1]) ? new Date(newFormData.dates[1]) : (newFormData.dates[1] ? newFormData.dates[1] : '');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!isNil(formInitialData.startTime) && !isEmpty(formInitialData.startTime)) {
|
if (!isNil(formInitialData.startTime) && !isEmpty(formInitialData.startTime)) {
|
||||||
newFormData.startTime = is(String, formInitialData.startTime)
|
newFormData.startTime = is(String, formInitialData.startTime)
|
||||||
@@ -305,7 +321,7 @@ const BandoEditFormStep1 = forwardRef(function ({ initialData, getFormErrors, st
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<FormField
|
{/*<FormField
|
||||||
type="datepickerrange"
|
type="datepickerrange"
|
||||||
disabled={shouldDisableField()}
|
disabled={shouldDisableField()}
|
||||||
fieldName="dates"
|
fieldName="dates"
|
||||||
@@ -314,7 +330,30 @@ const BandoEditFormStep1 = forwardRef(function ({ initialData, getFormErrors, st
|
|||||||
errors={errors}
|
errors={errors}
|
||||||
defaultValue={values['dates']}
|
defaultValue={values['dates']}
|
||||||
config={{ required: __('È obbligatorio', 'gepafin') }}
|
config={{ required: __('È obbligatorio', 'gepafin') }}
|
||||||
/>
|
/>*/}
|
||||||
|
<div className="appForm__cols">
|
||||||
|
<FormField
|
||||||
|
type="datepicker"
|
||||||
|
disabled={shouldDisableField()}
|
||||||
|
fieldName="startDate"
|
||||||
|
label={__('Data di inizio', 'gepafin')}
|
||||||
|
control={control}
|
||||||
|
errors={errors}
|
||||||
|
defaultValue={values['startDate']}
|
||||||
|
config={{ required: __('È obbligatorio', 'gepafin') }}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FormField
|
||||||
|
type="datepicker"
|
||||||
|
disabled={shouldDisableField()}
|
||||||
|
fieldName="endDate"
|
||||||
|
label={__('Data di fine', 'gepafin')}
|
||||||
|
control={control}
|
||||||
|
errors={errors}
|
||||||
|
defaultValue={values['endDate']}
|
||||||
|
config={{ required: __('È obbligatorio', 'gepafin') }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="appForm__cols">
|
<div className="appForm__cols">
|
||||||
<FormField
|
<FormField
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import LookupdataService from '../../../../service/lookupdata-service';
|
|||||||
import { storeSet } from '../../../../store';
|
import { storeSet } from '../../../../store';
|
||||||
import getTimeParsedFromString from '../../../../helpers/getTimeParsedFromString';
|
import getTimeParsedFromString from '../../../../helpers/getTimeParsedFromString';
|
||||||
import { mimeTypes } from '../../../../configData';
|
import { mimeTypes } from '../../../../configData';
|
||||||
|
import { wrap } from 'object-path-immutable';
|
||||||
|
|
||||||
const BandoEditFormStep2 = forwardRef(function ({ initialData, getFormErrors, status }, ref) {
|
const BandoEditFormStep2 = forwardRef(function ({ initialData, getFormErrors, status }, ref) {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@@ -46,41 +47,36 @@ const BandoEditFormStep2 = forwardRef(function ({ initialData, getFormErrors, st
|
|||||||
//const step2Props = ['threshold', 'criteria', 'checkList', 'docs', 'images'];
|
//const step2Props = ['threshold', 'criteria', 'checkList', 'docs', 'images'];
|
||||||
const toast = useRef(null);
|
const toast = useRef(null);
|
||||||
|
|
||||||
const onSubmit = (formData) => {
|
const onSubmit = () => {};
|
||||||
/*if (!isNil(formData.dates) && formData.dates.length) {
|
|
||||||
formData.dates = formData.dates.map(v => {
|
|
||||||
if (is(String, v)) {
|
|
||||||
return v;
|
|
||||||
} else {
|
|
||||||
const tzAwareDate = new TZDate(v, 'Europe/Berlin');
|
|
||||||
return tzAwareDate.toISOString().substring(0, 19);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const forSubmit = Object.keys(formData).reduce((acc, cur) => {
|
|
||||||
if (step2Props.includes(cur)) {
|
|
||||||
acc[cur] = formData[cur];
|
|
||||||
}
|
|
||||||
return acc;
|
|
||||||
}, {});
|
|
||||||
|
|
||||||
storeSet.main.setAsyncRequest();
|
|
||||||
BandoService.updateBandoStep2(formData.id, forSubmit, createCallback, errCreateCallback);*/
|
|
||||||
};
|
|
||||||
|
|
||||||
const onSaveDraft = () => {
|
const onSaveDraft = () => {
|
||||||
trigger();
|
trigger();
|
||||||
const formData = getValues();
|
let formData = klona(getValues());
|
||||||
if (!isNil(formData.dates) && formData.dates.length) {
|
formData.dates = [];
|
||||||
formData.dates = formData.dates.map(v => {
|
|
||||||
if (is(String, v)) {
|
if (formData.startDate) {
|
||||||
return v;
|
let starDate;
|
||||||
} else {
|
|
||||||
const tzAwareDate = new TZDate(v, 'Europe/Berlin');
|
if (is(String, formData.startDate)) {
|
||||||
return tzAwareDate.toISOString().substring(0, 19);
|
starDate = formData.startDate;
|
||||||
}
|
} else {
|
||||||
});
|
const tzAwareDate = new TZDate(formData.startDate, 'Europe/Berlin');
|
||||||
|
starDate = tzAwareDate.toISOString().substring(0, 19);
|
||||||
|
}
|
||||||
|
|
||||||
|
formData = wrap(formData).insert(['dates'], starDate, 0).value();
|
||||||
|
}
|
||||||
|
if (formData.endDate) {
|
||||||
|
let endDate;
|
||||||
|
|
||||||
|
if (is(String, formData.endDate)) {
|
||||||
|
endDate = formData.endDate;
|
||||||
|
} else {
|
||||||
|
const tzAwareDate = new TZDate(formData.endDate, 'Europe/Berlin');
|
||||||
|
endDate = tzAwareDate.toISOString().substring(0, 19);
|
||||||
|
}
|
||||||
|
|
||||||
|
formData = wrap(formData).insert(['dates'], endDate, 1).value();
|
||||||
}
|
}
|
||||||
if (!isNil(formData.startTime)) {
|
if (!isNil(formData.startTime)) {
|
||||||
if (!is(String, formData.startTime)) {
|
if (!is(String, formData.startTime)) {
|
||||||
@@ -88,7 +84,6 @@ const BandoEditFormStep2 = forwardRef(function ({ initialData, getFormErrors, st
|
|||||||
formData.startTime = tzAwareDate.toISOString().substring(11, 16);
|
formData.startTime = tzAwareDate.toISOString().substring(11, 16);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isNil(formData.endTime)) {
|
if (!isNil(formData.endTime)) {
|
||||||
if (!is(String, formData.endTime)) {
|
if (!is(String, formData.endTime)) {
|
||||||
const tzAwareDate = new TZDate(formData.endTime, 'Europe/Berlin');
|
const tzAwareDate = new TZDate(formData.endTime, 'Europe/Berlin');
|
||||||
@@ -96,6 +91,9 @@ const BandoEditFormStep2 = forwardRef(function ({ initialData, getFormErrors, st
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete formData.startDate;
|
||||||
|
delete formData.endDate;
|
||||||
|
|
||||||
storeSet.main.setAsyncRequest();
|
storeSet.main.setAsyncRequest();
|
||||||
BandoService.updateBandoStep2(formData.id, formData, createCallback, errCreateCallback);
|
BandoService.updateBandoStep2(formData.id, formData, createCallback, errCreateCallback);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,9 +76,9 @@ const BandoEdit = () => {
|
|||||||
BandoService.validateBando(id, validateCallback, errValidateCallback);
|
BandoService.validateBando(id, validateCallback, errValidateCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
const validateCallback = (data) => {
|
const validateCallback = (resp) => {
|
||||||
if (data.status === 'SUCCESS') {
|
if (resp.status === 'SUCCESS') {
|
||||||
setData({ ...data, status: data.data.status });
|
setData(resp.data);
|
||||||
if (bandoMsgs.current) {
|
if (bandoMsgs.current) {
|
||||||
bandoMsgs.current.show([
|
bandoMsgs.current.show([
|
||||||
{
|
{
|
||||||
@@ -100,19 +100,26 @@ const BandoEdit = () => {
|
|||||||
storeSet.main.unsetAsyncRequest();
|
storeSet.main.unsetAsyncRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
const errValidateCallback = (data) => {
|
const errValidateCallback = (resp) => {
|
||||||
if (data.status === 'VALIDATION_ERROR') {
|
if (resp.status === 'VALIDATION_ERROR') {
|
||||||
storeSet.main.unsetAsyncRequest();
|
storeSet.main.unsetAsyncRequest();
|
||||||
if (bandoMsgs.current) {
|
if (bandoMsgs.current) {
|
||||||
bandoMsgs.current.show(data.data.map((v, i) => ({
|
bandoMsgs.current.show(resp.data.map((v, i) => ({
|
||||||
id: i,
|
id: i,
|
||||||
sticky: true, severity: 'error', summary: '',
|
sticky: true, severity: 'error', summary: '',
|
||||||
detail: v,
|
detail: v,
|
||||||
closable: false
|
closable: false
|
||||||
})));
|
})));
|
||||||
}
|
}
|
||||||
|
if (toast.current) {
|
||||||
|
toast.current.show(resp.data.map((v, i) => ({
|
||||||
|
severity: 'error',
|
||||||
|
summary: '',
|
||||||
|
detail: v
|
||||||
|
})));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
standardErrCallback(data);
|
standardErrCallback(resp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,8 +129,8 @@ const BandoEdit = () => {
|
|||||||
BandoService.updateBandoStatus(id, publishCallback, errPublishCallback, [['status', 'PUBLISH']]);
|
BandoService.updateBandoStatus(id, publishCallback, errPublishCallback, [['status', 'PUBLISH']]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const publishCallback = (data) => {
|
const publishCallback = (resp) => {
|
||||||
if (data.status === 'SUCCESS') {
|
if (resp.status === 'SUCCESS') {
|
||||||
if (bandoMsgs.current) {
|
if (bandoMsgs.current) {
|
||||||
bandoMsgs.current.show([
|
bandoMsgs.current.show([
|
||||||
{
|
{
|
||||||
@@ -141,26 +148,31 @@ const BandoEdit = () => {
|
|||||||
detail: __('Pubblicato!', 'gepafin')
|
detail: __('Pubblicato!', 'gepafin')
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (data.data.docs) {
|
if (resp.data.docs) {
|
||||||
data.data.docs = data.data.docs
|
resp.data.docs = resp.data.docs
|
||||||
.filter(o => o.source === 'CALL' && o.type === 'DOCUMENT');
|
.filter(o => o.source === 'CALL' && o.type === 'DOCUMENT');
|
||||||
}
|
}
|
||||||
setData(data.data);
|
setData(resp.data);
|
||||||
}
|
}
|
||||||
storeSet.main.unsetAsyncRequest();
|
storeSet.main.unsetAsyncRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
const errPublishCallback = (data) => {
|
const errPublishCallback = (resp) => {
|
||||||
standardErrCallback(data);
|
standardErrCallback(resp);
|
||||||
}
|
}
|
||||||
|
|
||||||
const getCallback = (data) => {
|
const getCallback = (resp) => {
|
||||||
if (data.status === 'SUCCESS') {
|
if (resp.status === 'SUCCESS') {
|
||||||
if (!isNil(data.data.dates) && data.data.dates.length) {
|
if (!isNil(resp.data.dates) && resp.data.dates.length) {
|
||||||
data.data.dates = data.data.dates.map(v => is(String, v) ? new Date(v) : v);
|
if (resp.data.dates[0]) {
|
||||||
|
resp.data.startDate = is(String, resp.data.dates[0]) ? new Date(resp.data.dates[0]) : (resp.data.dates[0] ? resp.data.dates[0] : '');
|
||||||
|
}
|
||||||
|
if (resp.data.dates[1]) {
|
||||||
|
resp.data.endDate = is(String, resp.data.dates[1]) ? new Date(resp.data.dates[1]) : (resp.data.dates[1] ? resp.data.dates[1] : '');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.data.status === 'READY_TO_PUBLISH') {
|
if (resp.data.status === 'READY_TO_PUBLISH') {
|
||||||
bandoMsgs.current.clear();
|
bandoMsgs.current.clear();
|
||||||
bandoMsgs.current.show([
|
bandoMsgs.current.show([
|
||||||
{
|
{
|
||||||
@@ -170,7 +182,7 @@ const BandoEdit = () => {
|
|||||||
closable: false
|
closable: false
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
} else if (data.data.status === 'DRAFT') {
|
} else if (resp.data.status === 'DRAFT') {
|
||||||
if (bandoMsgs.current) {
|
if (bandoMsgs.current) {
|
||||||
bandoMsgs.current.clear();
|
bandoMsgs.current.clear();
|
||||||
bandoMsgs.current.show([
|
bandoMsgs.current.show([
|
||||||
@@ -183,26 +195,26 @@ const BandoEdit = () => {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (data.data.docs) {
|
if (resp.data.docs) {
|
||||||
data.data.docs = data.data.docs
|
resp.data.docs = resp.data.docs
|
||||||
.filter(o => o.source === 'CALL' && o.type === 'DOCUMENT');
|
.filter(o => o.source === 'CALL' && o.type === 'DOCUMENT');
|
||||||
}
|
}
|
||||||
setData(data.data);
|
setData(resp.data);
|
||||||
}
|
}
|
||||||
storeSet.main.unsetAsyncRequest();
|
storeSet.main.unsetAsyncRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
const errGetCallback = (data) => {
|
const errGetCallback = (resp) => {
|
||||||
set404FromErrorResponse(data);
|
set404FromErrorResponse(resp);
|
||||||
storeSet.main.unsetAsyncRequest();
|
storeSet.main.unsetAsyncRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
const standardErrCallback = (data) => {
|
const standardErrCallback = (resp) => {
|
||||||
if (bandoMsgs.current && data.message) {
|
if (bandoMsgs.current && resp.message) {
|
||||||
bandoMsgs.current.show([
|
bandoMsgs.current.show([
|
||||||
{
|
{
|
||||||
sticky: true, severity: 'error', summary: '',
|
sticky: true, severity: 'error', summary: '',
|
||||||
detail: data.message,
|
detail: resp.message,
|
||||||
closable: true
|
closable: true
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
@@ -210,9 +222,9 @@ const BandoEdit = () => {
|
|||||||
storeSet.main.unsetAsyncRequest();
|
storeSet.main.unsetAsyncRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
const getFormsCallback = (data) => {
|
const getFormsCallback = (resp) => {
|
||||||
if (data.status === 'SUCCESS') {
|
if (resp.status === 'SUCCESS') {
|
||||||
setForms(data.data);
|
setForms(resp.data);
|
||||||
}
|
}
|
||||||
storeSet.main.unsetAsyncRequest();
|
storeSet.main.unsetAsyncRequest();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import React, { useEffect, useState } from 'react';
|
|||||||
import { head, isEmpty, isNil } from 'ramda';
|
import { head, isEmpty, isNil } from 'ramda';
|
||||||
import { __, sprintf } from '@wordpress/i18n';
|
import { __, sprintf } from '@wordpress/i18n';
|
||||||
import { klona } from 'klona';
|
import { klona } from 'klona';
|
||||||
|
import { wrap } from 'object-path-immutable';
|
||||||
|
|
||||||
// store
|
// store
|
||||||
import { storeSet, useStore } from '../../../../store';
|
import { storeSet, useStore } from '../../../../store';
|
||||||
@@ -14,13 +15,17 @@ import { TabView, TabPanel } from 'primereact/tabview';
|
|||||||
import { InputSwitch } from 'primereact/inputswitch';
|
import { InputSwitch } from 'primereact/inputswitch';
|
||||||
import ElementSetting from './components/ElementSetting';
|
import ElementSetting from './components/ElementSetting';
|
||||||
import { Dropdown } from 'primereact/dropdown';
|
import { Dropdown } from 'primereact/dropdown';
|
||||||
|
import { MultiSelect } from 'primereact/multiselect';
|
||||||
|
|
||||||
const BuilderElementSettings = ({ closeSettings }) => {
|
const BuilderElementSettings = ({ closeSettingsFn }) => {
|
||||||
const elements = useStore().main.formElements();
|
const elements = useStore().main.formElements();
|
||||||
const activeElement = useStore().main.activeElement();
|
const activeElement = useStore().main.activeElement();
|
||||||
|
const criteriaOptions = useStore().main.bandoCriteria();
|
||||||
const [activeElementData, setActiveElementData] = useState({});
|
const [activeElementData, setActiveElementData] = useState({});
|
||||||
const [settings, setSettings] = useState([]);
|
const [settings, setSettings] = useState([]);
|
||||||
const [validators, setValidators] = useState({});
|
const [validators, setValidators] = useState({});
|
||||||
|
const [dynamicData, setDynamicData] = useState('');
|
||||||
|
const [criteria, setCriteria] = useState([]);
|
||||||
const numberBasedValidatorFields = ['min', 'max', 'minLength', 'maxLength'];
|
const numberBasedValidatorFields = ['min', 'max', 'minLength', 'maxLength'];
|
||||||
const customValidationOptions = [
|
const customValidationOptions = [
|
||||||
{ value: 'isPIVA', label: 'isPIVA' },
|
{ value: 'isPIVA', label: 'isPIVA' },
|
||||||
@@ -63,11 +68,14 @@ const BuilderElementSettings = ({ closeSettings }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const saveSettings = () => {
|
const saveSettings = () => {
|
||||||
activeElementData.settings = settings;
|
let newActiveElementData = klona(activeElementData);
|
||||||
activeElementData.validators = validators;
|
newActiveElementData = wrap(newActiveElementData).set(['settings'], settings).value();
|
||||||
const newElements = elements.map(o => o.id === activeElementData.id ? activeElementData : o);
|
newActiveElementData = wrap(newActiveElementData).set(['validators'], validators).value();
|
||||||
|
newActiveElementData = wrap(newActiveElementData).set(['dynamicData'], dynamicData).value();
|
||||||
|
newActiveElementData = wrap(newActiveElementData).set(['criteria'], criteria).value();
|
||||||
|
const newElements = elements.map(o => o.id === newActiveElementData.id ? newActiveElementData : o);
|
||||||
storeSet.main.formElements(newElements);
|
storeSet.main.formElements(newElements);
|
||||||
closeSettings();
|
closeSettingsFn();
|
||||||
}
|
}
|
||||||
|
|
||||||
const showField = (value, key) => {
|
const showField = (value, key) => {
|
||||||
@@ -92,17 +100,56 @@ const BuilderElementSettings = ({ closeSettings }) => {
|
|||||||
setValidators(newValidators);
|
setValidators(newValidators);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const onChangeCriteriaData = (value) => {
|
||||||
|
setCriteria(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const getDynamicDataOptions = (type) => {
|
||||||
|
switch (type) {
|
||||||
|
case 'datepicker' :
|
||||||
|
return [
|
||||||
|
{ label: 'user dateOfBirth', value: 'user.dateOfBirth' }
|
||||||
|
]
|
||||||
|
default :
|
||||||
|
return [
|
||||||
|
{ label: 'company name', value: 'company.companyName' },
|
||||||
|
{ label: 'company piva', value: 'company.vatNumber' },
|
||||||
|
{ label: 'company codiceFiscale', value: 'company.codiceFiscale' },
|
||||||
|
{ label: 'company address', value: 'company.address' },
|
||||||
|
{ label: 'company phoneNumber', value: 'company.phoneNumber' },
|
||||||
|
{ label: 'company city', value: 'company.city' },
|
||||||
|
{ label: 'company province', value: 'company.province' },
|
||||||
|
{ label: 'company cap', value: 'company.cap' },
|
||||||
|
{ label: 'company country', value: 'company.country' },
|
||||||
|
{ label: 'company pec', value: 'company.pec' },
|
||||||
|
{ label: 'company email', value: 'company.email' },
|
||||||
|
{ label: 'company contactName', value: 'company.contactName' },
|
||||||
|
{ label: 'company contactEmail', value: 'company.contactEmail' },
|
||||||
|
{ label: 'user email', value: 'user.email' },
|
||||||
|
{ label: 'user firstName', value: 'user.firstName' },
|
||||||
|
{ label: 'user lastName', value: 'user.lastName' },
|
||||||
|
{ label: 'user phoneNumber', value: 'user.phoneNumber' },
|
||||||
|
{ label: 'user codiceFiscale', value: 'user.codiceFiscale' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const chosen = head(elements.filter(o => o.id === activeElement));
|
const chosen = head(elements.filter(o => o.id === activeElement));
|
||||||
|
|
||||||
if (chosen) {
|
if (chosen) {
|
||||||
setActiveElementData(klona(chosen));
|
setActiveElementData(klona(chosen));
|
||||||
setSettings(klona(chosen.settings));
|
setSettings(klona(chosen.settings));
|
||||||
setValidators(klona(chosen.validators))
|
setValidators(klona(chosen.validators));
|
||||||
|
setDynamicData(chosen.dynamicData ? chosen.dynamicData : '');
|
||||||
|
setCriteria(chosen.criteria ? chosen.criteria : []);
|
||||||
} else {
|
} else {
|
||||||
setActiveElementData({});
|
setActiveElementData({});
|
||||||
setSettings([]);
|
setSettings([]);
|
||||||
setValidators({})
|
setValidators({});
|
||||||
|
setDynamicData('');
|
||||||
|
setCriteria([]);
|
||||||
}
|
}
|
||||||
}, [activeElement]);
|
}, [activeElement]);
|
||||||
|
|
||||||
@@ -118,6 +165,18 @@ const BuilderElementSettings = ({ closeSettings }) => {
|
|||||||
changeFn={onChange}
|
changeFn={onChange}
|
||||||
updateDataFn={onUpdateOptions}/>)
|
updateDataFn={onUpdateOptions}/>)
|
||||||
: null}
|
: null}
|
||||||
|
{['textinput', 'datepicker'].includes(activeElementData.name)
|
||||||
|
? <div className="formElementSettings__field">
|
||||||
|
<label htmlFor="dynamicData">{__('Dati dinamici', 'gepafin')}</label>
|
||||||
|
<Dropdown
|
||||||
|
id="dynamicData"
|
||||||
|
value={dynamicData}
|
||||||
|
onChange={(e) => setDynamicData(e.value)}
|
||||||
|
options={getDynamicDataOptions(activeElementData.name)}
|
||||||
|
optionLabel="label"
|
||||||
|
optionValue="value"
|
||||||
|
placeholder={__('Scegli', 'gepafin')}/>
|
||||||
|
</div> : null}
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
{!isEmpty(validators)
|
{!isEmpty(validators)
|
||||||
? <TabPanel header={__('Validation', 'gepafin')}>
|
? <TabPanel header={__('Validation', 'gepafin')}>
|
||||||
@@ -172,6 +231,20 @@ const BuilderElementSettings = ({ closeSettings }) => {
|
|||||||
</div> : null}
|
</div> : null}
|
||||||
</div>) : null}
|
</div>) : null}
|
||||||
</TabPanel> : null}
|
</TabPanel> : null}
|
||||||
|
<TabPanel header={__('Criteri', 'gepafin')}>
|
||||||
|
<div className="formElementSettings__field">
|
||||||
|
<label htmlFor="criteria">{__('Criteri di valutazione', 'gepafin')}</label>
|
||||||
|
<MultiSelect
|
||||||
|
id="criteria"
|
||||||
|
value={criteria}
|
||||||
|
onChange={(e) => onChangeCriteriaData(e.value)}
|
||||||
|
options={criteriaOptions}
|
||||||
|
optionLabel="label"
|
||||||
|
optionValue="value"
|
||||||
|
display="chip"
|
||||||
|
placeholder={__('Scegli', 'gepafin')}/>
|
||||||
|
</div>
|
||||||
|
</TabPanel>
|
||||||
</TabView>
|
</TabView>
|
||||||
|
|
||||||
<Button label={__('Salva', 'gepafin')} onClick={saveSettings}/>
|
<Button label={__('Salva', 'gepafin')} onClick={saveSettings}/>
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ const FormBuilder = () => {
|
|||||||
<>
|
<>
|
||||||
<Sidebar visible={!isEmpty(activeElement)} onHide={closeSettings} className="formBuilder__elementSettings">
|
<Sidebar visible={!isEmpty(activeElement)} onHide={closeSettings} className="formBuilder__elementSettings">
|
||||||
<h2>{__('Impostazioni del campo modulo', 'gepafin')}</h2>
|
<h2>{__('Impostazioni del campo modulo', 'gepafin')}</h2>
|
||||||
{!isEmpty(activeElement) ? <BuilderElementSettings closeSettings={closeSettings}/> : null}
|
{!isEmpty(activeElement) ? <BuilderElementSettings closeSettingsFn={closeSettings}/> : null}
|
||||||
</Sidebar>
|
</Sidebar>
|
||||||
<div className="formBuilder">
|
<div className="formBuilder">
|
||||||
<div className="formBuilder__main">
|
<div className="formBuilder__main">
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { useNavigate, useParams } from 'react-router-dom';
|
|||||||
import { DndProvider } from 'react-dnd';
|
import { DndProvider } from 'react-dnd';
|
||||||
import { HTML5Backend } from 'react-dnd-html5-backend';
|
import { HTML5Backend } from 'react-dnd-html5-backend';
|
||||||
import { klona } from 'klona';
|
import { klona } from 'klona';
|
||||||
import { isEmpty } from 'ramda';
|
import { isEmpty, pathOr } from 'ramda';
|
||||||
|
|
||||||
// store
|
// store
|
||||||
import { storeSet, storeGet, useStore } from '../../store';
|
import { storeSet, storeGet, useStore } from '../../store';
|
||||||
@@ -21,6 +21,7 @@ import { Messages } from 'primereact/messages';
|
|||||||
// api
|
// api
|
||||||
import FormsService from '../../service/forms-service';
|
import FormsService from '../../service/forms-service';
|
||||||
import set404FromErrorResponse from '../../helpers/set404FromErrorResponse';
|
import set404FromErrorResponse from '../../helpers/set404FromErrorResponse';
|
||||||
|
import BandoService from '../../service/bando-service';
|
||||||
|
|
||||||
// TODO temp data
|
// TODO temp data
|
||||||
//import { elementItems } from '../../tempData';
|
//import { elementItems } from '../../tempData';
|
||||||
@@ -243,7 +244,21 @@ const BandoFormsEdit = () => {
|
|||||||
storeSet.main.unsetAsyncRequest();
|
storeSet.main.unsetAsyncRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getBandoCallback = (data) => {
|
||||||
|
if (data.status === 'SUCCESS') {
|
||||||
|
const criteria = pathOr([], ['data', 'criteria'], data);
|
||||||
|
const criteriaOptions = criteria.map(o => ({value: o.id, label: o.value}));
|
||||||
|
console.log('criteriaOptions', criteriaOptions);
|
||||||
|
storeSet.main.bandoCriteria(criteriaOptions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const errGetBandoCallback = (data) => {
|
||||||
|
set404FromErrorResponse(data);
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
const bandoId = getBandoId();
|
||||||
const parsedFormId = parseInt(formId)
|
const parsedFormId = parseInt(formId)
|
||||||
const bandoFormId = !isNaN(parsedFormId) ? parsedFormId : 0;
|
const bandoFormId = !isNaN(parsedFormId) ? parsedFormId : 0;
|
||||||
|
|
||||||
@@ -254,11 +269,15 @@ const BandoFormsEdit = () => {
|
|||||||
storeSet.main.setAsyncRequest();
|
storeSet.main.setAsyncRequest();
|
||||||
FormsService.getFormById(bandoFormId, getFormCallback, errGetFormCallbacks);
|
FormsService.getFormById(bandoFormId, getFormCallback, errGetFormCallbacks);
|
||||||
}
|
}
|
||||||
|
if (bandoId) {
|
||||||
|
BandoService.getBando(bandoId, getBandoCallback, errGetBandoCallback);
|
||||||
|
}
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
storeSet.main.formId(0);
|
storeSet.main.formId(0);
|
||||||
storeSet.main.formLabel('');
|
storeSet.main.formLabel('');
|
||||||
storeSet.main.formElements([]);
|
storeSet.main.formElements([]);
|
||||||
|
storeSet.main.bandoCriteria([]);
|
||||||
}
|
}
|
||||||
}, [id, formId]);
|
}, [id, formId]);
|
||||||
|
|
||||||
|
|||||||
@@ -145,11 +145,11 @@ const BandoViewBeneficiario = () => {
|
|||||||
'isVisible': false
|
'isVisible': false
|
||||||
}
|
}
|
||||||
storeSet.main.setAsyncRequest();
|
storeSet.main.setAsyncRequest();
|
||||||
FaqItemService.addQuestion(id, obj, createCallBack, errCreateCallback, [['companyId', chosenCompanyId]])
|
FaqItemService.addQuestion(id, obj, createQuestionBack, errCreateQuestionCallback, [['companyId', chosenCompanyId]])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const createCallBack = (data) => {
|
const createQuestionBack = (data) => {
|
||||||
if (data.status === 'SUCCESS') {
|
if (data.status === 'SUCCESS') {
|
||||||
setNewQuestion('');
|
setNewQuestion('');
|
||||||
if (toast.current) {
|
if (toast.current) {
|
||||||
@@ -163,7 +163,7 @@ const BandoViewBeneficiario = () => {
|
|||||||
storeSet.main.unsetAsyncRequest();
|
storeSet.main.unsetAsyncRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
const errCreateCallback = (data) => {
|
const errCreateQuestionCallback = (data) => {
|
||||||
if (toast.current && data.message) {
|
if (toast.current && data.message) {
|
||||||
toast.current.show({
|
toast.current.show({
|
||||||
severity: 'error',
|
severity: 'error',
|
||||||
@@ -262,10 +262,10 @@ const BandoViewBeneficiario = () => {
|
|||||||
{!isAsyncRequest && !isEmpty(data)
|
{!isAsyncRequest && !isEmpty(data)
|
||||||
? <div className="appPage__content">
|
? <div className="appPage__content">
|
||||||
{!isEmpty(data.images)
|
{!isEmpty(data.images)
|
||||||
? <div><picture className="appPageSection__hero">
|
? <picture className="appPageSection__hero">
|
||||||
<source srcSet={data.images[0] ? data.images[0].filePath : ''}/>
|
<source srcSet={data.images[0] ? data.images[0].filePath : ''}/>
|
||||||
<img src={data.images[0] ? data.images[0].filePath : ''} alt={data.name}/>
|
<img src={data.images[0] ? data.images[0].filePath : ''} alt={data.name}/>
|
||||||
</picture></div> : null}
|
</picture> : null}
|
||||||
|
|
||||||
<div className="appPageSection__withBorder">
|
<div className="appPageSection__withBorder">
|
||||||
<h2>{__('Descrizione breve', 'gepafin')}</h2>
|
<h2>{__('Descrizione breve', 'gepafin')}</h2>
|
||||||
@@ -408,7 +408,7 @@ const BandoViewBeneficiario = () => {
|
|||||||
<div className="appPageSection">
|
<div className="appPageSection">
|
||||||
<h2>{__('Download Documenti', 'gepafin')}</h2>
|
<h2>{__('Download Documenti', 'gepafin')}</h2>
|
||||||
<div className="appPageSection__actions">
|
<div className="appPageSection__actions">
|
||||||
{/* <Button
|
{/* <Button
|
||||||
type="button"
|
type="button"
|
||||||
disabled={true}
|
disabled={true}
|
||||||
outlined
|
outlined
|
||||||
|
|||||||
@@ -2,13 +2,6 @@ import React, { useState, useEffect} from 'react';
|
|||||||
import { __ } from '@wordpress/i18n';
|
import { __ } from '@wordpress/i18n';
|
||||||
import { uniq } from 'ramda';
|
import { uniq } from 'ramda';
|
||||||
|
|
||||||
// tools
|
|
||||||
import getBandoLabel from '../../../../helpers/getBandoLabel';
|
|
||||||
import getBandoSeverity from '../../../../helpers/getBandoSeverity';
|
|
||||||
|
|
||||||
// store
|
|
||||||
import { storeSet } from '../../../../store';
|
|
||||||
|
|
||||||
// api
|
// api
|
||||||
import BandoService from '../../../../service/bando-service';
|
import BandoService from '../../../../service/bando-service';
|
||||||
|
|
||||||
@@ -19,11 +12,8 @@ import { Column } from 'primereact/column';
|
|||||||
import { InputText } from 'primereact/inputtext';
|
import { InputText } from 'primereact/inputtext';
|
||||||
import { IconField } from 'primereact/iconfield';
|
import { IconField } from 'primereact/iconfield';
|
||||||
import { InputIcon } from 'primereact/inputicon';
|
import { InputIcon } from 'primereact/inputicon';
|
||||||
import { Dropdown } from 'primereact/dropdown';
|
|
||||||
import { InputNumber } from 'primereact/inputnumber';
|
|
||||||
import { Button } from 'primereact/button';
|
import { Button } from 'primereact/button';
|
||||||
import { Calendar } from 'primereact/calendar';
|
import { Calendar } from 'primereact/calendar';
|
||||||
import { Tag } from 'primereact/tag';
|
|
||||||
import ProperBandoLabel from '../../../../components/ProperBandoLabel';
|
import ProperBandoLabel from '../../../../components/ProperBandoLabel';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
@@ -31,44 +21,12 @@ import { Link } from 'react-router-dom';
|
|||||||
const LatestBandiTable = () => {
|
const LatestBandiTable = () => {
|
||||||
const [items, setItems] = useState(null);
|
const [items, setItems] = useState(null);
|
||||||
const [filters, setFilters] = useState(null);
|
const [filters, setFilters] = useState(null);
|
||||||
const [loading, setLoading] = useState(false);
|
const [localAsyncRequest, setLocalAsyncRequest] = useState(false);
|
||||||
const [globalFilterValue, setGlobalFilterValue] = useState('');
|
const [globalFilterValue, setGlobalFilterValue] = useState('');
|
||||||
const [statuses, setStatuses] = useState([]);
|
const [statuses, setStatuses] = useState([]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// TODO
|
setLocalAsyncRequest(true);
|
||||||
/*const items = [
|
|
||||||
{
|
|
||||||
name: 'Bando Innovazione 2024',
|
|
||||||
start_date: '2024-08-08T00:00:00+00:00',
|
|
||||||
end_date: '2024-08-30T00:00:00+00:00',
|
|
||||||
submissions: 24,
|
|
||||||
status: 'PUBLISH',
|
|
||||||
id: 11
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Bando Sostenibilità 2024',
|
|
||||||
start_date: '2024-07-28T00:00:00+00:00',
|
|
||||||
end_date: '2024-08-15T00:00:00+00:00',
|
|
||||||
submissions: 35,
|
|
||||||
status: 'PUBLISH',
|
|
||||||
id: 9
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Bando A',
|
|
||||||
start_date: '2024-06-28T00:00:00+00:00',
|
|
||||||
end_date: '2024-06-15T00:00:00+00:00',
|
|
||||||
submissions: 2,
|
|
||||||
status: 'EXPIRED',
|
|
||||||
id: 2
|
|
||||||
}
|
|
||||||
]
|
|
||||||
setItems(getFormattedBandiData(items));
|
|
||||||
setStatuses(uniq(items.map(o => o.status)))
|
|
||||||
setLoading(false);
|
|
||||||
initFilters();*/
|
|
||||||
|
|
||||||
storeSet.main.setAsyncRequest();
|
|
||||||
BandoService.getBandi(getCallback, errGetCallbacks);
|
BandoService.getBandi(getCallback, errGetCallbacks);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
@@ -79,12 +37,11 @@ const LatestBandiTable = () => {
|
|||||||
setStatuses(uniq(data.data.map(o => o.status)))
|
setStatuses(uniq(data.data.map(o => o.status)))
|
||||||
initFilters();
|
initFilters();
|
||||||
}
|
}
|
||||||
storeSet.main.unsetAsyncRequest();
|
setLocalAsyncRequest(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
const errGetCallbacks = (data) => {
|
const errGetCallbacks = (data) => {
|
||||||
console.log('errGetCallbacks', data)
|
setLocalAsyncRequest(false);
|
||||||
storeSet.main.unsetAsyncRequest();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const getFormattedBandiData = (data) => {
|
const getFormattedBandiData = (data) => {
|
||||||
@@ -153,22 +110,10 @@ const LatestBandiTable = () => {
|
|||||||
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" />;
|
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 balanceFilterTemplate = (options) => {
|
|
||||||
return <InputNumber value={options.value} onChange={(e) => options.filterCallback(e.value, options.index)} />;
|
|
||||||
};
|
|
||||||
|
|
||||||
const statusBodyTemplate = (rowData) => {
|
const statusBodyTemplate = (rowData) => {
|
||||||
return <ProperBandoLabel status={rowData.status}/>;
|
return <ProperBandoLabel status={rowData.status}/>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const statusFilterTemplate = (options) => {
|
|
||||||
return <Dropdown value={options.value} options={statuses} onChange={(e) => options.filterCallback(e.value, options.index)} itemTemplate={statusItemTemplate} placeholder="Select One" className="p-column-filter" showClear />;
|
|
||||||
};
|
|
||||||
|
|
||||||
const statusItemTemplate = (option) => {
|
|
||||||
return <Tag value={getBandoLabel(option)} severity={getBandoSeverity(option)} />;
|
|
||||||
};
|
|
||||||
|
|
||||||
const actionsBodyTemplate = (rowData) => {
|
const actionsBodyTemplate = (rowData) => {
|
||||||
return <Link to={`/bandi/${rowData.id}`}>
|
return <Link to={`/bandi/${rowData.id}`}>
|
||||||
<Button severity="info" label={__('Modifica', 'gepafin')} icon="pi pi-pencil" size="small" iconPos="right" />
|
<Button severity="info" label={__('Modifica', 'gepafin')} icon="pi pi-pencil" size="small" iconPos="right" />
|
||||||
@@ -179,22 +124,22 @@ const LatestBandiTable = () => {
|
|||||||
|
|
||||||
return(
|
return(
|
||||||
<div className="appPageSection__table">
|
<div className="appPageSection__table">
|
||||||
<DataTable value={items} paginator showGridlines rows={10} loading={loading} dataKey="id"
|
<DataTable value={items} paginator showGridlines rows={10} loading={localAsyncRequest} dataKey="id"
|
||||||
filters={filters}
|
filters={filters}
|
||||||
globalFilterFields={['name', 'status']}
|
globalFilterFields={['name', 'status']}
|
||||||
header={header}
|
header={header}
|
||||||
emptyMessage={__('Nessun dato disponibile', 'gepafin')}
|
emptyMessage={__('Nessun dato disponibile', 'gepafin')}
|
||||||
onFilter={(e) => setFilters(e.filters)}>
|
onFilter={(e) => setFilters(e.filters)}>
|
||||||
<Column field="name" header={__('Nome Bando', 'gepafin')} filter filterPlaceholder="Search by name"
|
<Column field="name" header={__('Nome Bando', 'gepafin')} filter filterPlaceholder={__('Cerca il nome', 'gepafin')}
|
||||||
style={{ minWidth: '12rem' }}/>
|
style={{ minWidth: '8rem' }}/>
|
||||||
<Column header={__('Data Pubblicazione', 'gepafin')} filterField="start_date" dataType="date"
|
<Column header={__('Data Pubblicazione', 'gepafin')} filterField="start_date" dataType="date"
|
||||||
style={{ minWidth: '10rem' }}
|
style={{ minWidth: '8rem' }}
|
||||||
body={dateStartBodyTemplate} filter filterElement={dateFilterTemplate}/>
|
body={dateStartBodyTemplate} filter filterElement={dateFilterTemplate}/>
|
||||||
<Column header={__('Data Scadenza', 'gepafin')} filterField="end_date" dataType="date"
|
<Column header={__('Data Scadenza', 'gepafin')} filterField="end_date" dataType="date"
|
||||||
style={{ minWidth: '10rem' }}
|
style={{ minWidth: '8rem' }}
|
||||||
body={dateEndBodyTemplate} filter filterElement={dateFilterTemplate}/>
|
body={dateEndBodyTemplate} filter filterElement={dateFilterTemplate}/>
|
||||||
<Column field="status" header={__('Stato', 'gepafin')}
|
<Column field="status" header={__('Stato', 'gepafin')}
|
||||||
style={{ width: '120px' }} body={statusBodyTemplate} />
|
style={{ minWidth: '7rem' }} body={statusBodyTemplate} />
|
||||||
<Column header={__('Azioni', 'gepafin')}
|
<Column header={__('Azioni', 'gepafin')}
|
||||||
body={actionsBodyTemplate}/>
|
body={actionsBodyTemplate}/>
|
||||||
</DataTable>
|
</DataTable>
|
||||||
|
|||||||
@@ -110,10 +110,10 @@ const LatestUsersActivityTable = () => {
|
|||||||
emptyMessage={__('Nessun dato disponibile', 'gepafin')}
|
emptyMessage={__('Nessun dato disponibile', 'gepafin')}
|
||||||
onFilter={(e) => setFilters(e.filters)}>
|
onFilter={(e) => setFilters(e.filters)}>
|
||||||
<Column header={__('Timestamp', 'gepafin')} filterField="date" dataType="date"
|
<Column header={__('Timestamp', 'gepafin')} filterField="date" dataType="date"
|
||||||
style={{ minWidth: '10rem' }}
|
style={{ minWidth: '8rem' }}
|
||||||
body={dateBodyTemplate} filter filterElement={dateFilterTemplate}/>
|
body={dateBodyTemplate} filter filterElement={dateFilterTemplate}/>
|
||||||
<Column field="email" header={__('Utente', 'gepafin')} filter filterPlaceholder="Search by email"
|
<Column field="email" header={__('Utente', 'gepafin')} filter filterPlaceholder="Search by email"
|
||||||
style={{ minWidth: '12rem' }}/>
|
style={{ minWidth: '8rem' }}/>
|
||||||
<Column field="action" header={__('Azione', 'gepafin')}/>
|
<Column field="action" header={__('Azione', 'gepafin')}/>
|
||||||
<Column field="dettails" header={__('Dettagli', 'gepafin')}/>
|
<Column field="dettails" header={__('Dettagli', 'gepafin')}/>
|
||||||
</DataTable>
|
</DataTable>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import React, { useEffect, useState } from 'react';
|
|||||||
import { __ } from '@wordpress/i18n';
|
import { __ } from '@wordpress/i18n';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { pathOr } from 'ramda';
|
import { pathOr } from 'ramda';
|
||||||
|
import NumberFlow from '@number-flow/react';
|
||||||
|
|
||||||
// store
|
// store
|
||||||
//import { storeSet } from '../../store';
|
//import { storeSet } from '../../store';
|
||||||
@@ -13,6 +14,8 @@ import DashboardService from '../../service/dashboard-service';
|
|||||||
import LatestBandiTable from './components/LatestBandiTable';
|
import LatestBandiTable from './components/LatestBandiTable';
|
||||||
//import LatestUsersActivityTable from './components/LatestUsersActivityTable';
|
//import LatestUsersActivityTable from './components/LatestUsersActivityTable';
|
||||||
import { Button } from 'primereact/button';
|
import { Button } from 'primereact/button';
|
||||||
|
//import MyEvaluationsTable from '../DashboardPreInstructor/components/PreInstructorDomandeTable';
|
||||||
|
import AllDomandeTable from '../Domande/components/AllDomandeTable';
|
||||||
|
|
||||||
const Dashboard = () => {
|
const Dashboard = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@@ -34,10 +37,6 @@ const Dashboard = () => {
|
|||||||
console.log('onGoToSettings')
|
console.log('onGoToSettings')
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
function formatToMillions(num) {
|
|
||||||
return Math.abs(num) > 999 ? Math.sign(num)*((Math.abs(num)/1000000).toFixed(1)) + 'M' : Math.sign(num)*Math.abs(num)
|
|
||||||
}
|
|
||||||
|
|
||||||
const getStatValue = (key, fallback = '') => {
|
const getStatValue = (key, fallback = '') => {
|
||||||
return pathOr(fallback, [key], mainStats);
|
return pathOr(fallback, [key], mainStats);
|
||||||
}
|
}
|
||||||
@@ -67,27 +66,52 @@ const Dashboard = () => {
|
|||||||
<div className="statsBigBadges__grid">
|
<div className="statsBigBadges__grid">
|
||||||
<div className="statsBigBadges__gridItem">
|
<div className="statsBigBadges__gridItem">
|
||||||
<span>{__('Bandi attivi', 'gepafin')}</span>
|
<span>{__('Bandi attivi', 'gepafin')}</span>
|
||||||
<span>{getStatValue('numberOfActiveCalls', 0)}</span>
|
<span><NumberFlow
|
||||||
|
value={getStatValue('numberOfActiveCalls', 0)}
|
||||||
|
format={{ notation: 'compact' }}
|
||||||
|
locales="it-IT" /></span>
|
||||||
</div>
|
</div>
|
||||||
<div className="statsBigBadges__gridItem">
|
<div className="statsBigBadges__gridItem">
|
||||||
<span>{__('Utenti registrati', 'gepafin')}</span>
|
<span>{__('Utenti registrati', 'gepafin')}</span>
|
||||||
<span>{getStatValue('numberOfResgisteredUsers', 0)}</span>
|
<span><NumberFlow
|
||||||
|
value={getStatValue('numberOfResgisteredUsers', 0)}
|
||||||
|
format={{ notation: 'compact' }}
|
||||||
|
locales="it-IT" /></span>
|
||||||
</div>
|
</div>
|
||||||
<div className="statsBigBadges__gridItem">
|
<div className="statsBigBadges__gridItem">
|
||||||
<span>{__('Domande in pre-istruttoria', 'gepafin')}</span>
|
<span>{__('Domande in pre-istruttoria', 'gepafin')}</span>
|
||||||
<span>{getStatValue('numberOfSubmittedApplications', 0)}</span>
|
<span><NumberFlow
|
||||||
|
value={getStatValue('numberOfSubmittedApplications', 0)}
|
||||||
|
format={{ notation: 'compact' }}
|
||||||
|
locales="it-IT" /></span>
|
||||||
</div>
|
</div>
|
||||||
<div className="statsBigBadges__gridItem">
|
<div className="statsBigBadges__gridItem">
|
||||||
<span>{__('Domande in bozza', 'gepafin')}</span>
|
<span>{__('Domande in bozza', 'gepafin')}</span>
|
||||||
<span>{getStatValue('numberOfDraftApplications', 0)}</span>
|
<span><NumberFlow
|
||||||
|
value={getStatValue('numberOfDraftApplications', 0)}
|
||||||
|
format={{ notation: 'compact' }}
|
||||||
|
locales="it-IT" /></span>
|
||||||
</div>
|
</div>
|
||||||
<div className="statsBigBadges__gridItem">
|
<div className="statsBigBadges__gridItem">
|
||||||
<span>{__('Aziende', 'gepafin')}</span>
|
<span>{__('Aziende', 'gepafin')}</span>
|
||||||
<span>{getStatValue('numberOfCompany', 0)}</span>
|
<span><NumberFlow
|
||||||
|
value={getStatValue('numberOfCompany', 0)}
|
||||||
|
format={{ notation: 'compact' }}
|
||||||
|
locales="it-IT" /></span>
|
||||||
</div>
|
</div>
|
||||||
<div className="statsBigBadges__gridItem">
|
<div className="statsBigBadges__gridItem">
|
||||||
<span>{__('Totale finanziamenti attivi', 'gepafin')}</span>
|
<span>{__('Totale finanziamenti attivi', 'gepafin')}</span>
|
||||||
<span>€{formatToMillions(getStatValue('totalActiveFinancing', 0))}</span>
|
<span><NumberFlow
|
||||||
|
value={getStatValue('totalActiveFinancing', 0)}
|
||||||
|
format={{
|
||||||
|
notation: 'compact',
|
||||||
|
compactDisplay: 'short',
|
||||||
|
roundingMode: 'trunc',
|
||||||
|
style: 'currency',
|
||||||
|
currency: 'EUR',
|
||||||
|
currencyDisplay: 'symbol'
|
||||||
|
}}
|
||||||
|
locales="en-US" /></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -95,10 +119,17 @@ const Dashboard = () => {
|
|||||||
<div className="appPage__spacer"></div>
|
<div className="appPage__spacer"></div>
|
||||||
|
|
||||||
<div className="appPageSection">
|
<div className="appPageSection">
|
||||||
<h2>{__('Ultimi Bandi Pubblicati', 'gepafin')}</h2>
|
<h2>{__('Ultimi bandi pubblicati', 'gepafin')}</h2>
|
||||||
<LatestBandiTable/>
|
<LatestBandiTable/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="appPage__spacer"></div>
|
||||||
|
|
||||||
|
<div className="appPageSection">
|
||||||
|
<h2>{__('Ultime domande pubblicate', 'gepafin')}</h2>
|
||||||
|
<AllDomandeTable/>
|
||||||
|
</div>
|
||||||
|
|
||||||
{/*<div className="appPage__spacer"></div>
|
{/*<div className="appPage__spacer"></div>
|
||||||
|
|
||||||
<div className="appPageSection">
|
<div className="appPageSection">
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import { __ } from '@wordpress/i18n';
|
import { __ } from '@wordpress/i18n';
|
||||||
import { uniq } from 'ramda';
|
import { uniq } from 'ramda';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
// tools
|
|
||||||
import getBandoLabel from '../../../../helpers/getBandoLabel';
|
|
||||||
import getBandoSeverity from '../../../../helpers/getBandoSeverity';
|
|
||||||
|
|
||||||
// store
|
// store
|
||||||
import { storeSet } from '../../../../store';
|
import { storeSet } from '../../../../store';
|
||||||
@@ -19,13 +16,9 @@ import { Column } from 'primereact/column';
|
|||||||
import { InputText } from 'primereact/inputtext';
|
import { InputText } from 'primereact/inputtext';
|
||||||
import { IconField } from 'primereact/iconfield';
|
import { IconField } from 'primereact/iconfield';
|
||||||
import { InputIcon } from 'primereact/inputicon';
|
import { InputIcon } from 'primereact/inputicon';
|
||||||
import { Dropdown } from 'primereact/dropdown';
|
|
||||||
import { InputNumber } from 'primereact/inputnumber';
|
|
||||||
import { Button } from 'primereact/button';
|
import { Button } from 'primereact/button';
|
||||||
import { Calendar } from 'primereact/calendar';
|
import { Calendar } from 'primereact/calendar';
|
||||||
import { Tag } from 'primereact/tag';
|
|
||||||
import ProperBandoLabel from '../../../../components/ProperBandoLabel';
|
import ProperBandoLabel from '../../../../components/ProperBandoLabel';
|
||||||
import { Link } from 'react-router-dom';
|
|
||||||
|
|
||||||
|
|
||||||
const LatestBandiTable = () => {
|
const LatestBandiTable = () => {
|
||||||
@@ -43,7 +36,7 @@ const LatestBandiTable = () => {
|
|||||||
const getCallback = (data) => {
|
const getCallback = (data) => {
|
||||||
if (data.status === 'SUCCESS') {
|
if (data.status === 'SUCCESS') {
|
||||||
const newItems = data.data.filter(o => o.status === 'PUBLISH');
|
const newItems = data.data.filter(o => o.status === 'PUBLISH');
|
||||||
setItems(getFormattedBandiData(newItems));
|
setItems(getFormattedData(newItems));
|
||||||
setStatuses(uniq(data.data.map(o => o.status)))
|
setStatuses(uniq(data.data.map(o => o.status)))
|
||||||
initFilters();
|
initFilters();
|
||||||
}
|
}
|
||||||
@@ -55,7 +48,7 @@ const LatestBandiTable = () => {
|
|||||||
storeSet.main.unsetAsyncRequest();
|
storeSet.main.unsetAsyncRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
const getFormattedBandiData = (data) => {
|
const getFormattedData = (data) => {
|
||||||
return [...(data || [])].map((d) => {
|
return [...(data || [])].map((d) => {
|
||||||
d.start_date = new Date(d.dates[0]);
|
d.start_date = new Date(d.dates[0]);
|
||||||
d.end_date = new Date(d.dates[1]);
|
d.end_date = new Date(d.dates[1]);
|
||||||
@@ -89,18 +82,9 @@ const LatestBandiTable = () => {
|
|||||||
const initFilters = () => {
|
const initFilters = () => {
|
||||||
setFilters({
|
setFilters({
|
||||||
global: { value: null, matchMode: FilterMatchMode.CONTAINS },
|
global: { value: null, matchMode: FilterMatchMode.CONTAINS },
|
||||||
name: {
|
name: { operator: FilterOperator.AND, constraints: [{ value: null, matchMode: FilterMatchMode.STARTS_WITH }] },
|
||||||
operator: FilterOperator.AND,
|
start_date: { operator: FilterOperator.AND, constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }] },
|
||||||
constraints: [{ value: null, matchMode: FilterMatchMode.STARTS_WITH }]
|
end_date: { operator: FilterOperator.AND, constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }] },
|
||||||
},
|
|
||||||
start_date: {
|
|
||||||
operator: FilterOperator.AND,
|
|
||||||
constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }]
|
|
||||||
},
|
|
||||||
end_date: {
|
|
||||||
operator: FilterOperator.AND,
|
|
||||||
constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }]
|
|
||||||
},
|
|
||||||
status: { operator: FilterOperator.OR, constraints: [{ value: null, matchMode: FilterMatchMode.EQUALS }] }
|
status: { operator: FilterOperator.OR, constraints: [{ value: null, matchMode: FilterMatchMode.EQUALS }] }
|
||||||
});
|
});
|
||||||
setGlobalFilterValue('');
|
setGlobalFilterValue('');
|
||||||
@@ -109,12 +93,10 @@ const LatestBandiTable = () => {
|
|||||||
const renderHeader = () => {
|
const renderHeader = () => {
|
||||||
return (
|
return (
|
||||||
<div className="appTableHeader">
|
<div className="appTableHeader">
|
||||||
<Button type="button" icon="pi pi-filter-slash" label={__('Pulisci', 'gepafin')} outlined
|
<Button type="button" icon="pi pi-filter-slash" label={__('Pulisci', 'gepafin')} outlined onClick={clearFilter} />
|
||||||
onClick={clearFilter}/>
|
|
||||||
<IconField iconPosition="left">
|
<IconField iconPosition="left">
|
||||||
<InputIcon className="pi pi-search"/>
|
<InputIcon className="pi pi-search" />
|
||||||
<InputText value={globalFilterValue} onChange={onGlobalFilterChange}
|
<InputText value={globalFilterValue} onChange={onGlobalFilterChange} placeholder={__('Cerca', 'gepafin')} />
|
||||||
placeholder={__('Cerca', 'gepafin')}/>
|
|
||||||
</IconField>
|
</IconField>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@@ -129,29 +111,13 @@ const LatestBandiTable = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const dateFilterTemplate = (options) => {
|
const dateFilterTemplate = (options) => {
|
||||||
return <Calendar value={options.value} onChange={(e) => options.filterCallback(e.value, options.index)}
|
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" />;
|
||||||
dateFormat="mm/dd/yy" placeholder="mm/dd/yyyy" mask="99/99/9999"/>;
|
|
||||||
};
|
|
||||||
|
|
||||||
const balanceFilterTemplate = (options) => {
|
|
||||||
return <InputNumber value={options.value} onChange={(e) => options.filterCallback(e.value, options.index)}/>;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const statusBodyTemplate = (rowData) => {
|
const statusBodyTemplate = (rowData) => {
|
||||||
return <ProperBandoLabel status={rowData.status}/>;
|
return <ProperBandoLabel status={rowData.status}/>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const statusFilterTemplate = (options) => {
|
|
||||||
return <Dropdown value={options.value} options={statuses}
|
|
||||||
onChange={(e) => options.filterCallback(e.value, options.index)}
|
|
||||||
itemTemplate={statusItemTemplate} placeholder="Select One" className="p-column-filter"
|
|
||||||
showClear/>;
|
|
||||||
};
|
|
||||||
|
|
||||||
const statusItemTemplate = (option) => {
|
|
||||||
return <Tag value={getBandoLabel(option)} severity={getBandoSeverity(option)}/>;
|
|
||||||
};
|
|
||||||
|
|
||||||
const actionsBodyTemplate = (rowData) => {
|
const actionsBodyTemplate = (rowData) => {
|
||||||
return rowData.confidi
|
return rowData.confidi
|
||||||
? <Link to={`/bandi/${rowData.id}`}>
|
? <Link to={`/bandi/${rowData.id}`}>
|
||||||
@@ -173,16 +139,16 @@ const LatestBandiTable = () => {
|
|||||||
header={header}
|
header={header}
|
||||||
emptyMessage={__('Nessun dato disponibile', 'gepafin')}
|
emptyMessage={__('Nessun dato disponibile', 'gepafin')}
|
||||||
onFilter={(e) => setFilters(e.filters)}>
|
onFilter={(e) => setFilters(e.filters)}>
|
||||||
<Column field="name" header={__('Nome Bando', 'gepafin')} filter filterPlaceholder="Search by name"
|
<Column field="name" header={__('Nome Bando', 'gepafin')} filter filterPlaceholder={__('Cerca il nome', 'gepafin')}
|
||||||
style={{ minWidth: '12rem' }}/>
|
style={{ minWidth: '8rem' }}/>
|
||||||
<Column header={__('Data Pubblicazione', 'gepafin')} filterField="start_date" dataType="date"
|
<Column header={__('Data Pubblicazione', 'gepafin')} filterField="start_date" dataType="date"
|
||||||
style={{ minWidth: '10rem' }}
|
style={{ minWidth: '8rem' }}
|
||||||
body={dateStartBodyTemplate} filter filterElement={dateFilterTemplate}/>
|
body={dateStartBodyTemplate} filter filterElement={dateFilterTemplate}/>
|
||||||
<Column header={__('Data Scadenza', 'gepafin')} filterField="end_date" dataType="date"
|
<Column header={__('Data Scadenza', 'gepafin')} filterField="end_date" dataType="date"
|
||||||
style={{ minWidth: '10rem' }}
|
style={{ minWidth: '8rem' }}
|
||||||
body={dateEndBodyTemplate} filter filterElement={dateFilterTemplate}/>
|
body={dateEndBodyTemplate} filter filterElement={dateFilterTemplate}/>
|
||||||
<Column field="status" header={__('Stato', 'gepafin')}
|
<Column field="status" header={__('Stato', 'gepafin')}
|
||||||
style={{ width: '120px' }} body={statusBodyTemplate}/>
|
style={{ minWidth: '7rem' }} body={statusBodyTemplate} />
|
||||||
<Column header={__('Azioni', 'gepafin')}
|
<Column header={__('Azioni', 'gepafin')}
|
||||||
body={actionsBodyTemplate}/>
|
body={actionsBodyTemplate}/>
|
||||||
</DataTable>
|
</DataTable>
|
||||||
|
|||||||
@@ -1,11 +1,17 @@
|
|||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import { __ } from '@wordpress/i18n';
|
import { __ } from '@wordpress/i18n';
|
||||||
import { uniq } from 'ramda';
|
import { uniq, is } from 'ramda';
|
||||||
|
|
||||||
// tools
|
// tools
|
||||||
import getBandoLabel from '../../../../helpers/getBandoLabel';
|
import getBandoLabel from '../../../../helpers/getBandoLabel';
|
||||||
import getBandoSeverity from '../../../../helpers/getBandoSeverity';
|
import getBandoSeverity from '../../../../helpers/getBandoSeverity';
|
||||||
|
|
||||||
|
// store
|
||||||
|
import { useStore } from '../../../../store';
|
||||||
|
|
||||||
|
// api
|
||||||
|
import ApplicationService from '../../../../service/application-service';
|
||||||
|
|
||||||
// components
|
// components
|
||||||
import { FilterMatchMode, FilterOperator } from 'primereact/api';
|
import { FilterMatchMode, FilterOperator } from 'primereact/api';
|
||||||
import { DataTable } from 'primereact/datatable';
|
import { DataTable } from 'primereact/datatable';
|
||||||
@@ -20,38 +26,36 @@ import { Calendar } from 'primereact/calendar';
|
|||||||
import { Tag } from 'primereact/tag';
|
import { Tag } from 'primereact/tag';
|
||||||
import ProperBandoLabel from '../../../../components/ProperBandoLabel';
|
import ProperBandoLabel from '../../../../components/ProperBandoLabel';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import ApplicationService from '../../../../service/application-service';
|
|
||||||
import { storeSet, useStore } from '../../../../store';
|
|
||||||
import set404FromErrorResponse from '../../../../helpers/set404FromErrorResponse';
|
|
||||||
|
|
||||||
|
|
||||||
const MyLatestSubmissionsTable = () => {
|
const MyLatestSubmissionsTable = () => {
|
||||||
const chosenCompanyId = useStore().main.chosenCompanyId();
|
const chosenCompanyId = useStore().main.chosenCompanyId();
|
||||||
const isAsyncRequest = useStore().main.isAsyncRequest();
|
const [localAsyncRequest, setLocalAsyncRequest] = useState(false);
|
||||||
const [items, setItems] = useState(null);
|
const [items, setItems] = useState(null);
|
||||||
const [filters, setFilters] = useState(null);
|
const [filters, setFilters] = useState(null);
|
||||||
const [globalFilterValue, setGlobalFilterValue] = useState('');
|
const [globalFilterValue, setGlobalFilterValue] = useState('');
|
||||||
const [statuses, setStatuses] = useState([]);
|
const [statuses, setStatuses] = useState([]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
storeSet.main.setAsyncRequest();
|
setLocalAsyncRequest(true);
|
||||||
ApplicationService.getApplications(getApplCallback, errGetApplCallback, [['companyId', chosenCompanyId]])
|
ApplicationService.getApplications(getApplCallback, errGetApplCallback, [
|
||||||
|
['companyId', chosenCompanyId],
|
||||||
|
['statuses', ['DRAFT', 'SUBMIT', 'AWAITING', 'READY', 'DISCARD']]
|
||||||
|
])
|
||||||
}, [chosenCompanyId]);
|
}, [chosenCompanyId]);
|
||||||
|
|
||||||
const getApplCallback = (data) => {
|
const getApplCallback = (data) => {
|
||||||
if (data.status === 'SUCCESS') {
|
if (data.status === 'SUCCESS') {
|
||||||
if (data.data.length) {
|
if (is(Array, data.data)) {
|
||||||
setItems(getFormattedBandiData(data.data));
|
setItems(getFormattedBandiData(data.data));
|
||||||
setStatuses(uniq(items.map(o => o.status)))
|
setStatuses(uniq(items.map(o => o.status)))
|
||||||
initFilters();
|
initFilters();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
storeSet.main.unsetAsyncRequest();
|
setLocalAsyncRequest(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
const errGetApplCallback = (data) => {
|
const errGetApplCallback = (data) => {
|
||||||
set404FromErrorResponse(data);
|
setLocalAsyncRequest(false);
|
||||||
storeSet.main.unsetAsyncRequest();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const getFormattedBandiData = (data) => {
|
const getFormattedBandiData = (data) => {
|
||||||
@@ -165,26 +169,27 @@ const MyLatestSubmissionsTable = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="appPageSection__table">
|
<div className="appPageSection__table">
|
||||||
<DataTable value={items} paginator showGridlines rows={10} loading={isAsyncRequest} dataKey="id"
|
<DataTable value={items} paginator showGridlines rows={10} loading={localAsyncRequest} dataKey="id"
|
||||||
filters={filters}
|
filters={filters}
|
||||||
globalFilterFields={['name', 'status']}
|
globalFilterFields={['name', 'status']}
|
||||||
header={header}
|
header={header}
|
||||||
emptyMessage={__('Nessun dato disponibile', 'gepafin')}
|
emptyMessage={__('Nessun dato disponibile', 'gepafin')}
|
||||||
onFilter={(e) => setFilters(e.filters)}>
|
onFilter={(e) => setFilters(e.filters)}>
|
||||||
<Column field="callTitle" header={__('Bando', 'gepafin')} filter filterPlaceholder="Search by name"
|
<Column field="callTitle" header={__('Bando', 'gepafin')} filter filterPlaceholder={__('Cerca il nome', 'gepafin')}
|
||||||
style={{ minWidth: '12rem' }}/>
|
style={{ minWidth: '8rem' }}/>
|
||||||
<Column header={__('Scadenza', 'gepafin')} filterField="callEndDate" dataType="date"
|
<Column header={__('Scadenza', 'gepafin')} filterField="callEndDate" dataType="date"
|
||||||
style={{ minWidth: '10rem' }}
|
style={{ minWidth: '8rem' }}
|
||||||
body={dateEndBodyTemplate} filter filterElement={dateFilterTemplate}/>
|
body={dateEndBodyTemplate} filter filterElement={dateFilterTemplate}/>
|
||||||
<Column header={__('Ultima modifica', 'gepafin')} filterField="modifiedDate" dataType="date"
|
<Column header={__('Ultima modifica', 'gepafin')} filterField="modifiedDate" dataType="date"
|
||||||
style={{ minWidth: '10rem' }}
|
style={{ minWidth: '8rem' }}
|
||||||
body={dateModifyBodyTemplate} filter filterElement={dateFilterTemplate}/>
|
body={dateModifyBodyTemplate} filter filterElement={dateFilterTemplate}/>
|
||||||
<Column field="status" header={__('Stato', 'gepafin')} filterMenuStyle={{ width: '14rem' }}
|
<Column field="status" header={__('Stato', 'gepafin')} filterMenuStyle={{ width: '14rem' }}
|
||||||
style={{ width: '120px' }} body={statusBodyTemplate} filter
|
style={{ minWidth: '7rem' }} body={statusBodyTemplate} filter
|
||||||
filterElement={statusFilterTemplate}/>
|
filterElement={statusFilterTemplate}/>
|
||||||
<Column header={__('Progressi', 'gepafin')}
|
<Column header={__('Progressi', 'gepafin')}
|
||||||
style={{ minWidth: '10rem' }} field="progress" body={progressBodyTemplate}/>
|
style={{ minWidth: '10rem' }} field="progress" body={progressBodyTemplate}/>
|
||||||
<Column header={__('Azioni', 'gepafin')}
|
<Column header={__('Azioni', 'gepafin')}
|
||||||
|
style={{ minWidth: '10rem' }}
|
||||||
body={actionsBodyTemplate}/>
|
body={actionsBodyTemplate}/>
|
||||||
</DataTable>
|
</DataTable>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import React, { useEffect, useState } from 'react';
|
|||||||
import { __ } from '@wordpress/i18n';
|
import { __ } from '@wordpress/i18n';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { head, pathOr } from 'ramda';
|
import { head, pathOr } from 'ramda';
|
||||||
|
import NumberFlow from '@number-flow/react';
|
||||||
|
|
||||||
// store
|
// store
|
||||||
import { useStore } from '../../store';
|
import { useStore } from '../../store';
|
||||||
@@ -57,15 +58,24 @@ const DashboardBeneficiario = () => {
|
|||||||
<div className="statsBigBadges__grid">
|
<div className="statsBigBadges__grid">
|
||||||
<div className="statsBigBadges__gridItem">
|
<div className="statsBigBadges__gridItem">
|
||||||
<span>{__('Domande attive', 'gepafin')}</span>
|
<span>{__('Domande attive', 'gepafin')}</span>
|
||||||
<span>{getStatValue('numberOfApplications', 0)}</span>
|
<span><NumberFlow
|
||||||
|
value={getStatValue('numberOfApplications', 0)}
|
||||||
|
format={{ notation: 'compact' }}
|
||||||
|
locales="it-IT" /></span>
|
||||||
</div>
|
</div>
|
||||||
<div className="statsBigBadges__gridItem">
|
<div className="statsBigBadges__gridItem">
|
||||||
<span>{__('Bandi osservati', 'gepafin')}</span>
|
<span>{__('Bandi osservati', 'gepafin')}</span>
|
||||||
<span>{getStatValue('numberOfCalls', 0)}</span>
|
<span><NumberFlow
|
||||||
|
value={getStatValue('numberOfCalls', 0)}
|
||||||
|
format={{ notation: 'compact' }}
|
||||||
|
locales="it-IT" /></span>
|
||||||
</div>
|
</div>
|
||||||
<div className="statsBigBadges__gridItem">
|
<div className="statsBigBadges__gridItem">
|
||||||
<span>{__('Documenti da integrare', 'gepafin')}</span>
|
<span>{__('Documenti da integrare', 'gepafin')}</span>
|
||||||
<span>{getStatValue('numberOfIntegratedDocuments', 0)}</span>
|
<span><NumberFlow
|
||||||
|
value={getStatValue('numberOfIntegratedDocuments', 0)}
|
||||||
|
format={{ notation: 'compact' }}
|
||||||
|
locales="it-IT" /></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1,166 @@
|
|||||||
|
import React, { useState, useEffect} from 'react';
|
||||||
|
import { __ } from '@wordpress/i18n';
|
||||||
|
import { is, uniq } from 'ramda';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
|
// store
|
||||||
|
import { useStore } from '../../../../store';
|
||||||
|
|
||||||
|
// api
|
||||||
|
import AssignedApplicationService from '../../../../service/assigned-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 PreInstructorDomandeTable = () => {
|
||||||
|
const userData = useStore().main.userData();
|
||||||
|
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);
|
||||||
|
AssignedApplicationService.getAssignedApplications(getCallback, errGetCallbacks, [
|
||||||
|
['userId', userData.id]
|
||||||
|
]);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
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.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 },
|
||||||
|
callName: {
|
||||||
|
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 <Link to={`/domande/${rowData.applicationId}`}>
|
||||||
|
<Button severity="info" label={__('Valuta', 'gepafin')} icon="pi pi-eye" size="small" iconPos="right"/>
|
||||||
|
</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="applicationId" header={__('ID domanda', 'gepafin')}
|
||||||
|
filter filterPlaceholder={__('Cerca', 'gepafin')}
|
||||||
|
style={{ minWidth: '6rem' }}/>
|
||||||
|
<Column field="callName" header={__('Bando', 'gepafin')}
|
||||||
|
filter filterPlaceholder={__('Cerca', 'gepafin')}
|
||||||
|
style={{ minWidth: '8rem' }}/>
|
||||||
|
<Column header={__('Data ricezione', 'gepafin')} filterField="submissionDate" dataType="date"
|
||||||
|
style={{ minWidth: '8rem' }}
|
||||||
|
body={dateAppliedBodyTemplate} filter filterElement={dateFilterTemplate}/>
|
||||||
|
<Column header={__('Scadenza', 'gepafin')} filterField="callEndDate" dataType="date"
|
||||||
|
style={{ minWidth: '8rem' }}
|
||||||
|
body={dateEndBodyTemplate} filter filterElement={dateFilterTemplate}/>
|
||||||
|
<Column field="status" header={__('Stato', 'gepafin')}
|
||||||
|
style={{ minWidth: '7rem' }} body={statusBodyTemplate} />
|
||||||
|
<Column header={__('Azioni', 'gepafin')}
|
||||||
|
body={actionsBodyTemplate}/>
|
||||||
|
</DataTable>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PreInstructorDomandeTable;
|
||||||
75
src/pages/DashboardPreInstructor/index.js
Normal file
75
src/pages/DashboardPreInstructor/index.js
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { __ } from '@wordpress/i18n';
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
|
// store
|
||||||
|
//import { useStore } from '../../store';
|
||||||
|
|
||||||
|
// api
|
||||||
|
//import DashboardService from '../../service/dashboard-service';
|
||||||
|
|
||||||
|
// components
|
||||||
|
//import LatestBandiTable from './components/LatestBandiTable';
|
||||||
|
//import MyLatestSubmissionsTable from './components/MyLatestSubmissionsTable';
|
||||||
|
import { Button } from 'primereact/button';
|
||||||
|
import PreInstructorDomandeTable from './components/PreInstructorDomandeTable';
|
||||||
|
|
||||||
|
const DashboardPreInstructor = () => {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
//const [mainStats, setMainStats] = useState({});
|
||||||
|
|
||||||
|
const goToAllEvaluations = () => {
|
||||||
|
navigate('/domande');
|
||||||
|
}
|
||||||
|
|
||||||
|
return(
|
||||||
|
<div className="appPage">
|
||||||
|
<div className="appPage__pageHeader">
|
||||||
|
<h1>{__('Dashboard', 'gepafin')}</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/*<div className="appPage__spacer"></div>
|
||||||
|
|
||||||
|
<div className="appPageSection statsBigBadges">
|
||||||
|
<h2>{__('Panoramica di Sistema', 'gepafin')}</h2>
|
||||||
|
<div className="statsBigBadges__grid">
|
||||||
|
<div className="statsBigBadges__gridItem">
|
||||||
|
<span>{__('Domande attive', 'gepafin')}</span>
|
||||||
|
<span>{getStatValue('numberOfApplications', 0)}</span>
|
||||||
|
</div>
|
||||||
|
<div className="statsBigBadges__gridItem">
|
||||||
|
<span>{__('Bandi osservati', 'gepafin')}</span>
|
||||||
|
<span>{getStatValue('numberOfCalls', 0)}</span>
|
||||||
|
</div>
|
||||||
|
<div className="statsBigBadges__gridItem">
|
||||||
|
<span>{__('Documenti da integrare', 'gepafin')}</span>
|
||||||
|
<span>{getStatValue('numberOfIntegratedDocuments', 0)}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>*/}
|
||||||
|
|
||||||
|
<div className="appPage__spacer"></div>
|
||||||
|
|
||||||
|
<div className="appPageSection">
|
||||||
|
<h2>{__('Coda di lavoro', 'gepafin')}</h2>
|
||||||
|
<PreInstructorDomandeTable/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="appPage__spacer"></div>
|
||||||
|
|
||||||
|
<div className="appPageSection__hr">
|
||||||
|
<span>{__('Azioni rapide', 'gepafin')}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="appPageSection">
|
||||||
|
<div className="appPageSection__actions">
|
||||||
|
<Button
|
||||||
|
onClick={goToAllEvaluations}
|
||||||
|
label={__('Tutte le domande', 'gepafin')} icon="pi pi-arrow-right" iconPos="right"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DashboardPreInstructor;
|
||||||
353
src/pages/DomandaBeneficiario/index.js
Normal file
353
src/pages/DomandaBeneficiario/index.js
Normal file
@@ -0,0 +1,353 @@
|
|||||||
|
import React, { useState, useEffect, useRef } from 'react';
|
||||||
|
import { __, sprintf } from '@wordpress/i18n';
|
||||||
|
import { useNavigate, useParams } from 'react-router-dom';
|
||||||
|
import { is, isEmpty, isNil } from 'ramda';
|
||||||
|
import { wrap } from 'object-path-immutable';
|
||||||
|
|
||||||
|
// store
|
||||||
|
import { storeSet, useStore } from '../../store';
|
||||||
|
|
||||||
|
// api
|
||||||
|
import AmendmentsService from '../../service/amendments-service';
|
||||||
|
import CommunicationService from '../../service/communication-service';
|
||||||
|
|
||||||
|
// tools
|
||||||
|
import set404FromErrorResponse from '../../helpers/set404FromErrorResponse';
|
||||||
|
import getBandoLabel from '../../helpers/getBandoLabel';
|
||||||
|
import getDateFromISOstring from '../../helpers/getDateFromISOstring';
|
||||||
|
import renderHtmlContent from '../../helpers/renderHtmlContent';
|
||||||
|
import uniqid from '../../helpers/uniqid';
|
||||||
|
|
||||||
|
// components
|
||||||
|
import { Button } from 'primereact/button';
|
||||||
|
import BlockingOverlay from '../../components/BlockingOverlay';
|
||||||
|
import { Toast } from 'primereact/toast';
|
||||||
|
import { classNames } from 'primereact/utils';
|
||||||
|
import { Dialog } from 'primereact/dialog';
|
||||||
|
import { InputText } from 'primereact/inputtext';
|
||||||
|
import { InputTextarea } from 'primereact/inputtextarea';
|
||||||
|
|
||||||
|
const DomandaBeneficiario = () => {
|
||||||
|
const isAsyncRequest = useStore().main.isAsyncRequest();
|
||||||
|
const { id } = useParams();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const [data, setData] = useState({});
|
||||||
|
const [comms, setComms] = useState([]);
|
||||||
|
const [isVisibleNewCommDialog, setIsVisibleNewCommDialog] = useState(false);
|
||||||
|
const [newCommData, setNewCommData] = useState({});
|
||||||
|
const [isLoadingCommunication, setIsLoadingCommunication] = useState(false);
|
||||||
|
const [isVisibleEmailDialog, setIsVisibleEmailDialog] = useState(false);
|
||||||
|
const toast = useRef(null);
|
||||||
|
|
||||||
|
const goToArchivePage = () => {
|
||||||
|
navigate(`/domande`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const getCallback = (data) => {
|
||||||
|
if (data.status === 'SUCCESS') {
|
||||||
|
if (data.data.length) {
|
||||||
|
setData(getFormattedData(data.data[0]));
|
||||||
|
CommunicationService.getCommsByAmendmentId(data.data[0].id, getCommsCallback, errGetCommsCallback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
storeSet.main.unsetAsyncRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
const errGetCallback = (data) => {
|
||||||
|
if (toast.current && data.message) {
|
||||||
|
toast.current.show({
|
||||||
|
severity: 'error',
|
||||||
|
summary: '',
|
||||||
|
detail: data.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
set404FromErrorResponse(data);
|
||||||
|
storeSet.main.unsetAsyncRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
const getCommsCallback = (data) => {
|
||||||
|
if (data.status === 'SUCCESS') {
|
||||||
|
setComms(data.data.commentsList.map(o => getFormattedCommsData(o)));
|
||||||
|
}
|
||||||
|
storeSet.main.unsetAsyncRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
const errGetCommsCallback = (data) => {
|
||||||
|
if (toast.current && data.message) {
|
||||||
|
toast.current.show({
|
||||||
|
severity: 'error',
|
||||||
|
summary: '',
|
||||||
|
detail: data.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
set404FromErrorResponse(data);
|
||||||
|
storeSet.main.unsetAsyncRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
const getFormattedData = (data) => {
|
||||||
|
data.startDate = is(String, data.startDate) ? new Date(data.startDate) : (data.startDate ? data.startDate : '');
|
||||||
|
data.expirationDate = is(String, data.expirationDate) ? new Date(data.expirationDate) : (data.expirationDate ? data.expirationDate : '');
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getFormattedCommsData = (data) => {
|
||||||
|
data.id = isNil(data.id) ? uniqid('id') : data.id;
|
||||||
|
data.commentedDate = is(String, data.commentedDate) ? new Date(data.commentedDate) : (data.commentedDate ? data.commentedDate : '');
|
||||||
|
data.createdDate = is(String, data.createdDate) ? new Date(data.createdDate) : (data.createdDate ? data.createdDate : '');
|
||||||
|
data.updatedDate = is(String, data.updatedDate) ? new Date(data.updatedDate) : (data.updatedDate ? data.updatedDate : '');
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
const headerNewComDialog = () => {
|
||||||
|
return <span>{__('Aggiungi comunicazione', 'gepafin')}</span>
|
||||||
|
}
|
||||||
|
|
||||||
|
const hideNewComDialog = () => {
|
||||||
|
setIsVisibleNewCommDialog(false);
|
||||||
|
setNewCommData({
|
||||||
|
title: '',
|
||||||
|
comment: ''
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const footerNewComDialog = () => {
|
||||||
|
return <div>
|
||||||
|
<Button type="button" label={__('Anulla', 'gepafin')} onClick={hideNewComDialog} outlined/>
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
disabled={isLoadingCommunication || isEmpty(newCommData.title) || isEmpty(newCommData.comment)}
|
||||||
|
label={__('Invia', 'gepafin')} onClick={createCommunication}/>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
const openNewCommDialog = () => {
|
||||||
|
setIsVisibleNewCommDialog(true);
|
||||||
|
setNewCommData({
|
||||||
|
title: '',
|
||||||
|
comment: ''
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateNewCommData = (value, path) => {
|
||||||
|
const newData = wrap(newCommData).set(path.split('.'), value).value();
|
||||||
|
setNewCommData(newData);
|
||||||
|
}
|
||||||
|
|
||||||
|
const createCommunication = () => {
|
||||||
|
setIsLoadingCommunication(true);
|
||||||
|
CommunicationService.createCommunication(data.id, newCommData, createCommunicationCallback, errCreateCommunicationCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
const createCommunicationCallback = (data) => {
|
||||||
|
if (data.status === 'SUCCESS') {
|
||||||
|
if (toast.current) {
|
||||||
|
toast.current.show({
|
||||||
|
severity: 'success',
|
||||||
|
summary: '',
|
||||||
|
detail: data.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
setComms([...comms, getFormattedCommsData(data.data)])
|
||||||
|
setIsVisibleNewCommDialog(false);
|
||||||
|
}
|
||||||
|
setIsLoadingCommunication(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
const errCreateCommunicationCallback = (data) => {
|
||||||
|
if (toast.current && data.message) {
|
||||||
|
toast.current.show({
|
||||||
|
severity: 'error',
|
||||||
|
summary: '',
|
||||||
|
detail: data.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
set404FromErrorResponse(data);
|
||||||
|
setIsLoadingCommunication(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const parsedId = parseInt(id);
|
||||||
|
const entityId = !isNaN(parsedId) ? parsedId : 0;
|
||||||
|
|
||||||
|
AmendmentsService.getSoccorsoByApplId(entityId, getCallback, errGetCallback, [
|
||||||
|
['statuses', 'AWAITING']
|
||||||
|
]);
|
||||||
|
}, [id]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="appPage">
|
||||||
|
<div className="appPage__pageHeader">
|
||||||
|
<h1>{sprintf(__('Soccorso Istruttorio: richiesta integrazione documenti per domanda #%s', 'gepafin'), id)}</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="appPage__spacer"></div>
|
||||||
|
<Toast ref={toast}/>
|
||||||
|
<BlockingOverlay shouldDisplay={isAsyncRequest}/>
|
||||||
|
|
||||||
|
<div className="appPageSection__row">
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
outlined
|
||||||
|
onClick={goToArchivePage}
|
||||||
|
label={__('Indietro', 'gepafin')}
|
||||||
|
icon="pi pi-arrow-left" iconPos="left"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="appPage__spacer"></div>
|
||||||
|
|
||||||
|
<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.beneficiaryName}</span>
|
||||||
|
</p>
|
||||||
|
<p className="appPageSection__pMeta">
|
||||||
|
<span>{__('Inizio', 'gepafin')}</span>
|
||||||
|
<span>{getDateFromISOstring(data.startDate)}</span>
|
||||||
|
</p>
|
||||||
|
<p className="appPageSection__pMeta">
|
||||||
|
<span>{__('Scadenza', 'gepafin')}</span>
|
||||||
|
<span>{getDateFromISOstring(data.expirationDate)}</span>
|
||||||
|
</p>
|
||||||
|
<p className="appPageSection__pMeta">
|
||||||
|
<span>{__('Stato', 'gepafin')}</span>
|
||||||
|
<span>{getBandoLabel(data.status)}</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="appPageSection">
|
||||||
|
<h2>{__('Dettagli Richiesta', 'gepafin')}</h2>
|
||||||
|
<h3>{__('Documenti Richiesti', 'gepafin')}</h3>
|
||||||
|
<ol className="appPageSection__list">
|
||||||
|
{data.formFields
|
||||||
|
? data.formFields.map((o, i) => <li key={o.fieldId}
|
||||||
|
style={{ flexDirection: 'row' }}>
|
||||||
|
<span>{o.label}</span>
|
||||||
|
</li>) : null}
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="appPageSection">
|
||||||
|
<h3>{__('Note e spiegazioni', 'gepafin')}</h3>
|
||||||
|
<div className="appPageSection__withBorder grey ql-editor"
|
||||||
|
style={{ minHeight: '200px' }}>
|
||||||
|
{renderHtmlContent(data.note)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="appPageSection">
|
||||||
|
<h2>{__('Comunicazioni', 'gepafin')}</h2>
|
||||||
|
<table className="myTable">
|
||||||
|
<thead className="myThead">
|
||||||
|
<tr>
|
||||||
|
<th style={{ width: 250 }}>{__('Data', 'gepafin')}</th>
|
||||||
|
<th>{__('Comunicazione', 'gepafin')}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody className="myTbody">
|
||||||
|
{!isNil(comms) && !isEmpty(comms)
|
||||||
|
? comms.map((o, i) => <tr key={o.id}>
|
||||||
|
<td valign="top">
|
||||||
|
{getDateFromISOstring(o.commentedDate)}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<h3>{o.title}</h3>
|
||||||
|
<p>{o.comment}</p>
|
||||||
|
</td>
|
||||||
|
</tr>)
|
||||||
|
: <tr>
|
||||||
|
<td>-</td>
|
||||||
|
<td>-</td>
|
||||||
|
</tr>}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
style={{ marginTop: 30 }}
|
||||||
|
onClick={openNewCommDialog}
|
||||||
|
disabled={data.status === 'CLOSE'}
|
||||||
|
type="button"
|
||||||
|
label={__('Aggiungi Comunicazione', 'gepafin')}
|
||||||
|
icon="pi pi-plus" iconPos="right"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="appPageSection__message warning">
|
||||||
|
<i className="pi pi-exclamation-triangle"></i>
|
||||||
|
<span className="summary">{__('Attenzione', 'gepafin')}</span>
|
||||||
|
<span>{__('Inviare la documentazione richiesta completa delle integrazioni esclusivamente via PEC. In caso contarrio l’integrazione non può essere ritenuta valida.', 'gepafin')}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="appPageSection">
|
||||||
|
<div className="appPageSection__actions">
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
disabled={isAsyncRequest}
|
||||||
|
onClick={() => setIsVisibleEmailDialog(true)}
|
||||||
|
label={__('Invia documenti via PEC', 'gepafin')}
|
||||||
|
icon="pi pi-envelope" iconPos="right"/>
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
outlined
|
||||||
|
onClick={goToArchivePage}
|
||||||
|
disabled={isAsyncRequest}
|
||||||
|
label={__('Chiudi', 'gepafin')}
|
||||||
|
icon="pi pi-times" iconPos="right"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Dialog
|
||||||
|
visible={isVisibleNewCommDialog}
|
||||||
|
modal
|
||||||
|
header={headerNewComDialog}
|
||||||
|
footer={footerNewComDialog}
|
||||||
|
style={{ maxWidth: '600px', width: '100%' }}
|
||||||
|
onHide={hideNewComDialog}>
|
||||||
|
<div className="appForm__field">
|
||||||
|
<label
|
||||||
|
className={classNames({ 'p-error': isEmpty(newCommData.title) })}>
|
||||||
|
{__('Titolo', 'gepafin')}*
|
||||||
|
</label>
|
||||||
|
<InputText value={newCommData.title}
|
||||||
|
disabled={data.status === 'CLOSE'}
|
||||||
|
invalid={isEmpty(newCommData.title)}
|
||||||
|
onChange={(e) => updateNewCommData(e.target.value, 'title')}/>
|
||||||
|
|
||||||
|
<label
|
||||||
|
className={classNames({ 'p-error': isEmpty(newCommData.comment) })}>
|
||||||
|
{__('Contenuto', 'gepafin')}*
|
||||||
|
</label>
|
||||||
|
<InputTextarea
|
||||||
|
value={newCommData.comment}
|
||||||
|
disabled={data.status === 'CLOSE'}
|
||||||
|
rows={5} cols={30}
|
||||||
|
invalid={isEmpty(newCommData.comment)}
|
||||||
|
onChange={(e) => updateNewCommData(e.target.value, 'comment')}/>
|
||||||
|
</div>
|
||||||
|
</Dialog>
|
||||||
|
|
||||||
|
<Dialog
|
||||||
|
header={__('Invia documenti via PEC', 'gepafin')}
|
||||||
|
visible={isVisibleEmailDialog}
|
||||||
|
style={{ width: '50vw' }}
|
||||||
|
onHide={() => {if (!isVisibleEmailDialog) return; setIsVisibleEmailDialog(false); }}>
|
||||||
|
<p className="m-0">
|
||||||
|
{data.callEmail}
|
||||||
|
</p>
|
||||||
|
</Dialog>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DomandaBeneficiario;
|
||||||
564
src/pages/DomandaEditPreInstructor/index.js
Normal file
564
src/pages/DomandaEditPreInstructor/index.js
Normal file
@@ -0,0 +1,564 @@
|
|||||||
|
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, head } 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';
|
||||||
|
import AmendmentsService from '../../service/amendments-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';
|
||||||
|
import { Dialog } from 'primereact/dialog';
|
||||||
|
|
||||||
|
const DomandaEditPreInstructor = () => {
|
||||||
|
const isAsyncRequest = useStore().main.isAsyncRequest();
|
||||||
|
const { id } = useParams();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const [data, setData] = useState({});
|
||||||
|
const [isVisibleCriterionData, setIsVisibleCriterionData] = useState(0);
|
||||||
|
const [criterionDataTitle, setCriterionDataTitle] = useState('');
|
||||||
|
const [criterionDataContent, setCriterionDataContent] = useState('');
|
||||||
|
const [isAdmissible, setIsAdmissible] = useState(false);
|
||||||
|
const [connectedSoccorsoId, setConnectedSoccorsoId] = useState(0);
|
||||||
|
const toast = useRef(null);
|
||||||
|
|
||||||
|
const goToEvaluationsPage = () => {
|
||||||
|
navigate('/domande');
|
||||||
|
}
|
||||||
|
|
||||||
|
const doNewSoccorso = () => {
|
||||||
|
if (connectedSoccorsoId !== 0) {
|
||||||
|
navigate(`/domande/${id}/soccorso/${connectedSoccorsoId}`);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
navigate(`/domande/${id}/aggiungi-soccorso/`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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(data.assignedApplicationId, 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
const doApprove = () => {
|
||||||
|
const formData = {
|
||||||
|
status: 'APPROVED'
|
||||||
|
}
|
||||||
|
ApplicationEvaluationService.updateEvaluation(data.assignedApplicationId, formData, updateStatusCallback, errUpdateStatusCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
const doReject = () => {
|
||||||
|
const formData = {
|
||||||
|
status: 'REJECTED'
|
||||||
|
}
|
||||||
|
ApplicationEvaluationService.updateEvaluation(data.assignedApplicationId, formData, updateStatusCallback, errUpdateStatusCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateStatusCallback = (data) => {
|
||||||
|
if (data.status === 'SUCCESS') {
|
||||||
|
if (toast.current) {
|
||||||
|
toast.current.show({
|
||||||
|
severity: 'success',
|
||||||
|
summary: '',
|
||||||
|
detail: data.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
storeSet.main.unsetAsyncRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
const errUpdateStatusCallback = (data) => {
|
||||||
|
if (toast.current && data.message) {
|
||||||
|
toast.current.show({
|
||||||
|
severity: 'error',
|
||||||
|
summary: '',
|
||||||
|
detail: data.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
set404FromErrorResponse(data);
|
||||||
|
storeSet.main.unsetAsyncRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
const displayCriterionData = (id) => {
|
||||||
|
const criterion = head(data.criteria.filter(o => o.id === id));
|
||||||
|
setCriterionDataTitle(criterion.label);
|
||||||
|
const content = <div className="criterionRelatedData">
|
||||||
|
<h3>{__('I campi correlati')}</h3>
|
||||||
|
{criterion.criteriaMappedFields ? criterion.criteriaMappedFields.map(o => criteriaDataItem(o)) : null}
|
||||||
|
</div>;
|
||||||
|
setCriterionDataContent(content);
|
||||||
|
setIsVisibleCriterionData(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
const criteriaDataItem = (item) => {
|
||||||
|
let content = '';
|
||||||
|
|
||||||
|
if (is(String, item.fieldValue)) {
|
||||||
|
content = item.fieldValue;
|
||||||
|
} else if (item.fieldValue && item.fieldValue.length && !isNil(item.fieldValue[0].filePath)) {
|
||||||
|
content = <ul>
|
||||||
|
{item.fieldValue.map(o => <li key={o.id}>
|
||||||
|
{o.filePath ? <a href={o.filePath}>{o.name}</a> : null}
|
||||||
|
</li>)}
|
||||||
|
</ul>;
|
||||||
|
} else if (item.fieldValue && item.fieldValue.length && isNil(item.fieldValue[0].filePath)) {
|
||||||
|
const th = Object.keys(item.fieldValue[0]);
|
||||||
|
content = <table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
{th.map(v => <th key={v}>{v}</th>)}
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{item.fieldValue.map((o, i) => <tr key={i}>
|
||||||
|
{Object.values(o).map(v => <td key={v}>{v}</td>)}
|
||||||
|
</tr>)}
|
||||||
|
</tbody>
|
||||||
|
</table>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return <div key={item.id} className="criterionRelatedData__item">
|
||||||
|
<strong>{item.fieldLabel}</strong>
|
||||||
|
{content}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
const hideCriterionData = () => {
|
||||||
|
setIsVisibleCriterionData(0);
|
||||||
|
setCriterionDataTitle('');
|
||||||
|
setCriterionDataContent('');
|
||||||
|
}
|
||||||
|
|
||||||
|
const getAmendmentsCallback = (data) => {
|
||||||
|
if (data.status === 'SUCCESS') {
|
||||||
|
if (data.data.length) {
|
||||||
|
setConnectedSoccorsoId(data.data[0].id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const errGetAmendmentsCallback = () => {
|
||||||
|
}
|
||||||
|
|
||||||
|
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(() => {
|
||||||
|
const parsed = parseInt(id)
|
||||||
|
const entityId = !isNaN(parsed) ? parsed : 0;
|
||||||
|
|
||||||
|
storeSet.main.setAsyncRequest();
|
||||||
|
ApplicationEvaluationService.getEvaluationByApplId(getCallback, errGetCallback, [
|
||||||
|
['applicationId', entityId]
|
||||||
|
]);
|
||||||
|
AmendmentsService.getSoccorsoByApplId(entityId, getAmendmentsCallback, errGetAmendmentsCallback, [
|
||||||
|
['statuses', 'AWAITING']
|
||||||
|
]);
|
||||||
|
}, [id]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="appPage">
|
||||||
|
<div className="appPage__pageHeader">
|
||||||
|
<h1>{__('Valuta domanda', 'gepafin')}</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="appPage__spacer"></div>
|
||||||
|
<Toast ref={toast}/>
|
||||||
|
<BlockingOverlay shouldDisplay={isAsyncRequest}/>
|
||||||
|
|
||||||
|
<div className="appPageSection__row">
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
outlined
|
||||||
|
onClick={goToEvaluationsPage}
|
||||||
|
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"
|
||||||
|
onClick={() => displayCriterionData(o.id)}
|
||||||
|
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" style={{ marginBottom: '20px' }}>
|
||||||
|
<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}>
|
||||||
|
<div className="appPageSection" style={{
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'space-between'
|
||||||
|
}}>
|
||||||
|
<span>{o.label}</span>
|
||||||
|
<div className="appPageSection__iconActions">
|
||||||
|
{o.fileDetail && 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>
|
||||||
|
</div>
|
||||||
|
{o.fileDetail && o.fileDetail.length > 1
|
||||||
|
? <ul style={{
|
||||||
|
width: '100%',
|
||||||
|
paddingLeft: '15px',
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'column',
|
||||||
|
gap: '10px'
|
||||||
|
}}>
|
||||||
|
{o.fileDetail.map((k, i) => <li key={k.id} style={{
|
||||||
|
display: 'flex',
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'space-between'
|
||||||
|
}}>
|
||||||
|
<span>{k.name}</span>
|
||||||
|
<div className="appPageSection__iconActions">
|
||||||
|
<Button icon="pi pi-eye" rounded
|
||||||
|
onClick={() => window.open(k.filePath, '_blank').focus()}
|
||||||
|
outlined severity="info"
|
||||||
|
aria-label={__('Mostra', 'gepafin')}/>
|
||||||
|
</div>
|
||||||
|
</li>)}
|
||||||
|
</ul>
|
||||||
|
: null}
|
||||||
|
</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"
|
||||||
|
disabled={!data.id}
|
||||||
|
onClick={doNewSoccorso}
|
||||||
|
outlined
|
||||||
|
label={<>
|
||||||
|
{__('Richiedi Soccorso Istruttorio', 'gepafin')}
|
||||||
|
<i style={{ marginLeft: 7 }}>
|
||||||
|
<HelpIcon/>
|
||||||
|
</i>
|
||||||
|
</>}
|
||||||
|
/>
|
||||||
|
{data.id
|
||||||
|
? <Button
|
||||||
|
type="button"
|
||||||
|
onClick={doSaveDraft}
|
||||||
|
outlined
|
||||||
|
label={__('Salva bozza valutazione', 'gepafin')}
|
||||||
|
icon="pi pi-save" iconPos="right"/>
|
||||||
|
: <Button
|
||||||
|
type="button"
|
||||||
|
onClick={doSaveDraft}
|
||||||
|
label={__('Crea valutazione', 'gepafin')}
|
||||||
|
icon="pi pi-save" iconPos="right"/>}
|
||||||
|
{data.id
|
||||||
|
? <Button
|
||||||
|
type="button"
|
||||||
|
disabled={!isAdmissible}
|
||||||
|
onClick={doApprove}
|
||||||
|
label={__('Approva Domanda', 'gepafin')}
|
||||||
|
icon="pi pi-check" iconPos="right"/> : null}
|
||||||
|
{data.id
|
||||||
|
? <Button
|
||||||
|
type="button"
|
||||||
|
onClick={doReject}
|
||||||
|
label={__('Respingi Domanda', 'gepafin')}
|
||||||
|
icon="pi pi-times" iconPos="right"/> : null}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Dialog
|
||||||
|
header={criterionDataTitle}
|
||||||
|
visible={isVisibleCriterionData !== 0}
|
||||||
|
style={{ width: '50vw' }}
|
||||||
|
onHide={hideCriterionData}>
|
||||||
|
{criterionDataContent}
|
||||||
|
</Dialog>
|
||||||
|
|
||||||
|
</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 DomandaEditPreInstructor;
|
||||||
173
src/pages/Domande/components/AllDomandeTable/index.js
Normal file
173
src/pages/Domande/components/AllDomandeTable/index.js
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
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 AllDomandeTable = ({ openDialogFn, updaterString = '' }) => {
|
||||||
|
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, [
|
||||||
|
['statuses', 'SUBMIT']
|
||||||
|
]);
|
||||||
|
}, [updaterString]);
|
||||||
|
|
||||||
|
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 AllDomandeTable;
|
||||||
178
src/pages/Domande/index.js
Normal file
178
src/pages/Domande/index.js
Normal file
@@ -0,0 +1,178 @@
|
|||||||
|
import React, { useEffect, useRef, useState } from 'react';
|
||||||
|
import { __ } from '@wordpress/i18n';
|
||||||
|
import { isEmpty } from 'ramda';
|
||||||
|
|
||||||
|
// api
|
||||||
|
import UserService from '../../service/user-service';
|
||||||
|
import AssignedApplicationService from '../../service/assigned-application-service';
|
||||||
|
|
||||||
|
// store
|
||||||
|
import { storeSet } from '../../store';
|
||||||
|
|
||||||
|
// tools
|
||||||
|
import set404FromErrorResponse from '../../helpers/set404FromErrorResponse';
|
||||||
|
import uniqid from '../../helpers/uniqid';
|
||||||
|
|
||||||
|
// components
|
||||||
|
import AllDomandeTable from './components/AllDomandeTable';
|
||||||
|
import { Dialog } from 'primereact/dialog';
|
||||||
|
import { Button } from 'primereact/button';
|
||||||
|
import { classNames } from 'primereact/utils';
|
||||||
|
import { Dropdown } from 'primereact/dropdown';
|
||||||
|
|
||||||
|
const Domande = () => {
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
const [isVisibleEditDialog, setIsVisibleEditDialog] = useState(false);
|
||||||
|
const [roleId, setRoleId] = useState(0);
|
||||||
|
const [users, setUsers] = useState([]);
|
||||||
|
const [chosenUser, setChosenUser] = useState(0);
|
||||||
|
const [chosenApplication, setChosenApplication] = useState(0);
|
||||||
|
const [updaterString, setUpdaterString] = useState('');
|
||||||
|
const toast = useRef(null);
|
||||||
|
|
||||||
|
const getRolesCallback = (data) => {
|
||||||
|
if (data.status === 'SUCCESS') {
|
||||||
|
const roles = data.data
|
||||||
|
.filter(o => ['ROLE_PRE_INSTRUCTOR'].includes(o.roleType));
|
||||||
|
if (roles.length) {
|
||||||
|
setRoleId(roles[0].id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
const errGetRolesCallback = (data) => {
|
||||||
|
set404FromErrorResponse(data);
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
const getUsersCallback = (data) => {
|
||||||
|
if (data.status === 'SUCCESS') {
|
||||||
|
const users = data.data
|
||||||
|
.map(o => ({
|
||||||
|
name: `${o.firstName} ${o.lastName} (${o.email})`,
|
||||||
|
value: o.id
|
||||||
|
}));
|
||||||
|
setUsers(users);
|
||||||
|
}
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
const errGetUsersCallback = (data) => {
|
||||||
|
set404FromErrorResponse(data);
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
const headerEditDialog = () => {
|
||||||
|
return <span>{__('Assign application', 'gepafin')}</span>
|
||||||
|
}
|
||||||
|
|
||||||
|
const hideEditDialog = () => {
|
||||||
|
setIsVisibleEditDialog(false);
|
||||||
|
setChosenUser(0);
|
||||||
|
setChosenApplication(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
const footerEditDialog = () => {
|
||||||
|
return <div>
|
||||||
|
<Button type="button" label={__('Anulla', 'gepafin')} onClick={hideEditDialog} outlined/>
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
disabled={loading}
|
||||||
|
label={__('Invia', 'gepafin')} onClick={saveEditDialog}/>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
const openAssignDialog = (applId) => {
|
||||||
|
setChosenApplication(applId)
|
||||||
|
setIsVisibleEditDialog(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
const saveEditDialog = () => {
|
||||||
|
if (chosenUser !== 0 && chosenApplication !== 0) {
|
||||||
|
storeSet.main.setAsyncRequest();
|
||||||
|
AssignedApplicationService.assignApplication(chosenApplication, assignApplCallback, errAssignApplCallback, [
|
||||||
|
['userId', chosenUser]
|
||||||
|
]);
|
||||||
|
hideEditDialog();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const assignApplCallback = (data) => {
|
||||||
|
if (data.status === 'SUCCESS') {
|
||||||
|
if (toast.current) {
|
||||||
|
toast.current.show({
|
||||||
|
severity: 'success',
|
||||||
|
summary: '',
|
||||||
|
detail: data.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
setUpdaterString(uniqid());
|
||||||
|
}
|
||||||
|
storeSet.main.unsetAsyncRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
const errAssignApplCallback = (data) => {
|
||||||
|
if (toast.current && data.message) {
|
||||||
|
toast.current.show({
|
||||||
|
severity: 'error',
|
||||||
|
summary: '',
|
||||||
|
detail: data.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
set404FromErrorResponse(data);
|
||||||
|
storeSet.main.unsetAsyncRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (roleId !== 0) {
|
||||||
|
setLoading(true);
|
||||||
|
UserService.getUsers(getUsersCallback, errGetUsersCallback, [['roleId', roleId]])
|
||||||
|
}
|
||||||
|
}, [roleId]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (isVisibleEditDialog) {
|
||||||
|
setLoading(true);
|
||||||
|
UserService.getRoles(getRolesCallback, errGetRolesCallback)
|
||||||
|
}
|
||||||
|
}, [isVisibleEditDialog]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="appPage">
|
||||||
|
<div className="appPage__pageHeader">
|
||||||
|
<h1>{__('Gestione domande', 'gepafin')}</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="appPage__spacer"></div>
|
||||||
|
|
||||||
|
<div className="appPageSection">
|
||||||
|
<AllDomandeTable openDialogFn={openAssignDialog} updaterString={updaterString}/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Dialog
|
||||||
|
visible={isVisibleEditDialog}
|
||||||
|
modal
|
||||||
|
header={headerEditDialog}
|
||||||
|
footer={footerEditDialog}
|
||||||
|
style={{ maxWidth: '600px', width: '100%' }}
|
||||||
|
onHide={hideEditDialog}>
|
||||||
|
<div className="appForm__field">
|
||||||
|
<label
|
||||||
|
className={classNames({ 'p-error': isEmpty(chosenUser) || chosenUser === 0 || chosenApplication === 0 })}>
|
||||||
|
{__('Pre-istruttore', 'gepafin')}*
|
||||||
|
</label>
|
||||||
|
<Dropdown
|
||||||
|
value={chosenUser}
|
||||||
|
invalid={isEmpty(chosenUser) || chosenUser === 0 || chosenApplication === 0}
|
||||||
|
onChange={(e) => setChosenUser(e.value)}
|
||||||
|
options={users}
|
||||||
|
optionLabel="name"
|
||||||
|
optionValue="value"/>
|
||||||
|
</div>
|
||||||
|
</Dialog>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Domande;
|
||||||
@@ -0,0 +1,193 @@
|
|||||||
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import { __ } from '@wordpress/i18n';
|
||||||
|
import { is, uniq } from 'ramda';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
|
// store
|
||||||
|
import { useStore } from '../../../../store';
|
||||||
|
|
||||||
|
// api
|
||||||
|
import ApplicationService from '../../../../service/application-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 { 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';
|
||||||
|
import { Dropdown } from 'primereact/dropdown';
|
||||||
|
import { Tag } from 'primereact/tag';
|
||||||
|
|
||||||
|
|
||||||
|
const BeneficiarioDomandeTable = () => {
|
||||||
|
const chosenCompanyId = useStore().main.chosenCompanyId();
|
||||||
|
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(getApplCallback, errGetApplCallback, [
|
||||||
|
['companyId', chosenCompanyId],
|
||||||
|
['statuses', ['SOCCORSO', 'APPROVED', 'REJECTED', 'EVALUATION']]
|
||||||
|
])
|
||||||
|
}, [chosenCompanyId]);
|
||||||
|
|
||||||
|
const getApplCallback = (data) => {
|
||||||
|
if (data.status === 'SUCCESS') {
|
||||||
|
if (is(Array, data.data)) {
|
||||||
|
setItems(getFormattedBandiData(data.data));
|
||||||
|
setStatuses(uniq(items.map(o => o.status)))
|
||||||
|
initFilters();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setLocalAsyncRequest(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
const errGetApplCallback = (data) => {
|
||||||
|
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', {
|
||||||
|
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 }]
|
||||||
|
},
|
||||||
|
modifiedDate: {
|
||||||
|
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 dateSubmissionBodyTemplate = (rowData) => {
|
||||||
|
return formatDate(rowData.submissionDate);
|
||||||
|
};
|
||||||
|
|
||||||
|
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 statusFilterTemplate = (options) => {
|
||||||
|
return <Dropdown value={options.value} options={statuses}
|
||||||
|
onChange={(e) => options.filterCallback(e.value, options.index)}
|
||||||
|
itemTemplate={statusItemTemplate} placeholder="Select One" className="p-column-filter"
|
||||||
|
showClear/>;
|
||||||
|
};
|
||||||
|
|
||||||
|
const progressBodyTemplate = (options) => {
|
||||||
|
return '-';
|
||||||
|
};
|
||||||
|
|
||||||
|
const statusItemTemplate = (option) => {
|
||||||
|
return <Tag value={getBandoLabel(option)} severity={getBandoSeverity(option)}/>;
|
||||||
|
};
|
||||||
|
|
||||||
|
const actionsBodyTemplate = (rowData) => {
|
||||||
|
return rowData.status === 'SOCCORSO'
|
||||||
|
? <Link to={`/domande/${rowData.id}`}>
|
||||||
|
<Button severity="info" label={__('Dettagli', 'gepafin')} icon="pi pi-eye" size="small"
|
||||||
|
iconPos="right"/>
|
||||||
|
</Link> : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 il nome', 'gepafin')}
|
||||||
|
style={{ minWidth: '6rem' }}/>
|
||||||
|
<Column field="callTitle" header={__('Titolo bando', 'gepafin')} filter
|
||||||
|
filterPlaceholder={__('Cerca il nome', 'gepafin')}
|
||||||
|
style={{ minWidth: '8rem' }}/>
|
||||||
|
<Column header={__('Data di invio', 'gepafin')} filterField="submissionDate" dataType="date"
|
||||||
|
style={{ minWidth: '8rem' }}
|
||||||
|
body={dateSubmissionBodyTemplate} filter filterElement={dateFilterTemplate}/>
|
||||||
|
<Column field="status" header={__('Stato', 'gepafin')} filterMenuStyle={{ width: '14rem' }}
|
||||||
|
style={{ minWidth: '7rem' }} body={statusBodyTemplate} filter
|
||||||
|
filterElement={statusFilterTemplate}/>
|
||||||
|
<Column header={__('Esito', 'gepafin')}
|
||||||
|
style={{ minWidth: '7rem' }} field="progress" body={progressBodyTemplate}/>
|
||||||
|
<Column header={__('Azioni', 'gepafin')}
|
||||||
|
body={actionsBodyTemplate}/>
|
||||||
|
</DataTable>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default BeneficiarioDomandeTable;
|
||||||
23
src/pages/DomandeBeneficiario/index.js
Normal file
23
src/pages/DomandeBeneficiario/index.js
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { __ } from '@wordpress/i18n';
|
||||||
|
|
||||||
|
// components
|
||||||
|
import BeneficiarioDomandeTable from './components/BeneficiarioDomandeTable';
|
||||||
|
|
||||||
|
const DomandePreInstructor = () => {
|
||||||
|
return(
|
||||||
|
<div className="appPage">
|
||||||
|
<div className="appPage__pageHeader">
|
||||||
|
<h1>{__('Archivio domande', 'gepafin')}</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="appPage__spacer"></div>
|
||||||
|
|
||||||
|
<div className="appPageSection">
|
||||||
|
<BeneficiarioDomandeTable/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DomandePreInstructor;
|
||||||
23
src/pages/DomandePreInstructor/index.js
Normal file
23
src/pages/DomandePreInstructor/index.js
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { __ } from '@wordpress/i18n';
|
||||||
|
|
||||||
|
// components
|
||||||
|
import PreInstructorDomandeTable from '../DashboardPreInstructor/components/PreInstructorDomandeTable';
|
||||||
|
|
||||||
|
const DomandePreInstructor = () => {
|
||||||
|
return(
|
||||||
|
<div className="appPage">
|
||||||
|
<div className="appPage__pageHeader">
|
||||||
|
<h1>{__('Archivio domande', 'gepafin')}</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="appPage__spacer"></div>
|
||||||
|
|
||||||
|
<div className="appPageSection">
|
||||||
|
<PreInstructorDomandeTable/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DomandePreInstructor;
|
||||||
@@ -30,6 +30,10 @@ const LoginAdmin = () => {
|
|||||||
formState: { errors },
|
formState: { errors },
|
||||||
} = useForm({ mode: 'onChange' });
|
} = useForm({ mode: 'onChange' });
|
||||||
|
|
||||||
|
const gotToResetPassword = () => {
|
||||||
|
navigate('/reset-password');
|
||||||
|
}
|
||||||
|
|
||||||
const onSubmit = (formData) => {
|
const onSubmit = (formData) => {
|
||||||
errorMsgs.current.clear();
|
errorMsgs.current.clear();
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
@@ -67,10 +71,6 @@ const LoginAdmin = () => {
|
|||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
const gotToResetPassword = () => {
|
|
||||||
navigate('/reset-password');
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isEmpty(token)) {
|
if (!isEmpty(token)) {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
|||||||
@@ -129,88 +129,7 @@ const Profile = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="appPageSection">
|
<div className="appPageSection">
|
||||||
<h2>{__('Consensi', 'gepafin')}</h2>
|
<h2>{__('Impostazioni', 'gepafin')}</h2>
|
||||||
|
|
||||||
<div className="appForm__switchFieldWrapper">
|
|
||||||
<FormField
|
|
||||||
type="switch"
|
|
||||||
disabled={true}
|
|
||||||
fieldName="privacy"
|
|
||||||
label={''}
|
|
||||||
control={control}
|
|
||||||
errors={errors}
|
|
||||||
onLabel={''}
|
|
||||||
offLabel={''}
|
|
||||||
/>
|
|
||||||
<div>
|
|
||||||
{__('Dichiaro di aver preso visione, prima dell\'accesso al portale https://bandi.gepafin.it, dell\' "Informativa Privacy" all\'interno dell\'Appendice 10 dell\'Avviso secondo il Regolamento UE 2016/679 relativo alla protezione delle persone fisiche con riguardo al trattamento dei dati personale, nonché alla libera circolazione di tali dati e che abroga la Direttiva 95/46 CE.', 'gepafin')}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="appForm__switchFieldWrapper">
|
|
||||||
<FormField
|
|
||||||
type="switch"
|
|
||||||
disabled={true}
|
|
||||||
fieldName="terms"
|
|
||||||
label={''}
|
|
||||||
control={control}
|
|
||||||
errors={errors}
|
|
||||||
onLabel={''}
|
|
||||||
offLabel={''}
|
|
||||||
/>
|
|
||||||
<div>
|
|
||||||
{__('Termini e condizioni', 'gepafin')}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="appForm__switchFieldWrapper">
|
|
||||||
<FormField
|
|
||||||
type="switch"
|
|
||||||
fieldName="marketing"
|
|
||||||
label={''}
|
|
||||||
control={control}
|
|
||||||
errors={errors}
|
|
||||||
onLabel={''}
|
|
||||||
offLabel={''}
|
|
||||||
/>
|
|
||||||
<div>
|
|
||||||
{__('Invio di materiale pubblicitario, vendita diretta, compimento di ricerche di mercato o comunicazione commerciale riguardanti promozione e vendita di prodotti e servizi della Gepafin, mediante modalità di contatto automatizzate (posta elettronica, PEC, messaggi tramite canali informatici, network ed applicazioni web) e tradizionali (come posta cartacea e chiamate telefoniche con operatore)', 'gepafin')}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="appForm__switchFieldWrapper">
|
|
||||||
<FormField
|
|
||||||
type="switch"
|
|
||||||
fieldName="offers"
|
|
||||||
label={''}
|
|
||||||
control={control}
|
|
||||||
errors={errors}
|
|
||||||
onLabel={''}
|
|
||||||
offLabel={''}
|
|
||||||
/>
|
|
||||||
<div>
|
|
||||||
{__('Elaborazione, in forma elettronica, dei dati relativi ai rapporti e servizi forniti, per l’analisi di comportamenti e preferenze della clientela, da utilizzare a scopo commerciale, per la individuazione ed offerta di prodotti e servizi di suo interesse', 'gepafin')}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="appForm__switchFieldWrapper">
|
|
||||||
<FormField
|
|
||||||
type="switch"
|
|
||||||
fieldName="thirdParty"
|
|
||||||
label={''}
|
|
||||||
control={control}
|
|
||||||
errors={errors}
|
|
||||||
onLabel={''}
|
|
||||||
offLabel={''}
|
|
||||||
/>
|
|
||||||
<div>
|
|
||||||
{__('Comunicazione dei miei dati ad altre società in ambito bancario, finanziario od assicurativo e enti pubblici che li tratteranno per invio di materiale pubblicitario, vendita diretta, compimento di ricerche di mercato o comunicazione commerciale riguardanti loro prodotti o servizi, mediante le modalità automatizzate e tradizionali di comunicazione sopra indicate', 'gepafin')}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="appPageSection">
|
|
||||||
<h2>{__('Utenti Associati', 'gepafin')}</h2>
|
|
||||||
<div className="appForm__cols">
|
<div className="appForm__cols">
|
||||||
<FormField
|
<FormField
|
||||||
type="select"
|
type="select"
|
||||||
|
|||||||
288
src/pages/ProfileBeneficiario/index.js
Normal file
288
src/pages/ProfileBeneficiario/index.js
Normal file
@@ -0,0 +1,288 @@
|
|||||||
|
import React, { useMemo, useRef } from 'react';
|
||||||
|
import { __ } from '@wordpress/i18n';
|
||||||
|
import { useForm } from 'react-hook-form';
|
||||||
|
|
||||||
|
// store
|
||||||
|
import { storeSet, useStore } from '../../store';
|
||||||
|
|
||||||
|
// components
|
||||||
|
import set404FromErrorResponse from '../../helpers/set404FromErrorResponse';
|
||||||
|
import FormField from '../../components/FormField';
|
||||||
|
import { Button } from 'primereact/button';
|
||||||
|
import { Toast } from 'primereact/toast';
|
||||||
|
|
||||||
|
// api
|
||||||
|
import UserService from '../../service/user-service';
|
||||||
|
|
||||||
|
// tools
|
||||||
|
import getDateFromISOstring from '../../helpers/getDateFromISOstring';
|
||||||
|
|
||||||
|
const ProfileBeneficiario = () => {
|
||||||
|
const isAsyncRequest = useStore().main.isAsyncRequest();
|
||||||
|
const userData = useStore().main.userData();
|
||||||
|
const toast = useRef(null);
|
||||||
|
|
||||||
|
const {
|
||||||
|
control,
|
||||||
|
handleSubmit,
|
||||||
|
formState: { errors }
|
||||||
|
} = useForm({
|
||||||
|
defaultValues: useMemo(() => {
|
||||||
|
return userData;
|
||||||
|
}, [userData]),
|
||||||
|
mode: 'onChange'
|
||||||
|
});
|
||||||
|
|
||||||
|
const onSubmit = (formData) => {
|
||||||
|
storeSet.main.setAsyncRequest();
|
||||||
|
|
||||||
|
UserService.updateUser(userData.id, formData, updateCallback, updateError);
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateCallback = (data) => {
|
||||||
|
if (data.status === 'SUCCESS') {
|
||||||
|
storeSet.main.userData(data.data);
|
||||||
|
if (toast.current) {
|
||||||
|
toast.current.show({
|
||||||
|
severity: 'success',
|
||||||
|
summary: '',
|
||||||
|
detail: __('L\'utente è stato aggiornato!', 'gepafin')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
storeSet.main.unsetAsyncRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateError = (data) => {
|
||||||
|
set404FromErrorResponse(data);
|
||||||
|
storeSet.main.unsetAsyncRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="appPage">
|
||||||
|
<div className="appPage__pageHeader">
|
||||||
|
<h1>{__('Profilo utente', 'gepafin')}</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="appPage__spacer"></div>
|
||||||
|
<Toast ref={toast}/>
|
||||||
|
|
||||||
|
<form className="appForm" onSubmit={handleSubmit(onSubmit)}>
|
||||||
|
|
||||||
|
<div className="appPageSection">
|
||||||
|
<h2>{__('Informazioni personali', 'gepafin')}</h2>
|
||||||
|
<div className="appForm__cols">
|
||||||
|
<FormField
|
||||||
|
type="textinput"
|
||||||
|
disabled={true}
|
||||||
|
fieldName="firstName"
|
||||||
|
label={__('Nome', 'gepafin')}
|
||||||
|
control={control}
|
||||||
|
errors={errors}
|
||||||
|
config={{ required: __('È obbligatorio', 'gepafin') }}
|
||||||
|
placeholder="Francesco"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FormField
|
||||||
|
type="textinput"
|
||||||
|
disabled={true}
|
||||||
|
fieldName="lastName"
|
||||||
|
label={__('Cognome', 'gepafin')}
|
||||||
|
control={control}
|
||||||
|
errors={errors}
|
||||||
|
config={{ required: __('È obbligatorio', 'gepafin') }}
|
||||||
|
placeholder="Moli"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FormField
|
||||||
|
type="textinput"
|
||||||
|
disabled={true}
|
||||||
|
fieldName="codiceFiscale"
|
||||||
|
label={__('Codice fiscale', 'gepafin')}
|
||||||
|
control={control}
|
||||||
|
errors={errors}
|
||||||
|
config={{ required: __('È obbligatorio', 'gepafin') }}
|
||||||
|
placeholder="XXXXXXXX"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="appForm__cols">
|
||||||
|
<FormField
|
||||||
|
type="textinput"
|
||||||
|
fieldName="email"
|
||||||
|
label={__('Email', 'gepafin')}
|
||||||
|
control={control}
|
||||||
|
errors={errors}
|
||||||
|
config={{ required: __('È obbligatorio', 'gepafin') }}
|
||||||
|
placeholder="user@example.com"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FormField
|
||||||
|
type="textinput"
|
||||||
|
fieldName="phoneNumber"
|
||||||
|
label={__('Telefono', 'gepafin')}
|
||||||
|
control={control}
|
||||||
|
errors={errors}
|
||||||
|
config={{ required: __('È obbligatorio', 'gepafin') }}
|
||||||
|
placeholder="1234567"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="appPageSection">
|
||||||
|
<h2>{__('Consensi', 'gepafin')}</h2>
|
||||||
|
|
||||||
|
<div className="appForm__switchFieldWrapper">
|
||||||
|
<FormField
|
||||||
|
type="switch"
|
||||||
|
disabled={true}
|
||||||
|
fieldName="privacy"
|
||||||
|
label={''}
|
||||||
|
control={control}
|
||||||
|
errors={errors}
|
||||||
|
onLabel={''}
|
||||||
|
offLabel={''}
|
||||||
|
/>
|
||||||
|
<div>
|
||||||
|
{__('Dichiaro di aver preso visione, prima dell\'accesso al portale https://bandi.gepafin.it, dell\' "Informativa Privacy" all\'interno dell\'Appendice 10 dell\'Avviso secondo il Regolamento UE 2016/679 relativo alla protezione delle persone fisiche con riguardo al trattamento dei dati personale, nonché alla libera circolazione di tali dati e che abroga la Direttiva 95/46 CE.', 'gepafin')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="appForm__switchFieldWrapper">
|
||||||
|
<FormField
|
||||||
|
type="switch"
|
||||||
|
disabled={true}
|
||||||
|
fieldName="terms"
|
||||||
|
label={''}
|
||||||
|
control={control}
|
||||||
|
errors={errors}
|
||||||
|
onLabel={''}
|
||||||
|
offLabel={''}
|
||||||
|
/>
|
||||||
|
<div>
|
||||||
|
{__('Termini e condizioni', 'gepafin')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="appForm__switchFieldWrapper">
|
||||||
|
<FormField
|
||||||
|
type="switch"
|
||||||
|
fieldName="marketing"
|
||||||
|
label={''}
|
||||||
|
control={control}
|
||||||
|
errors={errors}
|
||||||
|
onLabel={''}
|
||||||
|
offLabel={''}
|
||||||
|
/>
|
||||||
|
<div>
|
||||||
|
{__('Invio di materiale pubblicitario, vendita diretta, compimento di ricerche di mercato o comunicazione commerciale riguardanti promozione e vendita di prodotti e servizi della Gepafin, mediante modalità di contatto automatizzate (posta elettronica, PEC, messaggi tramite canali informatici, network ed applicazioni web) e tradizionali (come posta cartacea e chiamate telefoniche con operatore)', 'gepafin')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="appForm__switchFieldWrapper">
|
||||||
|
<FormField
|
||||||
|
type="switch"
|
||||||
|
fieldName="offers"
|
||||||
|
label={''}
|
||||||
|
control={control}
|
||||||
|
errors={errors}
|
||||||
|
onLabel={''}
|
||||||
|
offLabel={''}
|
||||||
|
/>
|
||||||
|
<div>
|
||||||
|
{__('Elaborazione, in forma elettronica, dei dati relativi ai rapporti e servizi forniti, per l’analisi di comportamenti e preferenze della clientela, da utilizzare a scopo commerciale, per la individuazione ed offerta di prodotti e servizi di suo interesse', 'gepafin')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="appForm__switchFieldWrapper">
|
||||||
|
<FormField
|
||||||
|
type="switch"
|
||||||
|
fieldName="thirdParty"
|
||||||
|
label={''}
|
||||||
|
control={control}
|
||||||
|
errors={errors}
|
||||||
|
onLabel={''}
|
||||||
|
offLabel={''}
|
||||||
|
/>
|
||||||
|
<div>
|
||||||
|
{__('Comunicazione dei miei dati ad altre società in ambito bancario, finanziario od assicurativo e enti pubblici che li tratteranno per invio di materiale pubblicitario, vendita diretta, compimento di ricerche di mercato o comunicazione commerciale riguardanti loro prodotti o servizi, mediante le modalità automatizzate e tradizionali di comunicazione sopra indicate', 'gepafin')}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="appPageSection">
|
||||||
|
<h2>{__('Impostazioni', 'gepafin')}</h2>
|
||||||
|
<div className="appForm__cols">
|
||||||
|
<FormField
|
||||||
|
type="select"
|
||||||
|
disabled={true}
|
||||||
|
fieldName="language"
|
||||||
|
defaultValue={'it'}
|
||||||
|
label={__('Lingua predefinita', 'gepafin')}
|
||||||
|
control={control}
|
||||||
|
errors={errors}
|
||||||
|
config={{ required: __('È obbligatorio', 'gepafin') }}
|
||||||
|
options={[
|
||||||
|
{ label: __('Italiano', 'gepafin'), name: 'it' }
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FormField
|
||||||
|
type="select"
|
||||||
|
disabled={true}
|
||||||
|
fieldName="timezone"
|
||||||
|
defaultValue={'Europe/Rome'}
|
||||||
|
label={__('Fuso Orario', 'gepafin')}
|
||||||
|
control={control}
|
||||||
|
errors={errors}
|
||||||
|
config={{ required: __('È obbligatorio', 'gepafin') }}
|
||||||
|
options={[
|
||||||
|
{ label: __('Europe/Rome', 'gepafin'), name: 'Europe/Rome' }
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FormField
|
||||||
|
type="select"
|
||||||
|
disabled={true}
|
||||||
|
fieldName="dateformat"
|
||||||
|
defaultValue={'DD/MM/YY'}
|
||||||
|
label={__('Formato Data', 'gepafin')}
|
||||||
|
control={control}
|
||||||
|
errors={errors}
|
||||||
|
config={{ required: __('È obbligatorio', 'gepafin') }}
|
||||||
|
options={[
|
||||||
|
{ label: __('DD/MM/YY', 'gepafin'), name: 'DD/MM/YY' }
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="appPageSection">
|
||||||
|
<h2>{__('Sicurezza', 'gepafin')}</h2>
|
||||||
|
<div className="appForm__row">
|
||||||
|
<label>{__('Ultimo accesso', 'gepafin')}</label>
|
||||||
|
<span>{getDateFromISOstring(userData.lastLogin)}</span>
|
||||||
|
</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
|
||||||
|
disabled={isAsyncRequest}
|
||||||
|
label={__('Salva modifiche', 'gepafin')}
|
||||||
|
icon="pi pi-check" iconPos="right"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ProfileBeneficiario;
|
||||||
@@ -3,6 +3,7 @@ import { __, sprintf } from '@wordpress/i18n';
|
|||||||
import { useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
import { classNames } from 'primereact/utils';
|
import { classNames } from 'primereact/utils';
|
||||||
import { isEmpty } from 'ramda';
|
import { isEmpty } from 'ramda';
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
// tools
|
// tools
|
||||||
import AuthenticationService from '../../service/authentication-service';
|
import AuthenticationService from '../../service/authentication-service';
|
||||||
@@ -16,7 +17,10 @@ import LogoIcon from '../../icons/LogoIcon';
|
|||||||
import { Button } from 'primereact/button';
|
import { Button } from 'primereact/button';
|
||||||
import { Messages } from 'primereact/messages';
|
import { Messages } from 'primereact/messages';
|
||||||
|
|
||||||
|
const APP_HUB_ID = process.env.REACT_APP_HUB_ID;
|
||||||
|
|
||||||
const ResetPassword = () => {
|
const ResetPassword = () => {
|
||||||
|
const navigate = useNavigate();
|
||||||
const token = useStore().main.token();
|
const token = useStore().main.token();
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [resetPassToken, setResetPassToken] = useState('');
|
const [resetPassToken, setResetPassToken] = useState('');
|
||||||
@@ -30,14 +34,23 @@ const ResetPassword = () => {
|
|||||||
setValue
|
setValue
|
||||||
} = useForm({ mode: 'onChange' });
|
} = useForm({ mode: 'onChange' });
|
||||||
|
|
||||||
|
const gotToLoginAdmin = () => {
|
||||||
|
navigate('/loginadmin');
|
||||||
|
}
|
||||||
|
|
||||||
const onSubmit = (formData) => {
|
const onSubmit = (formData) => {
|
||||||
errorMsgs.current.clear();
|
errorMsgs.current.clear();
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
const request = {
|
const request = {
|
||||||
...formData
|
...formData,
|
||||||
|
hubUuid: APP_HUB_ID
|
||||||
}
|
}
|
||||||
|
|
||||||
AuthenticationService.forgotPassword(request, getCallback, errCallback);
|
if (request.token && !isEmpty(request.token)) {
|
||||||
|
AuthenticationService.resetPassword(request, getCallback, errCallback);
|
||||||
|
} else {
|
||||||
|
AuthenticationService.forgotPassword(request, getCallback, errCallback);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const getCallback = (data) => {
|
const getCallback = (data) => {
|
||||||
@@ -59,7 +72,7 @@ const ResetPassword = () => {
|
|||||||
errorMsgs.current.show([
|
errorMsgs.current.show([
|
||||||
{
|
{
|
||||||
sticky: true, severity: 'error', summary: '',
|
sticky: true, severity: 'error', summary: '',
|
||||||
detail: sprintf(__('%s', 'gepafin'), err),
|
detail: sprintf(__('%s', 'gepafin'), err.message),
|
||||||
closable: true
|
closable: true
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
@@ -104,7 +117,7 @@ const ResetPassword = () => {
|
|||||||
? <input
|
? <input
|
||||||
type="hidden"
|
type="hidden"
|
||||||
name="token"
|
name="token"
|
||||||
{...register('test', {
|
{...register('token', {
|
||||||
required: true
|
required: true
|
||||||
})}
|
})}
|
||||||
/> : null}
|
/> : null}
|
||||||
@@ -130,7 +143,7 @@ const ResetPassword = () => {
|
|||||||
type="textinput"
|
type="textinput"
|
||||||
inputtype="password"
|
inputtype="password"
|
||||||
fieldName="confirmPassword"
|
fieldName="confirmPassword"
|
||||||
label={__('Conferma Password', 'gepafin')}
|
label={__('Conferma password', 'gepafin')}
|
||||||
control={control}
|
control={control}
|
||||||
errors={errors}
|
errors={errors}
|
||||||
config={{
|
config={{
|
||||||
@@ -144,6 +157,10 @@ const ResetPassword = () => {
|
|||||||
<Button
|
<Button
|
||||||
label={__('Invia', 'gepafin')}
|
label={__('Invia', 'gepafin')}
|
||||||
disabled={loading}/>
|
disabled={loading}/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
label={__('Accedi', 'gepafin')}
|
||||||
|
link onClick={gotToLoginAdmin}/>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
300
src/pages/SoccorsoAddPreInstructor/index.js
Normal file
300
src/pages/SoccorsoAddPreInstructor/index.js
Normal file
@@ -0,0 +1,300 @@
|
|||||||
|
import React, { useState, useEffect, useRef } from 'react';
|
||||||
|
import { __ } from '@wordpress/i18n';
|
||||||
|
import { useNavigate, useParams } from 'react-router-dom';
|
||||||
|
import { isEmpty } from 'ramda';
|
||||||
|
import { wrap } from 'object-path-immutable';
|
||||||
|
|
||||||
|
// store
|
||||||
|
import { storeSet, useStore } from '../../store';
|
||||||
|
|
||||||
|
// api
|
||||||
|
import AmendmentsService from '../../service/amendments-service';
|
||||||
|
|
||||||
|
// tools
|
||||||
|
import set404FromErrorResponse from '../../helpers/set404FromErrorResponse';
|
||||||
|
|
||||||
|
// components
|
||||||
|
import { Skeleton } from 'primereact/skeleton';
|
||||||
|
import { Button } from 'primereact/button';
|
||||||
|
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 { InputSwitch } from 'primereact/inputswitch';
|
||||||
|
|
||||||
|
const SoccorsoEditPreInstructor = () => {
|
||||||
|
const isAsyncRequest = useStore().main.isAsyncRequest();
|
||||||
|
const { id, evaluationId } = useParams();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const [data, setData] = useState({});
|
||||||
|
const [formData, setFormData] = useState({});
|
||||||
|
const toast = useRef(null);
|
||||||
|
|
||||||
|
const goToEvaluationPage = () => {
|
||||||
|
navigate(`/domande/${id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const getCallback = (data) => {
|
||||||
|
if (data.status === 'SUCCESS') {
|
||||||
|
console.log(data.data)
|
||||||
|
setData(data.data);
|
||||||
|
setFormData(getFormattedFormData(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 getFormattedFormData = (data) => {
|
||||||
|
let newData = {};
|
||||||
|
newData.formFields = data.formFields;
|
||||||
|
newData.responseDays = 10;
|
||||||
|
newData.note = '';
|
||||||
|
newData.isSendNotification = true;
|
||||||
|
newData.isSendEmail = true;
|
||||||
|
return newData;
|
||||||
|
};
|
||||||
|
|
||||||
|
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(formData).set(path.split('.'), finalValue).value();
|
||||||
|
|
||||||
|
setFormData(newData);
|
||||||
|
}
|
||||||
|
|
||||||
|
const doCreate = () => {
|
||||||
|
storeSet.main.setAsyncRequest();
|
||||||
|
|
||||||
|
AmendmentsService.createSoccorso(formData, createCallback, errCreateCallback, [
|
||||||
|
['applicationEvaluationId', evaluationId]
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
const createCallback = (data) => {
|
||||||
|
if (data.status === 'SUCCESS') {
|
||||||
|
if (toast.current) {
|
||||||
|
toast.current.show({
|
||||||
|
severity: 'success',
|
||||||
|
summary: '',
|
||||||
|
detail: data.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
setTimeout(() => {
|
||||||
|
navigate(`/domande/${id}/soccorso/${data.data.id}`);
|
||||||
|
}, 1000)
|
||||||
|
}
|
||||||
|
storeSet.main.unsetAsyncRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
const errCreateCallback = (data) => {
|
||||||
|
if (toast.current && data.message) {
|
||||||
|
toast.current.show({
|
||||||
|
severity: 'error',
|
||||||
|
summary: '',
|
||||||
|
detail: data.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
set404FromErrorResponse(data);
|
||||||
|
storeSet.main.unsetAsyncRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const parsed = parseInt(evaluationId)
|
||||||
|
const entityId = !isNaN(parsed) ? parsed : 0;
|
||||||
|
|
||||||
|
storeSet.main.setAsyncRequest();
|
||||||
|
AmendmentsService.getSoccorsoByApplEvalId(entityId, getCallback, errGetCallback);
|
||||||
|
}, [evaluationId]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="appPage">
|
||||||
|
<div className="appPage__pageHeader">
|
||||||
|
<h1>{__('Richiesta Integrazione Documentale', '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 column">
|
||||||
|
<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.beneficiaryName}</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="appPageSection">
|
||||||
|
<div className="appPageSection columns">
|
||||||
|
<div>
|
||||||
|
<h3>{__('Note', 'gepafin')}</h3>
|
||||||
|
<div style={{marginBottom: '30px'}}>
|
||||||
|
<Editor
|
||||||
|
value={formData.note}
|
||||||
|
placeholder={__('Digita qui il messagio', 'gepafin')}
|
||||||
|
headerTemplate={header}
|
||||||
|
onTextChange={(e) => updateEvaluationValue(
|
||||||
|
e.htmlValue,
|
||||||
|
'note'
|
||||||
|
)}
|
||||||
|
style={{ height: 80 * 3, width: '100%' }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3>{__('Tempo per la Risposta (giorni)', 'gepafin')}</h3>
|
||||||
|
<div style={{marginBottom: '30px'}}>
|
||||||
|
<InputNumber
|
||||||
|
keyfilter="int"
|
||||||
|
value={formData.responseDays}
|
||||||
|
showButtons
|
||||||
|
onChange={(e) => updateEvaluationValue(
|
||||||
|
e.value,
|
||||||
|
'responseDays',
|
||||||
|
9999
|
||||||
|
)}/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3>{__('Notifica', 'gepafin')}</h3>
|
||||||
|
<div className="appPageSection__withBorder grey">
|
||||||
|
<div className="appForm__field row">
|
||||||
|
<InputSwitch
|
||||||
|
inputId="notify_email"
|
||||||
|
checked={formData.isSendEmail}
|
||||||
|
onChange={(e) => updateEvaluationValue(
|
||||||
|
e.value,
|
||||||
|
'isSendEmail'
|
||||||
|
)}/>
|
||||||
|
<label htmlFor="notify_email">{__('Notifiche Email', 'gepafin')}</label>
|
||||||
|
</div>
|
||||||
|
<div className="appForm__field row">
|
||||||
|
<InputSwitch
|
||||||
|
inputId="notify_push"
|
||||||
|
checked={formData.isSendNotification}
|
||||||
|
onChange={(e) => updateEvaluationValue(
|
||||||
|
e.value,
|
||||||
|
'isSendNotification'
|
||||||
|
)}/>
|
||||||
|
<label htmlFor="notify_push">{__('Notifiche Push', 'gepafin')}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{formData.formFields
|
||||||
|
? <div>
|
||||||
|
<h3>{__('Documenti da Integrare', 'gepafin')}</h3>
|
||||||
|
<div className="appPageSection__withBorder grey">
|
||||||
|
<div className="appPageSection__checklist">
|
||||||
|
{formData.formFields.map((o, i) => <div key={o.fieldId}>
|
||||||
|
<Checkbox
|
||||||
|
inputId={`checklist_${o.fieldId}`}
|
||||||
|
onChange={(e) => updateEvaluationValue(
|
||||||
|
e.checked,
|
||||||
|
`formFields.${i}.selected`
|
||||||
|
)}
|
||||||
|
checked={o.selected}></Checkbox>
|
||||||
|
<label htmlFor={`checklist_${o.fieldId}`}>{o.label}</label>
|
||||||
|
</div>)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
: null}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="appPageSection__message warning">
|
||||||
|
<i className="pi pi-exclamation-triangle"></i>
|
||||||
|
<span className="summary">{__('Attenzione', 'gepafin')}</span>
|
||||||
|
<span>{__("L'invio della richiesta di integrazione sospenderà il termine di valutazione della domanda.", 'gepafin')}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="appPageSection__hr">
|
||||||
|
<span>{__('Azioni', 'gepafin')}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="appPageSection">
|
||||||
|
<div className="appPageSection__actions">
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
outlined
|
||||||
|
label={__('Anulla', 'gepafin')}
|
||||||
|
icon="pi pi-times" iconPos="right"/>
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
onClick={doCreate}
|
||||||
|
label={__('Invia richiesta', 'gepafin')}
|
||||||
|
icon="pi pi-check" 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;
|
||||||
653
src/pages/SoccorsoEditPreInstructor/index.js
Normal file
653
src/pages/SoccorsoEditPreInstructor/index.js
Normal file
@@ -0,0 +1,653 @@
|
|||||||
|
import React, { useState, useEffect, useRef, useMemo } from 'react';
|
||||||
|
import { __ } from '@wordpress/i18n';
|
||||||
|
import { useNavigate, useParams } from 'react-router-dom';
|
||||||
|
import { is, isEmpty, isNil } from 'ramda';
|
||||||
|
import { wrap } from 'object-path-immutable';
|
||||||
|
import { klona } from 'klona';
|
||||||
|
import { useForm } from 'react-hook-form';
|
||||||
|
|
||||||
|
// store
|
||||||
|
import { storeSet, useStore } from '../../store';
|
||||||
|
|
||||||
|
// api
|
||||||
|
import AmendmentsService from '../../service/amendments-service';
|
||||||
|
import CommunicationService from '../../service/communication-service';
|
||||||
|
|
||||||
|
// tools
|
||||||
|
import set404FromErrorResponse from '../../helpers/set404FromErrorResponse';
|
||||||
|
import getBandoLabel from '../../helpers/getBandoLabel';
|
||||||
|
import getDateFromISOstring from '../../helpers/getDateFromISOstring';
|
||||||
|
import renderHtmlContent from '../../helpers/renderHtmlContent';
|
||||||
|
import uniqid from '../../helpers/uniqid';
|
||||||
|
|
||||||
|
// components
|
||||||
|
import { Button } from 'primereact/button';
|
||||||
|
import BlockingOverlay from '../../components/BlockingOverlay';
|
||||||
|
import { Toast } from 'primereact/toast';
|
||||||
|
import { classNames } from 'primereact/utils';
|
||||||
|
import { Dialog } from 'primereact/dialog';
|
||||||
|
import { InputText } from 'primereact/inputtext';
|
||||||
|
import { InputTextarea } from 'primereact/inputtextarea';
|
||||||
|
import FormField from '../../components/FormField';
|
||||||
|
import { Editor } from 'primereact/editor';
|
||||||
|
import { InputNumber } from 'primereact/inputnumber';
|
||||||
|
|
||||||
|
const SoccorsoEditPreInstructor = () => {
|
||||||
|
const isAsyncRequest = useStore().main.isAsyncRequest();
|
||||||
|
const { id, amendmentId } = useParams();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
const [data, setData] = useState({});
|
||||||
|
const [comms, setComms] = useState([]);
|
||||||
|
const [isVisibleNewCommDialog, setIsVisibleNewCommDialog] = useState(false);
|
||||||
|
const [newCommData, setNewCommData] = useState({});
|
||||||
|
const [isLoadingCommunication, setIsLoadingCommunication] = useState(false);
|
||||||
|
const [isVisibleExtendTimeDialog, setIsVisibleExtendTimeDialog] = useState(false);
|
||||||
|
const [extendedTime, setExtendedTime] = useState(3);
|
||||||
|
const [isLoadingExtendingTime, setIsLoadingExtendingTime] = useState(false);
|
||||||
|
const [isLoadingReminding, setIsLoadingReminding] = useState(false);
|
||||||
|
const toast = useRef(null);
|
||||||
|
const [formInitialData, setFormInitialData] = useState({});
|
||||||
|
const {
|
||||||
|
control,
|
||||||
|
handleSubmit,
|
||||||
|
formState: { errors },
|
||||||
|
setValue,
|
||||||
|
register,
|
||||||
|
trigger,
|
||||||
|
getValues
|
||||||
|
} = useForm({
|
||||||
|
defaultValues: useMemo(() => {
|
||||||
|
return formInitialData;
|
||||||
|
}, [formInitialData]), mode: 'onChange'
|
||||||
|
});
|
||||||
|
|
||||||
|
const goToEvaluationPage = () => {
|
||||||
|
navigate(`/domande/${id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const getCallback = (data) => {
|
||||||
|
if (data.status === 'SUCCESS') {
|
||||||
|
setData(getFormattedData(data.data));
|
||||||
|
const formDataInitial = data.data.applicationFormFields.reduce((acc, cur) => {
|
||||||
|
if (cur.fieldValue) {
|
||||||
|
acc[cur.fieldId] = cur.fieldValue;
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
setFormInitialData(formDataInitial);
|
||||||
|
CommunicationService.getCommsByAmendmentId(data.data.id, getCommsCallback, errGetCommsCallback);
|
||||||
|
}
|
||||||
|
//storeSet.main.unsetAsyncRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
const errGetCallback = (data) => {
|
||||||
|
if (toast.current && data.message) {
|
||||||
|
toast.current.show({
|
||||||
|
severity: 'error',
|
||||||
|
summary: '',
|
||||||
|
detail: data.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
set404FromErrorResponse(data);
|
||||||
|
storeSet.main.unsetAsyncRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
const getCommsCallback = (data) => {
|
||||||
|
if (data.status === 'SUCCESS') {
|
||||||
|
setComms(data.data.commentsList.map(o => getFormattedCommsData(o)));
|
||||||
|
}
|
||||||
|
storeSet.main.unsetAsyncRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
const errGetCommsCallback = (data) => {
|
||||||
|
if (toast.current && data.message) {
|
||||||
|
toast.current.show({
|
||||||
|
severity: 'error',
|
||||||
|
summary: '',
|
||||||
|
detail: data.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
set404FromErrorResponse(data);
|
||||||
|
storeSet.main.unsetAsyncRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
const getFormattedData = (data) => {
|
||||||
|
data.startDate = is(String, data.startDate) ? new Date(data.startDate) : (data.startDate ? data.startDate : '');
|
||||||
|
data.expirationDate = is(String, data.expirationDate) ? new Date(data.expirationDate) : (data.expirationDate ? data.expirationDate : '');
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getFormattedCommsData = (data) => {
|
||||||
|
data.id = isNil(data.id) ? uniqid('id') : data.id;
|
||||||
|
data.commentedDate = is(String, data.commentedDate) ? new Date(data.commentedDate) : (data.commentedDate ? data.commentedDate : '');
|
||||||
|
data.createdDate = is(String, data.createdDate) ? new Date(data.createdDate) : (data.createdDate ? data.createdDate : '');
|
||||||
|
data.updatedDate = is(String, data.updatedDate) ? new Date(data.updatedDate) : (data.updatedDate ? data.updatedDate : '');
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
const headerNewComDialog = () => {
|
||||||
|
return <span>{__('Aggiungi comunicazione', 'gepafin')}</span>
|
||||||
|
}
|
||||||
|
|
||||||
|
const hideNewComDialog = () => {
|
||||||
|
setIsVisibleNewCommDialog(false);
|
||||||
|
setNewCommData({
|
||||||
|
title: '',
|
||||||
|
comment: ''
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const footerNewComDialog = () => {
|
||||||
|
return <div>
|
||||||
|
<Button type="button" label={__('Anulla', 'gepafin')} onClick={hideNewComDialog} outlined/>
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
disabled={isLoadingCommunication || isEmpty(newCommData.title) || isEmpty(newCommData.comment)}
|
||||||
|
label={__('Invia', 'gepafin')} onClick={createCommunication}/>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
const openNewCommDialog = () => {
|
||||||
|
setIsVisibleNewCommDialog(true);
|
||||||
|
setNewCommData({
|
||||||
|
title: '',
|
||||||
|
comment: ''
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateNewCommData = (value, path) => {
|
||||||
|
const newData = wrap(newCommData).set(path.split('.'), value).value();
|
||||||
|
setNewCommData(newData);
|
||||||
|
}
|
||||||
|
|
||||||
|
const renderHeader = () => {
|
||||||
|
return (
|
||||||
|
<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 updateNewAmendmentData = (value, path) => {
|
||||||
|
const newData = wrap(data).set(path.split('.'), value).value();
|
||||||
|
setData(newData);
|
||||||
|
}
|
||||||
|
|
||||||
|
const createCommunication = () => {
|
||||||
|
setIsLoadingCommunication(true);
|
||||||
|
CommunicationService.createCommunication(amendmentId, newCommData, createCommunicationCallback, errCreateCommunicationCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
const createCommunicationCallback = (data) => {
|
||||||
|
if (data.status === 'SUCCESS') {
|
||||||
|
if (toast.current) {
|
||||||
|
toast.current.show({
|
||||||
|
severity: 'success',
|
||||||
|
summary: '',
|
||||||
|
detail: data.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
setComms([...comms, getFormattedCommsData(data.data)])
|
||||||
|
setIsVisibleNewCommDialog(false);
|
||||||
|
}
|
||||||
|
setIsLoadingCommunication(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
const errCreateCommunicationCallback = (data) => {
|
||||||
|
if (toast.current && data.message) {
|
||||||
|
toast.current.show({
|
||||||
|
severity: 'error',
|
||||||
|
summary: '',
|
||||||
|
detail: data.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
set404FromErrorResponse(data);
|
||||||
|
setIsLoadingCommunication(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
const onSubmit = () => {
|
||||||
|
};
|
||||||
|
|
||||||
|
const doUpdateAmendment = () => {
|
||||||
|
trigger();
|
||||||
|
let formValues = klona(getValues());
|
||||||
|
const newFormValues = Object.keys(formValues)
|
||||||
|
.reduce((acc, cur) => {
|
||||||
|
let fieldVal = formValues[cur];
|
||||||
|
|
||||||
|
fieldVal = isEmpty(fieldVal) ? null : fieldVal;
|
||||||
|
fieldVal = is(Array, fieldVal) ? fieldVal.map(o => o.id).join(',') : null;
|
||||||
|
|
||||||
|
acc.push({
|
||||||
|
'fieldId': cur,
|
||||||
|
'fieldValue': fieldVal
|
||||||
|
});
|
||||||
|
return acc;
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const submitData = {
|
||||||
|
updatedFormFields: newFormValues,
|
||||||
|
}
|
||||||
|
|
||||||
|
storeSet.main.setAsyncRequest();
|
||||||
|
AmendmentsService.updateSoccorso(amendmentId, submitData, updateAmendmentCallback, errUpdateAmendmentCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateAmendmentCallback = (data) => {
|
||||||
|
if (data.status === 'SUCCESS') {
|
||||||
|
if (toast.current) {
|
||||||
|
toast.current.show({
|
||||||
|
severity: 'success',
|
||||||
|
summary: '',
|
||||||
|
detail: data.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
storeSet.main.unsetAsyncRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
const errUpdateAmendmentCallback = (data) => {
|
||||||
|
if (toast.current && data.message) {
|
||||||
|
toast.current.show({
|
||||||
|
severity: 'error',
|
||||||
|
summary: '',
|
||||||
|
detail: data.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
set404FromErrorResponse(data);
|
||||||
|
storeSet.main.unsetAsyncRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
const doCloseAmendment = () => {
|
||||||
|
const submitData = {
|
||||||
|
internalNote: data.internalNote
|
||||||
|
}
|
||||||
|
storeSet.main.setAsyncRequest();
|
||||||
|
AmendmentsService.closeSoccorso(amendmentId, submitData, closeAmendmentCallback, errCloseAmendmentCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
const closeAmendmentCallback = (data) => {
|
||||||
|
if (data.status === 'SUCCESS') {
|
||||||
|
if (toast.current) {
|
||||||
|
toast.current.show({
|
||||||
|
severity: 'success',
|
||||||
|
summary: '',
|
||||||
|
detail: data.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (data.data.status) {
|
||||||
|
updateNewAmendmentData(data.data.status, 'status')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
storeSet.main.unsetAsyncRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
const errCloseAmendmentCallback = (data) => {
|
||||||
|
if (toast.current && data.message) {
|
||||||
|
toast.current.show({
|
||||||
|
severity: 'error',
|
||||||
|
summary: '',
|
||||||
|
detail: data.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
set404FromErrorResponse(data);
|
||||||
|
storeSet.main.unsetAsyncRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
const headerExtendRespDialog = () => {
|
||||||
|
return <span>{__('Estendi scadenza', 'gepafin')}</span>
|
||||||
|
}
|
||||||
|
|
||||||
|
const hideExtendRespDialog = () => {
|
||||||
|
setIsVisibleExtendTimeDialog(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
const footerExtendRespDialog = () => {
|
||||||
|
return <div>
|
||||||
|
<Button type="button" label={__('Anulla', 'gepafin')} onClick={hideExtendRespDialog} outlined/>
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
disabled={isLoadingExtendingTime || isEmpty(extendedTime)}
|
||||||
|
label={__('Invia', 'gepafin')} onClick={doExtendTimeResponse}/>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
const openExtendResponseTimeDialog = () => {
|
||||||
|
setIsVisibleExtendTimeDialog(true);
|
||||||
|
setExtendedTime(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
const doExtendTimeResponse = () => {
|
||||||
|
setIsLoadingExtendingTime(true);
|
||||||
|
AmendmentsService.extendSoccorso(amendmentId, extendedTime, extendCallback, errExtendCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
const extendCallback = (data) => {
|
||||||
|
if (data.status === 'SUCCESS') {
|
||||||
|
if (toast.current) {
|
||||||
|
toast.current.show({
|
||||||
|
severity: 'success',
|
||||||
|
summary: '',
|
||||||
|
detail: data.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
setIsVisibleExtendTimeDialog(false);
|
||||||
|
}
|
||||||
|
setIsLoadingExtendingTime(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
const errExtendCallback = (data) => {
|
||||||
|
if (toast.current && data.message) {
|
||||||
|
toast.current.show({
|
||||||
|
severity: 'error',
|
||||||
|
summary: '',
|
||||||
|
detail: data.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
set404FromErrorResponse(data);
|
||||||
|
setIsLoadingExtendingTime(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
const sendReminder = () => {
|
||||||
|
setIsLoadingReminding(true);
|
||||||
|
AmendmentsService.sendReminderForSoccorso(amendmentId, reminderCallback, errReminderCallback)
|
||||||
|
}
|
||||||
|
|
||||||
|
const reminderCallback = (data) => {
|
||||||
|
if (data.status === 'SUCCESS') {
|
||||||
|
if (toast.current) {
|
||||||
|
toast.current.show({
|
||||||
|
severity: 'success',
|
||||||
|
summary: '',
|
||||||
|
detail: data.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setIsLoadingReminding(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
const errReminderCallback = (data) => {
|
||||||
|
if (toast.current && data.message) {
|
||||||
|
toast.current.show({
|
||||||
|
severity: 'error',
|
||||||
|
summary: '',
|
||||||
|
detail: data.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
set404FromErrorResponse(data);
|
||||||
|
setIsLoadingReminding(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const parsedSoccorsoId = parseInt(amendmentId);
|
||||||
|
const soccorsoEntityId = !isNaN(parsedSoccorsoId) ? parsedSoccorsoId : 0;
|
||||||
|
|
||||||
|
AmendmentsService.getSoccorsoById(getCallback, errGetCallback, [['id', soccorsoEntityId]]);
|
||||||
|
}, [amendmentId]);
|
||||||
|
|
||||||
|
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>
|
||||||
|
|
||||||
|
<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.beneficiaryName}</span>
|
||||||
|
</p>
|
||||||
|
<p className="appPageSection__pMeta">
|
||||||
|
<span>{__('Inizio', 'gepafin')}</span>
|
||||||
|
<span>{getDateFromISOstring(data.startDate)}</span>
|
||||||
|
</p>
|
||||||
|
<p className="appPageSection__pMeta">
|
||||||
|
<span>{__('Scadenza', 'gepafin')}</span>
|
||||||
|
<span>{getDateFromISOstring(data.expirationDate)}</span>
|
||||||
|
</p>
|
||||||
|
<p className="appPageSection__pMeta">
|
||||||
|
<span>{__('Stato', 'gepafin')}</span>
|
||||||
|
<span>{getBandoLabel(data.status)}</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="appPageSection">
|
||||||
|
<h2>{__('Dettagli Richiesta', 'gepafin')}</h2>
|
||||||
|
<div className="appPageSection columns">
|
||||||
|
<div>
|
||||||
|
<h3>{__('Documenti Richiesti', 'gepafin')}</h3>
|
||||||
|
<ol className="appPageSection__list">
|
||||||
|
{data.formFields
|
||||||
|
? data.formFields.map((o, i) => <li key={o.fieldId} style={{ flexDirection: 'row' }}>
|
||||||
|
<span>{o.label}</span>
|
||||||
|
</li>) : null}
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h3>{__('Note e spiegazioni', 'gepafin')}</h3>
|
||||||
|
<div className="appPageSection__withBorder grey ql-editor"
|
||||||
|
style={{ minHeight: '200px' }}>
|
||||||
|
{renderHtmlContent(data.note)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="appPageSection">
|
||||||
|
<h2>{__('Comunicazioni', 'gepafin')}</h2>
|
||||||
|
<table className="myTable">
|
||||||
|
<thead className="myThead">
|
||||||
|
<tr>
|
||||||
|
<th style={{ width: 250 }}>{__('Data', 'gepafin')}</th>
|
||||||
|
<th>{__('Comunicazione', 'gepafin')}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody className="myTbody">
|
||||||
|
{!isNil(comms) && !isEmpty(comms)
|
||||||
|
? comms.map((o, i) => <tr key={o.id}>
|
||||||
|
<td valign="top">
|
||||||
|
{getDateFromISOstring(o.commentedDate)}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<h3>{o.title}</h3>
|
||||||
|
<p>{o.comment}</p>
|
||||||
|
</td>
|
||||||
|
</tr>)
|
||||||
|
: <tr>
|
||||||
|
<td>-</td>
|
||||||
|
<td>-</td>
|
||||||
|
</tr>}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
style={{ marginTop: 30 }}
|
||||||
|
onClick={openNewCommDialog}
|
||||||
|
disabled={data.status === 'CLOSE'}
|
||||||
|
type="button"
|
||||||
|
label={__('Aggiungi Comunicazione', 'gepafin')}
|
||||||
|
icon="pi pi-plus" iconPos="right"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="appPageSection">
|
||||||
|
<h2>{__('Documenti Ricevuti', 'gepafin')}</h2>
|
||||||
|
|
||||||
|
<form className="appForm" onSubmit={handleSubmit(onSubmit)}>
|
||||||
|
{data.formFields
|
||||||
|
? data.formFields.map((o, i) => {
|
||||||
|
/*const thisField = head(test.updatedFormFields.filter(j => j.fieldId === o.fieldId));
|
||||||
|
const value = pathOr({}, ['fieldValue'], thisField);
|
||||||
|
console.log('value', value, o.fieldId);*/
|
||||||
|
return <FormField
|
||||||
|
key={o.fieldId}
|
||||||
|
disabled={data.status === 'CLOSE'}
|
||||||
|
type="fileupload"
|
||||||
|
setDataFn={setValue}
|
||||||
|
fieldName={o.fieldId}
|
||||||
|
label={o.label}
|
||||||
|
control={control}
|
||||||
|
errors={errors}
|
||||||
|
defaultValue={formInitialData[o.fieldId] ? formInitialData[o.fieldId] : []}
|
||||||
|
accept={[]}
|
||||||
|
doctype="document"
|
||||||
|
register={register}
|
||||||
|
sourceId={data.applicationId}
|
||||||
|
source="application"
|
||||||
|
multiple={true}
|
||||||
|
/>
|
||||||
|
}) : null}
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
style={{ marginTop: 30 }}
|
||||||
|
type="button"
|
||||||
|
disabled={data.status === 'CLOSE'}
|
||||||
|
onClick={doUpdateAmendment}
|
||||||
|
label={__('Aggiorna', 'gepafin')}/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="appPage__spacer"></div>
|
||||||
|
|
||||||
|
<div className="appPageSection__hr">
|
||||||
|
<span>{__('Azioni', 'gepafin')}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="appPageSection">
|
||||||
|
<div className="appPageSection__actions">
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
onClick={sendReminder}
|
||||||
|
disabled={isLoadingReminding || data.status === 'CLOSE'}
|
||||||
|
outlined
|
||||||
|
label={__('Invia Sollecito', 'gepafin')}
|
||||||
|
icon="pi pi-send"
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
onClick={openExtendResponseTimeDialog}
|
||||||
|
disabled={isLoadingExtendingTime || data.status === 'CLOSE'}
|
||||||
|
outlined
|
||||||
|
label={__('Estendi Scadenza', 'gepafin')}
|
||||||
|
icon="pi pi-stopwatch"
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
onClick={doCloseAmendment}
|
||||||
|
disabled={isAsyncRequest || data.status === 'CLOSE'}
|
||||||
|
label={__('Chiudi Soccorso Istruttorio', 'gepafin')}
|
||||||
|
icon="pi pi-times" iconPos="right"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="appForm__field" style={{ marginTop: '-40px' }}>
|
||||||
|
<label>{__('Note Interne', 'gepafin')}</label>
|
||||||
|
<div style={{position: 'relative'}}>
|
||||||
|
<BlockingOverlay shouldDisplay={data.status === 'CLOSE'}/>
|
||||||
|
<Editor
|
||||||
|
value={data.internalNote}
|
||||||
|
readOnly={data.status === 'CLOSE'}
|
||||||
|
placeholder={__('Digita qui il messagio', 'gepafin')}
|
||||||
|
headerTemplate={header}
|
||||||
|
onTextChange={(e) => updateNewAmendmentData(
|
||||||
|
e.htmlValue,
|
||||||
|
'internalNote'
|
||||||
|
)}
|
||||||
|
style={{ height: 80 * 3, width: '100%' }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Dialog
|
||||||
|
visible={isVisibleNewCommDialog}
|
||||||
|
modal
|
||||||
|
header={headerNewComDialog}
|
||||||
|
footer={footerNewComDialog}
|
||||||
|
style={{ maxWidth: '600px', width: '100%' }}
|
||||||
|
onHide={hideNewComDialog}>
|
||||||
|
<div className="appForm__field">
|
||||||
|
<label
|
||||||
|
className={classNames({ 'p-error': isEmpty(newCommData.title) })}>
|
||||||
|
{__('Titolo', 'gepafin')}*
|
||||||
|
</label>
|
||||||
|
<InputText value={newCommData.title}
|
||||||
|
disabled={data.status === 'CLOSE'}
|
||||||
|
invalid={isEmpty(newCommData.title)}
|
||||||
|
onChange={(e) => updateNewCommData(e.target.value, 'title')}/>
|
||||||
|
|
||||||
|
<label
|
||||||
|
className={classNames({ 'p-error': isEmpty(newCommData.comment) })}>
|
||||||
|
{__('Contenuto', 'gepafin')}*
|
||||||
|
</label>
|
||||||
|
<InputTextarea
|
||||||
|
value={newCommData.comment}
|
||||||
|
disabled={data.status === 'CLOSE'}
|
||||||
|
rows={5} cols={30}
|
||||||
|
invalid={isEmpty(newCommData.comment)}
|
||||||
|
onChange={(e) => updateNewCommData(e.target.value, 'comment')}/>
|
||||||
|
</div>
|
||||||
|
</Dialog>
|
||||||
|
|
||||||
|
<Dialog
|
||||||
|
visible={isVisibleExtendTimeDialog}
|
||||||
|
modal
|
||||||
|
header={headerExtendRespDialog}
|
||||||
|
footer={footerExtendRespDialog}
|
||||||
|
style={{ maxWidth: '600px', width: '100%' }}
|
||||||
|
onHide={hideExtendRespDialog}>
|
||||||
|
<div className="appForm__field">
|
||||||
|
<label
|
||||||
|
className={classNames({ 'p-error': isEmpty(extendedTime) })}>
|
||||||
|
{__('Giorni', 'gepafin')}*
|
||||||
|
</label>
|
||||||
|
<InputNumber
|
||||||
|
keyfilter="int"
|
||||||
|
disabled={data.status === 'CLOSE'}
|
||||||
|
value={extendedTime}
|
||||||
|
showButtons
|
||||||
|
onChange={(e) => setExtendedTime(e.value)}/>
|
||||||
|
</div>
|
||||||
|
</Dialog>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SoccorsoEditPreInstructor;
|
||||||
@@ -0,0 +1,174 @@
|
|||||||
|
import React, { useState, useEffect} from 'react';
|
||||||
|
import { __ } from '@wordpress/i18n';
|
||||||
|
import { is, uniq } from 'ramda';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
|
// store
|
||||||
|
import { storeGet } from '../../../../store';
|
||||||
|
|
||||||
|
// api
|
||||||
|
|
||||||
|
|
||||||
|
// 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';
|
||||||
|
import AmendmentsService from '../../../../service/amendments-service';
|
||||||
|
|
||||||
|
|
||||||
|
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(() => {
|
||||||
|
const userData = storeGet.main.userData()
|
||||||
|
setLocalAsyncRequest(true);
|
||||||
|
AmendmentsService.getSoccorsoByPreInstructorId(userData.id, getCallback, errGetCallbacks);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
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.expirationDate = is(String, d.expirationDate) ? new Date(d.expirationDate) : (d.expirationDate ? d.expirationDate : '');
|
||||||
|
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 },
|
||||||
|
callName: {
|
||||||
|
operator: FilterOperator.AND,
|
||||||
|
constraints: [{ value: null, matchMode: FilterMatchMode.STARTS_WITH }]
|
||||||
|
},
|
||||||
|
beneficiaryName: {
|
||||||
|
operator: FilterOperator.AND,
|
||||||
|
constraints: [{ value: null, matchMode: FilterMatchMode.STARTS_WITH }]
|
||||||
|
},
|
||||||
|
startDate: {
|
||||||
|
operator: FilterOperator.AND,
|
||||||
|
constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }]
|
||||||
|
},
|
||||||
|
expirationDate: {
|
||||||
|
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 dateStartBodyTemplate = (rowData) => {
|
||||||
|
return formatDate(rowData.startDate);
|
||||||
|
};
|
||||||
|
|
||||||
|
const dateExpirationBodyTemplate = (rowData) => {
|
||||||
|
return formatDate(rowData.expirationDate);
|
||||||
|
};
|
||||||
|
|
||||||
|
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 <Link to={`/domande/${rowData.applicationId}/soccorso/${rowData.id}`}>
|
||||||
|
<Button severity="info" label={__('Dettagli', '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="applicationId" header={__('ID domanda', 'gepafin')}
|
||||||
|
filter filterPlaceholder={__('Cerca', 'gepafin')}
|
||||||
|
style={{ minWidth: '6rem' }}/>
|
||||||
|
<Column field="callName" header={__('Bando', 'gepafin')}
|
||||||
|
filter filterPlaceholder={__('Cerca', 'gepafin')}
|
||||||
|
style={{ minWidth: '8rem' }}/>
|
||||||
|
<Column field="beneficiaryName" header={__('Beneficiario', 'gepafin')}
|
||||||
|
filter filterPlaceholder={__('Cerca', 'gepafin')}
|
||||||
|
style={{ minWidth: '8rem' }}/>
|
||||||
|
<Column header={__('Data Richiesta', 'gepafin')}
|
||||||
|
filterField="startDate" dataType="date"
|
||||||
|
style={{ minWidth: '8rem' }}
|
||||||
|
body={dateStartBodyTemplate} filter filterElement={dateFilterTemplate}/>
|
||||||
|
<Column header={__('Scadenza', 'gepafin')}
|
||||||
|
filterField="expirationDate" dataType="date"
|
||||||
|
style={{ minWidth: '8rem' }}
|
||||||
|
body={dateExpirationBodyTemplate} filter filterElement={dateFilterTemplate}/>
|
||||||
|
<Column field="status" header={__('Stato', 'gepafin')}
|
||||||
|
style={{ minWidth: '7rem' }} 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;
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
import React, { useState, useEffect} from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import { __ } from '@wordpress/i18n';
|
import { __ } from '@wordpress/i18n';
|
||||||
import { is, uniq } from 'ramda';
|
import { uniq } from 'ramda';
|
||||||
|
|
||||||
// store
|
// store
|
||||||
import { storeSet, storeGet } from '../../../../store';
|
import { useStore, storeSet } from '../../../../store';
|
||||||
|
|
||||||
// tools
|
// tools
|
||||||
import getBandoSeverity from '../../../../helpers/getBandoSeverity';
|
import getBandoSeverity from '../../../../helpers/getBandoSeverity';
|
||||||
@@ -11,7 +11,7 @@ import getBandoLabel from '../../../../helpers/getBandoLabel';
|
|||||||
import getDateFromISOstring from '../../../../helpers/getDateFromISOstring';
|
import getDateFromISOstring from '../../../../helpers/getDateFromISOstring';
|
||||||
|
|
||||||
// api
|
// api
|
||||||
import BandoService from '../../../../service/bando-service';
|
import UserService from '../../../../service/user-service';
|
||||||
|
|
||||||
// components
|
// components
|
||||||
import { FilterMatchMode, FilterOperator } from 'primereact/api';
|
import { FilterMatchMode, FilterOperator } from 'primereact/api';
|
||||||
@@ -25,59 +25,37 @@ import { Button } from 'primereact/button';
|
|||||||
import { Calendar } from 'primereact/calendar';
|
import { Calendar } from 'primereact/calendar';
|
||||||
import { Tag } from 'primereact/tag';
|
import { Tag } from 'primereact/tag';
|
||||||
import ProperBandoLabel from '../../../../components/ProperBandoLabel';
|
import ProperBandoLabel from '../../../../components/ProperBandoLabel';
|
||||||
import { Link } from 'react-router-dom';
|
|
||||||
|
|
||||||
|
|
||||||
const AllUsersTable = () => {
|
const AllUsersTable = () => {
|
||||||
const [items, setItems] = useState(null);
|
const users = useStore().main.users();
|
||||||
const [filters, setFilters] = useState(null);
|
const [filters, setFilters] = useState(null);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [globalFilterValue, setGlobalFilterValue] = useState('');
|
const [globalFilterValue, setGlobalFilterValue] = useState('');
|
||||||
const [statuses, setStatuses] = useState([]);
|
const [statuses, setStatuses] = useState([]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
storeSet.main.setAsyncRequest();
|
if (!loading) {
|
||||||
const sample = [
|
setLoading(true);
|
||||||
{
|
UserService.getUsers(getCallback, errGetCallbacks);
|
||||||
id: 11,
|
}
|
||||||
name: 'Mario Rossi',
|
|
||||||
email: 'mario.rossi@example.com',
|
|
||||||
role: 'Beneficiario',
|
|
||||||
status: 'active',
|
|
||||||
last_access: '2024-08-01 10:30'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 12,
|
|
||||||
name: 'Mario Rossi2',
|
|
||||||
email: 'mario.rossi@example.com',
|
|
||||||
role: 'Beneficiario',
|
|
||||||
status: 'active',
|
|
||||||
last_access: '2024-08-01 10:30'
|
|
||||||
}
|
|
||||||
];
|
|
||||||
setItems(sample);
|
|
||||||
//BandoService.getBandi(getCallback, errGetCallbacks);
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
/*const getCallback = (data) => {
|
const getCallback = (data) => {
|
||||||
if (data.status === 'SUCCESS') {
|
if (data.status === 'SUCCESS') {
|
||||||
setItems(getFormattedBandiData(data.data));
|
storeSet.main.users(getFormattedData(data.data));
|
||||||
setStatuses(uniq(data.data.map(o => o.status)))
|
setStatuses(uniq(data.data.map(o => o.status)))
|
||||||
initFilters();
|
initFilters();
|
||||||
}
|
}
|
||||||
storeSet.main.unsetAsyncRequest();
|
setLoading(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
const errGetCallbacks = (data) => {
|
const errGetCallbacks = () => {
|
||||||
console.log('errGetCallbacks', data)
|
setLoading(false);
|
||||||
storeSet.main.unsetAsyncRequest();
|
}
|
||||||
}*/
|
|
||||||
|
|
||||||
const getFormattedData = (data) => {
|
const getFormattedData = (data) => {
|
||||||
return data.map((d) => {
|
return data
|
||||||
d.last_access = is(String, d.last_access) ? new Date(d.last_access) : (d.last_access ? d.last_access : '');
|
.filter(o => ['ROLE_SUPER_ADMIN', 'ROLE_PRE_INSTRUCTOR'].includes(o.role.roleType));
|
||||||
return d;
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const clearFilter = () => {
|
const clearFilter = () => {
|
||||||
@@ -97,8 +75,14 @@ const AllUsersTable = () => {
|
|||||||
const initFilters = () => {
|
const initFilters = () => {
|
||||||
setFilters({
|
setFilters({
|
||||||
global: { value: null, matchMode: FilterMatchMode.CONTAINS },
|
global: { value: null, matchMode: FilterMatchMode.CONTAINS },
|
||||||
name: { operator: FilterOperator.AND, constraints: [{ value: null, matchMode: FilterMatchMode.STARTS_WITH }] },
|
name: {
|
||||||
last_access: { operator: FilterOperator.AND, constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }] },
|
operator: FilterOperator.AND,
|
||||||
|
constraints: [{ value: null, matchMode: FilterMatchMode.STARTS_WITH }]
|
||||||
|
},
|
||||||
|
lastLogin: {
|
||||||
|
operator: FilterOperator.AND,
|
||||||
|
constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }]
|
||||||
|
},
|
||||||
status: { operator: FilterOperator.OR, constraints: [{ value: null, matchMode: FilterMatchMode.EQUALS }] },
|
status: { operator: FilterOperator.OR, constraints: [{ value: null, matchMode: FilterMatchMode.EQUALS }] },
|
||||||
});
|
});
|
||||||
setGlobalFilterValue('');
|
setGlobalFilterValue('');
|
||||||
@@ -107,21 +91,32 @@ const AllUsersTable = () => {
|
|||||||
const renderHeader = () => {
|
const renderHeader = () => {
|
||||||
return (
|
return (
|
||||||
<div className="appTableHeader">
|
<div className="appTableHeader">
|
||||||
<Button type="button" icon="pi pi-filter-slash" label={__('Pulisci', 'gepafin')} outlined onClick={clearFilter} />
|
<Button type="button" icon="pi pi-filter-slash" label={__('Pulisci', 'gepafin')} outlined
|
||||||
|
onClick={clearFilter}/>
|
||||||
<IconField iconPosition="left">
|
<IconField iconPosition="left">
|
||||||
<InputIcon className="pi pi-search" />
|
<InputIcon className="pi pi-search"/>
|
||||||
<InputText value={globalFilterValue} onChange={onGlobalFilterChange} placeholder={__('Cerca', 'gepafin')} />
|
<InputText value={globalFilterValue} onChange={onGlobalFilterChange}
|
||||||
|
placeholder={__('Cerca', 'gepafin')}/>
|
||||||
</IconField>
|
</IconField>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const dateLastAccessBodyTemplate = (rowData) => {
|
const dateLastAccessBodyTemplate = (rowData) => {
|
||||||
return getDateFromISOstring(rowData.last_access);
|
return getDateFromISOstring(rowData.lastLogin);
|
||||||
};
|
};
|
||||||
|
|
||||||
const dateFilterTemplate = (options) => {
|
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" />;
|
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 nameBodyTemplate = (rowData) => {
|
||||||
|
return `${rowData.firstName} ${rowData.lastName}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
const roleBodyTemplate = (rowData) => {
|
||||||
|
return rowData.role.roleName;
|
||||||
};
|
};
|
||||||
|
|
||||||
const statusBodyTemplate = (rowData) => {
|
const statusBodyTemplate = (rowData) => {
|
||||||
@@ -129,43 +124,53 @@ const AllUsersTable = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const statusFilterTemplate = (options) => {
|
const statusFilterTemplate = (options) => {
|
||||||
return <Dropdown value={options.value} options={statuses} onChange={(e) => options.filterCallback(e.value, options.index)} itemTemplate={statusItemTemplate} placeholder="Select One" className="p-column-filter" showClear />;
|
return <Dropdown value={options.value} options={statuses}
|
||||||
|
onChange={(e) => options.filterCallback(e.value, options.index)}
|
||||||
|
itemTemplate={statusItemTemplate} placeholder={__('Scegli uno', 'gepafin')}
|
||||||
|
className="p-column-filter"
|
||||||
|
showClear/>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const statusItemTemplate = (option) => {
|
const statusItemTemplate = (option) => {
|
||||||
return <Tag value={getBandoLabel(option)} severity={getBandoSeverity(option)} />;
|
return <Tag value={getBandoLabel(option)} severity={getBandoSeverity(option)}/>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const actionsBodyTemplate = (rowData) => {
|
/*const actionsBodyTemplate = (rowData) => {
|
||||||
return <Link to={`/utenti/${rowData.id}`}>
|
/!*return <Link to={`/utenti/${rowData.id}`}>
|
||||||
<Button severity="info" label={__('Modifica', 'gepafin')} icon="pi pi-pencil" size="small" iconPos="right" />
|
<Button severity="info" label={__('Modifica', 'gepafin')} icon="pi pi-pencil" size="small" iconPos="right"/>
|
||||||
</Link>
|
</Link>*!/
|
||||||
}
|
return null;
|
||||||
|
}*/
|
||||||
|
|
||||||
const header = renderHeader();
|
const header = renderHeader();
|
||||||
|
|
||||||
return(
|
return (
|
||||||
<div className="appPageSection__table">
|
<div className="appPageSection__table">
|
||||||
<DataTable value={items} paginator showGridlines rows={10} loading={loading} dataKey="id"
|
<DataTable value={users} paginator showGridlines rows={10} loading={loading} dataKey="id"
|
||||||
filters={filters}
|
filters={filters}
|
||||||
globalFilterFields={['name', 'status']}
|
globalFilterFields={['name', 'status']}
|
||||||
header={header}
|
header={header}
|
||||||
emptyMessage={__('Nessun dato disponibile', 'gepafin')}
|
emptyMessage={__('Nessun dato disponibile', 'gepafin')}
|
||||||
onFilter={(e) => setFilters(e.filters)}>
|
onFilter={(e) => setFilters(e.filters)}>
|
||||||
<Column field="name" header={__('Nome utente', 'gepafin')} filter filterPlaceholder="Search by name"
|
<Column body={nameBodyTemplate}
|
||||||
|
header={__('Nome utente', 'gepafin')}
|
||||||
|
filter filterPlaceholder={__('Cerca per nome', 'gepafin')}
|
||||||
style={{ minWidth: '12rem' }}/>
|
style={{ minWidth: '12rem' }}/>
|
||||||
<Column field="email" header={__('Email', 'gepafin')} filter filterPlaceholder="Search by email"
|
<Column field="email" header={__('Email', 'gepafin')}
|
||||||
|
filter filterPlaceholder={__('Cerca per email', 'gepafin')}
|
||||||
style={{ minWidth: '12rem' }}/>
|
style={{ minWidth: '12rem' }}/>
|
||||||
<Column field="role" header={__('Ruolo', 'gepafin')}
|
<Column body={roleBodyTemplate} header={__('Ruolo', 'gepafin')}
|
||||||
style={{ minWidth: '12rem' }}/>
|
style={{ minWidth: '12rem' }}/>
|
||||||
<Column field="status" header={__('Stato', 'gepafin')} filterMenuStyle={{ width: '14rem' }}
|
<Column field="status" header={__('Stato', 'gepafin')}
|
||||||
style={{ width: '120px' }} body={statusBodyTemplate} filter
|
filterMenuStyle={{ width: '14rem' }}
|
||||||
filterElement={statusFilterTemplate}/>
|
style={{ width: '120px' }} body={statusBodyTemplate}
|
||||||
<Column header={__('Ultimo accesso', 'gepafin')} filterField="last_access" dataType="date"
|
filter filterElement={statusFilterTemplate}/>
|
||||||
|
<Column header={__('Ultimo accesso', 'gepafin')}
|
||||||
|
filterField="lastLogin" dataType="date"
|
||||||
style={{ minWidth: '10rem' }}
|
style={{ minWidth: '10rem' }}
|
||||||
body={dateLastAccessBodyTemplate} filter filterElement={dateFilterTemplate}/>
|
body={dateLastAccessBodyTemplate} filter filterElement={dateFilterTemplate}/>
|
||||||
<Column header={__('Azioni', 'gepafin')}
|
{/*<Column header={__('Azioni', 'gepafin')}
|
||||||
body={actionsBodyTemplate}/>
|
body={actionsBodyTemplate}/>*/}
|
||||||
</DataTable>
|
</DataTable>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,6 +1,17 @@
|
|||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect, useRef } from 'react';
|
||||||
import { __ } from '@wordpress/i18n';
|
import { __ } from '@wordpress/i18n';
|
||||||
import { isEmpty, isNil } from 'ramda';
|
import { isEmpty, isNil } from 'ramda';
|
||||||
|
import { klona } from 'klona';
|
||||||
|
|
||||||
|
// store
|
||||||
|
import { storeSet, storeGet } from '../../store';
|
||||||
|
|
||||||
|
// service
|
||||||
|
import UserService from '../../service/user-service';
|
||||||
|
|
||||||
|
// tools
|
||||||
|
import set404FromErrorResponse from '../../helpers/set404FromErrorResponse';
|
||||||
|
import { isEmail } from '../../helpers/validators';
|
||||||
|
|
||||||
// components
|
// components
|
||||||
import AllUsersTable from './components/AllUsersTable';
|
import AllUsersTable from './components/AllUsersTable';
|
||||||
@@ -8,22 +19,25 @@ import { Button } from 'primereact/button';
|
|||||||
import { InputText } from 'primereact/inputtext';
|
import { InputText } from 'primereact/inputtext';
|
||||||
import { Dropdown } from 'primereact/dropdown';
|
import { Dropdown } from 'primereact/dropdown';
|
||||||
import { Dialog } from 'primereact/dialog';
|
import { Dialog } from 'primereact/dialog';
|
||||||
import UserService from '../../service/user-service';
|
|
||||||
import set404FromErrorResponse from '../../helpers/set404FromErrorResponse';
|
|
||||||
import { storeSet } from '../../store';
|
|
||||||
import { klona } from 'klona';
|
|
||||||
import { classNames } from 'primereact/utils';
|
import { classNames } from 'primereact/utils';
|
||||||
|
import { Toast } from 'primereact/toast';
|
||||||
|
|
||||||
|
const APP_HUB_ID = process.env.REACT_APP_HUB_ID;
|
||||||
|
|
||||||
const Users = () => {
|
const Users = () => {
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
const [isVisibleEditDialog, setIsVisibleEditDialog] = useState(false);
|
const [isVisibleEditDialog, setIsVisibleEditDialog] = useState(false);
|
||||||
const [newUserData, setNewUserData] = useState({
|
const [newUserData, setNewUserData] = useState({
|
||||||
firstName: '',
|
firstName: '',
|
||||||
lastName: '',
|
lastName: '',
|
||||||
email: '',
|
email: '',
|
||||||
phoneNumber: '',
|
phoneNumber: '',
|
||||||
role: ''
|
password: '',
|
||||||
|
confPassword: '',
|
||||||
|
roleId: 0
|
||||||
});
|
});
|
||||||
const [roles, setRoles] = useState([]);
|
const [roles, setRoles] = useState([]);
|
||||||
|
const toast = useRef(null);
|
||||||
|
|
||||||
const onCreateNewUser = () => {
|
const onCreateNewUser = () => {
|
||||||
setIsVisibleEditDialog(true);
|
setIsVisibleEditDialog(true);
|
||||||
@@ -40,12 +54,52 @@ const Users = () => {
|
|||||||
lastName: '',
|
lastName: '',
|
||||||
email: '',
|
email: '',
|
||||||
phoneNumber: '',
|
phoneNumber: '',
|
||||||
role: ''
|
password: '',
|
||||||
|
confPassword: '',
|
||||||
|
roleId: 0
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const saveEditDialog = () => {
|
const saveEditDialog = () => {
|
||||||
|
const emptyValues = Object.values(newUserData).filter(v => isEmpty(v));
|
||||||
|
|
||||||
|
if (isEmpty(emptyValues) && newUserData.password === newUserData.confPassword && !loading) {
|
||||||
|
setLoading(true);
|
||||||
|
const body = {
|
||||||
|
...newUserData,
|
||||||
|
hubUuid: APP_HUB_ID
|
||||||
|
}
|
||||||
|
|
||||||
|
UserService.createUser(body, createUserCallback, errCreateUserCallback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const createUserCallback = (data) => {
|
||||||
|
if (data.status === 'SUCCESS') {
|
||||||
|
const users = storeGet.main.users();
|
||||||
|
storeSet.main.users([data.data.user, ...users]);
|
||||||
|
if (toast.current) {
|
||||||
|
toast.current.show({
|
||||||
|
severity: 'success',
|
||||||
|
summary: '',
|
||||||
|
detail: data.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setLoading(false);
|
||||||
|
hideEditDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
const errCreateUserCallback = (data) => {
|
||||||
|
setLoading(false);
|
||||||
|
if (toast.current) {
|
||||||
|
toast.current.show({
|
||||||
|
severity: 'error',
|
||||||
|
summary: '',
|
||||||
|
detail: data.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
set404FromErrorResponse(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
const onChangeEditItem = (value, key) => {
|
const onChangeEditItem = (value, key) => {
|
||||||
@@ -59,18 +113,20 @@ const Users = () => {
|
|||||||
<Button type="button" label={__('Anulla', 'gepafin')} onClick={hideEditDialog} outlined/>
|
<Button type="button" label={__('Anulla', 'gepafin')} onClick={hideEditDialog} outlined/>
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
disabled={isEmpty(newUserData)}
|
disabled={isEmpty(newUserData) || loading}
|
||||||
label={__('Salva', 'gepafin')} onClick={saveEditDialog}/>
|
label={__('Salva', 'gepafin')} onClick={saveEditDialog}/>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
const getRolesCallback = (data) => {
|
const getRolesCallback = (data) => {
|
||||||
if (data.status === 'SUCCESS') {
|
if (data.status === 'SUCCESS') {
|
||||||
const roles = data.data.map(o => ({
|
const roles = data.data
|
||||||
name: o.roleName,
|
.filter(o => ['ROLE_SUPER_ADMIN', 'ROLE_PRE_INSTRUCTOR'].includes(o.roleType))
|
||||||
value: o.id
|
.map(o => ({
|
||||||
}));
|
name: o.roleName,
|
||||||
setRoles(roles)
|
value: o.id
|
||||||
|
}));
|
||||||
|
setRoles(roles);
|
||||||
}
|
}
|
||||||
storeSet.main.unsetAsyncRequest();
|
storeSet.main.unsetAsyncRequest();
|
||||||
}
|
}
|
||||||
@@ -80,19 +136,22 @@ const Users = () => {
|
|||||||
storeSet.main.unsetAsyncRequest();
|
storeSet.main.unsetAsyncRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isInvalidField = (data, key) => isEmpty(data[key]) || isNil(data[key])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isVisibleEditDialog) {
|
if (isVisibleEditDialog) {
|
||||||
UserService.getRoles(getRolesCallback, errGetRolesCallback)
|
UserService.getRoles(getRolesCallback, errGetRolesCallback)
|
||||||
}
|
}
|
||||||
}, [isVisibleEditDialog]);
|
}, [isVisibleEditDialog]);
|
||||||
|
|
||||||
return(
|
return (
|
||||||
<div className="appPage">
|
<div className="appPage">
|
||||||
<div className="appPage__pageHeader">
|
<div className="appPage__pageHeader">
|
||||||
<h1>{__('Gestione utenti', 'gepafin')}</h1>
|
<h1>{__('Gestione utenti', 'gepafin')}</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="appPage__spacer"></div>
|
<div className="appPage__spacer"></div>
|
||||||
|
<Toast ref={toast} />
|
||||||
|
|
||||||
<div className="appPageSection">
|
<div className="appPageSection">
|
||||||
<div className="appPageSection__actions">
|
<div className="appPageSection__actions">
|
||||||
@@ -101,7 +160,7 @@ const Users = () => {
|
|||||||
label={__('Crea nuovo')} icon="pi pi-plus" iconPos="right"/>
|
label={__('Crea nuovo')} icon="pi pi-plus" iconPos="right"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<AllUsersTable doRefresh={true}/>
|
<AllUsersTable/>
|
||||||
|
|
||||||
<Dialog
|
<Dialog
|
||||||
visible={isVisibleEditDialog}
|
visible={isVisibleEditDialog}
|
||||||
@@ -113,38 +172,74 @@ const Users = () => {
|
|||||||
<div className="appPage__spacer"></div>
|
<div className="appPage__spacer"></div>
|
||||||
<div className="appForm__cols">
|
<div className="appForm__cols">
|
||||||
<div className="appForm__field">
|
<div className="appForm__field">
|
||||||
<label className={classNames({ 'p-error': isEmpty(newUserData.firstName) || isNil(newUserData.firstName) })}>{__('Nome', 'gepafin')}*</label>
|
<label
|
||||||
|
className={classNames({ 'p-error': isInvalidField(newUserData, 'firstName') })}>
|
||||||
|
{__('Nome', 'gepafin')}*
|
||||||
|
</label>
|
||||||
<InputText value={newUserData.firstName}
|
<InputText value={newUserData.firstName}
|
||||||
invalid={isEmpty(newUserData.firstName) || isNil(newUserData.firstName)}
|
invalid={isInvalidField(newUserData, 'firstName')}
|
||||||
onChange={(e) => onChangeEditItem(e.target.value, 'firstName')}/>
|
onChange={(e) => onChangeEditItem(e.target.value, 'firstName')}/>
|
||||||
</div>
|
</div>
|
||||||
<div className="appForm__field">
|
<div className="appForm__field">
|
||||||
<label className={classNames({ 'p-error': isEmpty(newUserData.lastName) || isNil(newUserData.lastName) })}>{__('Cognome', 'gepafin')}*</label>
|
<label
|
||||||
|
className={classNames({ 'p-error': isInvalidField(newUserData, 'lastName') })}>
|
||||||
|
{__('Cognome', 'gepafin')}*
|
||||||
|
</label>
|
||||||
<InputText value={newUserData.lastName}
|
<InputText value={newUserData.lastName}
|
||||||
invalid={isEmpty(newUserData.lastName) || isNil(newUserData.lastName)}
|
invalid={isInvalidField(newUserData, 'lastName')}
|
||||||
onChange={(e) => onChangeEditItem(e.target.value, 'lastName')}/>
|
onChange={(e) => onChangeEditItem(e.target.value, 'lastName')}/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="appForm__cols">
|
<div className="appForm__cols">
|
||||||
<div className="appForm__field">
|
<div className="appForm__field">
|
||||||
<label className={classNames({ 'p-error': isEmpty(newUserData.email) || isNil(newUserData.email) })}>{__('Email', 'gepafin')}*</label>
|
<label
|
||||||
|
className={classNames({ 'p-error': isEmpty(newUserData.email) || isNil(newUserData.email) || !isEmail(newUserData.email) })}>
|
||||||
|
{__('Email', 'gepafin')}*
|
||||||
|
</label>
|
||||||
<InputText value={newUserData.email}
|
<InputText value={newUserData.email}
|
||||||
invalid={isEmpty(newUserData.email) || isNil(newUserData.email)}
|
invalid={isEmpty(newUserData.email) || isNil(newUserData.email) || !isEmail(newUserData.email)}
|
||||||
onChange={(e) => onChangeEditItem(e.target.value, 'email')}/>
|
onChange={(e) => onChangeEditItem(e.target.value, 'email')}/>
|
||||||
</div>
|
</div>
|
||||||
<div className="appForm__field">
|
<div className="appForm__field">
|
||||||
<label className={classNames({ 'p-error': isEmpty(newUserData.phoneNumber) || isNil(newUserData.phoneNumber) })}>{__('Telefono', 'gepafin')}</label>
|
<label
|
||||||
|
className={classNames({ 'p-error': isInvalidField(newUserData, 'phoneNumber') })}>
|
||||||
|
{__('Telefono', 'gepafin')}
|
||||||
|
</label>
|
||||||
<InputText value={newUserData.phoneNumber}
|
<InputText value={newUserData.phoneNumber}
|
||||||
invalid={isEmpty(newUserData.phoneNumber) || isNil(newUserData.phoneNumber)}
|
keyfilter="int"
|
||||||
|
invalid={isInvalidField(newUserData, 'phoneNumber')}
|
||||||
onChange={(e) => onChangeEditItem(e.target.value, 'phoneNumber')}/>
|
onChange={(e) => onChangeEditItem(e.target.value, 'phoneNumber')}/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="appForm__cols">
|
||||||
|
<div className="appForm__field">
|
||||||
|
<label
|
||||||
|
className={classNames({ 'p-error': isEmpty(newUserData.password) || isNil(newUserData.password) || newUserData.password !== newUserData.confPassword })}>
|
||||||
|
{__('Password', 'gepafin')}*
|
||||||
|
</label>
|
||||||
|
<InputText value={newUserData.password}
|
||||||
|
invalid={isEmpty(newUserData.password) || isNil(newUserData.password) || newUserData.password !== newUserData.confPassword}
|
||||||
|
onChange={(e) => onChangeEditItem(e.target.value, 'password')}/>
|
||||||
|
</div>
|
||||||
|
<div className="appForm__field">
|
||||||
|
<label
|
||||||
|
className={classNames({ 'p-error': isEmpty(newUserData.confPassword) || isNil(newUserData.confPassword) || newUserData.password !== newUserData.confPassword })}>
|
||||||
|
{__('Conferma password', 'gepafin')}*
|
||||||
|
</label>
|
||||||
|
<InputText value={newUserData.confPassword}
|
||||||
|
invalid={isEmpty(newUserData.confPassword) || isNil(newUserData.confPassword) || newUserData.password !== newUserData.confPassword}
|
||||||
|
onChange={(e) => onChangeEditItem(e.target.value, 'confPassword')}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div className="appForm__field">
|
<div className="appForm__field">
|
||||||
<label className={classNames({ 'p-error': isEmpty(newUserData.role) || isNil(newUserData.role) })}>{__('Ruolo', 'gepafin')}</label>
|
<label
|
||||||
|
className={classNames({ 'p-error': isEmpty(newUserData.roleId) || isNil(newUserData.roleId) || newUserData.roleId === 0 })}>
|
||||||
|
{__('Ruolo', 'gepafin')}*
|
||||||
|
</label>
|
||||||
<Dropdown
|
<Dropdown
|
||||||
value={newUserData.role}
|
value={newUserData.roleId}
|
||||||
invalid={isEmpty(newUserData.role) || isNil(newUserData.role)}
|
invalid={isEmpty(newUserData.roleId) || isNil(newUserData.roleId) || newUserData.roleId === 0}
|
||||||
onChange={(e) => onChangeEditItem(e.value, 'role')}
|
onChange={(e) => onChangeEditItem(e.value, 'roleId')}
|
||||||
options={roles}
|
options={roles}
|
||||||
optionLabel="name"
|
optionLabel="name"
|
||||||
optionValue="value"/>
|
optionValue="value"/>
|
||||||
|
|||||||
@@ -25,6 +25,16 @@ import ProfileCompany from './pages/ProfileCompany';
|
|||||||
import Users from './pages/Users';
|
import Users from './pages/Users';
|
||||||
import AddCompany from './pages/AddCompany';
|
import AddCompany from './pages/AddCompany';
|
||||||
import ResetPassword from './pages/ResetPassword';
|
import ResetPassword from './pages/ResetPassword';
|
||||||
|
import DashboardPreInstructor from './pages/DashboardPreInstructor';
|
||||||
|
import ProfileBeneficiario from './pages/ProfileBeneficiario';
|
||||||
|
import Domande from './pages/Domande';
|
||||||
|
import DomandePreInstructor from './pages/DomandePreInstructor';
|
||||||
|
import DomandaEditPreInstructor from './pages/DomandaEditPreInstructor';
|
||||||
|
import SoccorsoIstruttorioPreInstructor from './pages/SoccorsoIstruttorioPreInstructor';
|
||||||
|
import SoccorsoEditPreInstructor from './pages/SoccorsoEditPreInstructor';
|
||||||
|
import SoccorsoAddPreInstructor from './pages/SoccorsoAddPreInstructor';
|
||||||
|
import DomandeBeneficiario from './pages/DomandeBeneficiario';
|
||||||
|
import DomandaBeneficiario from './pages/DomandaBeneficiario';
|
||||||
|
|
||||||
const routes = ({ role, chosenCompanyId }) => {
|
const routes = ({ role, chosenCompanyId }) => {
|
||||||
|
|
||||||
@@ -34,62 +44,102 @@ const routes = ({ role, chosenCompanyId }) => {
|
|||||||
<Route path="/" element={<DefaultLayout>
|
<Route path="/" element={<DefaultLayout>
|
||||||
{'ROLE_SUPER_ADMIN' === role ? <Dashboard/> : null}
|
{'ROLE_SUPER_ADMIN' === role ? <Dashboard/> : null}
|
||||||
{'ROLE_BENEFICIARY' === role ? <DashboardBeneficiario/> : null}
|
{'ROLE_BENEFICIARY' === role ? <DashboardBeneficiario/> : null}
|
||||||
|
{'ROLE_PRE_INSTRUCTOR' === role ? <DashboardPreInstructor/> : null}
|
||||||
</DefaultLayout>}/>
|
</DefaultLayout>}/>
|
||||||
<Route path="/bandi" element={<DefaultLayout>
|
<Route path="/bandi" element={<DefaultLayout>
|
||||||
{'ROLE_SUPER_ADMIN' === role ? <Bandi/> : null}
|
{'ROLE_SUPER_ADMIN' === role ? <Bandi/> : null}
|
||||||
{'ROLE_BENEFICIARY' === role ? <BandiBeneficiario/> : null}
|
{'ROLE_BENEFICIARY' === role ? <BandiBeneficiario/> : null}
|
||||||
|
{'ROLE_PRE_INSTRUCTOR' === role ? <PageNotFound/> : null}
|
||||||
</DefaultLayout>}/>
|
</DefaultLayout>}/>
|
||||||
<Route path="/bandi/:id" element={<DefaultLayout>
|
<Route path="/bandi/:id" element={<DefaultLayout>
|
||||||
{'ROLE_SUPER_ADMIN' === role ? <BandoEdit/> : null}
|
{'ROLE_SUPER_ADMIN' === role ? <BandoEdit/> : null}
|
||||||
{'ROLE_BENEFICIARY' === role ? <BandoViewBeneficiario/> : null}
|
{'ROLE_BENEFICIARY' === role ? <BandoViewBeneficiario/> : null}
|
||||||
|
{'ROLE_PRE_INSTRUCTOR' === role ? <PageNotFound/> : null}
|
||||||
</DefaultLayout>}/>
|
</DefaultLayout>}/>
|
||||||
<Route path="/bandi/:id/preview" element={<DefaultLayout>
|
<Route path="/bandi/:id/preview" element={<DefaultLayout>
|
||||||
{'ROLE_SUPER_ADMIN' === role ? <BandoView/> : null}
|
{'ROLE_SUPER_ADMIN' === role ? <BandoView/> : null}
|
||||||
{'ROLE_BENEFICIARY' === role ? <PageNotFound/> : null}
|
{'ROLE_BENEFICIARY' === role ? <PageNotFound/> : null}
|
||||||
|
{'ROLE_PRE_INSTRUCTOR' === role ? <PageNotFound/> : null}
|
||||||
</DefaultLayout>}/>
|
</DefaultLayout>}/>
|
||||||
<Route path="/bandi/:id/preview-evaluation" element={<DefaultLayout>
|
<Route path="/bandi/:id/preview-evaluation" element={<DefaultLayout>
|
||||||
{'ROLE_SUPER_ADMIN' === role ? <BandoView/> : null}
|
{'ROLE_SUPER_ADMIN' === role ? <BandoView/> : null}
|
||||||
{'ROLE_BENEFICIARY' === role ? <PageNotFound/> : null}
|
{'ROLE_BENEFICIARY' === role ? <PageNotFound/> : null}
|
||||||
|
{'ROLE_PRE_INSTRUCTOR' === role ? <PageNotFound/> : null}
|
||||||
</DefaultLayout>}/>
|
</DefaultLayout>}/>
|
||||||
<Route path="/bandi/:id/forms" element={<DefaultLayout>
|
<Route path="/bandi/:id/forms" element={<DefaultLayout>
|
||||||
{'ROLE_SUPER_ADMIN' === role ? <BandoForms/> : null}
|
{'ROLE_SUPER_ADMIN' === role ? <BandoForms/> : null}
|
||||||
{'ROLE_BENEFICIARY' === role ? <PageNotFound/> : null}
|
{'ROLE_BENEFICIARY' === role ? <PageNotFound/> : null}
|
||||||
|
{'ROLE_PRE_INSTRUCTOR' === role ? <PageNotFound/> : null}
|
||||||
</DefaultLayout>}/>
|
</DefaultLayout>}/>
|
||||||
<Route path="/bandi/:id/forms/:formId" element={<DefaultLayout>
|
<Route path="/bandi/:id/forms/:formId" element={<DefaultLayout>
|
||||||
{'ROLE_SUPER_ADMIN' === role ? <BandoFormsEdit/> : null}
|
{'ROLE_SUPER_ADMIN' === role ? <BandoFormsEdit/> : null}
|
||||||
{'ROLE_BENEFICIARY' === role ? <PageNotFound/> : null}
|
{'ROLE_BENEFICIARY' === role ? <PageNotFound/> : null}
|
||||||
|
{'ROLE_PRE_INSTRUCTOR' === role ? <PageNotFound/> : null}
|
||||||
</DefaultLayout>}/>
|
</DefaultLayout>}/>
|
||||||
<Route path="/bandi/:id/forms/:formId/preview" element={<DefaultLayout>
|
<Route path="/bandi/:id/forms/:formId/preview" element={<DefaultLayout>
|
||||||
{'ROLE_SUPER_ADMIN' === role ? <BandoFormsPreview/> : null}
|
{'ROLE_SUPER_ADMIN' === role ? <BandoFormsPreview/> : null}
|
||||||
{'ROLE_BENEFICIARY' === role ? <PageNotFound/> : null}
|
{'ROLE_BENEFICIARY' === role ? <PageNotFound/> : null}
|
||||||
|
{'ROLE_PRE_INSTRUCTOR' === role ? <PageNotFound/> : null}
|
||||||
</DefaultLayout>}/>
|
</DefaultLayout>}/>
|
||||||
<Route path="/bandi/:id/flow" element={<DefaultLayout>
|
<Route path="/bandi/:id/flow" element={<DefaultLayout>
|
||||||
{'ROLE_SUPER_ADMIN' === role ? <BandoFlowEdit/> : null}
|
{'ROLE_SUPER_ADMIN' === role ? <BandoFlowEdit/> : null}
|
||||||
{'ROLE_BENEFICIARY' === role ? <PageNotFound/> : null}
|
{'ROLE_BENEFICIARY' === role ? <PageNotFound/> : null}
|
||||||
|
{'ROLE_PRE_INSTRUCTOR' === role ? <PageNotFound/> : null}
|
||||||
|
</DefaultLayout>}/>
|
||||||
|
<Route path="/domande" element={<DefaultLayout>
|
||||||
|
{'ROLE_SUPER_ADMIN' === role ? <Domande/> : null}
|
||||||
|
{'ROLE_BENEFICIARY' === role ? <DomandeBeneficiario/> : null}
|
||||||
|
{'ROLE_PRE_INSTRUCTOR' === role ? <DomandePreInstructor/> : null}
|
||||||
|
</DefaultLayout>}/>
|
||||||
|
<Route path="/domande/:id/" element={<DefaultLayout>
|
||||||
|
{'ROLE_SUPER_ADMIN' === role ? <PageNotFound/> : null}
|
||||||
|
{'ROLE_BENEFICIARY' === role ? <DomandaBeneficiario/> : null}
|
||||||
|
{'ROLE_PRE_INSTRUCTOR' === role ? <DomandaEditPreInstructor/> : null}
|
||||||
|
</DefaultLayout>}/>
|
||||||
|
<Route path="/domande/:id/aggiungi-soccorso" element={<DefaultLayout>
|
||||||
|
{'ROLE_SUPER_ADMIN' === role ? <PageNotFound/> : null}
|
||||||
|
{'ROLE_BENEFICIARY' === role ? <PageNotFound/> : null}
|
||||||
|
{'ROLE_PRE_INSTRUCTOR' === role ? <SoccorsoAddPreInstructor/> : null}
|
||||||
|
</DefaultLayout>}/>
|
||||||
|
<Route path="/domande/:id/soccorso/:amendmentId" 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>}/>
|
</DefaultLayout>}/>
|
||||||
<Route path="/imieibandi" element={<DefaultLayout>
|
<Route path="/imieibandi" element={<DefaultLayout>
|
||||||
{'ROLE_SUPER_ADMIN' === role ? <PageNotFound/> : null}
|
{'ROLE_SUPER_ADMIN' === role ? <PageNotFound/> : null}
|
||||||
{'ROLE_BENEFICIARY' === role ? <Applications/> : null}
|
{'ROLE_BENEFICIARY' === role ? <Applications/> : null}
|
||||||
|
{'ROLE_PRE_INSTRUCTOR' === role ? <PageNotFound/> : null}
|
||||||
</DefaultLayout>}/>
|
</DefaultLayout>}/>
|
||||||
<Route path="/imieibandi/:id/" element={<DefaultLayout>
|
<Route path="/imieibandi/:id/" element={<DefaultLayout>
|
||||||
{'ROLE_SUPER_ADMIN' === role ? <PageNotFound/> : null}
|
{'ROLE_SUPER_ADMIN' === role ? <PageNotFound/> : null}
|
||||||
{'ROLE_BENEFICIARY' === role ? <BandoApplication/> : null}
|
{'ROLE_BENEFICIARY' === role ? <BandoApplication/> : null}
|
||||||
|
{'ROLE_PRE_INSTRUCTOR' === role ? <PageNotFound/> : null}
|
||||||
</DefaultLayout>}/>
|
</DefaultLayout>}/>
|
||||||
<Route path="/profilo" element={<DefaultLayout>
|
<Route path="/profilo" element={<DefaultLayout>
|
||||||
{'ROLE_SUPER_ADMIN' === role ? <Profile/> : null}
|
{'ROLE_SUPER_ADMIN' === role ? <Profile/> : null}
|
||||||
{'ROLE_BENEFICIARY' === role ? <Profile/> : null}
|
{'ROLE_BENEFICIARY' === role ? <ProfileBeneficiario/> : null}
|
||||||
|
{'ROLE_PRE_INSTRUCTOR' === role ? <Profile/> : null}
|
||||||
</DefaultLayout>}/>
|
</DefaultLayout>}/>
|
||||||
<Route path="/profilo-aziendale" element={<DefaultLayout>
|
<Route path="/profilo-aziendale" element={<DefaultLayout>
|
||||||
{'ROLE_SUPER_ADMIN' === role ? <PageNotFound/> : null}
|
{'ROLE_SUPER_ADMIN' === role ? <PageNotFound/> : null}
|
||||||
{'ROLE_BENEFICIARY' === role && chosenCompanyId > 0 ? <ProfileCompany/> : <PageNotFound/>}
|
{'ROLE_BENEFICIARY' === role && chosenCompanyId > 0 ? <ProfileCompany/> : <PageNotFound/>}
|
||||||
|
{'ROLE_PRE_INSTRUCTOR' === role ? <PageNotFound/> : null}
|
||||||
</DefaultLayout>}/>
|
</DefaultLayout>}/>
|
||||||
<Route path="/agguingi-azienda" element={<DefaultLayout>
|
<Route path="/agguingi-azienda" element={<DefaultLayout>
|
||||||
{'ROLE_SUPER_ADMIN' === role ? <PageNotFound/> : null}
|
{'ROLE_SUPER_ADMIN' === role ? <PageNotFound/> : null}
|
||||||
{'ROLE_BENEFICIARY' === role ? <AddCompany/> : null}
|
{'ROLE_BENEFICIARY' === role ? <AddCompany/> : null}
|
||||||
|
{'ROLE_PRE_INSTRUCTOR' === role ? <PageNotFound/> : null}
|
||||||
</DefaultLayout>}/>
|
</DefaultLayout>}/>
|
||||||
<Route path="/utenti" element={<DefaultLayout>
|
<Route path="/utenti" element={<DefaultLayout>
|
||||||
{'ROLE_SUPER_ADMIN' === role ? <Users/> : null}
|
{'ROLE_SUPER_ADMIN' === role ? <Users/> : null}
|
||||||
{'ROLE_BENEFICIARY' === role ? <PageNotFound/> : null}
|
{'ROLE_BENEFICIARY' === role ? <PageNotFound/> : null}
|
||||||
|
{'ROLE_PRE_INSTRUCTOR' === role ? <PageNotFound/> : null}
|
||||||
</DefaultLayout>}/>
|
</DefaultLayout>}/>
|
||||||
</Route>
|
</Route>
|
||||||
<Route exact path="/reset-password" element={<ResetPassword/>}/>
|
<Route exact path="/reset-password" element={<ResetPassword/>}/>
|
||||||
|
|||||||
46
src/service/amendments-service.js
Normal file
46
src/service/amendments-service.js
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
import { NetworkService } from './network-service';
|
||||||
|
|
||||||
|
const API_BASE_URL = process.env.REACT_APP_API_EXECUTION_ADDRESS;
|
||||||
|
|
||||||
|
export default class AmendmentsService {
|
||||||
|
|
||||||
|
static getSoccorsoByApplEvalId = (id, callback, errCallback, queryParams) => {
|
||||||
|
NetworkService.get(`${API_BASE_URL}/amendments/applicationEvaluation/${id}`, callback, errCallback, queryParams);
|
||||||
|
};
|
||||||
|
|
||||||
|
static getSoccorsoByApplId = (id, callback, errCallback, queryParams) => {
|
||||||
|
NetworkService.get(`${API_BASE_URL}/amendments/application/${id}`, callback, errCallback, queryParams);
|
||||||
|
};
|
||||||
|
|
||||||
|
static getSoccorsoById = (callback, errCallback, queryParams) => {
|
||||||
|
NetworkService.get(`${API_BASE_URL}/amendments`, callback, errCallback, queryParams);
|
||||||
|
};
|
||||||
|
|
||||||
|
static getSoccorsoByPreInstructorId = (id, callback, errCallback, queryParams) => {
|
||||||
|
NetworkService.get(`${API_BASE_URL}/amendments/user/${id}`, callback, errCallback, queryParams);
|
||||||
|
};
|
||||||
|
|
||||||
|
static createSoccorso = (body, callback, errCallback, queryParams) => {
|
||||||
|
NetworkService.post(`${API_BASE_URL}/amendments`, body, callback, errCallback, queryParams);
|
||||||
|
};
|
||||||
|
|
||||||
|
static updateSoccorso = (id, body, callback, errCallback, queryParams) => {
|
||||||
|
NetworkService.put(`${API_BASE_URL}/amendments/${id}`, body, callback, errCallback, queryParams);
|
||||||
|
};
|
||||||
|
|
||||||
|
static extendSoccorso = (id, days, callback, errCallback, queryParams) => {
|
||||||
|
NetworkService.put(`${API_BASE_URL}/amendments/${id}/extendExpiration`, {}, callback, errCallback, [
|
||||||
|
['extendedDays', days]
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
|
static sendReminderForSoccorso = (id, callback, errCallback, queryParams) => {
|
||||||
|
NetworkService.post(`${API_BASE_URL}/amendments/${id}/reminder`, {}, callback, errCallback, queryParams);
|
||||||
|
};
|
||||||
|
|
||||||
|
static closeSoccorso = (id, body, callback, errCallback, queryParams) => {
|
||||||
|
NetworkService.put(`${API_BASE_URL}/amendments`, body, callback, errCallback, [
|
||||||
|
['id', id]
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
}
|
||||||
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 = (assignedApplicationId, body, callback, errCallback, queryParams) => {
|
||||||
|
NetworkService.put(`${API_BASE_URL}/applicationEvaluation/${assignedApplicationId}`, body, callback, errCallback, queryParams);
|
||||||
|
};
|
||||||
|
}
|
||||||
14
src/service/assigned-application-service.js
Normal file
14
src/service/assigned-application-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 AssignedApplicationService {
|
||||||
|
|
||||||
|
static getAssignedApplications = (callback, errCallback, queryParams) => {
|
||||||
|
NetworkService.get(`${API_BASE_URL}/assignedApplication`, callback, errCallback, queryParams);
|
||||||
|
};
|
||||||
|
|
||||||
|
static assignApplication = (id, callback, errCallback, queryParams) => {
|
||||||
|
NetworkService.post(`${API_BASE_URL}/assignedApplication/application/${id}`, {}, callback, errCallback, queryParams);
|
||||||
|
};
|
||||||
|
}
|
||||||
14
src/service/communication-service.js
Normal file
14
src/service/communication-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 CommunicationService {
|
||||||
|
|
||||||
|
static getCommsByAmendmentId = (id, callback, errCallback, queryParams) => {
|
||||||
|
NetworkService.get(`${API_BASE_URL}/communication/${id}`, callback, errCallback, queryParams);
|
||||||
|
};
|
||||||
|
|
||||||
|
static createCommunication = (id, body, callback, errCallback, queryParams) => {
|
||||||
|
NetworkService.post(`${API_BASE_URL}/communication/${id}`, body, callback, errCallback, queryParams);
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -371,7 +371,8 @@ export class NetworkService {
|
|||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
'Authorization': 'Bearer ' + storeGet.main.getToken(),
|
'Authorization': 'Bearer ' + storeGet.main.getToken(),
|
||||||
}
|
},
|
||||||
|
signal: AbortSignal.timeout(5000)
|
||||||
})
|
})
|
||||||
.then(async response => {
|
.then(async response => {
|
||||||
let status = response.status;
|
let status = response.status;
|
||||||
|
|||||||
@@ -4,10 +4,18 @@ const API_BASE_URL = process.env.REACT_APP_API_EXECUTION_ADDRESS;
|
|||||||
|
|
||||||
export default class UserService {
|
export default class UserService {
|
||||||
|
|
||||||
|
static getUsers = (callback, errCallback, queryParams) => {
|
||||||
|
NetworkService.get(`${API_BASE_URL}/user`, callback, errCallback, queryParams);
|
||||||
|
};
|
||||||
|
|
||||||
static updateUser = (id, body, callback, errCallback) => {
|
static updateUser = (id, body, callback, errCallback) => {
|
||||||
NetworkService.put(`${API_BASE_URL}/user/${id}`, body, callback, errCallback);
|
NetworkService.put(`${API_BASE_URL}/user/${id}`, body, callback, errCallback);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static createUser = (body, callback, errCallback) => {
|
||||||
|
NetworkService.post(`${API_BASE_URL}/user`, body, callback, errCallback);
|
||||||
|
};
|
||||||
|
|
||||||
static getRoles = (callback, errCallback) => {
|
static getRoles = (callback, errCallback) => {
|
||||||
NetworkService.get(`${API_BASE_URL}/role`, callback, errCallback);
|
NetworkService.get(`${API_BASE_URL}/role`, callback, errCallback);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ const initialStore = {
|
|||||||
token: '',
|
token: '',
|
||||||
companies: [],
|
companies: [],
|
||||||
chosenCompanyId: 0,
|
chosenCompanyId: 0,
|
||||||
|
users: [],
|
||||||
// bando form
|
// bando form
|
||||||
formInitialData: {},
|
formInitialData: {},
|
||||||
// form builder
|
// form builder
|
||||||
@@ -17,6 +18,7 @@ const initialStore = {
|
|||||||
elementItems: [],
|
elementItems: [],
|
||||||
activeElement: '',
|
activeElement: '',
|
||||||
draggingElementId: 0,
|
draggingElementId: 0,
|
||||||
|
bandoCriteria: [],
|
||||||
// flow
|
// flow
|
||||||
flowData: [],
|
flowData: [],
|
||||||
flowForms: [],
|
flowForms: [],
|
||||||
|
|||||||
Reference in New Issue
Block a user