- added new root manage UIs;

This commit is contained in:
Vitalii Kiiko
2026-03-24 16:51:14 +01:00
parent ddd036b070
commit 6eea331530
12 changed files with 695 additions and 28 deletions

View File

@@ -158,7 +158,8 @@ const AppSidebar = () => {
'ROOT_MANAGE_APPL_VIEW_DELETED',
'ROOT_MANAGE_APPL_DELETE_CONFIRM',
'ROOT_MANAGE_APPL_DELETE',
'ROOT_MANAGE_PEC_SEND'
'ROOT_MANAGE_PEC_SEND',
'ROOT_MANAGE_VIEW_LOG'
]).length
},
{

View File

@@ -0,0 +1,121 @@
import React, { useState, useRef, useCallback } from 'react';
import { __ } from '@wordpress/i18n';
// api
import AdminService from '../../../../service/admin-service';
// components
import { InputText } from 'primereact/inputtext';
import { InputTextarea } from 'primereact/inputtextarea';
import { Button } from 'primereact/button';
import { Toast } from 'primereact/toast';
const ManageSendPecSection = () => {
const [subject, setSubject] = useState('');
const [body, setBody] = useState('');
const [csvFile, setCsvFile] = useState(null);
const [attachment, setAttachment] = useState(null);
const [localAsyncRequest, setLocalAsyncRequest] = useState(false);
const toast = useRef(null);
const csvInputRef = useRef(null);
const attachmentInputRef = useRef(null);
const isSubmitDisabled = localAsyncRequest || !subject.trim() || !body.trim() || !csvFile;
const handleSubmit = useCallback(() => {
const formData = new FormData();
formData.append('subject', subject);
formData.append('body', body);
formData.append('csv_file', csvFile);
if (attachment) {
formData.append('attachment', attachment);
}
setLocalAsyncRequest(true);
AdminService.doSendPec(
formData,
(resp) => {
setLocalAsyncRequest(false);
if (resp && resp.status === 'ok') {
const detail = resp.data
? __(`Invio completato: ${resp.data.total_sent} inviati, ${resp.data.total_errors} errori`, 'gepafin')
: __('Invio completato con successo', 'gepafin');
if (toast.current) {
toast.current.show({ severity: 'success', summary: '', detail });
}
setSubject('');
setBody('');
setCsvFile(null);
setAttachment(null);
if (csvInputRef.current) csvInputRef.current.value = '';
if (attachmentInputRef.current) attachmentInputRef.current.value = '';
} else {
if (toast.current) {
toast.current.show({ severity: 'error', summary: '', detail: resp && resp.detail ? resp.detail : __('Errore durante l\'invio', 'gepafin') });
}
}
},
(resp) => {
setLocalAsyncRequest(false);
if (toast.current) {
toast.current.show({ severity: 'error', summary: '', detail: resp && resp.detail ? resp.detail : __('Errore durante l\'invio', 'gepafin') });
}
}
);
}, [subject, body, csvFile, attachment]);
return (
<div className="appPageSection">
<h2>{__('Invio PEC Massivo', 'gepafin')}</h2>
<Toast ref={toast}/>
<div className="appForm">
<div className="appForm__field">
<label htmlFor="pecSubject">{__('Oggetto', 'gepafin')} *</label>
<InputText
id="pecSubject"
value={subject}
onChange={(e) => setSubject(e.target.value)}
style={{ width: '100%' }}/>
</div>
<div className="appForm__field">
<label htmlFor="pecBody">{__('Corpo della PEC', 'gepafin')} *</label>
<InputTextarea
id="pecBody"
value={body}
onChange={(e) => setBody(e.target.value)}
rows={8}
style={{ width: '100%' }}/>
</div>
<div className="appForm__field">
<label htmlFor="pecCsv">{__('File CSV destinatari', 'gepafin')} *</label>
<input
ref={csvInputRef}
id="pecCsv"
type="file"
accept=".csv"
onChange={(e) => setCsvFile(e.target.files[0] || null)}/>
<small>{__('Il file CSV deve contenere gli indirizzi PEC nella prima colonna', 'gepafin')}</small>
</div>
<div className="appForm__field">
<label htmlFor="pecAttachment">{__('Allegato (opzionale)', 'gepafin')}</label>
<input
ref={attachmentInputRef}
id="pecAttachment"
type="file"
onChange={(e) => setAttachment(e.target.files[0] || null)}/>
</div>
<div className="appPageSection__actions">
<Button
type="button"
label={__('Invia PEC', 'gepafin')}
icon="pi pi-send"
loading={localAsyncRequest}
disabled={isSubmitDisabled}
onClick={handleSubmit}/>
</div>
</div>
</div>
);
};
export default ManageSendPecSection;

View File

@@ -1,46 +1,88 @@
import React from 'react';
import { __ } from '@wordpress/i18n';
import { intersection } from 'ramda';
import { useNavigate } from 'react-router-dom';
// store
import { useStoreValue } from '../../store';
// components
import ManageNdgSection from './components/ManageNdgSection';
import ManageApplStatusSection from './components/ManageApplStatusSection';
import ManageAmendmentReopenSection from './components/ManageAmendmentReopenSection';
import ManageAmendmentExtendSection from './components/ManageAmendmentExtendSection';
import ManageApplDeleteSection from './components/ManageApplDeleteSection';
import { Card } from 'primereact/card';
const navItems = [
{
permission: ['ROOT_MANAGE_NDG'],
route: '/admin/set-ndg',
label: __('Gestione NDG', 'gepafin'),
subtitle: __('Imposta il codice NDG per le domande', 'gepafin'),
icon: 'pi pi-id-card'
},
{
permission: ['ROOT_MANAGE_APPL_STATUS'],
route: '/admin/set-status',
label: __('Gestione Stato Domanda', 'gepafin'),
subtitle: __('Modifica lo stato delle domande', 'gepafin'),
icon: 'pi pi-list'
},
{
permission: ['ROOT_MANAGE_AMENDMENT_REOPEN'],
route: '/admin/amendment-reopen',
label: __('Riapri Integrazione', 'gepafin'),
subtitle: __('Riapri un\'integrazione chiusa', 'gepafin'),
icon: 'pi pi-refresh'
},
{
permission: ['ROOT_MANAGE_AMENDMENT_EXTEND'],
route: '/admin/amendment-extend',
label: __('Estendi Integrazione', 'gepafin'),
subtitle: __('Estendi la scadenza di un\'integrazione', 'gepafin'),
icon: 'pi pi-calendar-plus'
},
{
permission: ['ROOT_MANAGE_APPL_VIEW_DELETED', 'ROOT_MANAGE_APPL_DELETE_CONFIRM', 'ROOT_MANAGE_APPL_DELETE'],
route: '/admin/elimina-domande',
label: __('Elimina Domande', 'gepafin'),
subtitle: __('Gestione eliminazione domande', 'gepafin'),
icon: 'pi pi-trash'
},
{
permission: ['ROOT_MANAGE_VIEW_LOG'],
route: '/admin/log',
label: __('Log Operazioni', 'gepafin'),
subtitle: __('Storico delle operazioni amministrative', 'gepafin'),
icon: 'pi pi-history'
},
{
permission: ['ROOT_MANAGE_PEC_SEND'],
route: '/admin/send-pec',
label: __('Invio PEC Massivo', 'gepafin'),
subtitle: __('Invia PEC a più destinatari tramite file CSV', 'gepafin'),
icon: 'pi pi-envelope'
}
];
const Admin = () => {
const permissions = useStoreValue('getPermissions');
const navigate = useNavigate();
const hasNdg = intersection(permissions, ['ROOT_MANAGE_NDG']).length > 0;
const hasApplStatus = intersection(permissions, ['ROOT_MANAGE_APPL_STATUS']).length > 0;
const hasAmendmentReopen = intersection(permissions, ['ROOT_MANAGE_AMENDMENT_REOPEN']).length > 0;
const hasAmendmentExtend = intersection(permissions, ['ROOT_MANAGE_AMENDMENT_EXTEND']).length > 0;
const hasApplDelete = intersection(permissions, [
'ROOT_MANAGE_APPL_VIEW_DELETED',
'ROOT_MANAGE_APPL_DELETE_CONFIRM',
'ROOT_MANAGE_APPL_DELETE'
]).length > 0;
const canViewDeleted = intersection(permissions, ['ROOT_MANAGE_APPL_VIEW_DELETED']).length > 0;
const canDeleteConfirm = intersection(permissions, ['ROOT_MANAGE_APPL_DELETE_CONFIRM']).length > 0;
const canDelete = intersection(permissions, ['ROOT_MANAGE_APPL_DELETE']).length > 0;
const visibleItems = navItems.filter(
(item) => intersection(permissions, item.permission).length > 0
);
return <div className="appPage">
<div className="appPage__pageHeader"><h1>{__('Admin', 'gepafin')}</h1></div>
<div className="appPage__spacer"></div>
{hasNdg && <><ManageNdgSection/><div className="appPage__spacer"></div></>}
{hasApplStatus && <><ManageApplStatusSection/><div className="appPage__spacer"></div></>}
{hasAmendmentReopen && <><ManageAmendmentReopenSection/><div className="appPage__spacer"></div></>}
{hasAmendmentExtend && <><ManageAmendmentExtendSection/><div className="appPage__spacer"></div></>}
{hasApplDelete && <><ManageApplDeleteSection
canViewDeleted={canViewDeleted}
canDeleteConfirm={canDeleteConfirm}
canDelete={canDelete}
/><div className="appPage__spacer"></div></>}
<div style={{ display: 'flex', flexWrap: 'wrap', gap: '1rem' }}>
{visibleItems.map((item) => (
<Card
key={item.route}
title={<span><i className={item.icon} style={{ marginRight: '0.5rem' }}/>{item.label}</span>}
subTitle={item.subtitle}
style={{ width: '280px', cursor: 'pointer', padding: '0.5rem' }}
onClick={() => navigate(item.route)}
/>
))}
</div>
</div>
}

View File

@@ -0,0 +1,35 @@
import React, { useEffect } from 'react';
import { __ } from '@wordpress/i18n';
import { intersection } from 'ramda';
import { useNavigate } from 'react-router-dom';
// store
import { useStoreValue } from '../../store';
// components
import { Button } from 'primereact/button';
import ManageAmendmentExtendSection from '../Admin/components/ManageAmendmentExtendSection';
const AdminAmendmentExtend = () => {
const permissions = useStoreValue('getPermissions');
const navigate = useNavigate();
const hasPermission = intersection(permissions, ['ROOT_MANAGE_AMENDMENT_EXTEND']).length > 0;
useEffect(() => {
if (!hasPermission) navigate('/admin');
}, [hasPermission]);
return <div className="appPage">
<div className="appPage__pageHeader">
<h1>{__('Estendi Integrazione', 'gepafin')}</h1>
</div>
<div className="appPage__spacer"></div>
<div className="appPageSection__actions">
<Button type="button" outlined label={__('Indietro', 'gepafin')} icon="pi pi-arrow-left" onClick={() => navigate('/admin')}/>
</div>
<div className="appPage__spacer"></div>
{hasPermission && <ManageAmendmentExtendSection/>}
</div>
}
export default AdminAmendmentExtend;

View File

@@ -0,0 +1,35 @@
import React, { useEffect } from 'react';
import { __ } from '@wordpress/i18n';
import { intersection } from 'ramda';
import { useNavigate } from 'react-router-dom';
// store
import { useStoreValue } from '../../store';
// components
import { Button } from 'primereact/button';
import ManageAmendmentReopenSection from '../Admin/components/ManageAmendmentReopenSection';
const AdminAmendmentReopen = () => {
const permissions = useStoreValue('getPermissions');
const navigate = useNavigate();
const hasPermission = intersection(permissions, ['ROOT_MANAGE_AMENDMENT_REOPEN']).length > 0;
useEffect(() => {
if (!hasPermission) navigate('/admin');
}, [hasPermission]);
return <div className="appPage">
<div className="appPage__pageHeader">
<h1>{__('Riapri Integrazione', 'gepafin')}</h1>
</div>
<div className="appPage__spacer"></div>
<div className="appPageSection__actions">
<Button type="button" outlined label={__('Indietro', 'gepafin')} icon="pi pi-arrow-left" onClick={() => navigate('/admin')}/>
</div>
<div className="appPage__spacer"></div>
{hasPermission && <ManageAmendmentReopenSection/>}
</div>
}
export default AdminAmendmentReopen;

View File

@@ -0,0 +1,48 @@
import React, { useEffect } from 'react';
import { __ } from '@wordpress/i18n';
import { intersection } from 'ramda';
import { useNavigate } from 'react-router-dom';
// store
import { useStoreValue } from '../../store';
// components
import { Button } from 'primereact/button';
import ManageApplDeleteSection from '../Admin/components/ManageApplDeleteSection';
const DELETE_PERMISSIONS = [
'ROOT_MANAGE_APPL_VIEW_DELETED',
'ROOT_MANAGE_APPL_DELETE_CONFIRM',
'ROOT_MANAGE_APPL_DELETE'
];
const AdminEliminaDomande = () => {
const permissions = useStoreValue('getPermissions');
const navigate = useNavigate();
const hasPermission = intersection(permissions, DELETE_PERMISSIONS).length > 0;
const canViewDeleted = intersection(permissions, ['ROOT_MANAGE_APPL_VIEW_DELETED']).length > 0;
const canDeleteConfirm = intersection(permissions, ['ROOT_MANAGE_APPL_DELETE_CONFIRM']).length > 0;
const canDelete = intersection(permissions, ['ROOT_MANAGE_APPL_DELETE']).length > 0;
useEffect(() => {
if (!hasPermission) navigate('/admin');
}, [hasPermission]);
return <div className="appPage">
<div className="appPage__pageHeader">
<h1>{__('Elimina Domande', 'gepafin')}</h1>
</div>
<div className="appPage__spacer"></div>
<div className="appPageSection__actions">
<Button type="button" outlined label={__('Indietro', 'gepafin')} icon="pi pi-arrow-left" onClick={() => navigate('/admin')}/>
</div>
<div className="appPage__spacer"></div>
{hasPermission && <ManageApplDeleteSection
canViewDeleted={canViewDeleted}
canDeleteConfirm={canDeleteConfirm}
canDelete={canDelete}
/>}
</div>
}
export default AdminEliminaDomande;

244
src/pages/AdminLog/index.js Normal file
View File

@@ -0,0 +1,244 @@
import React, { useEffect, useState, useRef } from 'react';
import { __ } from '@wordpress/i18n';
import { intersection } from 'ramda';
import { useNavigate } from 'react-router-dom';
// store
import { useStoreValue } from '../../store';
// api
import AdminService from '../../service/admin-service';
// components
import { Button } from 'primereact/button';
import { InputText } from 'primereact/inputtext';
import { Calendar } from 'primereact/calendar';
import { DataTable } from 'primereact/datatable';
import { Column } from 'primereact/column';
import { Dialog } from 'primereact/dialog';
import { Toast } from 'primereact/toast';
const buildDiffRows = (oldData, newData) => {
const keys = Array.from(new Set([
...Object.keys(oldData || {}),
...Object.keys(newData || {})
]));
return keys.map((key) => ({
key,
old: oldData ? String(oldData[key] ?? '') : '',
new: newData ? String(newData[key] ?? '') : ''
}));
};
const AdminLog = () => {
const permissions = useStoreValue('getPermissions');
const navigate = useNavigate();
const toast = useRef(null);
const hasPermission = intersection(permissions, ['ROOT_MANAGE_VIEW_LOG']).length > 0;
const [callId, setCallId] = useState('');
const [userId, setUserId] = useState('');
const [dateFrom, setDateFrom] = useState(null);
const [dateTo, setDateTo] = useState(null);
const [items, setItems] = useState(null);
const [totalRecordsNum, setTotalRecordsNum] = useState(0);
const [loading, setLoading] = useState(false);
const [lazyState, setLazyState] = useState({ first: 0, rows: 10, page: 0 });
const [detailRow, setDetailRow] = useState(null);
useEffect(() => {
if (!hasPermission) navigate('/admin');
}, [hasPermission]);
const formatDate = (date) => {
if (!date) return undefined;
const d = new Date(date);
const year = d.getFullYear();
const month = String(d.getMonth() + 1).padStart(2, '0');
const day = String(d.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
};
const validate = () => {
if ((dateFrom && !dateTo) || (!dateFrom && dateTo)) {
toast.current.show({
severity: 'warn',
summary: __('Attenzione', 'gepafin'),
detail: __('Inserire sia la data di inizio che la data di fine.', 'gepafin')
});
return false;
}
if (dateFrom && dateTo && dateFrom > dateTo) {
toast.current.show({
severity: 'warn',
summary: __('Attenzione', 'gepafin'),
detail: __('La data di inizio non può essere superiore alla data di fine.', 'gepafin')
});
return false;
}
return true;
};
const fetchData = (page = 0, rows = lazyState.rows) => {
if (!validate()) return;
setLoading(true);
const queryParams = [
['page', page + 1],
['limit', rows]
];
if (callId) queryParams.push(['call_id', callId]);
if (userId) queryParams.push(['user_id', userId]);
if (dateFrom) queryParams.push(['date_from', formatDate(dateFrom)]);
if (dateTo) queryParams.push(['date_to', formatDate(dateTo)]);
AdminService.getAdminLog(
(resp) => {
if (resp && resp.status === 'ok') {
setItems(resp.records || []);
setTotalRecordsNum(resp.totalRecords || 0);
}
setLoading(false);
},
() => { setLoading(false); },
queryParams
);
};
const onPage = (event) => {
setLazyState(event);
fetchData(event.page, event.rows);
};
const azioniTemplate = (row) => (
<Button
size="small"
label={__('Mostra dettagli', 'gepafin')}
icon="pi pi-eye"
onClick={() => setDetailRow(row)}
/>
);
const userTemplate = (row) => {
return `${row.utente.email}`;
}
return <div className="appPage">
<Toast ref={toast}/>
<div className="appPage__pageHeader">
<h1>{__('Log Operazioni', 'gepafin')}</h1>
</div>
<div className="appPage__spacer"></div>
<div className="appPageSection__actions">
<Button type="button" outlined label={__('Indietro', 'gepafin')} icon="pi pi-arrow-left" onClick={() => navigate('/admin')}/>
</div>
<div className="appPage__spacer"></div>
<div className="appPageSection">
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: '1rem', marginBottom: '1rem' }}>
<div className="formLayout__col">
<label htmlFor="callId">{__('ID Bando', 'gepafin')}</label>
<InputText
id="callId"
value={callId}
onChange={(e) => setCallId(e.target.value)}
style={{ width: '100%' }}
/>
</div>
<div className="formLayout__col">
<label htmlFor="userId">{__('ID Utente', 'gepafin')}</label>
<InputText
id="userId"
value={userId}
onChange={(e) => setUserId(e.target.value)}
style={{ width: '100%' }}
/>
</div>
<div className="formLayout__col">
<label htmlFor="dateFrom">{__('Data da', 'gepafin')}</label>
<Calendar
id="dateFrom"
value={dateFrom}
onChange={(e) => setDateFrom(e.value)}
dateFormat="dd/mm/yy"
showIcon
style={{ width: '100%' }}
/>
</div>
<div className="formLayout__col">
<label htmlFor="dateTo">{__('Data a', 'gepafin')}</label>
<Calendar
id="dateTo"
value={dateTo}
onChange={(e) => setDateTo(e.value)}
dateFormat="dd/mm/yy"
showIcon
style={{ width: '100%' }}
/>
</div>
</div>
<Button
label={__('Cerca', 'gepafin')}
icon="pi pi-search"
size="small"
onClick={() => {
setLazyState((s) => ({ ...s, first: 0, page: 0 }));
fetchData(0);
}}
loading={loading}
/>
</div>
<div className="appPage__spacer"></div>
<div className="appPageSection__table">
<DataTable
value={items}
lazy
paginator
first={lazyState.first}
rows={lazyState.rows}
totalRecords={totalRecordsNum}
onPage={onPage}
loading={loading}
emptyMessage={__('Nessun risultato trovato.', 'gepafin')}
>
<Column field="user_action_id" header={__('ID', 'gepafin')}/>
<Column field="call_id" header={__('ID Bando', 'gepafin')}/>
<Column field="periodo" header={__('Periodo', 'gepafin')}/>
<Column header={__('Utente', 'gepafin')} body={userTemplate}/>
<Column field="action_context" header={__('Azione', 'gepafin')}/>
<Column header={__('Azioni', 'gepafin')} body={azioniTemplate}/>
</DataTable>
</div>
<Dialog
header={__('Dettagli operazione', 'gepafin')}
visible={!!detailRow}
style={{ width: '80vw' }}
onHide={() => setDetailRow(null)}
>
{detailRow && (detailRow.version_history || []).map((vh, idx) => (
<div key={vh.version_history_id ?? idx} style={{ marginBottom: '1.5rem' }}>
<h3 style={{ marginBottom: '0.5rem' }}>
{vh.table_name} {vh.version_history_action_type}
</h3>
<DataTable
value={buildDiffRows(vh.old_data, vh.new_data)}
size="small"
scrollable
scrollHeight="300px"
emptyMessage={__('Nessun dato.', 'gepafin')}
>
<Column field="key" header={__('Campo', 'gepafin')} style={{ width: '30%' }}/>
<Column field="old" header={__('Vecchio valore', 'gepafin')} style={{ width: '35%' }}/>
<Column field="new" header={__('Nuovo valore', 'gepafin')} style={{ width: '35%' }}/>
</DataTable>
</div>
))}
</Dialog>
</div>
}
export default AdminLog;

