Files
bflows-bandi-fe/src/layouts/DefaultLayout/components/AppSidebar/index.js
BFLOWS 7c508e743b feat(ar1-admin): pagina superadmin Configurazione AR1 (pattern Rendicontazione)
Seconda voce sidebar per superadmin, pattern identico a Rendicontazione:
- benef (APPLY_CALLS) -> 'Dichiarazione AR1' -> /ar1 (compilazione)
- superadmin (MANAGE_TENDERS) -> 'Configurazione AR1' -> /ar1-admin (config)

service/ar1Service.js: +11 metodi admin (adminList/Get Templates, adminUpdateLayout,
adminNewVersion, adminGet/Update Policy, CRUD PecSchedule, adminBulkRecompilation).

pages/Ar1AdminConfig.js (532 LOC): 4 tab PrimeReact TabView:
  1. Template AR1: DataTable 3 varianti, badge status ACTIVE/DRAFT/ARCHIVED,
     drawer detail con textarea JSON layout_config editabile + save,
     bottone 'nuova versione' con modale (semver regex + activate_now)
  2. Policy: form con InputNumber/InputSwitch/Checkbox per 6 campi policy
     (validity_days 30-1825, popup_dismiss_hours 1-168, popup_force_on_expired,
     auto_archive_on_company_document, company_document_category_id, allow_bulk)
  3. Regole Reminder PEC: DataTable CRUD con dialog edit, Chips, InputSwitch
  4. Invio Massivo PEC: 4 filtri (only_expired, only_missing, company_ids Chips,
     expired_before Calendar) + dry-run counter + confirm dialog + submit live

Sidebar: voce id=23 'Configurazione AR1' icon 'pi pi-cog' href '/ar1-admin'
permessi MANAGE_TENDERS (accanto a 'Rendicontazione').

Routes: /ar1-admin solo ROLE_SUPER_ADMIN, altri ruoli -> PageNotFound.

Parse check @babel/parser+JSX: 4 OK / 0 FAIL. Webpack compiled 1 warning (vecchio,
unrelated).
2026-04-23 11:06:18 +02:00

245 lines
8.2 KiB
JavaScript

