diff --git a/src/App.js b/src/App.js
index 7d3a901..2c0deea 100644
--- a/src/App.js
+++ b/src/App.js
@@ -4,7 +4,8 @@ import Routes from './routes';
import { createI18n, setLocaleData } from '@wordpress/i18n';
import { I18nProvider } from '@wordpress/react-i18n';
import './assets/scss/theme.scss';
-import { isEmpty, head } from 'ramda'
+import { isEmpty, head } from 'ramda';
+import { addLocale, PrimeReactProvider } from 'primereact/api';
// store
import { useStore, storeSet, storeGet } from './store';
@@ -18,6 +19,9 @@ function App() {
const role = useStore().main.getRole();
const chosenCompanyId = useStore().main.chosenCompanyId();
const isRedirectedOnceNoCompany = useStore().main.isRedirectedOnceNoCompany();
+ const value = {
+ locale: 'it',
+ };
const callback = (data) => {
if (data.status === 'SUCCESS') {
@@ -59,6 +63,51 @@ function App() {
storeSet.main.setAsyncRequest();
AuthenticationService.me(callback, errCallback);
+ addLocale('it', {
+ startsWith: 'Inizia con',
+ contains: 'Contiene',
+ notContains: 'Non contiene',
+ endsWith: 'Finisce con',
+ equals: 'Uguale a',
+ notEquals: 'Diverso da',
+ noFilter: 'Nessun filtro',
+ lt: 'Minore di',
+ lte: 'Minore o uguale a',
+ gt: 'Maggiore di',
+ gte: 'Maggiore o uguale a',
+ dateIs: 'Data uguale a',
+ dateIsNot: 'Data diversa da',
+ dateBefore: 'Data prima di',
+ dateAfter: 'Data dopo',
+ custom: 'Personalizzato',
+ clear: 'Cancella',
+ apply: 'Applica',
+ matchAll: 'Tutte le condizioni',
+ matchAny: 'Qualsiasi condizione',
+ addRule: 'Aggiungi regola',
+ removeRule: 'Rimuovi regola',
+ accept: 'Sì',
+ reject: 'No',
+ choose: 'Scegli',
+ upload: 'Carica',
+ cancel: 'Annulla',
+ dayNames: ['Domenica', 'Lunedì', 'Martedì', 'Mercoledì', 'Giovedì', 'Venerdì', 'Sabato'],
+ dayNamesShort: ['Dom', 'Lun', 'Mar', 'Mer', 'Gio', 'Ven', 'Sab'],
+ dayNamesMin: ['D', 'L', 'M', 'M', 'G', 'V', 'S'],
+ monthNames: ['Gennaio', 'Febbraio', 'Marzo', 'Aprile', 'Maggio', 'Giugno', 'Luglio', 'Agosto', 'Settembre', 'Ottobre', 'Novembre', 'Dicembre'],
+ monthNamesShort: ['Gen', 'Feb', 'Mar', 'Apr', 'Mag', 'Giu', 'Lug', 'Ago', 'Set', 'Ott', 'Nov', 'Dic'],
+ today: 'Oggi',
+ weekHeader: 'Sm',
+ firstDayOfWeek: 1,
+ dateFormat: 'dd/mm/yy',
+ weak: 'Debole',
+ medium: 'Medio',
+ strong: 'Forte',
+ passwordPrompt: 'Inserisci una password',
+ emptyMessage: 'Nessun risultato trovato',
+ emptyFilterMessage: 'Nessun risultato trovato'
+ });
+
fetch('/languages/en_US.json')
.then((res) => res.json())
.then(res => {
@@ -69,7 +118,9 @@ function App() {
return (
-
+
+
+
);
diff --git a/src/assets/scss/components/appPage.scss b/src/assets/scss/components/appPage.scss
index a07df79..a608ea4 100644
--- a/src/assets/scss/components/appPage.scss
+++ b/src/assets/scss/components/appPage.scss
@@ -113,6 +113,10 @@
font-weight: 600;
line-height: normal;
margin: 0 0 24px;
+ display: flex;
+ gap: 1rem;
+ flex-wrap: wrap;
+ align-items: center;
}
h3 {
diff --git a/src/helpers/getBandoLabel.js b/src/helpers/getBandoLabel.js
index 7cbf3bf..9a13e36 100644
--- a/src/helpers/getBandoLabel.js
+++ b/src/helpers/getBandoLabel.js
@@ -14,6 +14,9 @@ const getBandoLabel = (status) => {
case 'APPROVED':
return __('Approvato', 'gepafin');
+ case 'VALID':
+ return __('Valido', 'gepafin');
+
case 'READY_TO_PUBLISH':
return __('Pronto', 'gepafin');
@@ -29,6 +32,9 @@ const getBandoLabel = (status) => {
case 'ADMISSIBLE':
return __('Ammisibile', 'gepafin');
+ case 'DUE':
+ return __('In scadenza', 'gepafin');
+
case 'RESPONSE_RECEIVED':
return __('Riposta ricevuta', 'gepafin');
diff --git a/src/helpers/getBandoSeverity.js b/src/helpers/getBandoSeverity.js
index 03b8704..cd74015 100644
--- a/src/helpers/getBandoSeverity.js
+++ b/src/helpers/getBandoSeverity.js
@@ -12,6 +12,9 @@ const getBandoSeverity = (status) => {
case 'APPROVED':
return 'success';
+ case 'VALID':
+ return 'success';
+
case 'READY_TO_PUBLISH':
return 'info';
@@ -27,6 +30,9 @@ const getBandoSeverity = (status) => {
case 'ADMISSIBLE':
return 'info';
+ case 'DUE':
+ return 'warning';
+
case 'RESPONSE_RECEIVED':
return 'warning';
diff --git a/src/pages/DocumentsBeneficiary/components/DocumentsTable/index.js b/src/pages/DocumentsBeneficiary/components/DocumentsTable/index.js
new file mode 100644
index 0000000..6089454
--- /dev/null
+++ b/src/pages/DocumentsBeneficiary/components/DocumentsTable/index.js
@@ -0,0 +1,221 @@
+import React, { useState, useEffect } from 'react';
+import { __ } from '@wordpress/i18n';
+import { is, uniq } from 'ramda';
+import copy from 'copy-to-clipboard';
+import { Link } from 'react-router-dom';
+
+// store
+import { useStore } from '../../../../store';
+
+// tools
+import getBandoSeverity from '../../../../helpers/getBandoSeverity';
+import getBandoLabel from '../../../../helpers/getBandoLabel';
+import getDateFromISOstring from '../../../../helpers/getDateFromISOstring';
+
+// api
+import CompanyDocumentsService from '../../../../service/company-documents-service';
+
+// components
+import { FilterMatchMode, FilterOperator } from 'primereact/api';
+import { DataTable } from 'primereact/datatable';
+import { Column } from 'primereact/column';
+import { Dropdown } from 'primereact/dropdown';
+import { Button } from 'primereact/button';
+import { Calendar } from 'primereact/calendar';
+import { Tag } from 'primereact/tag';
+import ProperBandoLabel from '../../../../components/ProperBandoLabel';
+import translationStrings from '../../../../translationStringsForComponents';
+import { confirmPopup, ConfirmPopup } from 'primereact/confirmpopup';
+
+const DocumentsTable = ({ type, reload = 0 }) => {
+ const chosenCompanyId = useStore().main.chosenCompanyId();
+ const [docs, setDocs] = useState([]);
+ const [filters, setFilters] = useState(null);
+ const [loading, setLoading] = useState(false);
+ const [statuses, setStatuses] = useState([]);
+
+ useEffect(() => {
+ if (!loading && chosenCompanyId && chosenCompanyId !== 0 && reload !== 0) {
+ setLoading(true);
+ CompanyDocumentsService.getCompanyDocuments(chosenCompanyId, getCallback, errGetCallbacks, [
+ ['documentType', type]
+ ]);
+ }
+ }, [chosenCompanyId, reload]);
+
+ useEffect(() => {
+ setLoading(true);
+ CompanyDocumentsService.getCompanyDocuments(chosenCompanyId, getCallback, errGetCallbacks, [
+ ['documentType', type]
+ ]);
+ }, []);
+
+ const getCallback = (resp) => {
+ if (resp.status === 'SUCCESS') {
+ setDocs(getFormattedData(resp.data));
+ setStatuses(uniq(resp.data.map(o => o.status)))
+ initFilters();
+ }
+ setLoading(false);
+ }
+
+ const errGetCallbacks = () => {
+ setLoading(false);
+ }
+
+ const getFormattedData = (data) => {
+ return data.map((d) => {
+ d.callEndDate = is(String, d.callEndDate) ? new Date(d.callEndDate) : (d.callEndDate ? d.callEndDate : '');
+ return d;
+ });
+ };
+
+ const clearFilter = () => {
+ initFilters();
+ };
+
+ const initFilters = () => {
+ setFilters({
+ name: {
+ operator: FilterOperator.AND,
+ constraints: [{ value: null, matchMode: FilterMatchMode.STARTS_WITH }]
+ },
+ createdDate: {
+ operator: FilterOperator.AND,
+ constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }]
+ },
+ expirationDate: {
+ operator: FilterOperator.AND,
+ constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }]
+ }
+ });
+ };
+
+ const renderHeader = () => {
+ return (
+
+
+ );
+ };
+
+ const dateCreatedBodyTemplate = (rowData) => {
+ return getDateFromISOstring(rowData.createdDate);
+ };
+ const dateExpirationBodyTemplate = (rowData) => {
+ return getDateFromISOstring(rowData.expirationDate);
+ };
+
+ const dateFilterTemplate = (options) => {
+ return options.filterCallback(e.value, options.index)}
+ dateFormat="mm/dd/yy" placeholder="mm/dd/yyyy" mask="99/99/9999"/>;
+ };
+
+ const catBodyTemplate = (rowData) => {
+ return rowData.category.categoryName;
+ };
+
+ const statusBodyTemplate = (rowData) => {
+ return ;
+ };
+
+ const statusFilterTemplate = (options) => {
+ return options.filterCallback(e.value, options.index)}
+ itemTemplate={statusItemTemplate} placeholder={__('Scegli uno', 'gepafin')}
+ className="p-column-filter"
+ showClear/>;
+ };
+
+ const statusItemTemplate = (option) => {
+ return ;
+ };
+
+ const handleDeleteFile = (id) => {
+ setLoading(true);
+ CompanyDocumentsService.deleteCompanyDocument(id,(resp) => deleteCallback(resp, id), errDeleteCallback)
+ }
+
+ const deleteCallback = (resp, deletedId) => {
+ if (resp.status === 'SUCCESS') {
+ setDocs(docs.filter(o => o.id !== deletedId));
+ }
+ setLoading(false);
+ }
+
+ const errDeleteCallback = () => {
+ setLoading(false);
+ }
+
+ const actionsBodyTemplate = (rowData) => {
+ return
+
+ }
+
+ const confirmDelete = (event, id) => {
+ confirmPopup({
+ target: event.currentTarget,
+ message: __('Sei sicuro di voler rimuovere il file?', 'gepafin'),
+ acceptLabel: __('Si', 'gepafin'),
+ icon: 'pi pi-info-circle',
+ defaultFocus: 'reject',
+ acceptClassName: 'p-button-danger',
+ accept: () => {
+ handleDeleteFile(id);
+ },
+ reject: () => {
+ }
+ });
+ };
+
+ const header = renderHeader();
+
+ return (
+
+ setFilters(e.filters)}>
+
+
+
+
+
+
+
+
+ )
+}
+
+export default DocumentsTable;
diff --git a/src/pages/DocumentsBeneficiary/index.js b/src/pages/DocumentsBeneficiary/index.js
index a101868..7f99c92 100644
--- a/src/pages/DocumentsBeneficiary/index.js
+++ b/src/pages/DocumentsBeneficiary/index.js
@@ -1,23 +1,138 @@
-import React, { useEffect, useState, useCallback } from 'react';
+import React, { useCallback, useEffect, useState } from 'react';
import { __ } from '@wordpress/i18n';
-import { pathOr } from 'ramda';
+import { classNames } from 'primereact/utils';
+import { wrap } from 'object-path-immutable';
+import { isEmpty, isNil } from 'ramda';
-// store
-import { useStore } from '../../store';
+// api
+import DocumentCategoryService from '../../service/document-category-service';
// components
+import DocumentsTable from './components/DocumentsTable';
+import { Dialog } from 'primereact/dialog';
+import { Button } from 'primereact/button';
+import { Dropdown } from 'primereact/dropdown';
+import { InputText } from 'primereact/inputtext';
+import { useStore } from '../../store';
+import { Calendar } from 'primereact/calendar';
+import { FileUpload } from 'primereact/fileupload';
+import formatDateString from '../../helpers/formatDateString';
+import CompanyDocumentsService from '../../service/company-documents-service';
const DocumentsBeneficiary = () => {
+ const [loading, setLoading] = useState(false);
const chosenCompanyId = useStore().main.chosenCompanyId();
+ const [isVisibleAddNewDialog, setIsVisibleAddNewDialog] = useState(false);
+ const [categories, setCategories] = useState(false);
+ const [newFileData, setNewFileData] = useState({});
+ const [fileAttached, setFileAttached] = useState([]);
+ const [reloadHash, setReloadHash] = useState(0);
+ const today = new Date();
+ const tomorrow = new Date(today);
+ tomorrow.setDate(today.getDate() + 1);
- const getStats = (resp) => {}
+ const onCreateNew = useCallback((type) => {
+ const newData = wrap({})
+ .set(['documentType'], type)
+ .set(['documentCategoryId'], 0)
+ .set(['expirationDate'], '')
+ .set(['name'], '')
+ .value();
- const errGetStats = () => {}
+ setNewFileData(newData);
+ setFileAttached([]);
+ setIsVisibleAddNewDialog(true);
+ }, [newFileData, chosenCompanyId]);
+
+ const hideAddNewDialog = () => {
+ setIsVisibleAddNewDialog(false);
+ const newData = wrap({})
+ .set(['documentType'], '')
+ .set(['documentCategoryId'], 0)
+ .set(['expirationDate'], '')
+ .set(['name'], '')
+ .value();
+ setNewFileData(newData);
+ setFileAttached([]);
+ }
+
+ const headerAddNewDialog = () => {
+ return {__('Aggiungi file', 'gepafin')}
+ }
+
+ const footerAddNewDialog = () => {
+ return
+
+
+
+ }
+
+ const isValidForm = useCallback(() => {
+ return !isEmpty(fileAttached) && !Object.keys(newFileData).filter(k => isInvalidField(newFileData, k)
+ || newFileData[k] === 0).length
+ }, [fileAttached, newFileData]);
+
+ const doAddNew = useCallback(() => {
+ const submitData = {
+ ...newFileData,
+ expirationDate: formatDateString(newFileData.expirationDate)
+ }
+ const queryParams = Object.keys(submitData).map(k => [
+ k, submitData[k]
+ ]);
+
+ if (!isEmpty(fileAttached)) {
+ const formData = new FormData()
+ for (const file of fileAttached) {
+ formData.append('file', file)
+ }
+ setLoading(true);
+ CompanyDocumentsService.uploadCompanyDocument(chosenCompanyId, formData, uploadDoc, errUploadDoc, queryParams);
+ }
+ }, [fileAttached, newFileData, chosenCompanyId]);
+
+ const uploadDoc = (resp) => {
+ if (resp.status === 'SUCCESS') {
+ hideAddNewDialog();
+ setReloadHash(new Date().getTime())
+ }
+ setLoading(false);
+ }
+
+ const errUploadDoc = () => {
+ setLoading(false);
+ }
+
+ const isInvalidField = (data, key) => isEmpty(data[key]) || isNil(data[key]);
+
+ const onUpdateFieldValue = useCallback((value, name) => {
+ const newData = wrap(newFileData).set([name], value).value();
+ setNewFileData(newData);
+ }, [newFileData]);
+
+ const onFileSelect = (file) => {
+ setFileAttached(file.files);
+ }
+
+ const getCategories = (resp) => {
+ if (resp.status === 'SUCCESS') {
+ setCategories(resp.data.map(o => ({value: o.id, label: o.description})));
+ }
+ setLoading(false);
+ }
+
+ const errGetCategories = () => {
+ setLoading(false);
+ }
useEffect(() => {
-
- }, [chosenCompanyId]);
+ setLoading(true);
+ DocumentCategoryService.getCategories(getCategories, errGetCategories)
+ }, []);
return(
@@ -28,17 +143,86 @@ const DocumentsBeneficiary = () => {
-
{__('Documenti del rappresentante legale', 'gepafin')}
-
+
+ {__('Documenti del rappresentante legale', 'gepafin')}
+ onCreateNew('PERSONAL_DOCUMENT')}
+ size="small"
+ label={__('Aggiungi nuovo')} icon="pi pi-plus" iconPos="right"/>
+
+
-
{__('Documenti dell\'azienda', 'gepafin')}
-
+
+ {__('Documenti dell\'azienda', 'gepafin')}
+ onCreateNew('COMPANY_DOCUMENT')}
+ size="small"
+ label={__('Aggiungi nuovo')} icon="pi pi-plus" iconPos="right"/>
+
+
+
)
}
diff --git a/src/service/company-documents-service.js b/src/service/company-documents-service.js
new file mode 100644
index 0000000..9e6676b
--- /dev/null
+++ b/src/service/company-documents-service.js
@@ -0,0 +1,20 @@
+import { NetworkService } from './network-service';
+
+const API_BASE_URL = process.env.REACT_APP_API_EXECUTION_ADDRESS;
+
+export default class CompanyDocumentsService {
+
+ static getCompanyDocuments = (companyId, callback, errCallback, queryParams) => {
+ NetworkService.get(`${API_BASE_URL}/companyDocument/company/${companyId}`, callback, errCallback, queryParams);
+ };
+
+ static uploadCompanyDocument = (id, body, callback, errCallback, queryParams) => {
+ NetworkService.postMultiPart(`${API_BASE_URL}/companyDocument/company/${id}/upload`, body, callback, errCallback, queryParams);
+ };
+
+ static deleteCompanyDocument = (id, callback, errCallback) => {
+ NetworkService.delete(`${API_BASE_URL}/companyDocument`, {}, callback, errCallback, [
+ ['id', id]
+ ]);
+ };
+}
diff --git a/src/service/document-category-service.js b/src/service/document-category-service.js
new file mode 100644
index 0000000..1cdb30b
--- /dev/null
+++ b/src/service/document-category-service.js
@@ -0,0 +1,10 @@
+import { NetworkService } from './network-service';
+
+const API_BASE_URL = process.env.REACT_APP_API_EXECUTION_ADDRESS;
+
+export default class DocumentCategoryService {
+
+ static getCategories = (callback, errCallback) => {
+ NetworkService.get(`${API_BASE_URL}/documentCategory`, callback, errCallback);
+ };
+}
diff --git a/src/translationStringsForComponents.js b/src/translationStringsForComponents.js
index e33247e..2591a26 100644
--- a/src/translationStringsForComponents.js
+++ b/src/translationStringsForComponents.js
@@ -1,5 +1,6 @@
/* data table related */
import { __ } from '@wordpress/i18n';
+import { FilterMatchMode } from 'primereact/api';
const currentPageReportTemplate = '';