View File

@@ -0,0 +1,35 @@
import React, { useEffect } from 'react';
import { __ } from '@wordpress/i18n';
import { intersection } from 'ramda';
import { useNavigate } from 'react-router-dom';
// store
import { useStoreValue } from '../../store';
// components
import { Button } from 'primereact/button';
import ManageSendPecSection from '../Admin/components/ManageSendPecSection';
const AdminSendPec = () => {
const permissions = useStoreValue('getPermissions');
const navigate = useNavigate();
const hasPermission = intersection(permissions, ['ROOT_MANAGE_PEC_SEND']).length > 0;
useEffect(() => {
if (!hasPermission) navigate('/admin');
}, [hasPermission]);
return <div className="appPage">
<div className="appPage__pageHeader">
<h1>{__('Invio PEC Massivo', 'gepafin')}</h1>
</div>
<div className="appPage__spacer"></div>
<div className="appPageSection__actions">
<Button type="button" outlined label={__('Indietro', 'gepafin')} icon="pi pi-arrow-left" onClick={() => navigate('/admin')}/>
</div>
<div className="appPage__spacer"></div>
{hasPermission && <ManageSendPecSection/>}
</div>
}
export default AdminSendPec;

View File

@@ -0,0 +1,35 @@
import React, { useEffect } from 'react';
import { __ } from '@wordpress/i18n';
import { intersection } from 'ramda';
import { useNavigate } from 'react-router-dom';
// store
import { useStoreValue } from '../../store';
// components
import { Button } from 'primereact/button';
import ManageNdgSection from '../Admin/components/ManageNdgSection';
const AdminSetNdg = () => {
const permissions = useStoreValue('getPermissions');
const navigate = useNavigate();
const hasPermission = intersection(permissions, ['ROOT_MANAGE_NDG']).length > 0;
useEffect(() => {
if (!hasPermission) navigate('/admin');
}, [hasPermission]);
return <div className="appPage">
<div className="appPage__pageHeader">
<h1>{__('Gestione NDG', 'gepafin')}</h1>
</div>
<div className="appPage__spacer"></div>
<div className="appPageSection__actions">
<Button type="button" outlined label={__('Indietro', 'gepafin')} icon="pi pi-arrow-left" onClick={() => navigate('/admin')}/>
</div>
<div className="appPage__spacer"></div>
{hasPermission && <ManageNdgSection/>}
</div>
}
export default AdminSetNdg;