import React from 'react';
import { __ } from '@wordpress/i18n';
import { intersection, is } from 'ramda';
// store
import { useStoreValue } from '../../../../store';
// components
import { NavLink } from 'react-router-dom';
import HelpIcon from '../../../../icons/HelpIcon';
const AppSidebar = () => {
const permissions = useStoreValue('getPermissions');
const items = [
{
label: __('Riepilogo', 'gepafin'),
icon: 'pi pi-objects-column',
href: '/',
id: 1,
enable: true
},
{
label: __('Gestione bandi', 'gepafin'),
icon: 'pi pi-file',
href: '/bandi',
id: 2,
enable: intersection(permissions, ['MANAGE_TENDERS']).length
},
{
label: __('Istruttoria rendicontazioni', 'gepafin'),
icon: 'pi pi-check-square',
href: '/istruttoria',
id: 12,
enable: intersection(permissions, ['EVALUATE_APPLICATIONS']).length
},
{
label: __('Rendicontazione', 'gepafin'),
icon: 'pi pi-receipt',
href: '/rendicontazione',
id: 21,
enable: intersection(permissions, ['MANAGE_TENDERS']).length
},
{
label: __('Configurazione AR1', 'gepafin'),
icon: 'pi pi-id-card',
href: '/ar1-admin',
id: 23,
enable: intersection(permissions, ['MANAGE_TENDERS']).length
},
{
label: __('Dev: cambia utente', 'gepafin'),
icon: 'pi pi-user-edit',
href: '/dev-switch-user',
id: 99,
enable: intersection(permissions, ['MANAGE_USERS']).length
},
{
label: __('Domande in lavorazione', 'gepafin'),
icon: 'pi pi-file',
href: '/imieibandi',
id: 3,
enable: intersection(permissions, ['APPLY_CALLS', 'APPLY_CONFIDI_CALLS']).length
},
{
label: __('Dichiarazione AR1', 'gepafin'),
icon: 'pi pi-id-card',
href: '/ar1',
id: 22,
enable: intersection(permissions, ['APPLY_CALLS', 'APPLY_CONFIDI_CALLS']).length
},
{
label: __('Bandi disponibili', 'gepafin'),
icon: 'pi pi-bookmark',
href: '/bandi',
id: 4,
enable: intersection(permissions, ['VIEW_CALLS', 'VIEW_CONFIDI_CALLS']).length
},
{
label: __('Bandi osservati', 'gepafin'),
icon: 'pi pi-star',
href: '/bandi-osservati',
id: 5,
enable: intersection(permissions, ['VIEW_CALLS', 'VIEW_CONFIDI_CALLS']).length
},
{
label: __('Gestione domande', 'gepafin'),
icon: 'pi pi-file',
href: '/domande',
id: 6,
enable: intersection(permissions, ['VIEW_USERS', 'MANAGE_USERS', 'ASSIGED_APPLICATION']).length
},
{
label: __('Domande da valutare', 'gepafin'),
icon: 'pi pi-calendar-clock',
href: '/domande',
id: 7,
enable: intersection(permissions, ['EVALUATE_APPLICATIONS']).length && !intersection(permissions, ['ASSIGED_APPLICATION']).length
},
{
label: __('Bandi attivi', 'gepafin'),
icon: 'pi pi-file',
href: '/bandi',
id: 8,
enable: intersection(permissions, ['EVALUATE_APPLICATIONS']).length
},
{
label: __('Soccorso', 'gepafin'),
icon: <HelpIcon/>,
href: '/soccorso-istruttorio',
id: 9,
enable: intersection(permissions, ['EVALUATE_APPLICATIONS']).length
},
{
label: __('Archivio domande', 'gepafin'),
icon: 'pi pi-briefcase',
href: '/domande',
id: 10,
enable: intersection(permissions, ['APPLY_CALLS', 'APPLY_CONFIDI_CALLS']).length
},
{
label: __('Le mie rendicontazioni', 'gepafin'),
icon: 'pi pi-receipt',
href: '/rendicontazioni',
id: 11,
enable: intersection(permissions, ['APPLY_CALLS', 'APPLY_CONFIDI_CALLS']).length
},
{
label: __('Archivio domande', 'gepafin'),
icon: 'pi pi-briefcase',
href: '/domande-archivio',
id: 11,
enable: intersection(permissions, ['VIEW_USERS', 'MANAGE_USERS']).length
},
{
label: __('Archivio domande', 'gepafin'),
icon: 'pi pi-briefcase',
href: '/domande-archivio',
id: 12,
enable: intersection(permissions, ['EVALUATE_APPLICATIONS']).length
},
{
label: __('Area personale', 'gepafin'),
icon: 'pi pi-calendar-clock',
id: 17,
enable: intersection(permissions, ['ASSIGED_APPLICATION']).length
},
{
label: __('Domande da valutare', 'gepafin'),
icon: 'pi pi-calendar-clock',
href: '/mie-domande',
id: 18,
enable: intersection(permissions, ['ASSIGED_APPLICATION']).length
},
{
label: __('Soccorso istruttorio', 'gepafin'),
icon: <HelpIcon/>,
href: '/mio-soccorso-istruttorio',
id: 19,
enable: intersection(permissions, ['ASSIGED_APPLICATION']).length
},
{
label: __('Gestione utenti', 'gepafin'),
icon: 'pi pi-users',
href: '/utenti',
id: 13,
enable: intersection(permissions, ['VIEW_USERS', 'MANAGE_USERS']).length
},
{
label: __('Configurazione', 'gepafin'),
icon: 'pi pi-cog',
//href: '/configurazione',
id: 14,
enable: false
},
{
label: __('Statistiche', 'gepafin'),
icon: 'pi pi-chart-bar',
href: '/stats',
id: 15,
enable: intersection(permissions, ['APPLY_CALLS', 'APPLY_CONFIDI_CALLS']).length
},
{
label: __('Documenti', 'gepafin'),
icon: 'pi pi-folder-open',
href: '/documenti',
id: 16,
enable: intersection(permissions, ['APPLY_CALLS', 'APPLY_CONFIDI_CALLS']).length
},
{
label: __('Admin', 'gepafin'),
icon: 'pi pi-shield',
href: '/admin',
id: 20,
enable: intersection(permissions, [
'ROOT_MANAGE_NDG',
'ROOT_MANAGE_APPL_STATUS',
'ROOT_MANAGE_AMENDMENT_REOPEN',
'ROOT_MANAGE_AMENDMENT_EXTEND',
'ROOT_MANAGE_APPL_VIEW_DELETED',
'ROOT_MANAGE_APPL_DELETE_CONFIRM',
'ROOT_MANAGE_APPL_DELETE',
'ROOT_MANAGE_PEC_SEND',
'ROOT_MANAGE_VIEW_LOG'
]).length
},
{
label: __('Log di Sistema', 'gepafin'),
icon: 'pi pi-receipt',
clickFn: () => {
},
id: 16,
enable: false
}
]
return <aside>
<ul>
{items
.filter(o => o.enable)
.map(o => <li key={o.id}>
{o.href
? <NavLink to={o.href}>
{is(String, o.icon)
? <i className={o.icon}></i>
: o.icon}
<span>{o.label}</span>
</NavLink>
: (o.clickFn ?
<button onClick={() => {
}}>
{is(String, o.icon)
? <i className={o.icon}></i>
: o.icon}
<span>{o.label}</span>
</button>
: <div className="nonLink">
<span>{o.label}</span>
</div>)}
</li>)}
</ul>
</aside>
}
export default AppSidebar;