diff --git a/.distignore b/.distignore
new file mode 100644
index 0000000..e07a780
--- /dev/null
+++ b/.distignore
@@ -0,0 +1,5 @@
+.git
+node_modules
+build
+environments
+public
\ No newline at end of file
diff --git a/package.json b/package.json
index c998aa0..eb4ec21 100644
--- a/package.json
+++ b/package.json
@@ -14,9 +14,11 @@
"@wordpress/react-i18n": "4.8.0",
"@xyflow/react": "12.3.1",
"codice-fiscale-js": "2.3.22",
+ "copy-to-clipboard": "^3.3.3",
"deep-object-diff": "^1.1.9",
"dompurify": "3.1.7",
"fast-deep-equal": "3.1.3",
+ "hotkeys-js": "^3.13.7",
"html-react-parser": "5.1.16",
"jwt-decode": "4.0.0",
"klona": "2.0.6",
@@ -43,6 +45,7 @@
"@babel/plugin-syntax-jsx": "7.24.7",
"@wordpress/babel-plugin-makepot": "6.8.0",
"babel-plugin-macros": "3.1.0",
+ "node-wp-i18n": "^1.2.7",
"sass": "1.79.3",
"sass-loader": "16.0.2"
},
@@ -54,7 +57,8 @@
"build:dev": "cp environments/dev/* public/loaded-files && rm public/loaded-files/dev.env && cp environments/dev/dev.env .env && react-scripts build --mode development",
"build:prod": "cp environments/prod/* public/loaded-files && rm public/loaded-files/prod.env && cp environments/prod/prod.env .env && react-scripts build --mode production",
"test": "react-scripts test",
- "eject": "react-scripts eject"
+ "eject": "react-scripts eject",
+ "make-pot": "wpi18n makepot --domain-path=languages --domain=gepafin"
},
"eslintConfig": {
"extends": [
diff --git a/src/assets/scss/components/appPage.scss b/src/assets/scss/components/appPage.scss
index 1d913b1..8f40ad9 100644
--- a/src/assets/scss/components/appPage.scss
+++ b/src/assets/scss/components/appPage.scss
@@ -167,6 +167,7 @@
display: flex;
gap: 1rem;
align-items: center;
+ justify-content: space-between;
padding: 5px 0;
&.rowContent {
@@ -178,7 +179,7 @@
p {
margin: 0;
- flex: 1 1 100%;
+ /*flex: 1 1 100%;*/
}
ul, ol {
diff --git a/src/assets/scss/components/layout.scss b/src/assets/scss/components/layout.scss
index e226e1a..e350503 100644
--- a/src/assets/scss/components/layout.scss
+++ b/src/assets/scss/components/layout.scss
@@ -153,6 +153,16 @@ button[disabled] {
filter: grayscale(1);
}
+.iconBtn {
+ background: transparent;
+ border: none;
+
+ &:hover {
+ cursor: pointer;
+ color: var(--primary-text);
+ }
+}
+
@media (max-width: 800px) {
.inner {
flex-direction: column;
diff --git a/src/assets/scss/components/misc.scss b/src/assets/scss/components/misc.scss
index 2aad9b4..ca53588 100644
--- a/src/assets/scss/components/misc.scss
+++ b/src/assets/scss/components/misc.scss
@@ -8,10 +8,15 @@
.p-badge {
color: var(--menuitem-active-color);
}
-.p-button:not(.p-button-outlined, .p-button-secondary, .p-confirm-popup-reject, .p-button-link),
-.p-button:not(.p-button-outlined, .p-button-secondary, .p-confirm-popup-reject, .p-button-link) span {
+.p-button:not(.p-button-outlined, .p-button-secondary, .p-confirm-popup-reject, .p-button-link, .p-column-filter-add-button, .p-column-filter-remove-button),
+.p-button:not(.p-button-outlined, .p-button-secondary, .p-confirm-popup-reject, .p-button-link, .p-column-filter-add-button, .p-column-filter-remove-button) span {
color: var(--menuitem-active-color);
}
+.p-column-filter-remove-button {
+ span {
+ margin: 0 5px;
+ }
+}
.p-fileupload-row {
.p-button-danger {
background-color: #f44336;
diff --git a/src/components/UnsavedChangesDetector/index.js b/src/components/UnsavedChangesDetector/index.js
index fefef9d..53102cb 100644
--- a/src/components/UnsavedChangesDetector/index.js
+++ b/src/components/UnsavedChangesDetector/index.js
@@ -9,6 +9,7 @@ import { is, isNil } from 'ramda';
// store
import { storeGet } from '../../store';
+import formatDateString from '../../helpers/formatDateString';
const UnsavedChangesDetector = ({ getValuesFn }) => {
const warnIfUnsavedChanges = (event) => {
@@ -16,16 +17,15 @@ const UnsavedChangesDetector = ({ getValuesFn }) => {
formData.dates = [];
if (formData.startDate) {
- let starDate;
+ let startDate;
if (is(String, formData.startDate)) {
- starDate = formData.startDate;
+ startDate = formData.startDate;
} else {
- const tzAwareDate = new TZDate(formData.startDate, 'Europe/Berlin');
- starDate = tzAwareDate.toISOString().substring(0, 19);
+ startDate = formatDateString(formData.startDate);
}
- formData = wrap(formData).insert(['dates'], starDate, 0).value();
+ formData = wrap(formData).insert(['dates'], startDate, 0).value();
delete formData.startDate;
}
if (formData.endDate) {
@@ -34,8 +34,7 @@ const UnsavedChangesDetector = ({ getValuesFn }) => {
if (is(String, formData.endDate)) {
endDate = formData.endDate;
} else {
- const tzAwareDate = new TZDate(formData.endDate, 'Europe/Berlin');
- endDate = tzAwareDate.toISOString().substring(0, 19);
+ endDate = formatDateString(formData.endDate);
}
formData = wrap(formData).insert(['dates'], endDate, 1).value();
diff --git a/src/helpers/createUTCDate.js b/src/helpers/createUTCDate.js
new file mode 100644
index 0000000..0609380
--- /dev/null
+++ b/src/helpers/createUTCDate.js
@@ -0,0 +1,18 @@
+/**
+ *
+ * @param dateObj {Date}
+ * @return {Date}
+ */
+const createUTCDate = (dateObj) => {
+ const comps = {
+ year: dateObj.getFullYear(),
+ month: dateObj.getMonth(),
+ day: dateObj.getDate(),
+ hours: dateObj.getHours(),
+ minutes: dateObj.getMinutes(),
+ seconds: dateObj.getSeconds()
+ };
+ return new Date(Date.UTC(comps.year, comps.month, comps.day, 0, 0, 0));
+}
+
+export default createUTCDate;
\ No newline at end of file
diff --git a/src/helpers/formatDateString.js b/src/helpers/formatDateString.js
new file mode 100644
index 0000000..9690a1b
--- /dev/null
+++ b/src/helpers/formatDateString.js
@@ -0,0 +1,13 @@
+/**
+ *
+ * @param date {Date}
+ * @return {string}
+ */
+const formatDateString = (date) => {
+ const year = date.getFullYear();
+ const month = String(date.getMonth() + 1).padStart(2, '0');
+ const day = String(date.getDate()).padStart(2, '0');
+ return `${year}-${month}-${day}T00:00:00`;
+}
+
+export default formatDateString;
\ No newline at end of file
diff --git a/src/pages/Bandi/components/AllBandiTable/index.js b/src/pages/Bandi/components/AllBandiTable/index.js
index 236098e..6eeba6a 100644
--- a/src/pages/Bandi/components/AllBandiTable/index.js
+++ b/src/pages/Bandi/components/AllBandiTable/index.js
@@ -14,9 +14,6 @@ import BandoService from '../../../../service/bando-service';
import { FilterMatchMode, FilterOperator } from 'primereact/api';
import { DataTable } from 'primereact/datatable';
import { Column } from 'primereact/column';
-import { InputText } from 'primereact/inputtext';
-import { IconField } from 'primereact/iconfield';
-import { InputIcon } from 'primereact/inputicon';
import { Dropdown } from 'primereact/dropdown';
import { Button } from 'primereact/button';
import { Calendar } from 'primereact/calendar';
@@ -30,7 +27,6 @@ const AllBandiTable = () => {
const [items, setItems] = useState(null);
const [filters, setFilters] = useState(null);
const [localAsyncRequest, setLocalAsyncRequest] = useState(false);
- const [globalFilterValue, setGlobalFilterValue] = useState('');
const [statuses, setStatuses] = useState([]);
useEffect(() => {
@@ -62,16 +58,6 @@ const AllBandiTable = () => {
initFilters();
};
- const onGlobalFilterChange = (e) => {
- const value = e.target.value;
- let _filters = { ...filters };
-
- _filters['global'].value = value;
-
- setFilters(_filters);
- setGlobalFilterValue(value);
- };
-
const initFilters = () => {
setFilters({
global: { value: null, matchMode: FilterMatchMode.CONTAINS },
@@ -80,17 +66,12 @@ const AllBandiTable = () => {
end_date: { operator: FilterOperator.AND, constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }] },
status: { operator: FilterOperator.OR, constraints: [{ value: null, matchMode: FilterMatchMode.EQUALS }] },
});
- setGlobalFilterValue('');
};
const renderHeader = () => {
return (
-
-
-
-
);
};
@@ -134,13 +115,13 @@ const AllBandiTable = () => {
return(
setFilters(e.filters)}>
{
const chosenCompanyId = useStore().main.chosenCompanyId();
@@ -192,8 +192,7 @@ const BandoApplication = () => {
let fieldVal = formValues[cur];
if (formValues[cur] && formValues[cur].toISOString) {
- const tzAwareDate = new TZDate(formValues[cur], 'Europe/Berlin');
- fieldVal = tzAwareDate.toISOString().substring(0, 19);
+ fieldVal = formatDateString(formValues[cur]);
}
fieldVal = isEmpty(fieldVal) ? null : fieldVal;
diff --git a/src/pages/BandoEdit/components/BandoEditFormStep1/index.js b/src/pages/BandoEdit/components/BandoEditFormStep1/index.js
index 5d1d12b..04c7680 100644
--- a/src/pages/BandoEdit/components/BandoEditFormStep1/index.js
+++ b/src/pages/BandoEdit/components/BandoEditFormStep1/index.js
@@ -26,6 +26,7 @@ import { isEmail } from '../../../../helpers/validators';
import { storeSet } from '../../../../store';
import set404FromErrorResponse from '../../../../helpers/set404FromErrorResponse';
import getTimeParsedFromString from '../../../../helpers/getTimeParsedFromString';
+import formatDateString from '../../../../helpers/formatDateString';
const BandoEditFormStep1 = forwardRef(function ({ initialData, setInitialData, getFormErrors, status }, ref) {
const navigate = useNavigate();
@@ -62,8 +63,7 @@ const BandoEditFormStep1 = forwardRef(function ({ initialData, setInitialData, g
if (is(String, formData.startDate)) {
starDate = formData.startDate;
} else {
- const tzAwareDate = new TZDate(formData.startDate, 'Europe/Berlin');
- starDate = tzAwareDate.toISOString().substring(0, 19);
+ starDate = formatDateString(formData.startDate);
}
formData = wrap(formData).insert(['dates'], starDate, 0).value();
@@ -74,8 +74,7 @@ const BandoEditFormStep1 = forwardRef(function ({ initialData, setInitialData, g
if (is(String, formData.endDate)) {
endDate = formData.endDate;
} else {
- const tzAwareDate = new TZDate(formData.endDate, 'Europe/Berlin');
- endDate = tzAwareDate.toISOString().substring(0, 19);
+ endDate = formatDateString(formData.endDate);
}
formData = wrap(formData).insert(['dates'], endDate, 1).value();
diff --git a/src/pages/BandoEdit/components/BandoEditFormStep2/index.js b/src/pages/BandoEdit/components/BandoEditFormStep2/index.js
index d8483b2..c933642 100644
--- a/src/pages/BandoEdit/components/BandoEditFormStep2/index.js
+++ b/src/pages/BandoEdit/components/BandoEditFormStep2/index.js
@@ -23,6 +23,7 @@ import { storeSet } from '../../../../store';
import getTimeParsedFromString from '../../../../helpers/getTimeParsedFromString';
import { mimeTypes } from '../../../../configData';
import { wrap } from 'object-path-immutable';
+import formatDateString from '../../../../helpers/formatDateString';
const BandoEditFormStep2 = forwardRef(function ({ initialData, setInitialData, getFormErrors, status }, ref) {
const navigate = useNavigate();
@@ -60,8 +61,7 @@ const BandoEditFormStep2 = forwardRef(function ({ initialData, setInitialData, g
if (is(String, formData.startDate)) {
starDate = formData.startDate;
} else {
- const tzAwareDate = new TZDate(formData.startDate, 'Europe/Berlin');
- starDate = tzAwareDate.toISOString().substring(0, 19);
+ starDate = formatDateString(formData.starDate);
}
formData = wrap(formData).insert(['dates'], starDate, 0).value();
@@ -72,8 +72,7 @@ const BandoEditFormStep2 = forwardRef(function ({ initialData, setInitialData, g
if (is(String, formData.endDate)) {
endDate = formData.endDate;
} else {
- const tzAwareDate = new TZDate(formData.endDate, 'Europe/Berlin');
- endDate = tzAwareDate.toISOString().substring(0, 19);
+ endDate = formatDateString(formData.endDate);
}
formData = wrap(formData).insert(['dates'], endDate, 1).value();
diff --git a/src/pages/BandoForms/index.js b/src/pages/BandoForms/index.js
index cee1051..db0fdff 100644
--- a/src/pages/BandoForms/index.js
+++ b/src/pages/BandoForms/index.js
@@ -3,31 +3,36 @@ import { __ } from '@wordpress/i18n';
import { useParams, useNavigate } from 'react-router-dom';
import { isEmpty } from 'ramda';
import { classNames } from 'primereact/utils';
-import { klona } from 'klona';
-// components
-import { Button } from 'primereact/button';
-import { Dropdown } from 'primereact/dropdown';
+// store
+import { storeSet } from '../../store';
// service
import FormsService from '../../service/forms-service';
-// store
-import { storeSet } from '../../store';
-import set404FromErrorResponse from '../../helpers/set404FromErrorResponse';
-import BandoService from '../../service/bando-service';
+// tools
import uniqid from '../../helpers/uniqid';
+import set404FromErrorResponse from '../../helpers/set404FromErrorResponse';
+
+// components
+import { Button } from 'primereact/button';
+import { Dropdown } from 'primereact/dropdown';
+import BandoService from '../../service/bando-service';
import { Toast } from 'primereact/toast';
const BandoForms = () => {
const { id } = useParams();
const navigate = useNavigate()
- const [templates, setTemplates] = useState(null);
- const [selectedTemplate, setSelectedTemplate] = useState(null);
const [selectedForm, setSelectedForm] = useState(null);
- const [selectedForDuplicateForm, setSelectedForDuplicateForm] = useState(null);
+ const [selectedForDuplicateForm, setSelectedForDuplicateForm] = useState(0);
const [forms, setForms] = useState([]);
const [bandoStatus, setBandoStatus] = useState('');
+ const [allBandiOptions, setAllBandiOptions] = useState([]);
+ const [allBandiIsLoading, setAllBandiIsLoading] = useState(false);
+ const [selectedBandoIdForDuplicate, setSelectedBandoIdForDuplicate] = useState(0);
+ const [allFormsOptions, setAllFormsOptions] = useState([]);
+ const [allFormsIsLoading, setAllFormsIsLoading] = useState(false);
+ const [selectedFormIdForDuplicate, setSelectedFormIdForDuplicate] = useState(0);
const toast = useRef(null);
const doCreateNewForm = () => {
@@ -53,11 +58,11 @@ const BandoForms = () => {
if (!isEmpty(selectedFormArr)) {
storeSet.main.setAsyncRequest();
- FormsService.getFormById(selectedForDuplicateForm, getFormCallback, errGetFormCallbacks);
+ FormsService.getFormById(selectedForDuplicateForm, getFormDuplicateCallback, errGetFormDuplicateCallbacks);
}
}
- const getFormCallback = (data) => {
+ const getFormDuplicateCallback = (data) => {
if (data.status === 'SUCCESS') {
const newLabel = `${data.data.label} (copy)`;
@@ -76,9 +81,10 @@ const BandoForms = () => {
errFormCreateCallback
);
}
+ storeSet.main.unsetAsyncRequest();
}
- const errGetFormCallbacks = (data) => {
+ const errGetFormDuplicateCallbacks = (data) => {
set404FromErrorResponse(data);
storeSet.main.unsetAsyncRequest();
}
@@ -141,17 +147,52 @@ const BandoForms = () => {
storeSet.main.unsetAsyncRequest();
}
+ const getAllBandiCallback = (data) => {
+ if (data.status === 'SUCCESS') {
+ setAllBandiOptions(data.data.filter(o => o.id !== parseInt(id)).map(o => ({ label: o.name, value: o.id })))
+ }
+ setAllBandiIsLoading(false);
+ }
+
+ const errGetAllBandiCallback = () => {
+ setAllBandiIsLoading(false);
+ }
+
+ const getAllFormsCallback = (data) => {
+ if (data.status === 'SUCCESS') {
+ setAllFormsOptions(data.data.map(o => ({ label: o.label, value: o.id })));
+ }
+ setAllFormsIsLoading(false);
+ }
+
+ const errGetAllFormsCallback = () => {
+ setAllFormsIsLoading(false);
+ }
+
+ const doDuplicateFormOfAnotherBando = () => {
+ if (selectedBandoIdForDuplicate !== 0 && selectedFormIdForDuplicate !== 0) {
+ storeSet.main.setAsyncRequest();
+ FormsService.getFormById(selectedFormIdForDuplicate, getFormDuplicateCallback, errGetFormDuplicateCallbacks);
+ }
+ }
+
+ useEffect(() => {
+ if (selectedBandoIdForDuplicate !== 0) {
+ setAllFormsIsLoading(true);
+ FormsService.getFormsForCall(selectedBandoIdForDuplicate, getAllFormsCallback, errGetAllFormsCallback);
+ }
+ }, [selectedBandoIdForDuplicate]);
+
useEffect(() => {
const parsed = parseInt(id)
const bandoId = !isNaN(parsed) ? parsed : 0;
- setTemplates([
- { label: 'Form template', value: 11 }
- ])
-
storeSet.main.setAsyncRequest();
BandoService.getBando(id, getCallback, errGetCallback);
FormsService.getFormsForCall(bandoId, getFormsCallback, errGetFormsCallback);
+
+ setAllBandiIsLoading(true);
+ BandoService.getBandi(getAllBandiCallback, errGetAllBandiCallback);
}, [id]);
return (
@@ -164,7 +205,7 @@ const BandoForms = () => {
-
+
@@ -191,7 +232,7 @@ const BandoForms = () => {
*/}
-
{__('Crea un nuovo Form da Zero', 'gepafin')}
+
{__('Crea un nuovo Form o duplica', 'gepafin')}
{__('Inizia con un form completamente vuoto e personalizzabile', 'gepafin')}
{__('Duplica il form creato in precedenza', 'gepafin')}
-
setSelectedForDuplicateForm(e.value)}
- options={forms}
- optionLabel="label"
- placeholder={__('Seleziona form', 'gepafin')}/>
-
+
+ setSelectedForDuplicateForm(e.value)}
+ options={forms}
+ optionLabel="label"
+ placeholder={__('Seleziona form', 'gepafin')}/>
+
+
+
+
+
+
{__('Duplica il form dal altro bando', 'gepafin')}
+
+ setSelectedBandoIdForDuplicate(e.value)}
+ options={allBandiOptions}
+ placeholder={__('Seleziona bando', 'gepafin')}/>
+ setSelectedFormIdForDuplicate(e.value)}
+ options={allFormsOptions}
+ placeholder={__('Seleziona form', 'gepafin')}/>
+
+
diff --git a/src/pages/BandoFormsEdit/components/BuilderElementSettings/components/ElementSettingTableColumns-old/index.js b/src/pages/BandoFormsEdit/components/BuilderElementSettings/components/ElementSettingTableColumns-old/index.js
index ef568c0..6732a79 100644
--- a/src/pages/BandoFormsEdit/components/BuilderElementSettings/components/ElementSettingTableColumns-old/index.js
+++ b/src/pages/BandoFormsEdit/components/BuilderElementSettings/components/ElementSettingTableColumns-old/index.js
@@ -127,7 +127,7 @@ const ElementSettingTableColumns = ({
})}