View File

@@ -0,0 +1,35 @@
import React, { useEffect } from 'react';
import { __ } from '@wordpress/i18n';
import { intersection } from 'ramda';
import { useNavigate } from 'react-router-dom';
// store
import { useStoreValue } from '../../store';
// components
import { Button } from 'primereact/button';
import ManageApplStatusSection from '../Admin/components/ManageApplStatusSection';
const AdminSetStatus = () => {
const permissions = useStoreValue('getPermissions');
const navigate = useNavigate();
const hasPermission = intersection(permissions, ['ROOT_MANAGE_APPL_STATUS']).length > 0;
useEffect(() => {
if (!hasPermission) navigate('/admin');
}, [hasPermission]);
return <div className="appPage">
<div className="appPage__pageHeader">
<h1>{__('Gestione Stato Domanda', 'gepafin')}</h1>
</div>
<div className="appPage__spacer"></div>
<div className="appPageSection__actions">
<Button type="button" outlined label={__('Indietro', 'gepafin')} icon="pi pi-arrow-left" onClick={() => navigate('/admin')}/>
</div>
<div className="appPage__spacer"></div>
{hasPermission && <ManageApplStatusSection/>}
</div>
}
export default AdminSetStatus;

View File

@@ -57,6 +57,13 @@ import ResetPasswordAdmin from './pages/ResetPasswordAdmin';
import DashboardBeneficiarioConfidi from './pages/DashboardBeneficiarioConfidi';
import DashboardDirector from './pages/DashboardDirector';
import Admin from './pages/Admin';
import AdminSetNdg from './pages/AdminSetNdg';
import AdminSetStatus from './pages/AdminSetStatus';
import AdminAmendmentReopen from './pages/AdminAmendmentReopen';
import AdminAmendmentExtend from './pages/AdminAmendmentExtend';
import AdminEliminaDomande from './pages/AdminEliminaDomande';
import AdminLog from './pages/AdminLog';
import AdminSendPec from './pages/AdminSendPec';
const routes = ({ role, chosenCompanyId }) => {
@@ -291,6 +298,27 @@ const routes = ({ role, chosenCompanyId }) => {
<Route path="/admin" element={<DefaultLayout>
<Admin/>
</DefaultLayout>}/>
<Route path="/admin/set-ndg" element={<DefaultLayout>
<AdminSetNdg/>
</DefaultLayout>}/>
<Route path="/admin/set-status" element={<DefaultLayout>
<AdminSetStatus/>
</DefaultLayout>}/>
<Route path="/admin/amendment-reopen" element={<DefaultLayout>
<AdminAmendmentReopen/>
</DefaultLayout>}/>
<Route path="/admin/amendment-extend" element={<DefaultLayout>
<AdminAmendmentExtend/>
</DefaultLayout>}/>
<Route path="/admin/elimina-domande" element={<DefaultLayout>
<AdminEliminaDomande/>
</DefaultLayout>}/>
<Route path="/admin/log" element={<DefaultLayout>
<AdminLog/>
</DefaultLayout>}/>
<Route path="/admin/send-pec" element={<DefaultLayout>
<AdminSendPec/>
</DefaultLayout>}/>
</Route>
<Route exact path="/reset-password" element={<ResetPassword/>}/>
<Route exact path="/reset-password-admin" element={<ResetPasswordAdmin/>}/>

View File

@@ -19,4 +19,12 @@ export default class AdminService {
static doAmendmentExtend = (body, callback, errCallback, queryParams) => {
NetworkService.post(`${API_ADMIN_BASE_URL}/extend-days`, body, callback, errCallback, queryParams);
};
static doSendPec = (body, callback, errCallback, queryParams) => {
NetworkService.post(`${API_ADMIN_BASE_URL}/send-pec`, body, callback, errCallback, queryParams);
};
static getAdminLog = (callback, errCallback, queryParams) => {
NetworkService.get(`${API_ADMIN_BASE_URL}/admin-operations`, callback, errCallback, queryParams);
};
}