- added registartion page;
- implemented validation helper-functions; - fixed form fields datepicker and datepicker range; - updated routes logic; - fixed FAQ items editing/submission;
This commit is contained in:
18
package-lock.json
generated
18
package-lock.json
generated
@@ -10,11 +10,13 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
|
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
|
||||||
"@babel/preset-react": "^7.24.7",
|
"@babel/preset-react": "^7.24.7",
|
||||||
|
"@date-fns/tz": "^1.0.2",
|
||||||
"@emotion/react": "11.13.0",
|
"@emotion/react": "11.13.0",
|
||||||
"@emotion/styled": "11.13.0",
|
"@emotion/styled": "11.13.0",
|
||||||
"@wordpress/i18n": "^5.5.0",
|
"@wordpress/i18n": "^5.5.0",
|
||||||
"@wordpress/react-i18n": "^4.5.0",
|
"@wordpress/react-i18n": "^4.5.0",
|
||||||
"@xyflow/react": "^12.2.0",
|
"@xyflow/react": "^12.2.0",
|
||||||
|
"codice-fiscale-js": "^2.3.22",
|
||||||
"deep-object-diff": "^1.1.9",
|
"deep-object-diff": "^1.1.9",
|
||||||
"dompurify": "3.1.6",
|
"dompurify": "3.1.6",
|
||||||
"fast-deep-equal": "^3.1.3",
|
"fast-deep-equal": "^3.1.3",
|
||||||
@@ -33,6 +35,7 @@
|
|||||||
"react-hook-form": "7.52.2",
|
"react-hook-form": "7.52.2",
|
||||||
"react-router-dom": "6.26.0",
|
"react-router-dom": "6.26.0",
|
||||||
"react-scripts": "^5.0.1",
|
"react-scripts": "^5.0.1",
|
||||||
|
"validate.js": "^0.13.1",
|
||||||
"zustand": "4.5.4",
|
"zustand": "4.5.4",
|
||||||
"zustand-x": "3.0.4"
|
"zustand-x": "3.0.4"
|
||||||
},
|
},
|
||||||
@@ -2295,6 +2298,11 @@
|
|||||||
"postcss-selector-parser": "^6.0.10"
|
"postcss-selector-parser": "^6.0.10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@date-fns/tz": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@date-fns/tz/-/tz-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-iKxj0kXMy7Qe6vjK+flz33cpy2j0dnTKT5i54p3fFlB411J47aSs6HBg7LOO5X9LjDi2iNlctD9rFn738ySOGQ=="
|
||||||
|
},
|
||||||
"node_modules/@emotion/babel-plugin": {
|
"node_modules/@emotion/babel-plugin": {
|
||||||
"version": "11.12.0",
|
"version": "11.12.0",
|
||||||
"resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.12.0.tgz",
|
"resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.12.0.tgz",
|
||||||
@@ -6062,6 +6070,11 @@
|
|||||||
"node": ">= 4.0"
|
"node": ">= 4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/codice-fiscale-js": {
|
||||||
|
"version": "2.3.22",
|
||||||
|
"resolved": "https://registry.npmjs.org/codice-fiscale-js/-/codice-fiscale-js-2.3.22.tgz",
|
||||||
|
"integrity": "sha512-at+XQ3kTgIq0qMoBmP4UtrSlYvHp5X5KGEB0ZKykydMnYC28zBAbdbFDu7CsatlfoOa1vH4qBpNkOCXp/YqMmA=="
|
||||||
|
},
|
||||||
"node_modules/collect-v8-coverage": {
|
"node_modules/collect-v8-coverage": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz",
|
||||||
@@ -18103,6 +18116,11 @@
|
|||||||
"node": ">= 8"
|
"node": ">= 8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/validate.js": {
|
||||||
|
"version": "0.13.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/validate.js/-/validate.js-0.13.1.tgz",
|
||||||
|
"integrity": "sha512-PnFM3xiZ+kYmLyTiMgTYmU7ZHkjBZz2/+F0DaALc/uUtVzdCt1wAosvYJ5hFQi/hz8O4zb52FQhHZRC+uVkJ+g=="
|
||||||
|
},
|
||||||
"node_modules/vary": {
|
"node_modules/vary": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||||
|
|||||||
@@ -5,11 +5,13 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
|
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
|
||||||
"@babel/preset-react": "^7.24.7",
|
"@babel/preset-react": "^7.24.7",
|
||||||
|
"@date-fns/tz": "^1.0.2",
|
||||||
"@emotion/react": "11.13.0",
|
"@emotion/react": "11.13.0",
|
||||||
"@emotion/styled": "11.13.0",
|
"@emotion/styled": "11.13.0",
|
||||||
"@wordpress/i18n": "^5.5.0",
|
"@wordpress/i18n": "^5.5.0",
|
||||||
"@wordpress/react-i18n": "^4.5.0",
|
"@wordpress/react-i18n": "^4.5.0",
|
||||||
"@xyflow/react": "^12.2.0",
|
"@xyflow/react": "^12.2.0",
|
||||||
|
"codice-fiscale-js": "^2.3.22",
|
||||||
"deep-object-diff": "^1.1.9",
|
"deep-object-diff": "^1.1.9",
|
||||||
"dompurify": "3.1.6",
|
"dompurify": "3.1.6",
|
||||||
"fast-deep-equal": "^3.1.3",
|
"fast-deep-equal": "^3.1.3",
|
||||||
@@ -28,6 +30,7 @@
|
|||||||
"react-hook-form": "7.52.2",
|
"react-hook-form": "7.52.2",
|
||||||
"react-router-dom": "6.26.0",
|
"react-router-dom": "6.26.0",
|
||||||
"react-scripts": "^5.0.1",
|
"react-scripts": "^5.0.1",
|
||||||
|
"validate.js": "^0.13.1",
|
||||||
"zustand": "4.5.4",
|
"zustand": "4.5.4",
|
||||||
"zustand-x": "3.0.4"
|
"zustand-x": "3.0.4"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -77,7 +77,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.appForm__oneCol {
|
.appForm__col {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 7px;
|
gap: 7px;
|
||||||
@@ -87,18 +87,13 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.appForm__twoCols {
|
.appForm__cols {
|
||||||
display: flex;
|
display: grid;
|
||||||
gap: 1rem;
|
gap: 0.5rem;
|
||||||
justify-content: space-between;
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||||
flex-wrap: wrap;
|
width: 100%;
|
||||||
container-name: form_two_cols;
|
|
||||||
container-type: inline-size;
|
|
||||||
|
|
||||||
> div {
|
> div {
|
||||||
flex: 1 1 auto;
|
|
||||||
min-width: 300px;
|
|
||||||
max-width: 48%;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 14px;
|
gap: 14px;
|
||||||
@@ -111,14 +106,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@container form_two_cols (max-width: 620px) {
|
|
||||||
.appForm__twoCols {
|
|
||||||
> div {
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.appForm__repeaterItem {
|
.appForm__repeaterItem {
|
||||||
padding: 0.5rem 0.5rem 0.5rem 1rem;
|
padding: 0.5rem 0.5rem 0.5rem 1rem;
|
||||||
border-left: 3px solid #dadada;
|
border-left: 3px solid #dadada;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
.appPage {
|
.appPage {
|
||||||
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
flex-grow: 2;
|
flex-grow: 2;
|
||||||
@@ -9,6 +10,7 @@
|
|||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
line-height: normal;
|
line-height: normal;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,6 +134,9 @@
|
|||||||
|
|
||||||
&.rowContent {
|
&.rowContent {
|
||||||
padding: 7px 0;
|
padding: 7px 0;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 0.3rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
gap: 20px;
|
gap: 20px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
min-height: 500px;
|
height: 600px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.formBuilder__main {
|
.formBuilder__main {
|
||||||
@@ -21,6 +21,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.formBuilder__content {
|
.formBuilder__content {
|
||||||
|
height: 100%;
|
||||||
|
overflow-y: scroll;
|
||||||
flex-grow: 2;
|
flex-grow: 2;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -84,6 +86,8 @@
|
|||||||
list-style: none;
|
list-style: none;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
height: 100%;
|
||||||
|
overflow-y: scroll;
|
||||||
}
|
}
|
||||||
.formBuilder__elementItem {
|
.formBuilder__elementItem {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@@ -11,4 +11,30 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 540px;
|
max-width: 540px;
|
||||||
padding: 24px;
|
padding: 24px;
|
||||||
|
|
||||||
|
.appForm {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.appPageLogin__spidBtn.appPageLogin__spidBtn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
padding: 8px;
|
||||||
|
gap: 11px;
|
||||||
|
background: #06C;
|
||||||
|
border: none;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #FFF;
|
||||||
|
font-size: 17.25px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 15px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -91,10 +91,14 @@
|
|||||||
padding: 0.5rem;
|
padding: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.p-message-detail {
|
.p-message-detail, .p-progressbar-label {
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.p-dialog-content {
|
||||||
|
padding: 1rem 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
.blockingOverlay {
|
.blockingOverlay {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 999;
|
z-index: 999;
|
||||||
|
|||||||
@@ -4,12 +4,14 @@ import { isEmpty, head } from 'ramda';
|
|||||||
|
|
||||||
// store
|
// store
|
||||||
import { storeGet, storeSet } from '../../../../store';
|
import { storeGet, storeSet } from '../../../../store';
|
||||||
|
import { __ } from '@wordpress/i18n';
|
||||||
|
|
||||||
const NodeInitialForm = ({ data: { id, label = '' } }) => {
|
const NodeInitialForm = ({ data: { id, label = '' } }) => {
|
||||||
const [options, setOptions] = useState([]);
|
const flowData = storeGet.main.flowData();
|
||||||
|
//const [options, setOptions] = useState([]);
|
||||||
const [value, setValue] = useState('');
|
const [value, setValue] = useState('');
|
||||||
|
|
||||||
const onChangeFn = (e) => {
|
/*const onChangeFn = (e) => {
|
||||||
const { value } = e.target;
|
const { value } = e.target;
|
||||||
const data = {
|
const data = {
|
||||||
formId: String(id),
|
formId: String(id),
|
||||||
@@ -18,12 +20,14 @@ const NodeInitialForm = ({ data: { id, label = '' } }) => {
|
|||||||
}
|
}
|
||||||
setValue(value);
|
setValue(value);
|
||||||
storeSet.main.addFlowData(data);
|
storeSet.main.addFlowData(data);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
useEffect(() => {
|
/*useEffect(() => {
|
||||||
const forms = storeGet.main.flowForms();
|
const flowForms = storeGet.main.flowForms();
|
||||||
if (forms.length > 2) {
|
const flowData = storeGet.main.flowData();
|
||||||
const form = head(forms.filter(o => String(o.id) === String(id)))
|
|
||||||
|
if (flowForms.length > 2) {
|
||||||
|
const form = head(flowForms.filter(o => String(o.id) === String(id)))
|
||||||
const relevantFields = form
|
const relevantFields = form
|
||||||
? form.content
|
? form.content
|
||||||
.filter(o => ['radio', 'select'].includes(o.name))
|
.filter(o => ['radio', 'select'].includes(o.name))
|
||||||
@@ -31,20 +35,42 @@ const NodeInitialForm = ({ data: { id, label = '' } }) => {
|
|||||||
: [];
|
: [];
|
||||||
setOptions(relevantFields);
|
setOptions(relevantFields);
|
||||||
}
|
}
|
||||||
}, [id]);
|
|
||||||
|
const flowDataForm = head(flowData.filter(o => String(o.formId) === String(id)));
|
||||||
|
|
||||||
|
if (flowDataForm) {
|
||||||
|
setValue(flowDataForm.chosenField);
|
||||||
|
}
|
||||||
|
}, [id]);*/
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const flowForms = storeGet.main.flowForms();
|
||||||
|
const form = head(flowForms.filter(o => String(o.id) === String(id)));
|
||||||
|
const flowDataItem = head(flowData.filter(o => String(o.formId) === String(id)));
|
||||||
|
|
||||||
|
if (form && flowDataItem) {
|
||||||
|
const field = head(form.content.filter(o => o.id === flowDataItem.chosenField));
|
||||||
|
|
||||||
|
if (field) {
|
||||||
|
const label = head(field.settings.filter(o => o.name === 'label'));
|
||||||
|
setValue(label ? label.value : field.label);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [flowData]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="nodeInitialForm">
|
<div className="nodeInitialForm">
|
||||||
<label>
|
<label>
|
||||||
{label}
|
{label}
|
||||||
</label>
|
</label>
|
||||||
{options && !isEmpty(options)
|
<span>{value}</span>
|
||||||
|
{/*{options && !isEmpty(options)
|
||||||
? <select onChange={onChangeFn} value={value}>
|
? <select onChange={onChangeFn} value={value}>
|
||||||
<option value="">Choose form</option>
|
<option value="">{__('Scegli il campo', 'gepafin')}</option>
|
||||||
{options.map(o => <option key={o.name} value={o.name}>
|
{options.map(o => <option key={o.name} value={o.name}>
|
||||||
{o.label}
|
{o.label}
|
||||||
</option>)}
|
</option>)}
|
||||||
</select> : null}
|
</select> : null}*/}
|
||||||
<Handle
|
<Handle
|
||||||
type="source"
|
type="source"
|
||||||
position={Position.Bottom}
|
position={Position.Bottom}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { Handle, Position } from '@xyflow/react';
|
import { Handle, Position } from '@xyflow/react';
|
||||||
import { head, isEmpty } from 'ramda';
|
import { head, isEmpty } from 'ramda';
|
||||||
|
import { __ } from '@wordpress/i18n';
|
||||||
|
|
||||||
import { useStore, storeSet, storeGet } from '../../../../store';
|
import { useStore, storeSet, storeGet } from '../../../../store';
|
||||||
|
|
||||||
@@ -25,9 +26,10 @@ const NodeIntermediateForm = ({ data: { id, label = '' } }) => {
|
|||||||
const edge = head(flowEdges.filter(o => o.target === String(id)));
|
const edge = head(flowEdges.filter(o => o.target === String(id)));
|
||||||
if (edge) {
|
if (edge) {
|
||||||
const sourceForm = edge.source;
|
const sourceForm = edge.source;
|
||||||
const sourceFormData = head(flowData.filter(o => o.formId === sourceForm));
|
const sourceFormData = head(flowData.filter(o => String(o.formId) === sourceForm));
|
||||||
const flowForms = storeGet.main.flowForms();
|
const flowForms = storeGet.main.flowForms();
|
||||||
const form = head(flowForms.filter(o => String(o.id) === String(sourceForm)));
|
const form = head(flowForms.filter(o => String(o.id) === String(sourceForm)));
|
||||||
|
|
||||||
if (form && sourceFormData) {
|
if (form && sourceFormData) {
|
||||||
const { chosenField } = sourceFormData;
|
const { chosenField } = sourceFormData;
|
||||||
const field = head(form.content.filter(o => o.id === chosenField));
|
const field = head(form.content.filter(o => o.id === chosenField));
|
||||||
@@ -38,7 +40,12 @@ const NodeIntermediateForm = ({ data: { id, label = '' } }) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const flowDataForm = head(flowData.filter(o => String(o.formId) === String(id)));
|
||||||
|
|
||||||
|
if (flowDataForm) {
|
||||||
|
setValue(flowDataForm.chosenValue);
|
||||||
}
|
}
|
||||||
}, [flowEdges, flowData]);
|
}, [flowEdges, flowData]);
|
||||||
|
|
||||||
@@ -54,7 +61,7 @@ const NodeIntermediateForm = ({ data: { id, label = '' } }) => {
|
|||||||
</label>
|
</label>
|
||||||
{options && !isEmpty(options)
|
{options && !isEmpty(options)
|
||||||
? <select onChange={onChangeFn} value={value}>
|
? <select onChange={onChangeFn} value={value}>
|
||||||
<option value="">Choose form</option>
|
<option value="">{__('Scegli il valore', 'gepafin')}</option>
|
||||||
{options.map(o => <option key={o.name} value={o.name}>
|
{options.map(o => <option key={o.name} value={o.name}>
|
||||||
{o.label}
|
{o.label}
|
||||||
</option>)}
|
</option>)}
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ const nodeTypes = {
|
|||||||
intermediateForm: NodeIntermediateForm
|
intermediateForm: NodeIntermediateForm
|
||||||
};
|
};
|
||||||
|
|
||||||
const FlowBuilder = ({ initialForm = 0, finalForm = 0 }) => {
|
const FlowBuilder = ({ initialForm = 0, finalForm = 0, mainField = '' }) => {
|
||||||
const forms = useStore().main.flowForms();
|
const flowForms = useStore().main.flowForms();
|
||||||
const [nodes, setNodes] = useState([]);
|
const [nodes, setNodes] = useState([]);
|
||||||
const [edges, setEdges] = useState([]);
|
const [edges, setEdges] = useState([]);
|
||||||
|
|
||||||
@@ -33,13 +33,13 @@ const FlowBuilder = ({ initialForm = 0, finalForm = 0 }) => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (
|
if (
|
||||||
(forms.length === 2 && initialForm) ||
|
(flowForms.length === 2 && initialForm) ||
|
||||||
(forms.length > 2 && initialForm && finalForm)
|
(flowForms.length > 2 && initialForm && finalForm)
|
||||||
) {
|
) {
|
||||||
const total = (forms.length - 2) * (200 - 90);
|
const total = (flowForms.length - 2) * (200 - 90);
|
||||||
let coordinates = range(total * -1, total, 200);
|
let coordinates = range(total * -1, total, 200);
|
||||||
|
|
||||||
const initialNodes = forms.map(o => {
|
const initialNodes = flowForms.map(o => {
|
||||||
const formId = String(o.id);
|
const formId = String(o.id);
|
||||||
let obj;
|
let obj;
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ const FlowBuilder = ({ initialForm = 0, finalForm = 0 }) => {
|
|||||||
id: formId,
|
id: formId,
|
||||||
type: 'output',
|
type: 'output',
|
||||||
data: { label: o.label, id: formId },
|
data: { label: o.label, id: formId },
|
||||||
position: { x: 0, y: forms.length === 2 ? 150 : 300 },
|
position: { x: 0, y: flowForms.length === 2 ? 150 : 300 },
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const x = coordinates.splice(0, 1);
|
const x = coordinates.splice(0, 1);
|
||||||
@@ -71,29 +71,53 @@ const FlowBuilder = ({ initialForm = 0, finalForm = 0 }) => {
|
|||||||
|
|
||||||
let edges = [];
|
let edges = [];
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
forms.map(o => {
|
flowForms.map(o => {
|
||||||
const formId = String(o.id);
|
const formId = String(o.id);
|
||||||
|
|
||||||
if (formId !== String(initialForm) && formId !== String(finalForm)) {
|
if (formId !== String(initialForm) && formId !== String(finalForm)) {
|
||||||
edges.push({ id: `${initialForm}->${formId}`, source: String(initialForm), target: formId, type: 'smoothstep' });
|
edges.push({
|
||||||
|
id: `${initialForm}->${formId}`,
|
||||||
|
source: String(initialForm),
|
||||||
|
target: formId,
|
||||||
|
type: 'smoothstep'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if (formId !== String(initialForm) && formId !== String(finalForm) && String(finalForm) !== '0') {
|
if (formId !== String(initialForm) && formId !== String(finalForm) && String(finalForm) !== '0') {
|
||||||
edges.push({ id: `${formId}->${finalForm}`, source: formId, target: String(finalForm), type: 'smoothstep' });
|
edges.push({
|
||||||
|
id: `${formId}->${finalForm}`,
|
||||||
|
source: formId,
|
||||||
|
target: String(finalForm),
|
||||||
|
type: 'smoothstep'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (forms.length === 2 && initialForm && finalForm) {
|
if (flowForms.length === 2 && initialForm && finalForm) {
|
||||||
edges.push({ id: `${initialForm}->${finalForm}`, source: String(initialForm), target: String(finalForm), type: 'smoothstep' });
|
edges.push({
|
||||||
|
id: `${initialForm}->${finalForm}`,
|
||||||
|
source: String(initialForm),
|
||||||
|
target: String(finalForm),
|
||||||
|
type: 'smoothstep'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
setNodes(initialNodes);
|
setNodes(initialNodes);
|
||||||
setEdges(edges);
|
setEdges(edges);
|
||||||
storeSet.main.flowEdges(edges);
|
storeSet.main.flowEdges(edges);
|
||||||
|
|
||||||
|
if (!isEmpty(mainField)) {
|
||||||
|
const data = {
|
||||||
|
formId: String(initialForm),
|
||||||
|
chosenField: mainField,
|
||||||
|
chosenValue: ''
|
||||||
|
}
|
||||||
|
storeSet.main.addFlowData(data);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
setNodes([]);
|
setNodes([]);
|
||||||
setEdges([]);
|
setEdges([]);
|
||||||
}
|
}
|
||||||
}, [initialForm, finalForm, forms]);
|
}, [initialForm, finalForm, flowForms, mainField]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
!isEmpty(nodes) && !isEmpty(edges)
|
!isEmpty(nodes) && !isEmpty(edges)
|
||||||
|
|||||||
@@ -4,15 +4,16 @@ import { Controller } from 'react-hook-form';
|
|||||||
import { Checkbox } from 'primereact/checkbox';
|
import { Checkbox } from 'primereact/checkbox';
|
||||||
|
|
||||||
const Checkboxes = ({
|
const Checkboxes = ({
|
||||||
fieldName,
|
fieldName,
|
||||||
label,
|
label,
|
||||||
control,
|
control,
|
||||||
errors,
|
errors,
|
||||||
defaultValue = [],
|
defaultValue = [],
|
||||||
config = {},
|
config = {},
|
||||||
infoText = null,
|
infoText = null,
|
||||||
options = []
|
options = [],
|
||||||
}) => {
|
disabled = false
|
||||||
|
}) => {
|
||||||
const [fieldVal, setFieldVal] = useState(defaultValue);
|
const [fieldVal, setFieldVal] = useState(defaultValue);
|
||||||
|
|
||||||
const onCheckboxesChange = useCallback((e, updateFn) => {
|
const onCheckboxesChange = useCallback((e, updateFn) => {
|
||||||
@@ -37,6 +38,7 @@ const Checkboxes = ({
|
|||||||
options.map(o => <div className="appForm__fieldItem" key={o.name}>
|
options.map(o => <div className="appForm__fieldItem" key={o.name}>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
inputId={`${fieldName}_${o.name}`}
|
inputId={`${fieldName}_${o.name}`}
|
||||||
|
disabled={disabled}
|
||||||
name={fieldName}
|
name={fieldName}
|
||||||
value={o.name}
|
value={o.name}
|
||||||
onChange={(e) => onCheckboxesChange(e, field.onChange)}
|
onChange={(e) => onCheckboxesChange(e, field.onChange)}
|
||||||
|
|||||||
@@ -13,7 +13,8 @@ const Datepicker = ({
|
|||||||
config = {},
|
config = {},
|
||||||
infoText = null,
|
infoText = null,
|
||||||
minDate = null,
|
minDate = null,
|
||||||
maxDate = null
|
maxDate = null,
|
||||||
|
disabled = false
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -21,20 +22,22 @@ const Datepicker = ({
|
|||||||
{label}{config.required || config.isRequired ? '*' : null}
|
{label}{config.required || config.isRequired ? '*' : null}
|
||||||
</label>
|
</label>
|
||||||
<Controller
|
<Controller
|
||||||
name={fieldName}
|
name={fieldName}
|
||||||
control={control}
|
disabled={disabled}
|
||||||
defaultValue={defaultValue}
|
control={control}
|
||||||
rules={config}
|
defaultValue={defaultValue}
|
||||||
render={({ field, fieldState }) => (
|
rules={config}
|
||||||
<Calendar id={field.name}
|
render={({ field, fieldState }) => (
|
||||||
value={field.value ?? []}
|
<Calendar id={field.name}
|
||||||
onChange={(e) => field.onChange(e.value)}
|
value={field.value ?? []}
|
||||||
dateFormat="dd/mm/yy"
|
onChange={(e) => field.onChange(e.value)}
|
||||||
mask="99/99/9999"
|
dateFormat="dd/mm/yy"
|
||||||
showIcon
|
mask="99/99/9999"
|
||||||
minDate={minDate} maxDate={maxDate}
|
showIcon
|
||||||
className={classNames({ 'p-invalid': fieldState.invalid })}/>
|
minDate={minDate}
|
||||||
)}/>
|
maxDate={maxDate}
|
||||||
|
className={classNames({ 'p-invalid': fieldState.invalid })}/>
|
||||||
|
)}/>
|
||||||
{infoText ? <small>{infoText}</small> : null}
|
{infoText ? <small>{infoText}</small> : null}
|
||||||
</>)
|
</>)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,16 +7,17 @@ import { Controller } from 'react-hook-form';
|
|||||||
import { Calendar } from 'primereact/calendar';
|
import { Calendar } from 'primereact/calendar';
|
||||||
|
|
||||||
const DatepickerRange = ({
|
const DatepickerRange = ({
|
||||||
fieldName,
|
fieldName,
|
||||||
label,
|
label,
|
||||||
control,
|
control,
|
||||||
errors,
|
errors,
|
||||||
defaultValue = [],
|
defaultValue = [],
|
||||||
config = {},
|
config = {},
|
||||||
infoText = null,
|
infoText = null,
|
||||||
minDate = null,
|
minDate = null,
|
||||||
maxDate = null
|
maxDate = null,
|
||||||
}) => {
|
disabled = false
|
||||||
|
}) => {
|
||||||
const datesDefaultValue = !isNil(defaultValue) && defaultValue.length
|
const datesDefaultValue = !isNil(defaultValue) && defaultValue.length
|
||||||
? defaultValue.map(v => new Date(v))
|
? defaultValue.map(v => new Date(v))
|
||||||
: [];
|
: [];
|
||||||
@@ -26,25 +27,26 @@ const DatepickerRange = ({
|
|||||||
{label}{config.required ? '*' : null}
|
{label}{config.required ? '*' : null}
|
||||||
</label>
|
</label>
|
||||||
<Controller
|
<Controller
|
||||||
name={fieldName}
|
name={fieldName}
|
||||||
control={control}
|
control={control}
|
||||||
defaultValue={datesDefaultValue}
|
defaultValue={datesDefaultValue}
|
||||||
rules={config}
|
rules={config}
|
||||||
render={({ field, fieldState }) => (
|
render={({ field, fieldState }) => (
|
||||||
<Calendar id={field.name}
|
<Calendar id={field.name}
|
||||||
value={field.value}
|
disabled={disabled}
|
||||||
onChange={field.onChange}
|
value={field.value}
|
||||||
dateFormat="dd/mm/yy"
|
onChange={field.onChange}
|
||||||
mask="99/99/9999"
|
dateFormat="dd/mm/yy"
|
||||||
showIcon
|
mask="99/99/9999"
|
||||||
minDate={minDate}
|
showIcon
|
||||||
maxDate={maxDate}
|
minDate={minDate}
|
||||||
selectionMode="range"
|
maxDate={maxDate}
|
||||||
readOnlyInput
|
selectionMode="range"
|
||||||
hideOnRangeSelection
|
readOnlyInput
|
||||||
showButtonBar
|
hideOnRangeSelection
|
||||||
className={classNames({ 'p-invalid': fieldState.invalid })}/>
|
showButtonBar
|
||||||
)}/>
|
className={classNames({ 'p-invalid': fieldState.invalid })}/>
|
||||||
|
)}/>
|
||||||
{infoText ? <small>{infoText}</small> : null}
|
{infoText ? <small>{infoText}</small> : null}
|
||||||
</>)
|
</>)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,8 @@ const Fileupload = ({
|
|||||||
chooseLabel = __('Aggiungi file', 'gepafin'),
|
chooseLabel = __('Aggiungi file', 'gepafin'),
|
||||||
multiple = false,
|
multiple = false,
|
||||||
sourceId = 0,
|
sourceId = 0,
|
||||||
source = 'application'
|
source = 'application',
|
||||||
|
disabled = false
|
||||||
}) => {
|
}) => {
|
||||||
const [stateFieldData, setStateFieldData] = useState([]);
|
const [stateFieldData, setStateFieldData] = useState([]);
|
||||||
const [acceptFormats, setAcceptFormats] = useState('');
|
const [acceptFormats, setAcceptFormats] = useState('');
|
||||||
@@ -68,6 +69,7 @@ const Fileupload = ({
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<Button icon="pi pi-times" severity="danger"
|
<Button icon="pi pi-times" severity="danger"
|
||||||
|
disabled={disabled}
|
||||||
aria-label={__('Anulla', 'gepafin')}
|
aria-label={__('Anulla', 'gepafin')}
|
||||||
onClick={() => onTemplateRemove(file)}/>
|
onClick={() => onTemplateRemove(file)}/>
|
||||||
</div>
|
</div>
|
||||||
@@ -134,7 +136,7 @@ const Fileupload = ({
|
|||||||
}, [stateFieldData])
|
}, [stateFieldData])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
sourceId && sourceId !== 0
|
sourceId || sourceId === 0
|
||||||
? <>
|
? <>
|
||||||
<label htmlFor={fieldName} className={classNames({ 'p-error': errors[fieldName] })}>
|
<label htmlFor={fieldName} className={classNames({ 'p-error': errors[fieldName] })}>
|
||||||
{label}{config.required || config.isRequired ? '*' : null}
|
{label}{config.required || config.isRequired ? '*' : null}
|
||||||
@@ -142,6 +144,7 @@ const Fileupload = ({
|
|||||||
</label>
|
</label>
|
||||||
<FileUpload
|
<FileUpload
|
||||||
ref={inputRef}
|
ref={inputRef}
|
||||||
|
disabled={disabled}
|
||||||
id={fieldName}
|
id={fieldName}
|
||||||
name={fieldName}
|
name={fieldName}
|
||||||
url={'/document/uploadFile'}
|
url={'/document/uploadFile'}
|
||||||
|
|||||||
@@ -23,7 +23,8 @@ const FileuploadAsync = ({
|
|||||||
chooseLabel = __('Aggiungi immagine', 'gepafin'),
|
chooseLabel = __('Aggiungi immagine', 'gepafin'),
|
||||||
multiple = false,
|
multiple = false,
|
||||||
sourceId = 0,
|
sourceId = 0,
|
||||||
source = 'application'
|
source = 'application',
|
||||||
|
disabled = false
|
||||||
}) => {
|
}) => {
|
||||||
const [stateFieldData, setStateFieldData] = useState([]);
|
const [stateFieldData, setStateFieldData] = useState([]);
|
||||||
const [acceptFormats, setAcceptFormats] = useState('');
|
const [acceptFormats, setAcceptFormats] = useState('');
|
||||||
@@ -68,6 +69,7 @@ const FileuploadAsync = ({
|
|||||||
<div>
|
<div>
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
|
disabled={disabled}
|
||||||
icon="pi pi-times"
|
icon="pi pi-times"
|
||||||
severity="danger"
|
severity="danger"
|
||||||
aria-label={__('Anulla', 'gepafin')}
|
aria-label={__('Anulla', 'gepafin')}
|
||||||
@@ -144,6 +146,7 @@ const FileuploadAsync = ({
|
|||||||
</label>
|
</label>
|
||||||
<FileUpload
|
<FileUpload
|
||||||
ref={inputRef}
|
ref={inputRef}
|
||||||
|
disabled={disabled}
|
||||||
id={fieldName}
|
id={fieldName}
|
||||||
name={fieldName}
|
name={fieldName}
|
||||||
url={'/document/uploadFile'}
|
url={'/document/uploadFile'}
|
||||||
|
|||||||
@@ -18,7 +18,8 @@ const NumberInput = ({
|
|||||||
minFractionDigits = 0,
|
minFractionDigits = 0,
|
||||||
maxFractionDigits = 1,
|
maxFractionDigits = 1,
|
||||||
min,
|
min,
|
||||||
max
|
max,
|
||||||
|
disabled = false
|
||||||
}) => {
|
}) => {
|
||||||
const input = <Controller
|
const input = <Controller
|
||||||
name={fieldName}
|
name={fieldName}
|
||||||
@@ -27,6 +28,7 @@ const NumberInput = ({
|
|||||||
rules={config}
|
rules={config}
|
||||||
render={({ field, fieldState }) => (
|
render={({ field, fieldState }) => (
|
||||||
<InputNumber inputId={field.name}
|
<InputNumber inputId={field.name}
|
||||||
|
disabled={disabled}
|
||||||
value={field.value}
|
value={field.value}
|
||||||
onValueChange={(e) => field.onChange(e.value)}
|
onValueChange={(e) => field.onChange(e.value)}
|
||||||
min={min}
|
min={min}
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ const Radio = ({
|
|||||||
defaultValue,
|
defaultValue,
|
||||||
config = {},
|
config = {},
|
||||||
infoText = null,
|
infoText = null,
|
||||||
options = []
|
options = [],
|
||||||
|
disabled = false
|
||||||
}) => {
|
}) => {
|
||||||
const input = <Controller
|
const input = <Controller
|
||||||
name={fieldName}
|
name={fieldName}
|
||||||
@@ -22,6 +23,7 @@ const Radio = ({
|
|||||||
options.map(o => <div className="appForm__fieldItem" key={o.name}>
|
options.map(o => <div className="appForm__fieldItem" key={o.name}>
|
||||||
<RadioButton
|
<RadioButton
|
||||||
inputId={`${fieldName}_${o.name}`}
|
inputId={`${fieldName}_${o.name}`}
|
||||||
|
disabled={disabled}
|
||||||
name={fieldName}
|
name={fieldName}
|
||||||
value={o.name}
|
value={o.name}
|
||||||
onChange={(e) => field.onChange(e.value)}
|
onChange={(e) => field.onChange(e.value)}
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ const Select = ({
|
|||||||
inputgroup = false,
|
inputgroup = false,
|
||||||
icon = null,
|
icon = null,
|
||||||
placeholder = '',
|
placeholder = '',
|
||||||
options = []
|
options = [],
|
||||||
|
disabled = false
|
||||||
}) => {
|
}) => {
|
||||||
const input = <Controller
|
const input = <Controller
|
||||||
name={fieldName}
|
name={fieldName}
|
||||||
@@ -24,6 +25,7 @@ const Select = ({
|
|||||||
render={({ field, fieldState }) => (
|
render={({ field, fieldState }) => (
|
||||||
<Dropdown
|
<Dropdown
|
||||||
value={field.value}
|
value={field.value}
|
||||||
|
disabled={disabled}
|
||||||
onChange={(e) => field.onChange(e.value)}
|
onChange={(e) => field.onChange(e.value)}
|
||||||
options={options}
|
options={options}
|
||||||
optionLabel="label"
|
optionLabel="label"
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ const Switch = ({
|
|||||||
config = {},
|
config = {},
|
||||||
infoText = null,
|
infoText = null,
|
||||||
onLabel = '',
|
onLabel = '',
|
||||||
offLabel = ''
|
offLabel = '',
|
||||||
|
disabled = false
|
||||||
}) => {
|
}) => {
|
||||||
const properValue = !isNil(defaultValue) && !isEmpty(defaultValue) && defaultValue !== false;
|
const properValue = !isNil(defaultValue) && !isEmpty(defaultValue) && defaultValue !== false;
|
||||||
|
|
||||||
@@ -27,6 +28,7 @@ const Switch = ({
|
|||||||
render={({ field, fieldState }) => (
|
render={({ field, fieldState }) => (
|
||||||
<InputSwitch
|
<InputSwitch
|
||||||
checked={field.value}
|
checked={field.value}
|
||||||
|
disabled={disabled}
|
||||||
onChange={(e) => field.onChange(e.value)}
|
onChange={(e) => field.onChange(e.value)}
|
||||||
className={classNames({ 'p-invalid': fieldState.invalid })}/>
|
className={classNames({ 'p-invalid': fieldState.invalid })}/>
|
||||||
)}/>
|
)}/>
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ const TextArea = ({
|
|||||||
errors,
|
errors,
|
||||||
defaultValue,
|
defaultValue,
|
||||||
config = {},
|
config = {},
|
||||||
infoText = null
|
infoText = null,
|
||||||
|
disabled = false
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -25,6 +26,7 @@ const TextArea = ({
|
|||||||
rules={config}
|
rules={config}
|
||||||
render={({ field, fieldState }) => (
|
render={({ field, fieldState }) => (
|
||||||
<InputTextarea id={field.name}
|
<InputTextarea id={field.name}
|
||||||
|
disabled={disabled}
|
||||||
rows={rows}
|
rows={rows}
|
||||||
{...field}
|
{...field}
|
||||||
className={classNames({ 'p-invalid': fieldState.invalid })}/>
|
className={classNames({ 'p-invalid': fieldState.invalid })}/>
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ const TextInput = ({
|
|||||||
inputgroup = false,
|
inputgroup = false,
|
||||||
icon = null,
|
icon = null,
|
||||||
placeholder = '',
|
placeholder = '',
|
||||||
inputtype = 'text'
|
inputtype = 'text',
|
||||||
|
disabled = false
|
||||||
}) => {
|
}) => {
|
||||||
const input = <Controller
|
const input = <Controller
|
||||||
name={fieldName}
|
name={fieldName}
|
||||||
@@ -23,6 +24,7 @@ const TextInput = ({
|
|||||||
rules={config}
|
rules={config}
|
||||||
render={({ field, fieldState }) => (
|
render={({ field, fieldState }) => (
|
||||||
<InputText id={field.name}
|
<InputText id={field.name}
|
||||||
|
disabled={disabled}
|
||||||
{...field}
|
{...field}
|
||||||
type={inputtype}
|
type={inputtype}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ const Wysiwyg = ({
|
|||||||
errors,
|
errors,
|
||||||
defaultValue,
|
defaultValue,
|
||||||
config = {},
|
config = {},
|
||||||
infoText = null
|
infoText = null,
|
||||||
|
disabled = false
|
||||||
}) => {
|
}) => {
|
||||||
|
|
||||||
const renderHeader = () => {
|
const renderHeader = () => {
|
||||||
@@ -21,6 +22,13 @@ const Wysiwyg = ({
|
|||||||
<button className="ql-italic" aria-label="Italic"></button>
|
<button className="ql-italic" aria-label="Italic"></button>
|
||||||
<button className="ql-underline" aria-label="Underline"></button>
|
<button className="ql-underline" aria-label="Underline"></button>
|
||||||
<button className="ql-link" aria-label="Link"></button>
|
<button className="ql-link" aria-label="Link"></button>
|
||||||
|
<button className="ql-list" value="ordered"></button>
|
||||||
|
<button className="ql-header" value="1"></button>
|
||||||
|
<button className="ql-header" value="2"></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>
|
</span>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -40,6 +48,7 @@ const Wysiwyg = ({
|
|||||||
render={({ field, fieldState }) => (
|
render={({ field, fieldState }) => (
|
||||||
<Editor
|
<Editor
|
||||||
id={field.name}
|
id={field.name}
|
||||||
|
readOnly={disabled}
|
||||||
{...field}
|
{...field}
|
||||||
headerTemplate={header}
|
headerTemplate={header}
|
||||||
onTextChange={(e) => field.onChange(e.htmlValue)}
|
onTextChange={(e) => field.onChange(e.htmlValue)}
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ const FormFieldRepeater = ({
|
|||||||
register,
|
register,
|
||||||
label,
|
label,
|
||||||
infoText,
|
infoText,
|
||||||
config = {}
|
config = {},
|
||||||
|
disabled = false
|
||||||
}) => {
|
}) => {
|
||||||
const forMenu = useRef(null);
|
const forMenu = useRef(null);
|
||||||
const [stateFieldData, setStateFieldData] = useState([]);
|
const [stateFieldData, setStateFieldData] = useState([]);
|
||||||
@@ -72,11 +73,12 @@ const FormFieldRepeater = ({
|
|||||||
const properField = (item, i) => {
|
const properField = (item, i) => {
|
||||||
return !isNil(item.lookUpDataId)
|
return !isNil(item.lookUpDataId)
|
||||||
? <Dropdown value={item.value}
|
? <Dropdown value={item.value}
|
||||||
|
disabled={disabled}
|
||||||
onChange={(e) => selectItem(e, i)}
|
onChange={(e) => selectItem(e, i)}
|
||||||
optionDisabled={(opt) => usedExistingValues().includes(opt.value)}
|
optionDisabled={(opt) => usedExistingValues().includes(opt.value)}
|
||||||
options={stateOptionsData}
|
options={stateOptionsData}
|
||||||
optionLabel="value"/>
|
optionLabel="value"/>
|
||||||
: <InputText value={item.value} onInput={(e) => onInputChange(e, i)}/>
|
: <InputText disabled={disabled} value={item.value} onInput={(e) => onInputChange(e, i)}/>
|
||||||
}
|
}
|
||||||
|
|
||||||
const usedExistingValues = useCallback(() => {
|
const usedExistingValues = useCallback(() => {
|
||||||
@@ -101,7 +103,7 @@ const FormFieldRepeater = ({
|
|||||||
const ids = pluck('lookUpDataId', prevState)
|
const ids = pluck('lookUpDataId', prevState)
|
||||||
const objectsToAdd = klona(storeFieldData)
|
const objectsToAdd = klona(storeFieldData)
|
||||||
.filter(o => !ids.includes(o.lookUpDataId))
|
.filter(o => !ids.includes(o.lookUpDataId))
|
||||||
.map(o => ({...o, id: null}));
|
.map(o => ({ ...o, id: null }));
|
||||||
return [...prevState, ...objectsToAdd];
|
return [...prevState, ...objectsToAdd];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -123,12 +125,13 @@ const FormFieldRepeater = ({
|
|||||||
{stateFieldData.map((o, i) => <div key={i} className={classNames('appForm__repeaterItem')}>
|
{stateFieldData.map((o, i) => <div key={i} className={classNames('appForm__repeaterItem')}>
|
||||||
<div className="p-inputgroup flex-1">
|
<div className="p-inputgroup flex-1">
|
||||||
{properField(o, i)}
|
{properField(o, i)}
|
||||||
<Button type="button" icon="pi pi-times" className="p-button-danger" onClick={() => removeItem(i)}/>
|
<Button disabled={disabled} type="button" icon="pi pi-times" className="p-button-danger" onClick={() => removeItem(i)}/>
|
||||||
</div>
|
</div>
|
||||||
{isNil(o.lookUpDataId) && infoText ? <small>{infoText}</small> : null}
|
{isNil(o.lookUpDataId) && infoText ? <small>{infoText}</small> : null}
|
||||||
</div>)}
|
</div>)}
|
||||||
<Menu model={menuItems} popup ref={forMenu} id="aimedForMenu"/>
|
<Menu model={menuItems} popup ref={forMenu} id="aimedForMenu"/>
|
||||||
<Button type="button" iconPos="right" label={__('Aggiungi', 'gepafin')}
|
<Button type="button" iconPos="right" label={__('Aggiungi', 'gepafin')}
|
||||||
|
disabled={disabled}
|
||||||
icon="pi pi-chevron-down" onClick={(event) => forMenu.current.toggle(event)}
|
icon="pi pi-chevron-down" onClick={(event) => forMenu.current.toggle(event)}
|
||||||
aria-controls="aimedForMenu" aria-haspopup/>
|
aria-controls="aimedForMenu" aria-haspopup/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ const FormFieldRepeaterCriteria = ({
|
|||||||
register,
|
register,
|
||||||
label,
|
label,
|
||||||
infoText,
|
infoText,
|
||||||
config = {}
|
config = {},
|
||||||
|
disabled = false
|
||||||
}) => {
|
}) => {
|
||||||
const forMenu = useRef(null);
|
const forMenu = useRef(null);
|
||||||
const [stateFieldData, setStateFieldData] = useState([]);
|
const [stateFieldData, setStateFieldData] = useState([]);
|
||||||
@@ -78,10 +79,12 @@ const FormFieldRepeaterCriteria = ({
|
|||||||
const properField = (item, i) => {
|
const properField = (item, i) => {
|
||||||
return !isNil(item.lookUpDataId)
|
return !isNil(item.lookUpDataId)
|
||||||
? <Dropdown value={item.value}
|
? <Dropdown value={item.value}
|
||||||
|
disabled={disabled}
|
||||||
onChange={(e) => selectItem(e, i)}
|
onChange={(e) => selectItem(e, i)}
|
||||||
optionDisabled={(opt) => usedExistingValues().includes(opt.value)}
|
optionDisabled={(opt) => usedExistingValues().includes(opt.value)}
|
||||||
options={stateOptionsData} optionLabel="value"/>
|
options={stateOptionsData} optionLabel="value"/>
|
||||||
: <InputText value={item.value} onInput={(e) => onInputChange(e.target.value, i, 'value')}/>
|
: <InputText disabled={disabled} value={item.value}
|
||||||
|
onInput={(e) => onInputChange(e.target.value, i, 'value')}/>
|
||||||
}
|
}
|
||||||
|
|
||||||
const usedExistingValues = useCallback(() => {
|
const usedExistingValues = useCallback(() => {
|
||||||
@@ -111,7 +114,7 @@ const FormFieldRepeaterCriteria = ({
|
|||||||
const ids = pluck('lookUpDataId', prevState)
|
const ids = pluck('lookUpDataId', prevState)
|
||||||
const objectsToAdd = klona(storeFieldData)
|
const objectsToAdd = klona(storeFieldData)
|
||||||
.filter(o => !ids.includes(o.lookUpDataId))
|
.filter(o => !ids.includes(o.lookUpDataId))
|
||||||
.map(o => ({...o, id: null, score: 0}));
|
.map(o => ({ ...o, id: null, score: 0 }));
|
||||||
return [...prevState, ...objectsToAdd];
|
return [...prevState, ...objectsToAdd];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -130,27 +133,30 @@ const FormFieldRepeaterCriteria = ({
|
|||||||
<label htmlFor={fieldName} className={classNames({ 'p-error': errors[fieldName] || errors['threshold'] })}>
|
<label htmlFor={fieldName} className={classNames({ 'p-error': errors[fieldName] || errors['threshold'] })}>
|
||||||
{label}
|
{label}
|
||||||
</label>
|
</label>
|
||||||
<div className="appForm__oneCol">
|
<div className="appForm__col">
|
||||||
<label htmlFor="criterionThreshold">{__('Punteggio minimo per l’ammissione', 'gepafin')}</label>
|
<label htmlFor="criterionThreshold">{__('Punteggio minimo per l’ammissione', 'gepafin')}</label>
|
||||||
<InputNumber inputId="criterionThreshold"
|
<InputNumber inputId="criterionThreshold"
|
||||||
|
disabled={disabled}
|
||||||
value={threshold}
|
value={threshold}
|
||||||
showButtons
|
showButtons
|
||||||
onValueChange={(e) => onThresholdChange(e.value)}/>
|
onValueChange={(e) => onThresholdChange(e.value)}/>
|
||||||
</div>
|
</div>
|
||||||
{stateFieldData.map((o, i) => <div key={i}
|
{stateFieldData.map((o, i) => <div key={i}
|
||||||
className={classNames('appForm__field', 'appForm__repeaterItem')}>
|
className={classNames('appForm__field', 'appForm__repeaterItem')}>
|
||||||
<div className="appForm__twoCols">
|
<div className="appForm__cols">
|
||||||
<div>
|
<div>
|
||||||
<label>{__('Nome criterio di valutazione', 'gepafin')}</label>
|
<label>{__('Nome criterio di valutazione', 'gepafin')}</label>
|
||||||
<div className="p-inputgroup flex-1">
|
<div className="p-inputgroup flex-1">
|
||||||
{properField(o, i)}
|
{properField(o, i)}
|
||||||
<Button type="button" icon="pi pi-times" className="p-button-danger" onClick={() => removeItem(i)}/>
|
<Button disabled={disabled} type="button" icon="pi pi-times" className="p-button-danger"
|
||||||
|
onClick={() => removeItem(i)}/>
|
||||||
</div>
|
</div>
|
||||||
{isNil(o.lookUpDataId) && infoText ? <small>{infoText}</small> : null}
|
{isNil(o.lookUpDataId) && infoText ? <small>{infoText}</small> : null}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label htmlFor="criterionMin">{__('Punteggio', 'gepafin')}</label>
|
<label htmlFor="criterionMin">{__('Punteggio', 'gepafin')}</label>
|
||||||
<InputNumber inputId="criterionMin"
|
<InputNumber inputId="criterionMin"
|
||||||
|
disabled={disabled}
|
||||||
value={o.score}
|
value={o.score}
|
||||||
showButtons
|
showButtons
|
||||||
onValueChange={(e) => onInputChange(e.value, i, 'score')}/>
|
onValueChange={(e) => onInputChange(e.value, i, 'score')}/>
|
||||||
@@ -159,6 +165,7 @@ const FormFieldRepeaterCriteria = ({
|
|||||||
</div>)}
|
</div>)}
|
||||||
<Menu model={menuItems} popup ref={forMenu} id="aimedForMenu"/>
|
<Menu model={menuItems} popup ref={forMenu} id="aimedForMenu"/>
|
||||||
<Button type="button" iconPos="right" label={__('Aggiungi', 'gepafin')}
|
<Button type="button" iconPos="right" label={__('Aggiungi', 'gepafin')}
|
||||||
|
disabled={disabled}
|
||||||
icon="pi pi-chevron-down" onClick={(event) => forMenu.current.toggle(event)}
|
icon="pi pi-chevron-down" onClick={(event) => forMenu.current.toggle(event)}
|
||||||
aria-controls="aimedForMenu" aria-haspopup/>
|
aria-controls="aimedForMenu" aria-haspopup/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -8,10 +8,10 @@ import { diff } from 'deep-object-diff';
|
|||||||
import { Button } from 'primereact/button';
|
import { Button } from 'primereact/button';
|
||||||
import { Dropdown } from 'primereact/dropdown';
|
import { Dropdown } from 'primereact/dropdown';
|
||||||
import { Accordion, AccordionTab } from 'primereact/accordion';
|
import { Accordion, AccordionTab } from 'primereact/accordion';
|
||||||
import { ToggleButton } from 'primereact/togglebutton';
|
|
||||||
import { Dialog } from 'primereact/dialog';
|
import { Dialog } from 'primereact/dialog';
|
||||||
import { InputText } from 'primereact/inputtext';
|
import { InputText } from 'primereact/inputtext';
|
||||||
import { InputTextarea } from 'primereact/inputtextarea';
|
import { InputTextarea } from 'primereact/inputtextarea';
|
||||||
|
import { InputSwitch } from 'primereact/inputswitch';
|
||||||
|
|
||||||
const FormFieldRepeaterFaq = ({
|
const FormFieldRepeaterFaq = ({
|
||||||
data,
|
data,
|
||||||
@@ -21,13 +21,15 @@ const FormFieldRepeaterFaq = ({
|
|||||||
errors,
|
errors,
|
||||||
register,
|
register,
|
||||||
label,
|
label,
|
||||||
config = {}
|
config = {},
|
||||||
|
disabled = false
|
||||||
}) => {
|
}) => {
|
||||||
const [stateFieldData, setStateFieldData] = useState([]);
|
const [stateFieldData, setStateFieldData] = useState([]);
|
||||||
const [stateOptionsData, setStateOptionsData] = useState([]);
|
const [stateOptionsData, setStateOptionsData] = useState([]);
|
||||||
const [question, setQuestion] = useState('');
|
const [question, setQuestion] = useState('');
|
||||||
const [answer, setAnswer] = useState('');
|
const [answer, setAnswer] = useState('');
|
||||||
const [title, setTitle] = useState('');
|
const [title, setTitle] = useState('');
|
||||||
|
const [isVisible, setIsVisible] = useState(false);
|
||||||
const [editDataIndex, setEditDataIndex] = useState(null);
|
const [editDataIndex, setEditDataIndex] = useState(null);
|
||||||
const [isVisibleEditDialog, setIsVisibleEditDialog] = useState(false);
|
const [isVisibleEditDialog, setIsVisibleEditDialog] = useState(false);
|
||||||
|
|
||||||
@@ -39,7 +41,7 @@ const FormFieldRepeaterFaq = ({
|
|||||||
const selectItem = (e) => {
|
const selectItem = (e) => {
|
||||||
const targetedOption = head(stateOptionsData.filter(o => o.value === e.value));
|
const targetedOption = head(stateOptionsData.filter(o => o.value === e.value));
|
||||||
if (targetedOption) {
|
if (targetedOption) {
|
||||||
setStateFieldData([...stateFieldData, {...targetedOption, isVisible: true}]);
|
setStateFieldData([...stateFieldData, { ...targetedOption, isVisible: true }]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,22 +50,12 @@ const FormFieldRepeaterFaq = ({
|
|||||||
setStateFieldData([...stateFieldData, newItem]);
|
setStateFieldData([...stateFieldData, newItem]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const setChecked = (e, index) => {
|
|
||||||
e.preventDefault();
|
|
||||||
const newData = stateFieldData.map((o, i) => {
|
|
||||||
if (i === index) {
|
|
||||||
o.isVisible = e.value;
|
|
||||||
}
|
|
||||||
return o;
|
|
||||||
});
|
|
||||||
setStateFieldData(newData);
|
|
||||||
}
|
|
||||||
|
|
||||||
const editItem = (e, index) => {
|
const editItem = (e, index) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
setTitle(stateFieldData[index].title);
|
setTitle(stateFieldData[index].title);
|
||||||
setQuestion(stateFieldData[index].value);
|
setQuestion(stateFieldData[index].value);
|
||||||
setAnswer(stateFieldData[index].response);
|
setAnswer(stateFieldData[index].response);
|
||||||
|
setIsVisible(stateFieldData[index].isVisible);
|
||||||
setEditDataIndex(index);
|
setEditDataIndex(index);
|
||||||
setIsVisibleEditDialog(true);
|
setIsVisibleEditDialog(true);
|
||||||
}
|
}
|
||||||
@@ -73,6 +65,7 @@ const FormFieldRepeaterFaq = ({
|
|||||||
setQuestion('');
|
setQuestion('');
|
||||||
setAnswer('');
|
setAnswer('');
|
||||||
setTitle('');
|
setTitle('');
|
||||||
|
setIsVisible(false);
|
||||||
setEditDataIndex(null);
|
setEditDataIndex(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,8 +74,10 @@ const FormFieldRepeaterFaq = ({
|
|||||||
setTitle(value);
|
setTitle(value);
|
||||||
} else if (key === 'value') {
|
} else if (key === 'value') {
|
||||||
setQuestion(value);
|
setQuestion(value);
|
||||||
} else {
|
} else if (key === 'response') {
|
||||||
setAnswer(value)
|
setAnswer(value)
|
||||||
|
} else {
|
||||||
|
setIsVisible(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,6 +87,7 @@ const FormFieldRepeaterFaq = ({
|
|||||||
o.title = title;
|
o.title = title;
|
||||||
o.value = question;
|
o.value = question;
|
||||||
o.response = answer;
|
o.response = answer;
|
||||||
|
o.isVisible = isVisible;
|
||||||
return o
|
return o
|
||||||
} else {
|
} else {
|
||||||
return o;
|
return o;
|
||||||
@@ -102,6 +98,7 @@ const FormFieldRepeaterFaq = ({
|
|||||||
setQuestion('');
|
setQuestion('');
|
||||||
setAnswer('');
|
setAnswer('');
|
||||||
setTitle('');
|
setTitle('');
|
||||||
|
setIsVisible(false);
|
||||||
setEditDataIndex(null);
|
setEditDataIndex(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,10 +108,10 @@ const FormFieldRepeaterFaq = ({
|
|||||||
|
|
||||||
const footerEditDialog = () => {
|
const footerEditDialog = () => {
|
||||||
return <div>
|
return <div>
|
||||||
<Button type="button" label={__('Anulla', 'gepafin')} onClick={hideEditDialog} outlined/>
|
<Button type="button" disabled={disabled} label={__('Anulla', 'gepafin')} onClick={hideEditDialog} outlined/>
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
disabled={isEmpty(title) || isEmpty(question) || isEmpty(answer)}
|
disabled={isEmpty(title) || isEmpty(question) || isEmpty(answer) || disabled}
|
||||||
label={__('Salva', 'gepafin')} onClick={saveEditDialog}/>
|
label={__('Salva', 'gepafin')} onClick={saveEditDialog}/>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@@ -156,37 +153,40 @@ const FormFieldRepeaterFaq = ({
|
|||||||
</label>
|
</label>
|
||||||
<div className="appForm__faqHeaderControls">
|
<div className="appForm__faqHeaderControls">
|
||||||
<Button type="button" iconPos="left" label={__('Aggiungi', 'gepafin')}
|
<Button type="button" iconPos="left" label={__('Aggiungi', 'gepafin')}
|
||||||
|
disabled={disabled}
|
||||||
icon="pi pi-plus" onClick={addNewItem}/>
|
icon="pi pi-plus" onClick={addNewItem}/>
|
||||||
<Dropdown onChange={(e) => selectItem(e)}
|
<Dropdown onChange={(e) => selectItem(e)}
|
||||||
|
disabled={disabled}
|
||||||
optionDisabled={(opt) => usedExistingValues().includes(opt.title)}
|
optionDisabled={(opt) => usedExistingValues().includes(opt.title)}
|
||||||
options={stateOptionsData}
|
options={stateOptionsData}
|
||||||
placeholder={__('Scegli tra quelli pre-creati', 'gepafin')}
|
placeholder={__('Scegli tra quelli pre-creati', 'gepafin')}
|
||||||
optionLabel="title"/>
|
optionLabel="title"/>
|
||||||
</div>
|
</div>
|
||||||
<Accordion activeIndex={0}>
|
<Accordion activeIndex={0}>
|
||||||
{stateFieldData.map((o, i) => <AccordionTab key={i}
|
{stateFieldData.map((o, i) => <AccordionTab key={i} tabIndex={i}
|
||||||
header={
|
header={
|
||||||
<div className="appForm__faqTab">
|
<div className="appForm__faqTab">
|
||||||
<div className="appForm__faqTabItem">
|
<div className="appForm__faqTabItem">
|
||||||
<ToggleButton
|
<span>
|
||||||
onIcon="pi pi-eye"
|
{o.value}
|
||||||
offIcon="pi pi-eye-slash"
|
</span>
|
||||||
onLabel=""
|
|
||||||
offLabel=""
|
|
||||||
checked={o.isVisible}
|
|
||||||
onChange={(e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
setChecked(e, i);
|
|
||||||
}}/>
|
|
||||||
{o.value}
|
|
||||||
</div>
|
</div>
|
||||||
<div className="appForm__faqTabItem">
|
<div className="appForm__faqTabItem">
|
||||||
|
{o.isVisible
|
||||||
|
? <i className="pi pi-eye"
|
||||||
|
style={{ fontSize: '1.5rem' }}></i> : null}
|
||||||
|
{!o.isVisible
|
||||||
|
? <i className="pi pi-eye-slash"
|
||||||
|
style={{ fontSize: '1.5rem' }}></i> : null}
|
||||||
<Button icon="pi pi-pencil" severity="success"
|
<Button icon="pi pi-pencil" severity="success"
|
||||||
|
disabled={disabled}
|
||||||
|
className="actionBtn"
|
||||||
type="button"
|
type="button"
|
||||||
aria-label={__('Modifica', 'gepafin')}
|
aria-label={__('Modifica', 'gepafin')}
|
||||||
onClick={(e) => editItem(e, i)}/>
|
onClick={(e) => editItem(e, i)}/>
|
||||||
<Button icon="pi pi-times" severity="danger"
|
<Button icon="pi pi-times" severity="danger"
|
||||||
|
disabled={disabled}
|
||||||
|
className="actionBtn"
|
||||||
type="button"
|
type="button"
|
||||||
aria-label={__('Cancella', 'gepafin')}
|
aria-label={__('Cancella', 'gepafin')}
|
||||||
onClick={() => removeItem(i)}/>
|
onClick={() => removeItem(i)}/>
|
||||||
@@ -203,7 +203,7 @@ const FormFieldRepeaterFaq = ({
|
|||||||
visible={isVisibleEditDialog}
|
visible={isVisibleEditDialog}
|
||||||
modal header={headerEditDialog}
|
modal header={headerEditDialog}
|
||||||
footer={footerEditDialog}
|
footer={footerEditDialog}
|
||||||
style={{ maxWidth: '50rem' }}
|
style={{ maxWidth: '600px', width: '100%' }}
|
||||||
onHide={hideEditDialog}>
|
onHide={hideEditDialog}>
|
||||||
<div className="appPage__spacer"></div>
|
<div className="appPage__spacer"></div>
|
||||||
<div className="appForm__field">
|
<div className="appForm__field">
|
||||||
@@ -220,6 +220,10 @@ const FormFieldRepeaterFaq = ({
|
|||||||
rows={5}
|
rows={5}
|
||||||
cols={30}/>
|
cols={30}/>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="appForm__field">
|
||||||
|
<label>{__('Pubblicato?', 'gepafin')}</label>
|
||||||
|
<InputSwitch checked={isVisible} onChange={(e) => onChangeEditItem(e.value, 'isVisible')}/>
|
||||||
|
</div>
|
||||||
<div className="appPage__spacer"></div>
|
<div className="appPage__spacer"></div>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
6
src/configData.js
Normal file
6
src/configData.js
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
export const mimeTypes = [
|
||||||
|
{ name: 'PDF file', code: 'application/pdf' },
|
||||||
|
{ name: 'ZIP file', code: 'application/zip' },
|
||||||
|
{ name: 'Immagine', code: 'image/*' },
|
||||||
|
{ name: 'Word doc', code: 'application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document' }
|
||||||
|
];
|
||||||
5
src/helpers/renderHtmlContent.js
Normal file
5
src/helpers/renderHtmlContent.js
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import parse from 'html-react-parser';
|
||||||
|
|
||||||
|
const renderHtmlContent = (content) => parse(content);
|
||||||
|
|
||||||
|
export default renderHtmlContent;
|
||||||
@@ -1,27 +1,58 @@
|
|||||||
|
import validate from 'validate.js';
|
||||||
|
import { match, isEmpty } from 'ramda';
|
||||||
|
import CodiceFiscale from 'codice-fiscale-js';
|
||||||
|
|
||||||
export const isPIVA = (v) => {
|
export const isPIVA = (v) => {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// example: DSDDSD99P23B352G
|
||||||
export const isCodiceFiscale = (v) => {
|
export const isCodiceFiscale = (v) => {
|
||||||
return false;
|
//const regexp = new RegExp(/^(?:[A-Z][AEIOU][AEIOUX]|[AEIOU]X{2}|[B-DF-HJ-NP-TV-Z]{2}[A-Z]){2}(?:[\dLMNP-V]{2}(?:[A-EHLMPR-T](?:[04LQ][1-9MNP-V]|[15MR][\dLMNP-V]|[26NS][0-8LMNP-U])|[DHPS][37PT][0L]|[ACELMRT][37PT][01LM]|[AC-EHLMPR-T][26NS][9V])|(?:[02468LNQSU][048LQU]|[13579MPRTV][26NS])B[26NS][9V])(?:[A-MZ][1-9MNP-V][\dLMNP-V]{2}|[A-M][0L](?:[1-9MNP-V][\dLMNP-V]|[0L][1-9MNP-V]))[A-Z]$/, 'i')
|
||||||
|
//return !isEmpty(match(regexp, v));
|
||||||
|
return CodiceFiscale.check(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const isCAP = (v) => {
|
export const isCAP = (v) => {
|
||||||
return false;
|
const regexp = new RegExp(/^[0-9]{5}$/)
|
||||||
|
return !isEmpty(match(regexp, v));
|
||||||
}
|
}
|
||||||
|
|
||||||
export const isIBAN = (v) => {
|
export const isIBAN = (v) => {
|
||||||
return false;
|
const regexp = new RegExp(/^((NO)[0-9A-Z]{2}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}[ ][0-9A-Z]{3}|(NO)[0-9A-Z]{13}|(BE)[0-9A-Z]{2}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}|(BE)[0-9A-Z]{14}|(DK|FO|FI|GL|NL)[0-9A-Z]{2}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}[ ][0-9A-Z]{2}|(DK|FO|FI|GL|NL)[0-9A-Z]{16}|(MK|SI)[0-9A-Z]{2}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}[ ][0-9A-Z]{3}|(MK|SI)[0-9A-Z]{17}|(BA|EE|KZ|LT|LU|AT)[0-9A-Z]{2}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}|(BA|EE|KZ|LT|LU|AT)[0-9A-Z]{18}|(HR|LI|LV|CH)[0-9A-Z]{2}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}[ ][0-9A-Z]{1}|(HR|LI|LV|CH)[0-9A-Z]{19}|(BG|DE|IE|ME|RS|GB)[0-9A-Z]{2}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}[ ][0-9A-Z]{2}|(BG|DE|IE|ME|RS|GB)[0-9A-Z]{20}|(GI|IL)[0-9A-Z]{2}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}[ ][0-9A-Z]{3}|(GI|IL)[0-9A-Z]{21}|(AD|CZ|SA|RO|SK|ES|SE|TN)[0-9A-Z]{2}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}|(AD|CZ|SA|RO|SK|ES|SE|TN)[0-9A-Z]{22}|(PT)[0-9A-Z]{2}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}[ ][0-9A-Z]{1}|(PT)[0-9A-Z]{23}|(IS|TR)[0-9A-Z]{2}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}[ ][0-9A-Z]{2}|(IS|TR)[0-9A-Z]{24}|(FR|GR|IT|MC|SM)[0-9A-Z]{2}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}[ ][0-9A-Z]{3}|(FR|GR|IT|MC|SM)[0-9A-Z]{25}|(AL|CY|HU|LB|PL)[0-9A-Z]{2}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}|(AL|CY|HU|LB|PL)[0-9A-Z]{26}|(MU)[0-9A-Z]{2}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}[ ][0-9A-Z]{2}|(MU)[0-9A-Z]{28}|(MT)[0-9A-Z]{2}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}[ ][0-9A-Z]{4}[ ][0-9A-Z]{3}|(MT)[0-9A-Z]{29})$/)
|
||||||
|
return !isEmpty(match(regexp, v));
|
||||||
}
|
}
|
||||||
|
|
||||||
export const isEmail = (v) => {
|
export const isEmail = (v) => {
|
||||||
return false;
|
const constraints = {
|
||||||
|
from: {
|
||||||
|
email: true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const res = validate({from: v}, constraints);
|
||||||
|
return !res;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const isEmailPEC = (v) => {
|
export const isEmailPEC = (v) => {
|
||||||
return false;
|
const constraints = {
|
||||||
|
from: {
|
||||||
|
email: true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const res = validate({from: v}, constraints);
|
||||||
|
return !res;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const isUrl = (v) => {
|
export const isUrl = (v) => {
|
||||||
return false;
|
const constraints = {
|
||||||
|
from: {
|
||||||
|
url: true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const res = validate({from: v}, constraints);
|
||||||
|
return !res;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const isMarcaDaBollo = (v) => {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
@@ -23,14 +23,14 @@ const AppSidebar = () => {
|
|||||||
{
|
{
|
||||||
label: __('Gestione Bandi', 'gepafin'),
|
label: __('Gestione Bandi', 'gepafin'),
|
||||||
icon: 'pi pi-file',
|
icon: 'pi pi-file',
|
||||||
href: '/tenders',
|
href: '/bandi',
|
||||||
id: 2,
|
id: 2,
|
||||||
enable: intersection(permissions, ['MANAGE_TENDERS']).length
|
enable: intersection(permissions, ['MANAGE_TENDERS']).length
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: __('Domande in lavorazione', 'gepafin'),
|
label: __('Domande in lavorazione', 'gepafin'),
|
||||||
icon: 'pi pi-file',
|
icon: 'pi pi-file',
|
||||||
href: '/applications',
|
href: '/imieibandi',
|
||||||
id: 11,
|
id: 11,
|
||||||
enable: intersection(permissions, ['APPLY_CALLS']).length
|
enable: intersection(permissions, ['APPLY_CALLS']).length
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ const AllBandiTable = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const actionsBodyTemplate = (rowData) => {
|
const actionsBodyTemplate = (rowData) => {
|
||||||
return <Link to={`/tenders/${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" />
|
||||||
</Link>
|
</Link>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ const Bandi = () => {
|
|||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const onGoToCreateNewBando = () => {
|
const onGoToCreateNewBando = () => {
|
||||||
navigate('/tenders/new');
|
navigate('/bandi/new');
|
||||||
}
|
}
|
||||||
|
|
||||||
return(
|
return(
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect, useCallback, useRef } from 'react';
|
||||||
import { __ } from '@wordpress/i18n';
|
import { __, sprintf } from '@wordpress/i18n';
|
||||||
import { useNavigate, useParams } from 'react-router-dom';
|
import { useNavigate, useParams } from 'react-router-dom';
|
||||||
import { klona } from 'klona';
|
import { klona } from 'klona';
|
||||||
import { head, is, isNil } from 'ramda';
|
import { head, range } from 'ramda';
|
||||||
import { useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
|
|
||||||
// store
|
// store
|
||||||
import { storeSet, useStore } from '../../store';
|
import { storeSet, useStore } from '../../store';
|
||||||
|
|
||||||
// api
|
// api
|
||||||
import FormsService from '../../service/forms-service';
|
import ApplicationService from '../../service/application-service';
|
||||||
|
|
||||||
// tools
|
// tools
|
||||||
import {
|
import {
|
||||||
@@ -19,7 +19,8 @@ import {
|
|||||||
isIBAN,
|
isIBAN,
|
||||||
isEmail,
|
isEmail,
|
||||||
isEmailPEC,
|
isEmailPEC,
|
||||||
isUrl
|
isUrl,
|
||||||
|
isMarcaDaBollo
|
||||||
} from '../../helpers/validators';
|
} from '../../helpers/validators';
|
||||||
|
|
||||||
// components
|
// components
|
||||||
@@ -27,17 +28,21 @@ import { Skeleton } from 'primereact/skeleton';
|
|||||||
import { Button } from 'primereact/button';
|
import { Button } from 'primereact/button';
|
||||||
import FormField from '../../components/FormField';
|
import FormField from '../../components/FormField';
|
||||||
import set404FromErrorResponse from '../../helpers/set404FromErrorResponse';
|
import set404FromErrorResponse from '../../helpers/set404FromErrorResponse';
|
||||||
|
import { Steps } from 'primereact/steps';
|
||||||
import { formData as testformData } from '../../tempData';
|
import { Toast } from 'primereact/toast';
|
||||||
import BandoService from '../../service/bando-service';
|
import { TZDate } from '@date-fns/tz';
|
||||||
import ApplicationService from '../../service/application-service';
|
|
||||||
|
|
||||||
const BandoApplication = () => {
|
const BandoApplication = () => {
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [formData, setFormData] = useState([]);
|
const [formData, setFormData] = useState([]);
|
||||||
const [formName, setFormName] = useState('');
|
const [bandoTitle, setBandoTitle] = useState('');
|
||||||
|
const [formId, setFormId] = useState('');
|
||||||
|
const [totalSteps, setTotalSteps] = useState(0);
|
||||||
|
const [activeStep, setActiveStep] = useState(1);
|
||||||
|
const [stepItems, setStepItems] = useState([{ label: 'Passo' }]);
|
||||||
const isAsyncRequest = useStore().main.isAsyncRequest();
|
const isAsyncRequest = useStore().main.isAsyncRequest();
|
||||||
|
const toast = useRef(null);
|
||||||
const {
|
const {
|
||||||
control,
|
control,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
@@ -48,7 +53,6 @@ const BandoApplication = () => {
|
|||||||
getValues,
|
getValues,
|
||||||
} = useForm({ defaultValues: {}, mode: 'onChange' });
|
} = useForm({ defaultValues: {}, mode: 'onChange' });
|
||||||
const values = getValues();
|
const values = getValues();
|
||||||
|
|
||||||
const validationFns = {
|
const validationFns = {
|
||||||
isPIVA,
|
isPIVA,
|
||||||
isCodiceFiscale,
|
isCodiceFiscale,
|
||||||
@@ -56,54 +60,117 @@ const BandoApplication = () => {
|
|||||||
isIBAN,
|
isIBAN,
|
||||||
isEmail,
|
isEmail,
|
||||||
isEmailPEC,
|
isEmailPEC,
|
||||||
isUrl
|
isUrl,
|
||||||
|
isMarcaDaBollo
|
||||||
}
|
}
|
||||||
|
|
||||||
const onSubmit = () => {};
|
const onSubmit = () => {
|
||||||
|
};
|
||||||
|
|
||||||
const saveDraft = () => {
|
const saveDraft = useCallback(() => {
|
||||||
trigger();
|
trigger();
|
||||||
const formData = getValues();
|
const formData = getValues();
|
||||||
const newFormData = Object.keys(formData).reduce((acc, cur) => {
|
const newFormData = Object.keys(formData).reduce((acc, cur) => {
|
||||||
|
let fieldVal = formData[cur];
|
||||||
|
if (formData[cur] && formData[cur].toISOString) {
|
||||||
|
const tzAwareDate = new TZDate(formData[cur], 'Europe/Berlin');
|
||||||
|
fieldVal = tzAwareDate.toISOString().substring(0, 19);
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldVal = !fieldVal ? null : fieldVal;
|
||||||
acc.push({
|
acc.push({
|
||||||
'fieldId': cur,
|
'fieldId': cur,
|
||||||
'fieldValue': formData[cur] && formData[cur].getMonth ? formData[cur].toISOString() : formData[cur]
|
'fieldValue': fieldVal
|
||||||
});
|
});
|
||||||
return acc;
|
return acc;
|
||||||
}, []);
|
}, []);
|
||||||
console.log('newFormData', newFormData);
|
const submitData = {
|
||||||
console.log('errors', errors);
|
formFields: newFormData
|
||||||
};
|
}
|
||||||
|
|
||||||
|
if (formId) {
|
||||||
|
const applId = getApplicationId();
|
||||||
|
storeSet.main.setAsyncRequest();
|
||||||
|
ApplicationService.submitForm(applId, submitData, submitFormCallback, errSubmitFormCallback, [
|
||||||
|
['formId', formId]
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}, [errors]);
|
||||||
|
|
||||||
const getApplicationId = () => {
|
const getApplicationId = () => {
|
||||||
const parsed = parseInt(id)
|
const parsed = parseInt(id)
|
||||||
return !isNaN(parsed) ? parsed : 0;
|
return !isNaN(parsed) ? parsed : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const getCallback = (data) => {
|
const goBackward = () => {
|
||||||
|
if (formId) {
|
||||||
|
const applId = getApplicationId();
|
||||||
|
storeSet.main.setAsyncRequest();
|
||||||
|
ApplicationService.getApplicationForm(applId, getApplFormCallback, errGetApplFormCallbacks, [
|
||||||
|
['formId', formId],
|
||||||
|
['action', 'PREVIOUS']
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const goForward = () => {
|
||||||
|
if (formId) {
|
||||||
|
const applId = getApplicationId();
|
||||||
|
storeSet.main.setAsyncRequest();
|
||||||
|
ApplicationService.getApplicationForm(applId, getApplFormCallback, errGetApplFormCallbacks, [
|
||||||
|
['formId', formId],
|
||||||
|
['action', 'NEXT']
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const submitFormCallback = (data) => {
|
||||||
if (data.status === 'SUCCESS') {
|
if (data.status === 'SUCCESS') {
|
||||||
/*const forms = data.data;
|
console.log(data.data);
|
||||||
setFormName(forms[0].label);
|
if (toast.current) {
|
||||||
const elements = klona(forms[0].content);
|
toast.current.show({
|
||||||
setFormData(elements);*/
|
severity: 'success',
|
||||||
//console.log('testformData.content', testformData.content);
|
summary: '',
|
||||||
setFormName(testformData.label);
|
detail: __('Saved!', 'gepafin')
|
||||||
setFormData(testformData.content);
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
storeSet.main.unsetAsyncRequest();
|
storeSet.main.unsetAsyncRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
const errGetCallbacks = (data) => {
|
const errSubmitFormCallback = (data) => {
|
||||||
set404FromErrorResponse(data);
|
set404FromErrorResponse(data);
|
||||||
storeSet.main.unsetAsyncRequest();
|
storeSet.main.unsetAsyncRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getApplFormCallback = (data) => {
|
||||||
|
if (data.status === 'SUCCESS') {
|
||||||
|
console.log('getApplFormCallback', data.data);
|
||||||
|
setBandoTitle(data.data.callTitle);
|
||||||
|
setFormData(data.data.applicationFormResponse.content);
|
||||||
|
setFormId(data.data.formId);
|
||||||
|
setTotalSteps(data.data.totalFormSteps);
|
||||||
|
setActiveStep(data.data.currentStep)
|
||||||
|
}
|
||||||
|
storeSet.main.unsetAsyncRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
const errGetApplFormCallbacks = (data) => {
|
||||||
|
set404FromErrorResponse(data);
|
||||||
|
storeSet.main.unsetAsyncRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const rangeArr = range(1, totalSteps + 1);
|
||||||
|
setStepItems(rangeArr.map(() => ({ label: 'Passo' })));
|
||||||
|
}, [totalSteps])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const applId = getApplicationId();
|
const applId = getApplicationId();
|
||||||
|
|
||||||
if (applId) {
|
if (applId) {
|
||||||
storeSet.main.setAsyncRequest();
|
storeSet.main.setAsyncRequest();
|
||||||
ApplicationService.getApplication(applId, getCallback, errGetCallbacks);
|
ApplicationService.getApplicationForm(applId, getApplFormCallback, errGetApplFormCallbacks);
|
||||||
}
|
}
|
||||||
}, [id]);
|
}, [id]);
|
||||||
|
|
||||||
@@ -111,7 +178,7 @@ const BandoApplication = () => {
|
|||||||
<div className="appPage">
|
<div className="appPage">
|
||||||
{!isAsyncRequest
|
{!isAsyncRequest
|
||||||
? <div className="appPage__pageHeader">
|
? <div className="appPage__pageHeader">
|
||||||
<h1>{formName}</h1>
|
<h1>{sprintf(__('Domanda per il Bando: %s', 'gepafin'), bandoTitle)}</h1>
|
||||||
</div>
|
</div>
|
||||||
: <>
|
: <>
|
||||||
<Skeleton width="20%" height="1rem" className="mb-2"></Skeleton>
|
<Skeleton width="20%" height="1rem" className="mb-2"></Skeleton>
|
||||||
@@ -120,6 +187,12 @@ const BandoApplication = () => {
|
|||||||
|
|
||||||
<div className="appPage__spacer"></div>
|
<div className="appPage__spacer"></div>
|
||||||
|
|
||||||
|
{!isAsyncRequest
|
||||||
|
? <Steps model={stepItems} activeIndex={activeStep - 1}/> : null}
|
||||||
|
|
||||||
|
<div className="appPage__spacer"></div>
|
||||||
|
|
||||||
|
<Toast ref={toast}/>
|
||||||
{!isAsyncRequest
|
{!isAsyncRequest
|
||||||
? <div className="appPage__content">
|
? <div className="appPage__content">
|
||||||
<form className="appForm" onSubmit={handleSubmit(onSubmit)}>
|
<form className="appForm" onSubmit={handleSubmit(onSubmit)}>
|
||||||
@@ -132,7 +205,7 @@ const BandoApplication = () => {
|
|||||||
let mimeValue = '';
|
let mimeValue = '';
|
||||||
|
|
||||||
if (mime) {
|
if (mime) {
|
||||||
mimeValue = mime.value.join(',');
|
mimeValue = mime.value.map(o => o.code).join(',');
|
||||||
}
|
}
|
||||||
|
|
||||||
const validations = Object.keys(o.validators).reduce((acc, cur) => {
|
const validations = Object.keys(o.validators).reduce((acc, cur) => {
|
||||||
@@ -169,7 +242,7 @@ const BandoApplication = () => {
|
|||||||
config={validations}
|
config={validations}
|
||||||
options={options ? options.value : []}
|
options={options ? options.value : []}
|
||||||
setDataFn={setValue}
|
setDataFn={setValue}
|
||||||
sourceId={1}
|
sourceId={getApplicationId()}
|
||||||
/>
|
/>
|
||||||
})}
|
})}
|
||||||
|
|
||||||
@@ -181,17 +254,26 @@ const BandoApplication = () => {
|
|||||||
|
|
||||||
<div className="appPageSection">
|
<div className="appPageSection">
|
||||||
<div className="appPageSection__actions">
|
<div className="appPageSection__actions">
|
||||||
|
{activeStep > 1 && activeStep <= totalSteps
|
||||||
|
? <Button
|
||||||
|
type="button"
|
||||||
|
onClick={goBackward}
|
||||||
|
label={__('Vai indietro', 'gepafin')}
|
||||||
|
icon="pi pi-arrow-left"
|
||||||
|
iconPos="left"/> : null}
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
|
disabled={isAsyncRequest}
|
||||||
onClick={saveDraft}
|
onClick={saveDraft}
|
||||||
outlined
|
outlined
|
||||||
label={__('Salva bozza', 'gepafin')} icon="pi pi-save" iconPos="right"/>
|
label={__('Salva bozza', 'gepafin')} icon="pi pi-save" iconPos="right"/>
|
||||||
<Button
|
{activeStep < totalSteps
|
||||||
type="button"
|
? <Button
|
||||||
disabled={true}
|
type="button"
|
||||||
onClick={() => {
|
onClick={goForward}
|
||||||
}}
|
label={__('Vai avanti', 'gepafin')}
|
||||||
label={__('Vai avanti', 'gepafin')} icon="pi pi-arrow-right" iconPos="right"/>
|
icon="pi pi-arrow-right"
|
||||||
|
iconPos="right"/> : null}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { isNil } from 'ramda';
|
|||||||
// components
|
// components
|
||||||
import { Button } from 'primereact/button';
|
import { Button } from 'primereact/button';
|
||||||
|
|
||||||
const BandoEditFormActions = ({ id, openPreview, openPreviewEvaluation }) => {
|
const BandoEditFormActions = ({ id, openPreview, openPreviewEvaluation, status }) => {
|
||||||
return (
|
return (
|
||||||
<div className="appPageSection">
|
<div className="appPageSection">
|
||||||
<div className="appPageSection__actions">
|
<div className="appPageSection__actions">
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { useNavigate } from 'react-router-dom';
|
|||||||
import { useForm } from 'react-hook-form';
|
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';
|
||||||
|
|
||||||
// components
|
// components
|
||||||
import FormField from '../../../../components/FormField';
|
import FormField from '../../../../components/FormField';
|
||||||
@@ -20,7 +21,7 @@ import LookupdataService from '../../../../service/lookupdata-service';
|
|||||||
// store
|
// store
|
||||||
import { storeSet, useStore } from '../../../../store';
|
import { storeSet, useStore } from '../../../../store';
|
||||||
|
|
||||||
const BandoEditFormStep1 = forwardRef(function ({ initialData, getFormErrors }, ref) {
|
const BandoEditFormStep1 = forwardRef(function ({ initialData, getFormErrors, status }, ref) {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const isAsyncRequest = useStore().main.isAsyncRequest();
|
const isAsyncRequest = useStore().main.isAsyncRequest();
|
||||||
const [aimedToOptions, setAimedToOptions] = useState([]);
|
const [aimedToOptions, setAimedToOptions] = useState([]);
|
||||||
@@ -34,8 +35,7 @@ const BandoEditFormStep1 = forwardRef(function ({ initialData, getFormErrors },
|
|||||||
register,
|
register,
|
||||||
trigger,
|
trigger,
|
||||||
getValues,
|
getValues,
|
||||||
clearErrors,
|
clearErrors
|
||||||
reset
|
|
||||||
} = useForm({
|
} = useForm({
|
||||||
defaultValues: useMemo(() => {
|
defaultValues: useMemo(() => {
|
||||||
return formInitialData;
|
return formInitialData;
|
||||||
@@ -46,9 +46,17 @@ const BandoEditFormStep1 = forwardRef(function ({ initialData, getFormErrors },
|
|||||||
|
|
||||||
const onSubmit = (formData) => {
|
const onSubmit = (formData) => {
|
||||||
if (!isNil(formData.dates) && formData.dates.length) {
|
if (!isNil(formData.dates) && formData.dates.length) {
|
||||||
formData.dates = formData.dates.map(v => is(String, v) ? v : v.toISOString());
|
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) {
|
if (!formData.id) {
|
||||||
BandoService.createBando(formData, createCallback, errCreateCallback);
|
BandoService.createBando(formData, createCallback, errCreateCallback);
|
||||||
} else {
|
} else {
|
||||||
@@ -57,6 +65,7 @@ const BandoEditFormStep1 = forwardRef(function ({ initialData, getFormErrors },
|
|||||||
};
|
};
|
||||||
|
|
||||||
const createCallback = (data) => {
|
const createCallback = (data) => {
|
||||||
|
storeSet.main.unsetAsyncRequest();
|
||||||
if (data.status === 'SUCCESS') {
|
if (data.status === 'SUCCESS') {
|
||||||
toast.current.show({
|
toast.current.show({
|
||||||
severity: 'success',
|
severity: 'success',
|
||||||
@@ -65,24 +74,24 @@ const BandoEditFormStep1 = forwardRef(function ({ initialData, getFormErrors },
|
|||||||
});
|
});
|
||||||
const values = getValues();
|
const values = getValues();
|
||||||
if (!values.id && data.data.id) {
|
if (!values.id && data.data.id) {
|
||||||
navigate(`/tenders/${data.data.id}`);
|
navigate(`/bandi/${data.data.id}`);
|
||||||
} else {
|
} else {
|
||||||
setFormInitialData(data.data);
|
setFormInitialData(data.data);
|
||||||
reset();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const errCreateCallback = (data) => {
|
const errCreateCallback = (data) => {
|
||||||
console.log('errCreateCallback', data);
|
console.log('errCreateCallback', data);
|
||||||
|
storeSet.main.unsetAsyncRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
const openPreview = () => {
|
const openPreview = () => {
|
||||||
navigate(`/tenders/${values.id}/preview`);
|
navigate(`/bandi/${values.id}/preview`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const openPreviewEvaluation = () => {
|
const openPreviewEvaluation = () => {
|
||||||
navigate(`/tenders/${values.id}/preview-evaluation`);
|
navigate(`/bandi/${values.id}/preview-evaluation`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const lookupdataCallback = (data) => {
|
const lookupdataCallback = (data) => {
|
||||||
@@ -118,6 +127,10 @@ const BandoEditFormStep1 = forwardRef(function ({ initialData, getFormErrors },
|
|||||||
storeSet.main.unsetAsyncRequest();
|
storeSet.main.unsetAsyncRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const shouldDisableField = () => {
|
||||||
|
return values.status === 'PUBLISH'
|
||||||
|
}
|
||||||
|
|
||||||
useImperativeHandle(
|
useImperativeHandle(
|
||||||
ref,
|
ref,
|
||||||
() => {
|
() => {
|
||||||
@@ -144,14 +157,10 @@ const BandoEditFormStep1 = forwardRef(function ({ initialData, getFormErrors },
|
|||||||
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 : ''));
|
newFormData.dates = formInitialData.dates.map(v => is(String, v) ? new Date(v) : (v ? v : ''));
|
||||||
}
|
}
|
||||||
reset(newFormData);
|
Object.keys(newFormData).map(v => setValue(v, newFormData[v]));
|
||||||
}, [formInitialData]);
|
}, [formInitialData]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isAsyncRequest !== 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
trigger().then(() => clearErrors());
|
trigger().then(() => clearErrors());
|
||||||
LookupdataService.getItems(lookupdataCallback, errLookupdataCallback, [['type', ['AIMED_TO', 'FAQ']]]);
|
LookupdataService.getItems(lookupdataCallback, errLookupdataCallback, [['type', ['AIMED_TO', 'FAQ']]]);
|
||||||
|
|
||||||
@@ -165,6 +174,7 @@ const BandoEditFormStep1 = forwardRef(function ({ initialData, getFormErrors },
|
|||||||
<UnsavedChangesDetector getValuesFn={getValues}/>
|
<UnsavedChangesDetector getValuesFn={getValues}/>
|
||||||
<FormField
|
<FormField
|
||||||
type="switch"
|
type="switch"
|
||||||
|
disabled={shouldDisableField()}
|
||||||
fieldName="confidi"
|
fieldName="confidi"
|
||||||
label={__('Bando Confidi', 'gepafin')}
|
label={__('Bando Confidi', 'gepafin')}
|
||||||
control={control}
|
control={control}
|
||||||
@@ -176,6 +186,7 @@ const BandoEditFormStep1 = forwardRef(function ({ initialData, getFormErrors },
|
|||||||
|
|
||||||
<FormField
|
<FormField
|
||||||
type="textinput"
|
type="textinput"
|
||||||
|
disabled={shouldDisableField()}
|
||||||
fieldName="name"
|
fieldName="name"
|
||||||
label={__('Titolo del Bando', 'gepafin')}
|
label={__('Titolo del Bando', 'gepafin')}
|
||||||
control={control}
|
control={control}
|
||||||
@@ -185,7 +196,8 @@ const BandoEditFormStep1 = forwardRef(function ({ initialData, getFormErrors },
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<FormField
|
<FormField
|
||||||
type="textarea"
|
type="wysiwyg"
|
||||||
|
disabled={shouldDisableField()}
|
||||||
fieldName="descriptionShort"
|
fieldName="descriptionShort"
|
||||||
label={__('Descrizione breve', 'gepafin')}
|
label={__('Descrizione breve', 'gepafin')}
|
||||||
control={control}
|
control={control}
|
||||||
@@ -197,7 +209,8 @@ const BandoEditFormStep1 = forwardRef(function ({ initialData, getFormErrors },
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<FormField
|
<FormField
|
||||||
type="textarea"
|
type="wysiwyg"
|
||||||
|
disabled={shouldDisableField()}
|
||||||
fieldName="descriptionLong"
|
fieldName="descriptionLong"
|
||||||
label={__('Descrizione completa', 'gepafin')}
|
label={__('Descrizione completa', 'gepafin')}
|
||||||
control={control}
|
control={control}
|
||||||
@@ -213,6 +226,7 @@ const BandoEditFormStep1 = forwardRef(function ({ initialData, getFormErrors },
|
|||||||
|
|
||||||
<FormFieldRepeater
|
<FormFieldRepeater
|
||||||
data={values['aimedTo']}
|
data={values['aimedTo']}
|
||||||
|
disabled={shouldDisableField()}
|
||||||
setDataFn={setValue}
|
setDataFn={setValue}
|
||||||
fieldName="aimedTo"
|
fieldName="aimedTo"
|
||||||
options={aimedToOptions}
|
options={aimedToOptions}
|
||||||
@@ -221,9 +235,8 @@ const BandoEditFormStep1 = forwardRef(function ({ initialData, getFormErrors },
|
|||||||
trigger={trigger}
|
trigger={trigger}
|
||||||
config={{
|
config={{
|
||||||
validate: {
|
validate: {
|
||||||
minOneItem: v => !isEmpty(v) || __('Almeno 1 tipo di destinatari', 'gepafin'),
|
minOneItem: v => (v && !isEmpty(v)) || __('Almeno 1 tipo di destinatari', 'gepafin'),
|
||||||
noEmptyValue: v => v
|
noEmptyValue: v => v.filter(o => isEmpty(o.value)).length === 0 || __('Non lasciare il valore vuoto', 'gepafin')
|
||||||
.filter(o => isEmpty(o.value)).length === 0 || __('Non lasciare il valore vuoto', 'gepafin')
|
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
label={<>{__('A chi si rivolge', 'gepafin')}*
|
label={<>{__('A chi si rivolge', 'gepafin')}*
|
||||||
@@ -232,6 +245,7 @@ const BandoEditFormStep1 = forwardRef(function ({ initialData, getFormErrors },
|
|||||||
|
|
||||||
<FormField
|
<FormField
|
||||||
type="textarea"
|
type="textarea"
|
||||||
|
disabled={shouldDisableField()}
|
||||||
fieldName="documentationRequested"
|
fieldName="documentationRequested"
|
||||||
label={__('Documentazione richiesta', 'gepafin')}
|
label={__('Documentazione richiesta', 'gepafin')}
|
||||||
control={control}
|
control={control}
|
||||||
@@ -244,6 +258,7 @@ const BandoEditFormStep1 = forwardRef(function ({ initialData, getFormErrors },
|
|||||||
|
|
||||||
<FormField
|
<FormField
|
||||||
type="datepickerrange"
|
type="datepickerrange"
|
||||||
|
disabled={shouldDisableField()}
|
||||||
fieldName="dates"
|
fieldName="dates"
|
||||||
label={__('Dati di pubblicazione', 'gepafin')}
|
label={__('Dati di pubblicazione', 'gepafin')}
|
||||||
control={control}
|
control={control}
|
||||||
@@ -253,9 +268,10 @@ const BandoEditFormStep1 = forwardRef(function ({ initialData, getFormErrors },
|
|||||||
/*minDate={minDateStart}*/
|
/*minDate={minDateStart}*/
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className="appForm__twoCols">
|
<div className="appForm__cols">
|
||||||
<FormField
|
<FormField
|
||||||
type="numberinput"
|
type="numberinput"
|
||||||
|
disabled={shouldDisableField()}
|
||||||
fieldName="amount"
|
fieldName="amount"
|
||||||
label={__('Dotazione del Bando', 'gepafin')}
|
label={__('Dotazione del Bando', 'gepafin')}
|
||||||
control={control}
|
control={control}
|
||||||
@@ -268,6 +284,7 @@ const BandoEditFormStep1 = forwardRef(function ({ initialData, getFormErrors },
|
|||||||
|
|
||||||
<FormField
|
<FormField
|
||||||
type="numberinput"
|
type="numberinput"
|
||||||
|
disabled={shouldDisableField()}
|
||||||
fieldName="amountMax"
|
fieldName="amountMax"
|
||||||
label={__('Importo massimo per Progetto', 'gepafin')}
|
label={__('Importo massimo per Progetto', 'gepafin')}
|
||||||
control={control}
|
control={control}
|
||||||
@@ -304,6 +321,7 @@ const BandoEditFormStep1 = forwardRef(function ({ initialData, getFormErrors },
|
|||||||
<Toast ref={toast} />
|
<Toast ref={toast} />
|
||||||
<BandoEditFormActions
|
<BandoEditFormActions
|
||||||
id={values.id}
|
id={values.id}
|
||||||
|
status={status}
|
||||||
openPreview={openPreview}
|
openPreview={openPreview}
|
||||||
openPreviewEvaluation={openPreviewEvaluation}/>
|
openPreviewEvaluation={openPreviewEvaluation}/>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { useNavigate } from 'react-router-dom';
|
|||||||
import { useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
import { is, isEmpty, isNil } from 'ramda';
|
import { is, isEmpty, isNil } from 'ramda';
|
||||||
import { klona } from 'klona';
|
import { klona } from 'klona';
|
||||||
|
import { TZDate } from '@date-fns/tz';
|
||||||
|
|
||||||
// components
|
// components
|
||||||
import FormField from '../../../../components/FormField';
|
import FormField from '../../../../components/FormField';
|
||||||
@@ -20,7 +21,7 @@ import LookupdataService from '../../../../service/lookupdata-service';
|
|||||||
// store
|
// store
|
||||||
import { storeSet } from '../../../../store';
|
import { storeSet } from '../../../../store';
|
||||||
|
|
||||||
const BandoEditFormStep2 = forwardRef(function ({ initialData, getFormErrors }, ref) {
|
const BandoEditFormStep2 = forwardRef(function ({ initialData, getFormErrors, status }, ref) {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [criteriaOptions, setCriteriaOptions] = useState([]);
|
const [criteriaOptions, setCriteriaOptions] = useState([]);
|
||||||
const [checklistOptions, setChecklistOptions] = useState([]);
|
const [checklistOptions, setChecklistOptions] = useState([]);
|
||||||
@@ -33,8 +34,7 @@ const BandoEditFormStep2 = forwardRef(function ({ initialData, getFormErrors },
|
|||||||
register,
|
register,
|
||||||
trigger,
|
trigger,
|
||||||
getValues,
|
getValues,
|
||||||
clearErrors,
|
clearErrors
|
||||||
reset
|
|
||||||
} = useForm({
|
} = useForm({
|
||||||
defaultValues: useMemo(() => {
|
defaultValues: useMemo(() => {
|
||||||
return formInitialData;
|
return formInitialData;
|
||||||
@@ -46,7 +46,14 @@ const BandoEditFormStep2 = forwardRef(function ({ initialData, getFormErrors },
|
|||||||
|
|
||||||
const onSubmit = (formData) => {
|
const onSubmit = (formData) => {
|
||||||
if (!isNil(formData.dates) && formData.dates.length) {
|
if (!isNil(formData.dates) && formData.dates.length) {
|
||||||
formData.dates = formData.dates.map(v => is(String, v) ? v : v.toISOString());
|
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) => {
|
const forSubmit = Object.keys(formData).reduce((acc, cur) => {
|
||||||
@@ -56,10 +63,12 @@ const BandoEditFormStep2 = forwardRef(function ({ initialData, getFormErrors },
|
|||||||
return acc;
|
return acc;
|
||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
|
storeSet.main.setAsyncRequest();
|
||||||
BandoService.updateBandoStep2(formData.id, forSubmit, createCallback, errCreateCallback);
|
BandoService.updateBandoStep2(formData.id, forSubmit, createCallback, errCreateCallback);
|
||||||
};
|
};
|
||||||
|
|
||||||
const createCallback = (data) => {
|
const createCallback = (data) => {
|
||||||
|
storeSet.main.unsetAsyncRequest();
|
||||||
if (data.status === 'SUCCESS') {
|
if (data.status === 'SUCCESS') {
|
||||||
toast.current.show({
|
toast.current.show({
|
||||||
severity: 'success',
|
severity: 'success',
|
||||||
@@ -68,11 +77,11 @@ const BandoEditFormStep2 = forwardRef(function ({ initialData, getFormErrors },
|
|||||||
});
|
});
|
||||||
const newFormData = {...formInitialData, ...data.data};
|
const newFormData = {...formInitialData, ...data.data};
|
||||||
setFormInitialData(newFormData);
|
setFormInitialData(newFormData);
|
||||||
reset(newFormData);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const errCreateCallback = (data) => {
|
const errCreateCallback = (data) => {
|
||||||
|
storeSet.main.unsetAsyncRequest();
|
||||||
console.log('errCreateCallback', data);
|
console.log('errCreateCallback', data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,11 +118,11 @@ const BandoEditFormStep2 = forwardRef(function ({ initialData, getFormErrors },
|
|||||||
}
|
}
|
||||||
|
|
||||||
const openPreview = () => {
|
const openPreview = () => {
|
||||||
navigate(`/tenders/${values.id}/preview`);
|
navigate(`/bandi/${values.id}/preview`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const openPreviewEvaluation = () => {
|
const openPreviewEvaluation = () => {
|
||||||
navigate(`/tenders/${values.id}/preview-evaluation`);
|
navigate(`/bandi/${values.id}/preview-evaluation`);
|
||||||
}
|
}
|
||||||
|
|
||||||
useImperativeHandle(
|
useImperativeHandle(
|
||||||
@@ -142,7 +151,7 @@ const BandoEditFormStep2 = forwardRef(function ({ initialData, getFormErrors },
|
|||||||
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 : ''));
|
newFormData.dates = formInitialData.dates.map(v => is(String, v) ? new Date(v) : (v ? v : ''));
|
||||||
}
|
}
|
||||||
reset(newFormData);
|
Object.keys(newFormData).map(v => setValue(v, newFormData[v]));
|
||||||
}, [formInitialData]);
|
}, [formInitialData]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -154,11 +163,16 @@ const BandoEditFormStep2 = forwardRef(function ({ initialData, getFormErrors },
|
|||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const shouldDisableField = () => {
|
||||||
|
return values.status === 'PUBLISH'
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form className="appForm" onSubmit={handleSubmit(onSubmit)}>
|
<form className="appForm" onSubmit={handleSubmit(onSubmit)}>
|
||||||
<UnsavedChangesDetector getValuesFn={getValues}/>
|
<UnsavedChangesDetector getValuesFn={getValues}/>
|
||||||
<FormFieldRepeaterCriteria
|
<FormFieldRepeaterCriteria
|
||||||
data={values}
|
data={values}
|
||||||
|
disabled={shouldDisableField()}
|
||||||
setDataFn={setValue}
|
setDataFn={setValue}
|
||||||
fieldName="criteria"
|
fieldName="criteria"
|
||||||
options={criteriaOptions}
|
options={criteriaOptions}
|
||||||
@@ -177,6 +191,7 @@ const BandoEditFormStep2 = forwardRef(function ({ initialData, getFormErrors },
|
|||||||
|
|
||||||
<FormField
|
<FormField
|
||||||
type="fileuploadasync"
|
type="fileuploadasync"
|
||||||
|
disabled={shouldDisableField()}
|
||||||
setDataFn={setValue}
|
setDataFn={setValue}
|
||||||
fieldName="docs"
|
fieldName="docs"
|
||||||
label={__('Documentazione', 'gepafin')}
|
label={__('Documentazione', 'gepafin')}
|
||||||
@@ -195,6 +210,7 @@ const BandoEditFormStep2 = forwardRef(function ({ initialData, getFormErrors },
|
|||||||
|
|
||||||
<FormField
|
<FormField
|
||||||
type="fileuploadasync"
|
type="fileuploadasync"
|
||||||
|
disabled={shouldDisableField()}
|
||||||
setDataFn={setValue}
|
setDataFn={setValue}
|
||||||
fieldName="images"
|
fieldName="images"
|
||||||
label={__('Immagine del Bando', 'gepafin')}
|
label={__('Immagine del Bando', 'gepafin')}
|
||||||
@@ -209,6 +225,7 @@ const BandoEditFormStep2 = forwardRef(function ({ initialData, getFormErrors },
|
|||||||
|
|
||||||
<FormFieldRepeater
|
<FormFieldRepeater
|
||||||
data={values['checkList']}
|
data={values['checkList']}
|
||||||
|
disabled={shouldDisableField()}
|
||||||
setDataFn={setValue}
|
setDataFn={setValue}
|
||||||
fieldName="checkList"
|
fieldName="checkList"
|
||||||
options={checklistOptions}
|
options={checklistOptions}
|
||||||
@@ -234,6 +251,7 @@ const BandoEditFormStep2 = forwardRef(function ({ initialData, getFormErrors },
|
|||||||
<Toast ref={toast} />
|
<Toast ref={toast} />
|
||||||
<BandoEditFormActions
|
<BandoEditFormActions
|
||||||
id={values.id}
|
id={values.id}
|
||||||
|
status={status}
|
||||||
openPreview={openPreview}
|
openPreview={openPreview}
|
||||||
openPreviewEvaluation={openPreviewEvaluation}/>
|
openPreviewEvaluation={openPreviewEvaluation}/>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import React, { useState, useEffect, useRef } from 'react';
|
import React, { useState, useEffect, useRef } from 'react';
|
||||||
import { __ } from '@wordpress/i18n';
|
import { __ } from '@wordpress/i18n';
|
||||||
import { useNavigate, useParams } from 'react-router-dom';
|
import { useNavigate, useParams } from 'react-router-dom';
|
||||||
import { is, isNil } from 'ramda';
|
import { is, isNil, isEmpty } from 'ramda';
|
||||||
|
|
||||||
// store
|
// store
|
||||||
import { storeSet, useStore } from '../../store';
|
import { storeSet, useStore } from '../../store';
|
||||||
@@ -93,11 +93,11 @@ const BandoEdit = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const openBandoFormManagement = () => {
|
const openBandoFormManagement = () => {
|
||||||
navigate(`/tenders/${id}/forms`);
|
navigate(`/bandi/${id}/forms`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const openBandoFlowManagement = () => {
|
const openBandoFlowManagement = () => {
|
||||||
navigate(`/tenders/${id}/flow`);
|
navigate(`/bandi/${id}/flow`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const validateBando = () => {
|
const validateBando = () => {
|
||||||
@@ -108,6 +108,7 @@ const BandoEdit = () => {
|
|||||||
|
|
||||||
const validateCallback = (data) => {
|
const validateCallback = (data) => {
|
||||||
if (data.status === 'SUCCESS') {
|
if (data.status === 'SUCCESS') {
|
||||||
|
setData({...data, status: data.data.status});
|
||||||
if (bandoMsgs.current) {
|
if (bandoMsgs.current) {
|
||||||
bandoMsgs.current.show([
|
bandoMsgs.current.show([
|
||||||
{
|
{
|
||||||
@@ -123,7 +124,19 @@ const BandoEdit = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const errValidateCallback = (data) => {
|
const errValidateCallback = (data) => {
|
||||||
standardErrCallback(data);
|
if (data.status === 'VALIDATION_ERROR') {
|
||||||
|
storeSet.main.unsetAsyncRequest();
|
||||||
|
if (bandoMsgs.current) {
|
||||||
|
bandoMsgs.current.show(data.data.map((v, i) => ({
|
||||||
|
id: i,
|
||||||
|
sticky: true, severity: 'error', summary: '',
|
||||||
|
detail: v,
|
||||||
|
closable: false
|
||||||
|
})));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
standardErrCallback(data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const publishBando = () => {
|
const publishBando = () => {
|
||||||
@@ -144,6 +157,7 @@ const BandoEdit = () => {
|
|||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
setData(data.data);
|
||||||
}
|
}
|
||||||
storeSet.main.unsetAsyncRequest();
|
storeSet.main.unsetAsyncRequest();
|
||||||
}
|
}
|
||||||
@@ -276,23 +290,24 @@ const BandoEdit = () => {
|
|||||||
icon="pi pi-check"
|
icon="pi pi-check"
|
||||||
iconPos="right"/>
|
iconPos="right"/>
|
||||||
</div> : null*/}
|
</div> : null*/}
|
||||||
{!isAsyncRequest
|
{!isEmpty(data)
|
||||||
? <Steps
|
? <Steps
|
||||||
model={stepItems}
|
model={stepItems}
|
||||||
activeIndex={activeStep}
|
activeIndex={activeStep}
|
||||||
readOnly={false}/>
|
readOnly={false}/>
|
||||||
: <BlockingOverlay shouldDisplay={isAsyncRequest}/>}
|
: null}
|
||||||
|
<BlockingOverlay shouldDisplay={isAsyncRequest}/>
|
||||||
|
|
||||||
<div className="appPage__spacer"></div>
|
<div className="appPage__spacer"></div>
|
||||||
|
|
||||||
<Messages ref={bandoMsgs}/>
|
<Messages ref={bandoMsgs}/>
|
||||||
|
|
||||||
{!isAsyncRequest
|
{!isEmpty(data)
|
||||||
? <>
|
? <>
|
||||||
{activeStep === 0
|
{activeStep === 0
|
||||||
? <BandoEditFormStep1 initialData={data} ref={formRef}/> : null}
|
? <BandoEditFormStep1 initialData={data} ref={formRef} status={data.status}/> : null}
|
||||||
{activeStep === 1
|
{activeStep === 1
|
||||||
? <BandoEditFormStep2 initialData={data} ref={formRef}/> : null}
|
? <BandoEditFormStep2 initialData={data} ref={formRef} status={data.status}/> : null}
|
||||||
|
|
||||||
<div className="appPageSection">
|
<div className="appPageSection">
|
||||||
<h2>{__('Crea o modifica il Form compilabile dal Beneficiario', 'gepafin')}</h2>
|
<h2>{__('Crea o modifica il Form compilabile dal Beneficiario', 'gepafin')}</h2>
|
||||||
@@ -300,11 +315,13 @@ const BandoEdit = () => {
|
|||||||
<div className="row">
|
<div className="row">
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
|
outlined={data.status === 'PUBLISH'}
|
||||||
onClick={openBandoFormManagement}
|
onClick={openBandoFormManagement}
|
||||||
label={__('Crea/modifica form', 'gepafin')}/>
|
label={__('Crea/modifica form', 'gepafin')}/>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
|
outlined={data.status === 'PUBLISH'}
|
||||||
onClick={openBandoFlowManagement}
|
onClick={openBandoFlowManagement}
|
||||||
icon="pi pi-sitemap"
|
icon="pi pi-sitemap"
|
||||||
iconPos="right"
|
iconPos="right"
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import React, { useEffect, useState, useCallback, useRef } from 'react';
|
import React, { useEffect, useState, useCallback, useRef } from 'react';
|
||||||
import { __ } from '@wordpress/i18n';
|
import { __, sprintf } from '@wordpress/i18n';
|
||||||
import { useNavigate, useParams } from 'react-router-dom';
|
import { useNavigate, useParams } from 'react-router-dom';
|
||||||
import { isEmpty, head } from 'ramda';
|
import { isEmpty, head } from 'ramda';
|
||||||
|
|
||||||
// store
|
// store
|
||||||
import { storeSet, useStore } from '../../store';
|
import { storeGet, storeSet, useStore } from '../../store';
|
||||||
|
|
||||||
// api
|
// api
|
||||||
import FormsService from '../../service/forms-service';
|
import FormsService from '../../service/forms-service';
|
||||||
@@ -19,6 +19,7 @@ import FlowBuilder from '../../components/FlowBuilder';
|
|||||||
import { Messages } from 'primereact/messages';
|
import { Messages } from 'primereact/messages';
|
||||||
import FlowService from '../../service/flow-service';
|
import FlowService from '../../service/flow-service';
|
||||||
import { confirmPopup, ConfirmPopup } from 'primereact/confirmpopup';
|
import { confirmPopup, ConfirmPopup } from 'primereact/confirmpopup';
|
||||||
|
import { Toast } from 'primereact/toast';
|
||||||
|
|
||||||
const BandoFlowEdit = () => {
|
const BandoFlowEdit = () => {
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
@@ -28,8 +29,12 @@ const BandoFlowEdit = () => {
|
|||||||
const flowEdges = useStore().main.flowEdges();
|
const flowEdges = useStore().main.flowEdges();
|
||||||
const [formOptions, setFormOptions] = useState([]);
|
const [formOptions, setFormOptions] = useState([]);
|
||||||
const [initialForm, setInitialForm] = useState(0);
|
const [initialForm, setInitialForm] = useState(0);
|
||||||
|
const [mainFieldOptions, setMainFieldOptions] = useState([]);
|
||||||
|
const [mainField, setMainField] = useState('');
|
||||||
|
const [isFlowAllowed, setIsFlowAllowed] = useState(false);
|
||||||
const [finalForm, setFinalForm] = useState(0);
|
const [finalForm, setFinalForm] = useState(0);
|
||||||
const flowMsgs = useRef(null);
|
const flowMsgs = useRef(null);
|
||||||
|
const toast = useRef(null);
|
||||||
|
|
||||||
const getBandoId = () => {
|
const getBandoId = () => {
|
||||||
const parsed = parseInt(id)
|
const parsed = parseInt(id)
|
||||||
@@ -38,7 +43,7 @@ const BandoFlowEdit = () => {
|
|||||||
|
|
||||||
const goBack = () => {
|
const goBack = () => {
|
||||||
const bandoId = getBandoId();
|
const bandoId = getBandoId();
|
||||||
navigate(`/tenders/${bandoId}/forms`);
|
navigate(`/bandi/${bandoId}/forms`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const confirmDelete = (event) => {
|
const confirmDelete = (event) => {
|
||||||
@@ -55,9 +60,15 @@ const BandoFlowEdit = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const doDelete = () => {
|
const doDelete = () => {
|
||||||
|
if (flowMsgs.current) {
|
||||||
|
flowMsgs.current.clear();
|
||||||
|
}
|
||||||
storeSet.main.flowData([]);
|
storeSet.main.flowData([]);
|
||||||
storeSet.main.flowEdges([]);
|
storeSet.main.flowEdges([]);
|
||||||
setInitialForm(0);
|
setInitialForm(0);
|
||||||
|
setMainFieldOptions([]);
|
||||||
|
setMainField('');
|
||||||
|
setIsFlowAllowed(false);
|
||||||
setFinalForm(0);
|
setFinalForm(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,15 +105,12 @@ const BandoFlowEdit = () => {
|
|||||||
|
|
||||||
const getFlowCreateCallback = (data) => {
|
const getFlowCreateCallback = (data) => {
|
||||||
if (data.status === 'SUCCESS') {
|
if (data.status === 'SUCCESS') {
|
||||||
if (flowMsgs.current) {
|
if (toast.current) {
|
||||||
flowMsgs.current.show([
|
toast.current.show({
|
||||||
{
|
severity: 'success',
|
||||||
id: '99',
|
summary: '',
|
||||||
sticky: true, severity: 'success', summary: '',
|
detail: __('Il flusso è stato aggiornato corretamente!', 'gepafin')
|
||||||
detail: __('Flow è salvato.', 'gepafin'),
|
});
|
||||||
closable: false
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
storeSet.main.unsetAsyncRequest();
|
storeSet.main.unsetAsyncRequest();
|
||||||
@@ -117,7 +125,7 @@ const BandoFlowEdit = () => {
|
|||||||
if (data.status === 'SUCCESS') {
|
if (data.status === 'SUCCESS') {
|
||||||
const formOptions = data.data.map(o => ({ label: o.label, value: o.id }))
|
const formOptions = data.data.map(o => ({ label: o.label, value: o.id }))
|
||||||
storeSet.main.flowForms(data.data);
|
storeSet.main.flowForms(data.data);
|
||||||
setFormOptions(formOptions);
|
setFormOptions([{label: '', value: ''}, ...formOptions]);
|
||||||
}
|
}
|
||||||
storeSet.main.unsetAsyncRequest();
|
storeSet.main.unsetAsyncRequest();
|
||||||
}
|
}
|
||||||
@@ -133,7 +141,11 @@ const BandoFlowEdit = () => {
|
|||||||
storeSet.main.flowEdges(data.data.flowEdges);
|
storeSet.main.flowEdges(data.data.flowEdges);
|
||||||
setInitialForm(data.data.initialForm);
|
setInitialForm(data.data.initialForm);
|
||||||
setFinalForm(data.data.finalForm);
|
setFinalForm(data.data.finalForm);
|
||||||
|
const flowDataItem = head(data.data.flowData.filter(o => !isEmpty(o.chosenField)));
|
||||||
|
|
||||||
|
if (flowDataItem) {
|
||||||
|
setMainField(flowDataItem.chosenField);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
storeSet.main.unsetAsyncRequest();
|
storeSet.main.unsetAsyncRequest();
|
||||||
}
|
}
|
||||||
@@ -143,6 +155,66 @@ const BandoFlowEdit = () => {
|
|||||||
storeSet.main.unsetAsyncRequest();
|
storeSet.main.unsetAsyncRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const flowForms = storeGet.main.flowForms();
|
||||||
|
const form = head(flowForms.filter(o => String(o.id) === String(initialForm)))
|
||||||
|
const field = form ? head(form.content.filter(o => o.id === mainField)) : null;
|
||||||
|
let options = [];
|
||||||
|
|
||||||
|
if (field) {
|
||||||
|
options = head(field.settings.filter(o => o.name === 'options'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (field && options.value && options.value.length === flowForms.length - 2) {
|
||||||
|
setIsFlowAllowed(true);
|
||||||
|
} else {
|
||||||
|
setIsFlowAllowed(false);
|
||||||
|
let msg = 'Non è possibile creare il flusso. Il campo principale deve avere esattamente %s opzioni.';
|
||||||
|
|
||||||
|
if (flowForms.length - 2 === 1) {
|
||||||
|
msg = 'Non è possibile creare il flusso. Il campo principale deve avere esattamente %s opzione.';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flowMsgs.current && !isEmpty(mainField)) {
|
||||||
|
flowMsgs.current.clear();
|
||||||
|
flowMsgs.current.show([
|
||||||
|
{
|
||||||
|
id: '1',
|
||||||
|
sticky: true, severity: 'error', summary: '',
|
||||||
|
detail: sprintf(
|
||||||
|
__(msg, 'gepafin'),
|
||||||
|
flowForms.length - 2
|
||||||
|
),
|
||||||
|
closable: false
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [mainField]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setMainField('');
|
||||||
|
setMainFieldOptions([]);
|
||||||
|
const flowForms = storeGet.main.flowForms();
|
||||||
|
const form = head(flowForms.filter(o => String(o.id) === String(initialForm)))
|
||||||
|
const relevantFields = form
|
||||||
|
? form.content
|
||||||
|
.filter(o => ['radio', 'select'].includes(o.name))
|
||||||
|
.map(o => {
|
||||||
|
const label = head(o.settings.filter(o => o.name === 'label'));
|
||||||
|
return { value: o.id, label: label ? label.value : o.label };
|
||||||
|
})
|
||||||
|
: [];
|
||||||
|
setMainFieldOptions([
|
||||||
|
{label: isEmpty(relevantFields) ? __('Nessun scelta', 'gepafin') : '', value: ''},
|
||||||
|
...relevantFields]
|
||||||
|
);
|
||||||
|
|
||||||
|
if (flowForms.length === 2) {
|
||||||
|
setIsFlowAllowed(true)
|
||||||
|
}
|
||||||
|
}, [initialForm]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const bandoId = getBandoId();
|
const bandoId = getBandoId();
|
||||||
storeSet.main.setAsyncRequest();
|
storeSet.main.setAsyncRequest();
|
||||||
@@ -161,6 +233,8 @@ const BandoFlowEdit = () => {
|
|||||||
closable: false
|
closable: false
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
|
} else {
|
||||||
|
flowMsgs.current.clear();
|
||||||
}
|
}
|
||||||
}, [forms]);
|
}, [forms]);
|
||||||
|
|
||||||
@@ -170,7 +244,7 @@ const BandoFlowEdit = () => {
|
|||||||
storeSet.main.flowData([]);
|
storeSet.main.flowData([]);
|
||||||
storeSet.main.flowEdges([]);
|
storeSet.main.flowEdges([]);
|
||||||
}
|
}
|
||||||
}, [])
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="appPage">
|
<div className="appPage">
|
||||||
@@ -184,28 +258,42 @@ const BandoFlowEdit = () => {
|
|||||||
<div className="appPage__spacer"></div>
|
<div className="appPage__spacer"></div>
|
||||||
|
|
||||||
<div className="appPageSection">
|
<div className="appPageSection">
|
||||||
<div className="row">
|
<div className="appForm__cols">
|
||||||
<div className="appForm__field">
|
<div className="appForm__field">
|
||||||
<label htmlFor="initialForm">{__('Scegli form iniziale', 'gepafin')}</label>
|
<label htmlFor="initialForm">{__('Scegli form iniziale', 'gepafin')}</label>
|
||||||
<Dropdown
|
<Dropdown
|
||||||
id="initialForm"
|
id="initialForm"
|
||||||
value={initialForm}
|
value={initialForm}
|
||||||
onChange={(e) => updateInitialForm(e.value)}
|
onChange={(e) => updateInitialForm(e.value)}
|
||||||
optionDisabled={(opt) => finalForm === opt.value}
|
optionDisabled={(opt) => finalForm === opt.value || isEmpty(opt.value)}
|
||||||
options={formOptions}
|
options={formOptions}
|
||||||
optionLabel="label"
|
optionLabel="label"
|
||||||
optionValue="value"
|
optionValue="value"
|
||||||
placeholder={__('Scegli il form', 'gepafin')}/>
|
placeholder={__('Scegli il form', 'gepafin')}/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{forms.length > 2
|
{forms.length > 2 && initialForm && mainFieldOptions
|
||||||
|
? <div className="appForm__field">
|
||||||
|
<label htmlFor="mainField">{__('Scegli il campo principale', 'gepafin')}</label>
|
||||||
|
<Dropdown
|
||||||
|
id="mainField"
|
||||||
|
value={mainField}
|
||||||
|
onChange={(e) => setMainField(e.value)}
|
||||||
|
optionDisabled={(opt) => isEmpty(opt.value)}
|
||||||
|
options={mainFieldOptions}
|
||||||
|
optionLabel="label"
|
||||||
|
optionValue="value"
|
||||||
|
placeholder={__('Scegli il campo', 'gepafin')}/>
|
||||||
|
</div> : null}
|
||||||
|
|
||||||
|
{forms.length > 2 && mainField && isFlowAllowed || forms.length === 2 && isFlowAllowed
|
||||||
? <div className="appForm__field">
|
? <div className="appForm__field">
|
||||||
<label htmlFor="finalForm">{__('Scegli form finale', 'gepafin')}</label>
|
<label htmlFor="finalForm">{__('Scegli form finale', 'gepafin')}</label>
|
||||||
<Dropdown
|
<Dropdown
|
||||||
id="finalForm"
|
id="finalForm"
|
||||||
value={finalForm}
|
value={finalForm}
|
||||||
onChange={(e) => setFinalForm(e.value)}
|
onChange={(e) => setFinalForm(e.value)}
|
||||||
optionDisabled={(opt) => initialForm === opt.value}
|
optionDisabled={(opt) => initialForm === opt.value || isEmpty(opt.value)}
|
||||||
options={formOptions}
|
options={formOptions}
|
||||||
optionLabel="label"
|
optionLabel="label"
|
||||||
optionValue="value"
|
optionValue="value"
|
||||||
@@ -217,13 +305,14 @@ const BandoFlowEdit = () => {
|
|||||||
<div className="appPage__spacer"></div>
|
<div className="appPage__spacer"></div>
|
||||||
|
|
||||||
<div className="appPageSection">
|
<div className="appPageSection">
|
||||||
{forms.length >= 2
|
<Messages ref={flowMsgs}/>
|
||||||
? <FlowBuilder initialForm={initialForm} finalForm={finalForm}/>
|
{forms.length >= 2 && isFlowAllowed
|
||||||
: <Messages ref={flowMsgs}/>}
|
? <FlowBuilder initialForm={initialForm} finalForm={finalForm} mainField={mainField}/> : null}
|
||||||
</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">
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -24,26 +24,26 @@ const BandoForms = () => {
|
|||||||
const [forms, setForms] = useState([]);
|
const [forms, setForms] = useState([]);
|
||||||
|
|
||||||
const doCreateNewForm = () => {
|
const doCreateNewForm = () => {
|
||||||
navigate(`/tenders/${id}/forms/new`);
|
navigate(`/bandi/${id}/forms/new`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const goToEditBando = () => {
|
const goToEditBando = () => {
|
||||||
navigate(`/tenders/${id}`);
|
navigate(`/bandi/${id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const openBandoFlowManagement = () => {
|
const openBandoFlowManagement = () => {
|
||||||
navigate(`/tenders/${id}/flow`);
|
navigate(`/bandi/${id}/flow`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const goToEditForm = () => {
|
const goToEditForm = () => {
|
||||||
if (selectedForm && selectedForm !== 0) {
|
if (selectedForm && selectedForm !== 0) {
|
||||||
navigate(`/tenders/${id}/forms/${selectedForm}`);
|
navigate(`/bandi/${id}/forms/${selectedForm}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const goToEditFormFromTemplate = () => {
|
const goToEditFormFromTemplate = () => {
|
||||||
console.log('goToEditFormFromTemplate', selectedTemplate)
|
console.log('goToEditFormFromTemplate', selectedTemplate)
|
||||||
//navigate(`/tenders/${id}`);
|
//navigate(`/bandi/${id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const getFormsCallback = (data) => {
|
const getFormsCallback = (data) => {
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ import { __ } from '@wordpress/i18n';
|
|||||||
// components
|
// components
|
||||||
import ElementSettingRepeater from '../ElementSettingRepeater';
|
import ElementSettingRepeater from '../ElementSettingRepeater';
|
||||||
import { InputText } from 'primereact/inputtext';
|
import { InputText } from 'primereact/inputtext';
|
||||||
|
import { MultiSelect } from 'primereact/multiselect';
|
||||||
|
|
||||||
|
import { mimeTypes } from '../../../../../../configData';
|
||||||
|
|
||||||
const ElementSetting = ({ setting, changeFn, updateDataFn }) => {
|
const ElementSetting = ({ setting, changeFn, updateDataFn }) => {
|
||||||
|
|
||||||
@@ -19,7 +22,15 @@ const ElementSetting = ({ setting, changeFn, updateDataFn }) => {
|
|||||||
<label htmlFor={setting.name}>{settingLabels[setting.name]}</label>
|
<label htmlFor={setting.name}>{settingLabels[setting.name]}</label>
|
||||||
{setting.name === 'options'
|
{setting.name === 'options'
|
||||||
? <ElementSettingRepeater value={setting.value} name={setting.name} setDataFn={updateDataFn}/>
|
? <ElementSettingRepeater value={setting.value} name={setting.name} setDataFn={updateDataFn}/>
|
||||||
: <InputText id={setting.name} aria-describedby={`${setting.name}-help`}
|
: setting.name === 'mime'
|
||||||
|
? <MultiSelect
|
||||||
|
value={setting.value}
|
||||||
|
onChange={(e) => updateDataFn(setting.name, e.value)}
|
||||||
|
options={mimeTypes}
|
||||||
|
optionLabel="name"
|
||||||
|
display="chip"
|
||||||
|
placeholder={__('Scegli', 'gepafin')} />
|
||||||
|
: <InputText id={setting.name} aria-describedby={`${setting.name}-help`}
|
||||||
value={setting.value}
|
value={setting.value}
|
||||||
onChange={(e) => changeFn(e.target.value, setting.name)}/>}
|
onChange={(e) => changeFn(e.target.value, setting.name)}/>}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ const ElementSettingRepeater = ({
|
|||||||
<Button icon="pi pi-times" className="p-button-danger" onClick={() => removeItem(i)}/>
|
<Button icon="pi pi-times" className="p-button-danger" onClick={() => removeItem(i)}/>
|
||||||
</div>
|
</div>
|
||||||
</div>)}
|
</div>)}
|
||||||
<Button type="button" label={__('Aggiungi', 'gepafin')} onClick={addNewItem}/>
|
<Button type="button" outlined label={__('Aggiungi', 'gepafin')} onClick={addNewItem}/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { head, 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';
|
||||||
|
|
||||||
@@ -13,6 +13,7 @@ import { Tag } from 'primereact/tag';
|
|||||||
import { TabView, TabPanel } from 'primereact/tabview';
|
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';
|
||||||
|
|
||||||
const BuilderElementSettings = ({ closeSettings }) => {
|
const BuilderElementSettings = ({ closeSettings }) => {
|
||||||
const elements = useStore().main.formElements();
|
const elements = useStore().main.formElements();
|
||||||
@@ -20,7 +21,17 @@ const BuilderElementSettings = ({ closeSettings }) => {
|
|||||||
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 textBasedValidatorFields = ['min', 'max', 'minLength', 'maxLength', 'pattern', 'custom'];
|
const textBasedValidatorFields = ['min', 'max', 'minLength', 'maxLength', 'pattern'];
|
||||||
|
const customValidationOptions = [
|
||||||
|
{value: 'isPIVA', label: 'isPIVA'},
|
||||||
|
{value: 'isCodiceFiscale', label: 'isCodiceFiscale'},
|
||||||
|
{value: 'isCAP', label: 'isCAP'},
|
||||||
|
{value: 'isIBAN', label: 'isIBAN'},
|
||||||
|
{value: 'isEmail', label: 'isEmail'},
|
||||||
|
{value: 'isEmailPEC', label: 'isEmailPEC'},
|
||||||
|
{value: 'isUrl', label: 'isUrl'},
|
||||||
|
{value: 'isMarcaDaBollo', label: 'isMarcaDaBollo'}
|
||||||
|
]
|
||||||
|
|
||||||
const onChange = (value, name) => {
|
const onChange = (value, name) => {
|
||||||
const newSettings = settings
|
const newSettings = settings
|
||||||
@@ -89,7 +100,7 @@ const BuilderElementSettings = ({ closeSettings }) => {
|
|||||||
setSettings([]);
|
setSettings([]);
|
||||||
setValidators({})
|
setValidators({})
|
||||||
}
|
}
|
||||||
}, [activeElement])
|
}, [activeElement]);
|
||||||
|
|
||||||
return (activeElementData
|
return (activeElementData
|
||||||
? <div className="formElementSettings">
|
? <div className="formElementSettings">
|
||||||
@@ -110,13 +121,13 @@ const BuilderElementSettings = ({ closeSettings }) => {
|
|||||||
className="formElementSettings__field" key={k}>
|
className="formElementSettings__field" key={k}>
|
||||||
{k === 'isRequired'
|
{k === 'isRequired'
|
||||||
? <div className="formElementSettings__field">
|
? <div className="formElementSettings__field">
|
||||||
<label htmlFor={k}>{__('Required?', 'gepafin')}</label>
|
<label htmlFor={k}>{__('Obligatorio?', 'gepafin')}</label>
|
||||||
<InputSwitch
|
<InputSwitch
|
||||||
checked={validators[k]}
|
checked={validators[k]}
|
||||||
onChange={(e) => toggleRequired(e.value, k)}/>
|
onChange={(e) => toggleRequired(e.value, k)}/>
|
||||||
</div>
|
</div>
|
||||||
: null}
|
: null}
|
||||||
{textBasedValidatorFields.includes(k)
|
{textBasedValidatorFields.includes(k) || 'custom' === k
|
||||||
? <div className="formElementSettings__field">
|
? <div className="formElementSettings__field">
|
||||||
<label htmlFor={`enable_${k}`}>{sprintf(__('Set %s', 'gepafin'), k)}</label>
|
<label htmlFor={`enable_${k}`}>{sprintf(__('Set %s', 'gepafin'), k)}</label>
|
||||||
<InputSwitch
|
<InputSwitch
|
||||||
@@ -124,6 +135,19 @@ const BuilderElementSettings = ({ closeSettings }) => {
|
|||||||
onChange={(e) => showField(e.value, k)}/>
|
onChange={(e) => showField(e.value, k)}/>
|
||||||
</div>
|
</div>
|
||||||
: null}
|
: null}
|
||||||
|
{k === 'custom' && !isNil(validators[k])
|
||||||
|
? <div className="formElementSettings__field">
|
||||||
|
<label htmlFor={k}>{__('Personalizzato', 'gepafin')}</label>
|
||||||
|
<Dropdown
|
||||||
|
id={`enable_${k}`}
|
||||||
|
value={validators[k]}
|
||||||
|
onChange={(e) => onChangeValidator(e.value, k)}
|
||||||
|
options={customValidationOptions}
|
||||||
|
optionLabel="label"
|
||||||
|
optionValue="value"
|
||||||
|
placeholder={__('Scegli', 'gepafin')}/>
|
||||||
|
</div>
|
||||||
|
: null}
|
||||||
{textBasedValidatorFields.includes(k) && !isNil(validators[k])
|
{textBasedValidatorFields.includes(k) && !isNil(validators[k])
|
||||||
? <div className="formElementSettings__field">
|
? <div className="formElementSettings__field">
|
||||||
<label htmlFor={k}>{k}</label>
|
<label htmlFor={k}>{k}</label>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useCallback } from 'react'
|
import React, { useCallback, useEffect } from 'react'
|
||||||
import { __ } from '@wordpress/i18n';
|
import { __ } from '@wordpress/i18n';
|
||||||
import { isEmpty } from 'ramda';
|
import { isEmpty } from 'ramda';
|
||||||
|
|
||||||
@@ -47,6 +47,12 @@ const FormBuilder = () => {
|
|||||||
storeSet.main.activeElement('');
|
storeSet.main.activeElement('');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
return () => {
|
||||||
|
storeSet.main.activeElement('');
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Sidebar visible={!isEmpty(activeElement)} onHide={closeSettings} className="formBuilder__elementSettings">
|
<Sidebar visible={!isEmpty(activeElement)} onHide={closeSettings} className="formBuilder__elementSettings">
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState, useRef } from 'react';
|
||||||
import { __ } from '@wordpress/i18n';
|
import { __ } from '@wordpress/i18n';
|
||||||
import { useNavigate, useParams } from 'react-router-dom';
|
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';
|
||||||
|
|
||||||
// store
|
// store
|
||||||
import { storeSet, storeGet, useStore } from '../../store';
|
import { storeSet, storeGet, useStore } from '../../store';
|
||||||
@@ -13,17 +14,23 @@ import FormBuilder from './components/FormBuilder';
|
|||||||
import { Button } from 'primereact/button';
|
import { Button } from 'primereact/button';
|
||||||
import { ConfirmPopup, confirmPopup } from 'primereact/confirmpopup';
|
import { ConfirmPopup, confirmPopup } from 'primereact/confirmpopup';
|
||||||
import { InputText } from 'primereact/inputtext';
|
import { InputText } from 'primereact/inputtext';
|
||||||
|
import { Toast } from 'primereact/toast';
|
||||||
|
import { ConfirmDialog } from 'primereact/confirmdialog';
|
||||||
|
|
||||||
// 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 { elementItems } from '../../tempData';
|
import { elementItems } from '../../tempData';
|
||||||
|
import { Messages } from 'primereact/messages';
|
||||||
|
|
||||||
const BandoFormsEdit = () => {
|
const BandoFormsEdit = () => {
|
||||||
const { id, formId } = useParams();
|
const { id, formId } = useParams();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [formName, setFormName] = useState('');
|
const [formName, setFormName] = useState('');
|
||||||
|
const [visibleConfirmation, setVisibleConfirmation] = useState(false);
|
||||||
const isAsyncRequest = useStore().main.isAsyncRequest();
|
const isAsyncRequest = useStore().main.isAsyncRequest();
|
||||||
|
const formMsgs = useRef(null);
|
||||||
|
const toast = useRef(null);
|
||||||
|
|
||||||
const getBandoId = () => {
|
const getBandoId = () => {
|
||||||
const parsed = parseInt(id)
|
const parsed = parseInt(id)
|
||||||
@@ -32,13 +39,46 @@ const BandoFormsEdit = () => {
|
|||||||
|
|
||||||
const goBack = () => {
|
const goBack = () => {
|
||||||
const bandoId = getBandoId();
|
const bandoId = getBandoId();
|
||||||
navigate(`/tenders/${bandoId}/forms`);
|
navigate(`/bandi/${bandoId}/forms`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const doSave = (shouldRedirect = false) => {
|
const doSave = (shouldRedirect = false) => {
|
||||||
|
if (formMsgs.current) {
|
||||||
|
formMsgs.current.clear();
|
||||||
|
}
|
||||||
|
|
||||||
const content = storeGet.main.formElements();
|
const content = storeGet.main.formElements();
|
||||||
|
|
||||||
|
if (isEmpty(formName) || isEmpty(content)) {
|
||||||
|
if (isEmpty(formName)) {
|
||||||
|
if (formMsgs.current) {
|
||||||
|
formMsgs.current.show([
|
||||||
|
{
|
||||||
|
id: '99',
|
||||||
|
sticky: true, severity: 'error', summary: '',
|
||||||
|
detail: __('Nome di form è obligatorio.', 'gepafin'),
|
||||||
|
closable: true
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isEmpty(content)) {
|
||||||
|
if (formMsgs.current) {
|
||||||
|
formMsgs.current.show([
|
||||||
|
{
|
||||||
|
id: '99',
|
||||||
|
sticky: true, severity: 'error', summary: '',
|
||||||
|
detail: __('Devi aggiungere almeno uno campo.', 'gepafin'),
|
||||||
|
closable: true
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const bandoId = getBandoId();
|
const bandoId = getBandoId();
|
||||||
const parsedFormId = parseInt(formId)
|
const parsedFormId = parseInt(formId);
|
||||||
const bandoFormId = !isNaN(parsedFormId) ? parsedFormId : 0;
|
const bandoFormId = !isNaN(parsedFormId) ? parsedFormId : 0;
|
||||||
const formData = {
|
const formData = {
|
||||||
label: formName,
|
label: formName,
|
||||||
@@ -47,9 +87,20 @@ const BandoFormsEdit = () => {
|
|||||||
|
|
||||||
storeSet.main.setAsyncRequest();
|
storeSet.main.setAsyncRequest();
|
||||||
if (bandoFormId === 0) {
|
if (bandoFormId === 0) {
|
||||||
FormsService.createFormForCall(bandoId, formData, (data) => formCreateCallback(data, shouldRedirect), errFormCreateCallback);
|
FormsService.createFormForCall(
|
||||||
|
bandoId,
|
||||||
|
formData,
|
||||||
|
(data) => formCreateCallback(data, shouldRedirect),
|
||||||
|
errFormCreateCallback
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
FormsService.updateForm(bandoFormId, formData, (data) => formCreateCallback(data, shouldRedirect), errFormCreateCallback);
|
FormsService.updateForm(
|
||||||
|
bandoFormId,
|
||||||
|
formData,
|
||||||
|
(data) => formCreateCallback(data, shouldRedirect),
|
||||||
|
errFormCreateCallback,
|
||||||
|
[['forceDeleteFlow', false]]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,18 +109,59 @@ const BandoFormsEdit = () => {
|
|||||||
storeSet.main.unsetAsyncRequest();
|
storeSet.main.unsetAsyncRequest();
|
||||||
const bandoId = getBandoId();
|
const bandoId = getBandoId();
|
||||||
if (shouldRedirect) {
|
if (shouldRedirect) {
|
||||||
navigate(`/tenders/${bandoId}/forms/${data.data.id}/preview`);
|
navigate(`/bandi/${bandoId}/forms/${data.data.id}/preview`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (data.data.id) {
|
if (data.data.id) {
|
||||||
navigate(`/tenders/${bandoId}/forms/${data.data.id}`);
|
navigate(`/bandi/${bandoId}/forms/${data.data.id}`);
|
||||||
|
}
|
||||||
|
if (toast.current) {
|
||||||
|
toast.current.show({
|
||||||
|
severity: 'success',
|
||||||
|
summary: '',
|
||||||
|
detail: __('Il form è stato aggiornato corretamente!', 'gepafin')
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const errFormCreateCallback = (data) => {
|
const errFormCreateCallback = (data) => {
|
||||||
console.log('errFormCreateCallback', data)
|
|
||||||
storeSet.main.unsetAsyncRequest();
|
storeSet.main.unsetAsyncRequest();
|
||||||
|
if (data.status === 'BAD_REQUEST') {
|
||||||
|
setVisibleConfirmation(true);
|
||||||
|
} else {
|
||||||
|
if (toast.current) {
|
||||||
|
toast.current.show({
|
||||||
|
severity: 'error',
|
||||||
|
summary: '',
|
||||||
|
detail: data.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const acceptModification = () => {
|
||||||
|
const content = storeGet.main.formElements();
|
||||||
|
const parsedFormId = parseInt(formId);
|
||||||
|
const bandoFormId = !isNaN(parsedFormId) ? parsedFormId : 0;
|
||||||
|
const formData = {
|
||||||
|
label: formName,
|
||||||
|
content
|
||||||
|
}
|
||||||
|
|
||||||
|
storeSet.main.setAsyncRequest();
|
||||||
|
|
||||||
|
FormsService.updateForm(
|
||||||
|
bandoFormId,
|
||||||
|
formData,
|
||||||
|
(data) => formCreateCallback(data, false),
|
||||||
|
errFormCreateCallback,
|
||||||
|
[['forceDeleteFlow', true]]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const rejectModification = () => {
|
||||||
|
setVisibleConfirmation(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
const openPreview = () => {
|
const openPreview = () => {
|
||||||
@@ -101,7 +193,7 @@ const BandoFormsEdit = () => {
|
|||||||
const formDeleteCallback = (data) => {
|
const formDeleteCallback = (data) => {
|
||||||
if (data.status === 'SUCCESS') {
|
if (data.status === 'SUCCESS') {
|
||||||
const bandoId = getBandoId();
|
const bandoId = getBandoId();
|
||||||
navigate(`/tenders/${bandoId}/forms`);
|
navigate(`/bandi/${bandoId}/forms`);
|
||||||
}
|
}
|
||||||
storeSet.main.unsetAsyncRequest();
|
storeSet.main.unsetAsyncRequest();
|
||||||
}
|
}
|
||||||
@@ -170,6 +262,19 @@ const BandoFormsEdit = () => {
|
|||||||
|
|
||||||
<div className="appPage__spacer"></div>
|
<div className="appPage__spacer"></div>
|
||||||
|
|
||||||
|
<Messages ref={formMsgs}/>
|
||||||
|
<ConfirmDialog
|
||||||
|
group="declarative"
|
||||||
|
visible={visibleConfirmation}
|
||||||
|
onHide={() => setVisibleConfirmation(false)}
|
||||||
|
message={__('Le modifiche al modulo influiscono sul flusso precedentemente creato, quindi deve essere ricreato. Confermi le modifiche?', 'gepafin')}
|
||||||
|
header={__('Conferma le modifiche', 'gepafin')}
|
||||||
|
icon="pi pi-exclamation-triangle"
|
||||||
|
accept={acceptModification}
|
||||||
|
acceptLabel={__('Si', 'gepafin')}
|
||||||
|
reject={rejectModification}
|
||||||
|
style={{ maxWidth: '500px' }} />
|
||||||
|
|
||||||
<div className="appForm__field">
|
<div className="appForm__field">
|
||||||
<label htmlFor="label">{__('Assegna un nome a questo form', 'gepafin')}</label>
|
<label htmlFor="label">{__('Assegna un nome a questo form', 'gepafin')}</label>
|
||||||
<InputText
|
<InputText
|
||||||
@@ -190,6 +295,7 @@ const BandoFormsEdit = () => {
|
|||||||
|
|
||||||
<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">
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -17,6 +17,18 @@ import { Button } from 'primereact/button';
|
|||||||
import FormField from '../../components/FormField';
|
import FormField from '../../components/FormField';
|
||||||
import set404FromErrorResponse from '../../helpers/set404FromErrorResponse';
|
import set404FromErrorResponse from '../../helpers/set404FromErrorResponse';
|
||||||
|
|
||||||
|
// tools
|
||||||
|
import {
|
||||||
|
isCAP,
|
||||||
|
isCodiceFiscale,
|
||||||
|
isEmail,
|
||||||
|
isEmailPEC,
|
||||||
|
isIBAN,
|
||||||
|
isMarcaDaBollo,
|
||||||
|
isPIVA,
|
||||||
|
isUrl
|
||||||
|
} from '../../helpers/validators';
|
||||||
|
|
||||||
const BandoFormsPreview = () => {
|
const BandoFormsPreview = () => {
|
||||||
const { id, formId } = useParams();
|
const { id, formId } = useParams();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@@ -28,8 +40,20 @@ const BandoFormsPreview = () => {
|
|||||||
handleSubmit,
|
handleSubmit,
|
||||||
formState: { errors },
|
formState: { errors },
|
||||||
getValues,
|
getValues,
|
||||||
|
register,
|
||||||
|
setValue
|
||||||
} = useForm({ defaultValues: {}, mode: 'onChange' });
|
} = useForm({ defaultValues: {}, mode: 'onChange' });
|
||||||
const values = getValues();
|
const values = getValues();
|
||||||
|
const validationFns = {
|
||||||
|
isPIVA,
|
||||||
|
isCodiceFiscale,
|
||||||
|
isCAP,
|
||||||
|
isIBAN,
|
||||||
|
isEmail,
|
||||||
|
isEmailPEC,
|
||||||
|
isUrl,
|
||||||
|
isMarcaDaBollo
|
||||||
|
}
|
||||||
|
|
||||||
const onSubmit = () => {}
|
const onSubmit = () => {}
|
||||||
|
|
||||||
@@ -38,7 +62,7 @@ const BandoFormsPreview = () => {
|
|||||||
const bandoId = !isNaN(parsedId) ? parsedId : 0;
|
const bandoId = !isNaN(parsedId) ? parsedId : 0;
|
||||||
const parsedFormId = parseInt(formId)
|
const parsedFormId = parseInt(formId)
|
||||||
const bandoFormId = !isNaN(parsedFormId) ? parsedFormId : 0;
|
const bandoFormId = !isNaN(parsedFormId) ? parsedFormId : 0;
|
||||||
navigate(`/tenders/${bandoId}/forms/${bandoFormId}`);
|
navigate(`/bandi/${bandoId}/forms/${bandoFormId}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const getFormCallback = (data) => {
|
const getFormCallback = (data) => {
|
||||||
@@ -94,17 +118,49 @@ const BandoFormsPreview = () => {
|
|||||||
const label = head(o.settings.filter(o => o.name === 'label'));
|
const label = head(o.settings.filter(o => o.name === 'label'));
|
||||||
const placeholder = head(o.settings.filter(o => o.name === 'placeholder'));
|
const placeholder = head(o.settings.filter(o => o.name === 'placeholder'));
|
||||||
const options = head(o.settings.filter(o => o.name === 'options'));
|
const options = head(o.settings.filter(o => o.name === 'options'));
|
||||||
|
const step = head(o.settings.filter(o => o.name === 'step'));
|
||||||
|
const mime = head(o.settings.filter(o => o.name === 'mime'));
|
||||||
|
let mimeValue = '';
|
||||||
|
|
||||||
|
if (mime) {
|
||||||
|
mimeValue = mime.value.map(o => o.code).join(',');
|
||||||
|
}
|
||||||
|
|
||||||
|
const validations = Object.keys(o.validators).reduce((acc, cur) => {
|
||||||
|
if (o.validators[cur]) {
|
||||||
|
if (['min', 'max', 'minLength', 'maxLength', 'maxSize'].includes(cur)) {
|
||||||
|
acc[cur] = parseInt(o.validators[cur]);
|
||||||
|
} else if ('pattern' === cur) {
|
||||||
|
acc[cur] = new RegExp(o.validators[cur])
|
||||||
|
} else if ('isRequired' === cur) {
|
||||||
|
acc[cur] = o.validators[cur]
|
||||||
|
} else if ('custom' === cur && validationFns[o.validators[cur]]) {
|
||||||
|
if (!acc.validate) {
|
||||||
|
acc.validate = {}
|
||||||
|
}
|
||||||
|
acc.validate[cur] = validationFns[o.validators[cur]]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
|
||||||
return <FormField
|
return <FormField
|
||||||
key={o.id}
|
key={o.id}
|
||||||
type={o.name}
|
type={o.name}
|
||||||
fieldName={`field_${o.id}`}
|
fieldName={o.id}
|
||||||
label={label ? label.value : ''}
|
label={label ? label.value : ''}
|
||||||
placeholder={placeholder ? placeholder.value : ''}
|
placeholder={placeholder ? placeholder.value : ''}
|
||||||
control={control}
|
control={control}
|
||||||
|
register={register}
|
||||||
errors={errors}
|
errors={errors}
|
||||||
defaultValue={values[`field_${o.id}`]}
|
defaultValue={values[o.id]}
|
||||||
config={o.validators}
|
maxFractionDigits={step}
|
||||||
|
accept={mimeValue}
|
||||||
|
config={validations}
|
||||||
options={options ? options.value : []}
|
options={options ? options.value : []}
|
||||||
|
setDataFn={setValue}
|
||||||
|
sourceId={0}
|
||||||
/>
|
/>
|
||||||
})}
|
})}
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import { Button } from 'primereact/button';
|
|||||||
import BandoService from '../../service/bando-service';
|
import BandoService from '../../service/bando-service';
|
||||||
import { Messages } from 'primereact/messages';
|
import { Messages } from 'primereact/messages';
|
||||||
import set404FromErrorResponse from '../../helpers/set404FromErrorResponse';
|
import set404FromErrorResponse from '../../helpers/set404FromErrorResponse';
|
||||||
|
import renderHtmlContent from '../../helpers/renderHtmlContent';
|
||||||
|
|
||||||
const BandoView = () => {
|
const BandoView = () => {
|
||||||
const isAsyncRequest = useStore().main.isAsyncRequest();
|
const isAsyncRequest = useStore().main.isAsyncRequest();
|
||||||
@@ -29,7 +30,7 @@ const BandoView = () => {
|
|||||||
const bandoMsgs = useRef(null);
|
const bandoMsgs = useRef(null);
|
||||||
|
|
||||||
const closePreview = () => {
|
const closePreview = () => {
|
||||||
navigate(`/tenders/${id}`);
|
navigate(`/bandi/${id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const getCallback = (data) => {
|
const getCallback = (data) => {
|
||||||
@@ -102,7 +103,7 @@ const BandoView = () => {
|
|||||||
<div className="appPageSection__withBorder">
|
<div className="appPageSection__withBorder">
|
||||||
<h2>{__('Descrizione breve', 'gepafin')}</h2>
|
<h2>{__('Descrizione breve', 'gepafin')}</h2>
|
||||||
<div className="row rowContent">
|
<div className="row rowContent">
|
||||||
<p>{data.descriptionShort}</p>
|
{renderHtmlContent(data.descriptionShort)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -133,7 +134,7 @@ const BandoView = () => {
|
|||||||
<div className="appPageSection__withBorder">
|
<div className="appPageSection__withBorder">
|
||||||
<h2>{__('Descrizione dettagliata', 'gepafin')}</h2>
|
<h2>{__('Descrizione dettagliata', 'gepafin')}</h2>
|
||||||
<div className="row rowContent">
|
<div className="row rowContent">
|
||||||
<p>{data.descriptionLong}</p>
|
{renderHtmlContent(data.descriptionLong)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -196,6 +197,7 @@ const BandoView = () => {
|
|||||||
<label htmlFor="newQuestion">{__('Fai una domanda', 'gepafin')}</label>
|
<label htmlFor="newQuestion">{__('Fai una domanda', 'gepafin')}</label>
|
||||||
<InputTextarea
|
<InputTextarea
|
||||||
id="newQuestion"
|
id="newQuestion"
|
||||||
|
disabled
|
||||||
rows={7}
|
rows={7}
|
||||||
value={newQuestion}
|
value={newQuestion}
|
||||||
placeholder={__('Digita qui la tua domanda', 'gepafin')}
|
placeholder={__('Digita qui la tua domanda', 'gepafin')}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import { Messages } from 'primereact/messages';
|
|||||||
import set404FromErrorResponse from '../../helpers/set404FromErrorResponse';
|
import set404FromErrorResponse from '../../helpers/set404FromErrorResponse';
|
||||||
import FaqItemService from '../../service/faq-item-service';
|
import FaqItemService from '../../service/faq-item-service';
|
||||||
import ApplicationService from '../../service/application-service';
|
import ApplicationService from '../../service/application-service';
|
||||||
|
import renderHtmlContent from '../../helpers/renderHtmlContent';
|
||||||
|
|
||||||
const BandoViewBeneficiario = () => {
|
const BandoViewBeneficiario = () => {
|
||||||
const isAsyncRequest = useStore().main.isAsyncRequest();
|
const isAsyncRequest = useStore().main.isAsyncRequest();
|
||||||
@@ -28,7 +29,7 @@ const BandoViewBeneficiario = () => {
|
|||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [data, setData] = useState({});
|
const [data, setData] = useState({});
|
||||||
const [newQuestion, setNewQuestion] = useState('');
|
const [newQuestion, setNewQuestion] = useState('');
|
||||||
const [isApplRequest, setIsApplRequest] = useState(true);
|
const [applicationObj, setApplicationObj] = useState(true);
|
||||||
const bandoMsgs = useRef(null);
|
const bandoMsgs = useRef(null);
|
||||||
|
|
||||||
const scaricaBando = () => {
|
const scaricaBando = () => {
|
||||||
@@ -39,8 +40,38 @@ const BandoViewBeneficiario = () => {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getBandoId = () => {
|
||||||
|
const parsed = parseInt(id)
|
||||||
|
return !isNaN(parsed) ? parsed : 0;
|
||||||
|
}
|
||||||
|
|
||||||
const submitApplication = () => {
|
const submitApplication = () => {
|
||||||
navigate(`/tenders/${id}/application`);
|
if (applicationObj && applicationObj.id) {
|
||||||
|
navigate(`/imieibandi/${applicationObj.id}`);
|
||||||
|
} else {
|
||||||
|
const bandoId = getBandoId();
|
||||||
|
ApplicationService.createApplication(bandoId, {}, createApplCallback, errCreateApplCallback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const createApplCallback = (data) => {
|
||||||
|
storeSet.main.unsetAsyncRequest();
|
||||||
|
if (data.status === 'SUCCESS') {
|
||||||
|
navigate(`/imieibandi/${data.data.id}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const errCreateApplCallback = (data) => {
|
||||||
|
if (bandoMsgs.current && data.message) {
|
||||||
|
bandoMsgs.current.show([
|
||||||
|
{
|
||||||
|
sticky: true, severity: 'error', summary: '',
|
||||||
|
detail: data.message,
|
||||||
|
closable: true
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
storeSet.main.unsetAsyncRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
const saveToFavourites = () => {
|
const saveToFavourites = () => {
|
||||||
@@ -102,7 +133,6 @@ const BandoViewBeneficiario = () => {
|
|||||||
if (data.status === 'SUCCESS') {
|
if (data.status === 'SUCCESS') {
|
||||||
setData(getFormattedBandiData(data.data));
|
setData(getFormattedBandiData(data.data));
|
||||||
}
|
}
|
||||||
storeSet.main.unsetAsyncRequest();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const errGetBandoCallback = (data) => {
|
const errGetBandoCallback = (data) => {
|
||||||
@@ -116,7 +146,6 @@ const BandoViewBeneficiario = () => {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
set404FromErrorResponse(data);
|
set404FromErrorResponse(data);
|
||||||
storeSet.main.unsetAsyncRequest();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const getFormattedBandiData = (data) => {
|
const getFormattedBandiData = (data) => {
|
||||||
@@ -126,31 +155,23 @@ const BandoViewBeneficiario = () => {
|
|||||||
|
|
||||||
const getApplCallback = (data) => {
|
const getApplCallback = (data) => {
|
||||||
if (data.status === 'SUCCESS') {
|
if (data.status === 'SUCCESS') {
|
||||||
console.log(data.data)
|
if(data.data.length) {
|
||||||
|
setApplicationObj(data.data[0]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
storeSet.main.unsetAsyncRequest();
|
storeSet.main.unsetAsyncRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
const errGetApplCallback = (data) => {
|
const errGetApplCallback = (data) => {
|
||||||
/*if (bandoMsgs.current && data.message) {
|
|
||||||
bandoMsgs.current.show([
|
|
||||||
{
|
|
||||||
sticky: true, severity: 'error', summary: '',
|
|
||||||
detail: data.message,
|
|
||||||
closable: true
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
}*/
|
|
||||||
set404FromErrorResponse(data);
|
set404FromErrorResponse(data);
|
||||||
storeSet.main.unsetAsyncRequest();
|
storeSet.main.unsetAsyncRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const parsed = parseInt(id)
|
const bandoId = getBandoId();
|
||||||
const bandoId = !isNaN(parsed) ? parsed : 0;
|
|
||||||
storeSet.main.setAsyncRequest();
|
storeSet.main.setAsyncRequest();
|
||||||
BandoService.getBando(bandoId, getBandoCallback, errGetBandoCallback);
|
BandoService.getBando(bandoId, getBandoCallback, errGetBandoCallback);
|
||||||
ApplicationService.getApplications(getApplCallback, errGetApplCallback)
|
ApplicationService.getApplications(getApplCallback, errGetApplCallback, [['callId', bandoId]])
|
||||||
}, [id]);
|
}, [id]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -181,7 +202,7 @@ const BandoViewBeneficiario = () => {
|
|||||||
<div className="appPageSection__withBorder">
|
<div className="appPageSection__withBorder">
|
||||||
<h2>{__('Descrizione breve', 'gepafin')}</h2>
|
<h2>{__('Descrizione breve', 'gepafin')}</h2>
|
||||||
<div className="row rowContent">
|
<div className="row rowContent">
|
||||||
<p>{data.descriptionShort}</p>
|
{renderHtmlContent(data.descriptionShort)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -212,7 +233,7 @@ const BandoViewBeneficiario = () => {
|
|||||||
<div className="appPageSection__withBorder">
|
<div className="appPageSection__withBorder">
|
||||||
<h2>{__('Descrizione dettagliata', 'gepafin')}</h2>
|
<h2>{__('Descrizione dettagliata', 'gepafin')}</h2>
|
||||||
<div className="row rowContent">
|
<div className="row rowContent">
|
||||||
<p>{data.descriptionLong}</p>
|
{renderHtmlContent(data.descriptionLong)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -309,7 +330,7 @@ const BandoViewBeneficiario = () => {
|
|||||||
icon="pi pi-download" iconPos="right"/>
|
icon="pi pi-download" iconPos="right"/>
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
disabled={isApplRequest}
|
disabled={isAsyncRequest}
|
||||||
onClick={submitApplication}
|
onClick={submitApplication}
|
||||||
label={__('Presenta Domanda', 'gepafin')}
|
label={__('Presenta Domanda', 'gepafin')}
|
||||||
icon="pi pi-save" iconPos="right"/>
|
icon="pi pi-save" iconPos="right"/>
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ const LatestBandiTable = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const actionsBodyTemplate = (rowData) => {
|
const actionsBodyTemplate = (rowData) => {
|
||||||
return <Link to={`/tenders/${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" />
|
||||||
</Link>
|
</Link>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ const Dashboard = () => {
|
|||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const onGoToCreateNewBando = () => {
|
const onGoToCreateNewBando = () => {
|
||||||
navigate('/tenders/new');
|
navigate('/bandi/new');
|
||||||
}
|
}
|
||||||
|
|
||||||
const onGoToUsers = () => {
|
const onGoToUsers = () => {
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ const LatestBandiTable = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const actionsBodyTemplate = (rowData) => {
|
const actionsBodyTemplate = (rowData) => {
|
||||||
return <Link to={`/tenders/${rowData.id}`}>
|
return <Link to={`/bandi/${rowData.id}`}>
|
||||||
<Button severity="info" label={__('Partecipa', 'gepafin')} icon="pi pi-arrow-right" size="small" iconPos="right" />
|
<Button severity="info" label={__('Partecipa', 'gepafin')} icon="pi pi-arrow-right" size="small" iconPos="right" />
|
||||||
</Link>
|
</Link>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ const MyLatestSubmissionsTable = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const actionsBodyTemplate = (rowData) => {
|
const actionsBodyTemplate = (rowData) => {
|
||||||
return <Link to={`/applications/${rowData.id}`}>
|
return <Link to={`/imieibandi/${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>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,6 +62,10 @@ const Login = () => {
|
|||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const loginWithSpid = () => {
|
||||||
|
console.log('spid')
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isEmpty(token)) {
|
if (!isEmpty(token)) {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
@@ -80,6 +84,36 @@ const Login = () => {
|
|||||||
|
|
||||||
<Messages ref={errorMsgs}/>
|
<Messages ref={errorMsgs}/>
|
||||||
|
|
||||||
|
<button className="appPageLogin__spidBtn" onClick={loginWithSpid}>
|
||||||
|
<svg width="31" height="31" viewBox="0 0 31 31" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g clipPath="url(#clip0_1156_13356)">
|
||||||
|
<path
|
||||||
|
d="M30.5767 15.0422C30.5767 23.3285 23.8629 30.0422 15.5767 30.0422C7.29552 30.0422 0.57666 23.3285 0.57666 15.0422C0.57666 6.75599 7.29552 0.0422363 15.5767 0.0422363C23.8629 0.0422363 30.5767 6.75599 30.5767 15.0422Z"
|
||||||
|
fill="white"/>
|
||||||
|
<path
|
||||||
|
d="M15.6175 16.3288C14.3717 16.3288 13.3455 15.9102 12.5389 15.0627C11.7322 14.2203 11.3289 13.1736 11.3289 11.9279C11.3289 10.677 11.7322 9.6406 12.5338 8.81351C13.3353 7.98642 14.3564 7.57287 15.6073 7.57287C16.853 7.57287 17.869 7.99152 18.6502 8.84414C19.4313 9.69166 19.8244 10.7332 19.8244 11.984C19.8244 13.2247 19.4313 14.2611 18.6502 15.0882C17.869 15.9102 16.8632 16.3288 15.6175 16.3288Z"
|
||||||
|
fill="#0066CC"/>
|
||||||
|
<path
|
||||||
|
d="M11.3289 22.4605C11.3289 21.2097 11.7322 20.1733 12.5287 19.3462C13.3302 18.5191 14.3513 18.1055 15.6124 18.1055C16.8581 18.1055 17.8741 18.5242 18.6502 19.3768C19.4313 20.2294 19.8244 21.271 19.8244 22.5167"
|
||||||
|
fill="#0066CC"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<clipPath id="clip0_1156_13356">
|
||||||
|
<rect width="30" height="30" fill="white" transform="translate(0.57666 0.0422363)"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
<span>{__('Entra con SPID', 'gepafin')}</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div className="appPage__spacer"></div>
|
||||||
|
|
||||||
|
<div className="appPageSection__hr">
|
||||||
|
<span>{__('Oppure', 'gepafin')}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="appPage__spacer"></div>
|
||||||
|
|
||||||
<form className="appForm" onSubmit={handleSubmit(onSubmit)}>
|
<form className="appForm" onSubmit={handleSubmit(onSubmit)}>
|
||||||
<FormField
|
<FormField
|
||||||
type="textinput"
|
type="textinput"
|
||||||
@@ -101,7 +135,9 @@ const Login = () => {
|
|||||||
config={{ required: __('È obbligatorio', 'gepafin') }}
|
config={{ required: __('È obbligatorio', 'gepafin') }}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Button label={__('Accedi', 'gepafin')} disabled={loading}/>
|
<Button
|
||||||
|
label={__('Accedi', 'gepafin')}
|
||||||
|
disabled={loading}/>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
177
src/pages/Registration/index.js
Normal file
177
src/pages/Registration/index.js
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
import React, { useRef, useState, useEffect } from 'react';
|
||||||
|
import { __, sprintf } from '@wordpress/i18n';
|
||||||
|
import { useForm } from 'react-hook-form';
|
||||||
|
import { classNames } from 'primereact/utils';
|
||||||
|
import { isEmpty } from 'ramda';
|
||||||
|
|
||||||
|
// api
|
||||||
|
import AuthenticationService from '../../service/authentication-service';
|
||||||
|
|
||||||
|
// tools
|
||||||
|
import { isCodiceFiscale, isEmail } from '../../helpers/validators';
|
||||||
|
|
||||||
|
// store
|
||||||
|
import { storeSet, useStore } from '../../store';
|
||||||
|
|
||||||
|
// components
|
||||||
|
import FormField from '../../components/FormField';
|
||||||
|
import LogoIcon from '../../icons/LogoIcon';
|
||||||
|
import { Button } from 'primereact/button';
|
||||||
|
import { Messages } from 'primereact/messages';
|
||||||
|
|
||||||
|
const Registration = () => {
|
||||||
|
const token = useStore().main.token();
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
const errorMsgs = useRef(null);
|
||||||
|
const {
|
||||||
|
control,
|
||||||
|
handleSubmit,
|
||||||
|
formState: { errors },
|
||||||
|
} = useForm({ mode: 'onChange' });
|
||||||
|
|
||||||
|
const onSubmit = (formData) => {
|
||||||
|
errorMsgs.current.clear();
|
||||||
|
//setLoading(true);
|
||||||
|
console.log('formData', formData, errors);
|
||||||
|
|
||||||
|
//AuthenticationService.login(request, regCallback, regError);
|
||||||
|
};
|
||||||
|
|
||||||
|
const regCallback = (data) => {
|
||||||
|
if (data.status === 'SUCCESS') {
|
||||||
|
storeSet.main.setAuthData({
|
||||||
|
token: data.data.token,
|
||||||
|
userData: data.data.user
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
errorMsgs.current.show([
|
||||||
|
{
|
||||||
|
sticky: true, severity: 'error', summary: '',
|
||||||
|
detail: data.message,
|
||||||
|
closable: true
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
const regError = (err) => {
|
||||||
|
errorMsgs.current.show([
|
||||||
|
{
|
||||||
|
sticky: true, severity: 'error', summary: '',
|
||||||
|
detail: sprintf(__('%s', 'gepafin'), err),
|
||||||
|
closable: true
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isEmpty(token)) {
|
||||||
|
setLoading(true);
|
||||||
|
window.location.replace('/')
|
||||||
|
}
|
||||||
|
}, [token]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={classNames(['appPage', 'appPageLogin'])}>
|
||||||
|
<div className="appPageLogin__wrapper">
|
||||||
|
<LogoIcon/>
|
||||||
|
|
||||||
|
<h1>{__('Completamento anagrafica personale', 'gepafin')}</h1>
|
||||||
|
<span>{__('Per favore, inserisci i tuoi dati.', 'gepafin')}</span>
|
||||||
|
|
||||||
|
<div className="appPage__spacer"></div>
|
||||||
|
|
||||||
|
<Messages ref={errorMsgs}/>
|
||||||
|
|
||||||
|
<form className="appForm" onSubmit={handleSubmit(onSubmit)}>
|
||||||
|
<div className="appForm__cols">
|
||||||
|
<FormField
|
||||||
|
type="textinput"
|
||||||
|
fieldName="first_name"
|
||||||
|
label={__('Nome', 'gepafin')}
|
||||||
|
control={control}
|
||||||
|
errors={errors}
|
||||||
|
config={{ required: __('È obbligatorio', 'gepafin') }}
|
||||||
|
placeholder="Francesco"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FormField
|
||||||
|
type="textinput"
|
||||||
|
fieldName="second_name"
|
||||||
|
label={__('Cognome', 'gepafin')}
|
||||||
|
control={control}
|
||||||
|
errors={errors}
|
||||||
|
config={{ required: __('È obbligatorio', 'gepafin') }}
|
||||||
|
placeholder="Molini"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="appForm__cols">
|
||||||
|
<FormField
|
||||||
|
type="textinput"
|
||||||
|
fieldName="fiscal_code"
|
||||||
|
label={__('Codice fiscale', 'gepafin')}
|
||||||
|
control={control}
|
||||||
|
errors={errors}
|
||||||
|
config={{
|
||||||
|
required: __('È obbligatorio', 'gepafin'),
|
||||||
|
validate: {
|
||||||
|
isCodiceFiscale
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
placeholder="ABC1234"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FormField
|
||||||
|
type="datepicker"
|
||||||
|
fieldName="birth_date"
|
||||||
|
label={__('Data di nascita', 'gepafin')}
|
||||||
|
control={control}
|
||||||
|
errors={errors}
|
||||||
|
config={{ required: __('È obbligatorio', 'gepafin') }}
|
||||||
|
placeholder=""
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="appForm__cols">
|
||||||
|
<FormField
|
||||||
|
type="textinput"
|
||||||
|
fieldName="email"
|
||||||
|
label={__('Email', 'gepafin')}
|
||||||
|
control={control}
|
||||||
|
errors={errors}
|
||||||
|
config={{
|
||||||
|
required: __('È obbligatorio', 'gepafin'),
|
||||||
|
validate: {
|
||||||
|
isEmail
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
placeholder="sample@example.com"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<FormField
|
||||||
|
type="textinput"
|
||||||
|
fieldName="phone"
|
||||||
|
label={__('Telefono', 'gepafin')}
|
||||||
|
control={control}
|
||||||
|
errors={errors}
|
||||||
|
config={{
|
||||||
|
required: __('È obbligatorio', 'gepafin'),
|
||||||
|
positive: v => parseInt(v) > 0
|
||||||
|
}}
|
||||||
|
placeholder=""
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
label={__('Accedi', 'gepafin')}
|
||||||
|
disabled={loading}/>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Registration;
|
||||||
@@ -17,6 +17,7 @@ import BandoFormsPreview from './pages/BandoFormsPreview';
|
|||||||
import BandoFlowEdit from './pages/BandoFlowEdit';
|
import BandoFlowEdit from './pages/BandoFlowEdit';
|
||||||
import Applications from './pages/Applications';
|
import Applications from './pages/Applications';
|
||||||
import BandoApplication from './pages/BandoApplication';
|
import BandoApplication from './pages/BandoApplication';
|
||||||
|
import Registration from './pages/Registration';
|
||||||
|
|
||||||
const routes = ({ role }) => {
|
const routes = ({ role }) => {
|
||||||
return (
|
return (
|
||||||
@@ -26,48 +27,49 @@ const routes = ({ role }) => {
|
|||||||
{'ROLE_SUPER_ADMIN' === role ? <Dashboard/> : null}
|
{'ROLE_SUPER_ADMIN' === role ? <Dashboard/> : null}
|
||||||
{'ROLE_BENEFICIARY' === role ? <DashboardBeneficiario/> : null}
|
{'ROLE_BENEFICIARY' === role ? <DashboardBeneficiario/> : null}
|
||||||
</DefaultLayout>}/>
|
</DefaultLayout>}/>
|
||||||
<Route path="/tenders" element={<DefaultLayout>
|
<Route path="/bandi" element={<DefaultLayout>
|
||||||
{'ROLE_SUPER_ADMIN' === role ? <Bandi/> : null}
|
{'ROLE_SUPER_ADMIN' === role ? <Bandi/> : null}
|
||||||
{'ROLE_BENEFICIARY' === role ? <PageNotFound/> : null}
|
{'ROLE_BENEFICIARY' === role ? <PageNotFound/> : null}
|
||||||
</DefaultLayout>}/>
|
</DefaultLayout>}/>
|
||||||
<Route path="/tenders/: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}
|
||||||
</DefaultLayout>}/>
|
</DefaultLayout>}/>
|
||||||
<Route path="/tenders/: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}
|
||||||
</DefaultLayout>}/>
|
</DefaultLayout>}/>
|
||||||
<Route path="/tenders/: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}
|
||||||
</DefaultLayout>}/>
|
</DefaultLayout>}/>
|
||||||
<Route path="/tenders/: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}
|
||||||
</DefaultLayout>}/>
|
</DefaultLayout>}/>
|
||||||
<Route path="/tenders/: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}
|
||||||
</DefaultLayout>}/>
|
</DefaultLayout>}/>
|
||||||
<Route path="/tenders/: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}
|
||||||
</DefaultLayout>}/>
|
</DefaultLayout>}/>
|
||||||
<Route path="/tenders/: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}
|
||||||
</DefaultLayout>}/>
|
</DefaultLayout>}/>
|
||||||
<Route path="/applications" 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}
|
||||||
</DefaultLayout>}/>
|
</DefaultLayout>}/>
|
||||||
<Route path="/applications/: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}
|
||||||
</DefaultLayout>}/>
|
</DefaultLayout>}/>
|
||||||
</Route>
|
</Route>
|
||||||
<Route exact path="/login" element={<Login/>}/>
|
<Route exact path="/login" element={<Login/>}/>
|
||||||
|
<Route exact path="/registration" element={<Registration/>}/>
|
||||||
{/*<Route exact path="/forgot-password" element={<ForgotPassword/>}/>*/}
|
{/*<Route exact path="/forgot-password" element={<ForgotPassword/>}/>*/}
|
||||||
<Route path="*" element={<PageNotFound/>}/>
|
<Route path="*" element={<PageNotFound/>}/>
|
||||||
</Routes>)
|
</Routes>)
|
||||||
|
|||||||
@@ -4,11 +4,23 @@ const API_BASE_URL = process.env.REACT_APP_API_EXECUTION_ADDRESS;
|
|||||||
|
|
||||||
export default class ApplicationService {
|
export default class ApplicationService {
|
||||||
|
|
||||||
static getApplications = (callback, errCallback) => {
|
static getApplications = (callback, errCallback, queryParams) => {
|
||||||
NetworkService.get(`${API_BASE_URL}/application`, callback, errCallback);
|
NetworkService.get(`${API_BASE_URL}/application`, callback, errCallback, queryParams);
|
||||||
};
|
};
|
||||||
|
|
||||||
static getApplication = (id, callback, errCallback) => {
|
static getApplication = (id, callback, errCallback) => {
|
||||||
NetworkService.get(`${API_BASE_URL}/application/${id}`, callback, errCallback);
|
NetworkService.get(`${API_BASE_URL}/application/${id}`, callback, errCallback);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static getApplicationForm = (id, callback, errCallback, queryParams) => {
|
||||||
|
NetworkService.get(`${API_BASE_URL}/application/${id}/form/next-previous`, callback, errCallback, queryParams);
|
||||||
|
};
|
||||||
|
|
||||||
|
static createApplication = (id, body, callback, errCallback) => {
|
||||||
|
NetworkService.post(`${API_BASE_URL}/application/call/${id}`, body, callback, errCallback);
|
||||||
|
};
|
||||||
|
|
||||||
|
static submitForm = (id, body, callback, errCallback, queryParams) => {
|
||||||
|
NetworkService.put(`${API_BASE_URL}/application/${id}`, body, callback, errCallback, queryParams);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,19 +62,11 @@ export default class AuthenticationService {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static registerUser = (registerRequest, callback, errCallback) => {
|
static registerUser = (registerRequest, callback, errCallback) => {
|
||||||
NetworkService.post(`${API_BASE_URL}/user/register`, registerRequest, callback, errCallback);
|
NetworkService.unauthorizedPost(`${API_BASE_URL}/user`, registerRequest, callback, errCallback);
|
||||||
};
|
};
|
||||||
|
|
||||||
static forgotPassword = (request, callback, errCallback) => {
|
static forgotPassword = (request, callback, errCallback) => {
|
||||||
NetworkService.unauthorizedPost(`${API_BASE_URL}/user/reset_password_request/?email=` + request, {}, callback, errCallback);
|
NetworkService.unauthorizedPost(`${API_BASE_URL}/user/reset-password`, {}, callback, errCallback);
|
||||||
}
|
|
||||||
|
|
||||||
static checkTokenForgotPassword = (request, callback, errCallback) => {
|
|
||||||
NetworkService.unauthorizedGet(`${API_BASE_URL}/user/reset_token_check/?token=` + request, {}, callback, errCallback);
|
|
||||||
}
|
|
||||||
|
|
||||||
static changePassword = (request, callback, errCallback) => {
|
|
||||||
NetworkService.unauthorizedPatch(`${API_BASE_URL}/user/reset_password`, request, callback, errCallback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static me = (callback, errCallback) => {
|
static me = (callback, errCallback) => {
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ export default class FormsService {
|
|||||||
NetworkService.post(`${API_BASE_URL}/form/call/${id}`, body, callback, errCallback);
|
NetworkService.post(`${API_BASE_URL}/form/call/${id}`, body, callback, errCallback);
|
||||||
};
|
};
|
||||||
|
|
||||||
static updateForm = (id, body, callback, errCallback) => {
|
static updateForm = (id, body, callback, errCallback, queryParams) => {
|
||||||
NetworkService.put(`${API_BASE_URL}/form/${id}`, body, callback, errCallback);
|
NetworkService.put(`${API_BASE_URL}/form/${id}`, body, callback, errCallback, queryParams);
|
||||||
};
|
};
|
||||||
|
|
||||||
static getFormById = (id, callback, errCallback) => {
|
static getFormById = (id, callback, errCallback) => {
|
||||||
|
|||||||
@@ -570,8 +570,6 @@ export const elementItems = [
|
|||||||
],
|
],
|
||||||
validators: {
|
validators: {
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
minLength: 11,
|
|
||||||
maxLength: 11,
|
|
||||||
custom: 'isPIVA'
|
custom: 'isPIVA'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -593,8 +591,6 @@ export const elementItems = [
|
|||||||
],
|
],
|
||||||
validators: {
|
validators: {
|
||||||
isRequired: true,
|
isRequired: true,
|
||||||
minLength: 11,
|
|
||||||
maxLength: 16,
|
|
||||||
custom: 'isCodiceFiscale'
|
custom: 'isCodiceFiscale'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -649,11 +645,11 @@ export const elementItems = [
|
|||||||
settings: [
|
settings: [
|
||||||
{
|
{
|
||||||
name: "label",
|
name: "label",
|
||||||
value: "nome@esempio.it"
|
value: "Campo Email"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "placeholder",
|
name: "placeholder",
|
||||||
value: ""
|
value: "nome@esempio.it"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
validators: {
|
validators: {
|
||||||
@@ -670,11 +666,11 @@ export const elementItems = [
|
|||||||
settings: [
|
settings: [
|
||||||
{
|
{
|
||||||
name: "label",
|
name: "label",
|
||||||
value: "nome@pec.it"
|
value: "Campo PEC"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "placeholder",
|
name: "placeholder",
|
||||||
value: ""
|
value: "nome@pec.it"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
validators: {
|
validators: {
|
||||||
@@ -702,54 +698,26 @@ export const elementItems = [
|
|||||||
isRequired: false,
|
isRequired: false,
|
||||||
custom: 'isUrl'
|
custom: 'isUrl'
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 18,
|
||||||
|
sortOrder: 18,
|
||||||
|
name: 'textinput',
|
||||||
|
label: 'Marca da bollo',
|
||||||
|
description: 'Per inserire codice di marca da bollo',
|
||||||
|
settings: [
|
||||||
|
{
|
||||||
|
name: "label",
|
||||||
|
value: "Marca da bollo"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "placeholder",
|
||||||
|
value: "Numero identificativo"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
validators: {
|
||||||
|
isRequired: false,
|
||||||
|
custom: 'isMarcaDaBollo'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
/*
|
|
||||||
const flowData = {
|
|
||||||
"initialForm":9,
|
|
||||||
"finalForm":13,
|
|
||||||
"flowData":[
|
|
||||||
{
|
|
||||||
"formId":"9",
|
|
||||||
"chosenField":"a0acf568c8",
|
|
||||||
"chosenValue":""
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"formId":"12",
|
|
||||||
"chosenField":"",
|
|
||||||
"chosenValue":"o8bf116e28"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"formId":"11",
|
|
||||||
"chosenField":"",
|
|
||||||
"chosenValue":"o1eb76229d"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"flowEdges":[
|
|
||||||
{
|
|
||||||
"id":"9->12",
|
|
||||||
"source":"9",
|
|
||||||
"target":"12",
|
|
||||||
"type":"smoothstep"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id":"12->13",
|
|
||||||
"source":"12",
|
|
||||||
"target":"13",
|
|
||||||
"type":"smoothstep"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id":"9->11",
|
|
||||||
"source":"9",
|
|
||||||
"target":"11",
|
|
||||||
"type":"smoothstep"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id":"11->13",
|
|
||||||
"source":"11",
|
|
||||||
"target":"13",
|
|
||||||
"type":"smoothstep"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}*/
|
|
||||||
|
|||||||
15
yarn.lock
15
yarn.lock
@@ -1283,6 +1283,11 @@
|
|||||||
resolved "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz"
|
resolved "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz"
|
||||||
integrity sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw==
|
integrity sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw==
|
||||||
|
|
||||||
|
"@date-fns/tz@^1.0.2":
|
||||||
|
version "1.0.2"
|
||||||
|
resolved "https://registry.npmjs.org/@date-fns/tz/-/tz-1.0.2.tgz"
|
||||||
|
integrity sha512-iKxj0kXMy7Qe6vjK+flz33cpy2j0dnTKT5i54p3fFlB411J47aSs6HBg7LOO5X9LjDi2iNlctD9rFn738ySOGQ==
|
||||||
|
|
||||||
"@emotion/babel-plugin@^11.12.0":
|
"@emotion/babel-plugin@^11.12.0":
|
||||||
version "11.12.0"
|
version "11.12.0"
|
||||||
resolved "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.12.0.tgz"
|
resolved "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.12.0.tgz"
|
||||||
@@ -3530,6 +3535,11 @@ coa@^2.0.2:
|
|||||||
chalk "^2.4.1"
|
chalk "^2.4.1"
|
||||||
q "^1.1.2"
|
q "^1.1.2"
|
||||||
|
|
||||||
|
codice-fiscale-js@^2.3.22:
|
||||||
|
version "2.3.22"
|
||||||
|
resolved "https://registry.npmjs.org/codice-fiscale-js/-/codice-fiscale-js-2.3.22.tgz"
|
||||||
|
integrity sha512-at+XQ3kTgIq0qMoBmP4UtrSlYvHp5X5KGEB0ZKykydMnYC28zBAbdbFDu7CsatlfoOa1vH4qBpNkOCXp/YqMmA==
|
||||||
|
|
||||||
collect-v8-coverage@^1.0.0:
|
collect-v8-coverage@^1.0.0:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz"
|
resolved "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz"
|
||||||
@@ -10155,6 +10165,11 @@ v8-to-istanbul@^8.1.0:
|
|||||||
convert-source-map "^1.6.0"
|
convert-source-map "^1.6.0"
|
||||||
source-map "^0.7.3"
|
source-map "^0.7.3"
|
||||||
|
|
||||||
|
validate.js@^0.13.1:
|
||||||
|
version "0.13.1"
|
||||||
|
resolved "https://registry.npmjs.org/validate.js/-/validate.js-0.13.1.tgz"
|
||||||
|
integrity sha512-PnFM3xiZ+kYmLyTiMgTYmU7ZHkjBZz2/+F0DaALc/uUtVzdCt1wAosvYJ5hFQi/hz8O4zb52FQhHZRC+uVkJ+g==
|
||||||
|
|
||||||
vary@~1.1.2:
|
vary@~1.1.2:
|
||||||
version "1.1.2"
|
version "1.1.2"
|
||||||
resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz"
|
resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz"
|
||||||
|
|||||||
Reference in New Issue
Block a user