- added page 'manage users';

- changed field type for 'reuqested documents';
- added disable state logic for 'edit form' btn for unsaved call;
This commit is contained in:
Vitalii Kiiko
2024-09-30 09:53:12 +02:00
parent 4be858ca74
commit 8ee159824f
9 changed files with 141 additions and 69 deletions

View File

@@ -42,7 +42,7 @@
} }
} }
input[disabled], div.p-disabled { input[disabled], div.p-disabled:not(.p-inputswitch) {
background-color: #e3e3e3; background-color: #e3e3e3;
} }
} }

View File

@@ -19,11 +19,10 @@ import BandoService from '../../../../service/bando-service';
import LookupdataService from '../../../../service/lookupdata-service'; import LookupdataService from '../../../../service/lookupdata-service';
// store // store
import { storeSet, useStore } from '../../../../store'; import { storeSet } from '../../../../store';
const BandoEditFormStep1 = forwardRef(function ({ initialData, getFormErrors, status }, ref) { const BandoEditFormStep1 = forwardRef(function ({ initialData, getFormErrors, status }, ref) {
const navigate = useNavigate(); const navigate = useNavigate();
const isAsyncRequest = useStore().main.isAsyncRequest();
const [aimedToOptions, setAimedToOptions] = useState([]); const [aimedToOptions, setAimedToOptions] = useState([]);
const [faqOptions, setFaqOptions] = useState([]); const [faqOptions, setFaqOptions] = useState([]);
const [formInitialData, setFormInitialData] = useState(initialData); const [formInitialData, setFormInitialData] = useState(initialData);
@@ -244,7 +243,7 @@ const BandoEditFormStep1 = forwardRef(function ({ initialData, getFormErrors, st
/> />
<FormField <FormField
type="textarea" type="wysiwyg"
disabled={shouldDisableField()} disabled={shouldDisableField()}
fieldName="documentationRequested" fieldName="documentationRequested"
label={__('Documentazione richiesta', 'gepafin')} label={__('Documentazione richiesta', 'gepafin')}

View File

@@ -314,12 +314,14 @@ const BandoEdit = () => {
<div className="row"> <div className="row">
<Button <Button
type="button" type="button"
disabled={!['DRAFT', 'PUBLISH', 'READY_TO_PUBLISH'].includes(data.status)}
outlined={data.status === 'PUBLISH'} outlined={data.status === 'PUBLISH'}
onClick={openBandoFormManagement} onClick={openBandoFormManagement}
label={__('Crea/modifica form', 'gepafin')}/> label={__('Crea/modifica form', 'gepafin')}/>
<Button <Button
type="button" type="button"
disabled={!['DRAFT', 'PUBLISH', 'READY_TO_PUBLISH'].includes(data.status)}
outlined={data.status === 'PUBLISH'} outlined={data.status === 'PUBLISH'}
onClick={openBandoFlowManagement} onClick={openBandoFlowManagement}
icon="pi pi-sitemap" icon="pi pi-sitemap"
@@ -333,7 +335,7 @@ const BandoEdit = () => {
{o.label} {o.label}
</li>)} </li>)}
</ul> </ul>
: <p>No forms created yet.</p>} : <p>{__('Nessun modulo creato ancora', 'gepafin')}</p>}
</div> </div>
<div className="appPage__spacer"></div> <div className="appPage__spacer"></div>

View File

@@ -61,7 +61,7 @@ const FormBuilder = () => {
</Sidebar> </Sidebar>
<div className="formBuilder"> <div className="formBuilder">
<div className="formBuilder__main"> <div className="formBuilder__main">
<h2>{__('Trascina qui gli elementi del Form', 'gepafin')}</h2> <h2>{__('Trascina qui gli elementi del Form', 'gepafin')}*</h2>
<div className="formBuilder__content"> <div className="formBuilder__content">
{!isEmpty(elements) {!isEmpty(elements)
? elements.map((field, i) => renderField(field, i)) ? elements.map((field, i) => renderField(field, i))

View File

@@ -278,7 +278,7 @@ const BandoFormsEdit = () => {
style={{ maxWidth: '500px' }} /> 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
id="label" id="label"
value={formName} value={formName}

View File

@@ -28,7 +28,7 @@ import ProperBandoLabel from '../../../../components/ProperBandoLabel';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
const AllBandiTable = () => { const AllUsersTable = () => {
const [items, setItems] = useState(null); const [items, setItems] = useState(null);
const [filters, setFilters] = useState(null); const [filters, setFilters] = useState(null);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
@@ -37,10 +37,29 @@ const AllBandiTable = () => {
useEffect(() => { useEffect(() => {
storeSet.main.setAsyncRequest(); storeSet.main.setAsyncRequest();
BandoService.getBandi(getCallback, errGetCallbacks); const sample = [
{
id: 11,
name: 'Mario Rossi',
email: 'mario.rossi@example.com',
role: 'Beneficiario',
status: 'active',
last_access: '2024-08-01 10:30'
},
{
id: 12,
name: 'Mario Rossi2',
email: 'mario.rossi@example.com',
role: 'Beneficiario',
status: 'active',
last_access: '2024-08-01 10:30'
}
];
setItems(sample);
//BandoService.getBandi(getCallback, errGetCallbacks);
}, []); }, []);
const getCallback = (data) => { /*const getCallback = (data) => {
if (data.status === 'SUCCESS') { if (data.status === 'SUCCESS') {
setItems(getFormattedBandiData(data.data)); setItems(getFormattedBandiData(data.data));
setStatuses(uniq(data.data.map(o => o.status))) setStatuses(uniq(data.data.map(o => o.status)))
@@ -52,11 +71,11 @@ const AllBandiTable = () => {
const errGetCallbacks = (data) => { const errGetCallbacks = (data) => {
console.log('errGetCallbacks', data) console.log('errGetCallbacks', data)
storeSet.main.unsetAsyncRequest(); storeSet.main.unsetAsyncRequest();
} }*/
const getFormattedBandiData = (data) => { const getFormattedData = (data) => {
return data.map((d) => { return data.map((d) => {
d.dates = d.dates.map(v => is(String, v) ? new Date(v) : (v ? v : '')); d.last_access = is(String, d.last_access) ? new Date(d.last_access) : (d.last_access ? d.last_access : '');
return d; return d;
}); });
}; };
@@ -79,8 +98,7 @@ const AllBandiTable = () => {
setFilters({ setFilters({
global: { value: null, matchMode: FilterMatchMode.CONTAINS }, global: { value: null, matchMode: FilterMatchMode.CONTAINS },
name: { operator: FilterOperator.AND, constraints: [{ value: null, matchMode: FilterMatchMode.STARTS_WITH }] }, name: { operator: FilterOperator.AND, constraints: [{ value: null, matchMode: FilterMatchMode.STARTS_WITH }] },
start_date: { operator: FilterOperator.AND, constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }] }, last_access: { operator: FilterOperator.AND, constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }] },
end_date: { operator: FilterOperator.AND, constraints: [{ value: null, matchMode: FilterMatchMode.DATE_IS }] },
status: { operator: FilterOperator.OR, constraints: [{ value: null, matchMode: FilterMatchMode.EQUALS }] }, status: { operator: FilterOperator.OR, constraints: [{ value: null, matchMode: FilterMatchMode.EQUALS }] },
}); });
setGlobalFilterValue(''); setGlobalFilterValue('');
@@ -98,12 +116,8 @@ const AllBandiTable = () => {
); );
}; };
const dateStartBodyTemplate = (rowData) => { const dateLastAccessBodyTemplate = (rowData) => {
return getDateFromISOstring(rowData.dates[0]); return getDateFromISOstring(rowData.last_access);
};
const dateEndBodyTemplate = (rowData) => {
return getDateFromISOstring(rowData.dates[1]);
}; };
const dateFilterTemplate = (options) => { const dateFilterTemplate = (options) => {
@@ -123,7 +137,7 @@ const AllBandiTable = () => {
}; };
const actionsBodyTemplate = (rowData) => { const actionsBodyTemplate = (rowData) => {
return <Link to={`/bandi/${rowData.id}`}> return <Link to={`/utenti/${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>
} }
@@ -137,17 +151,18 @@ const AllBandiTable = () => {
globalFilterFields={['name', 'status']} globalFilterFields={['name', 'status']}
header={header} header={header}
emptyMessage="Nothing found." onFilter={(e) => setFilters(e.filters)}> emptyMessage="Nothing found." onFilter={(e) => setFilters(e.filters)}>
<Column field="name" header={__('Nome Bando', 'gepafin')} filter filterPlaceholder="Search by name" <Column field="name" header={__('Nome utente', 'gepafin')} filter filterPlaceholder="Search by name"
style={{ minWidth: '12rem' }}/>
<Column field="email" header={__('Email', 'gepafin')} filter filterPlaceholder="Search by email"
style={{ minWidth: '12rem' }}/>
<Column field="role" header={__('Ruolo', 'gepafin')}
style={{ minWidth: '12rem' }}/> style={{ minWidth: '12rem' }}/>
<Column header={__('Data Pubblicazione', 'gepafin')} filterField="start_date" dataType="date"
style={{ minWidth: '10rem' }}
body={dateStartBodyTemplate} filter filterElement={dateFilterTemplate}/>
<Column header={__('Data Scadenza', 'gepafin')} filterField="end_date" dataType="date"
style={{ minWidth: '10rem' }}
body={dateEndBodyTemplate} filter filterElement={dateFilterTemplate}/>
<Column field="status" header={__('Stato', 'gepafin')} filterMenuStyle={{ width: '14rem' }} <Column field="status" header={__('Stato', 'gepafin')} filterMenuStyle={{ width: '14rem' }}
style={{ width: '120px' }} body={statusBodyTemplate} filter style={{ width: '120px' }} body={statusBodyTemplate} filter
filterElement={statusFilterTemplate}/> filterElement={statusFilterTemplate}/>
<Column header={__('Ultimo accesso', 'gepafin')} filterField="last_access" dataType="date"
style={{ minWidth: '10rem' }}
body={dateLastAccessBodyTemplate} filter filterElement={dateFilterTemplate}/>
<Column header={__('Azioni', 'gepafin')} <Column header={__('Azioni', 'gepafin')}
body={actionsBodyTemplate}/> body={actionsBodyTemplate}/>
</DataTable> </DataTable>
@@ -155,4 +170,4 @@ const AllBandiTable = () => {
) )
} }
export default AllBandiTable; export default AllUsersTable;

93
src/pages/Users/index.js Normal file
View File

@@ -0,0 +1,93 @@
import React, { useState } from 'react';
import { __ } from '@wordpress/i18n';
import { isEmpty } from 'ramda';
// components
import AllUsersTable from './components/AllUsersTable';
import { Button } from 'primereact/button';
import { InputText } from 'primereact/inputtext';
import { InputTextarea } from 'primereact/inputtextarea';
import { InputSwitch } from 'primereact/inputswitch';
import { Dialog } from 'primereact/dialog';
const Users = () => {
const [isVisibleEditDialog, setIsVisibleEditDialog] = useState(false);
const [newUserData, setNewUserData] = useState({});
const onCreateNewUser = () => {
setIsVisibleEditDialog(true);
}
const headerEditDialog = () => {
return <span>{__('Aggiungi utente', 'gepafin')}</span>
}
const hideEditDialog = () => {
setIsVisibleEditDialog(false);
setNewUserData({});
}
const saveEditDialog = () => {
}
const onChangeEditItem = (value, key) => {
}
const footerEditDialog = () => {
return <div>
<Button type="button" label={__('Anulla', 'gepafin')} onClick={hideEditDialog} outlined/>
<Button
type="button"
disabled={isEmpty(newUserData)}
label={__('Salva', 'gepafin')} onClick={saveEditDialog}/>
</div>
}
return(
<div className="appPage">
<div className="appPage__pageHeader">
<h1>{__('Gestione utenti', 'gepafin')}</h1>
</div>
<div className="appPage__spacer"></div>
<div className="appPageSection">
<div className="appPageSection__actions">
<Button
onClick={onCreateNewUser}
label={__('Crea nuovo')} icon="pi pi-plus" iconPos="right"/>
</div>
<AllUsersTable doRefresh={true}/>
<Dialog
visible={isVisibleEditDialog}
modal header={headerEditDialog}
footer={footerEditDialog}
style={{ maxWidth: '600px', width: '100%' }}
onHide={hideEditDialog}>
<div className="appPage__spacer"></div>
<div className="appForm__field">
<label>{__('Nome', 'gepafin')}</label>
<InputText value={''} onChange={(e) => onChangeEditItem(e.target.value, 'firstName')}/>
</div>
<div className="appForm__field">
<label>{__('Cognome', 'gepafin')}</label>
<InputText value={''} onChange={(e) => onChangeEditItem(e.target.value, 'lastName')}/>
</div>
<div className="appForm__field">
<label>{__('Risposta', 'gepafin')}</label>
<InputTextarea value={''} onChange={(e) => onChangeEditItem(e.target.value, 'response')}
rows={5}
cols={30}/>
</div>
<div className="appPage__spacer"></div>
</Dialog>
</div>
</div>
)
}
export default Users;

View File

@@ -1,37 +0,0 @@
import React from 'react';
import { __ } from '@wordpress/i18n';
import { useNavigate } from 'react-router-dom';
// components
import AllBandiTable from './components/AllBandiTable';
import { Button } from 'primereact/button';
const Utenti = () => {
const navigate = useNavigate();
const onCreateNewUser = () => {
navigate('/utenti/new');
}
return(
<div className="appPage">
<div className="appPage__pageHeader">
<h1>{__('Gestione utenti', 'gepafin')}</h1>
</div>
<div className="appPage__spacer"></div>
<div className="appPageSection">
<div className="appPageSection__actions">
<Button
onClick={onCreateNewUser}
label={__('Crea nuovo bando')} icon="pi pi-plus" iconPos="right"/>
</div>
<AllBandiTable/>
</div>
</div>
)
}
export default Utenti;

View File

@@ -22,7 +22,7 @@ import BandiBeneficiario from './pages/BandiBeneficiario';
import LoginAdmin from './pages/LoginAdmin'; import LoginAdmin from './pages/LoginAdmin';
import Profile from './pages/Profile'; import Profile from './pages/Profile';
import ProfileCompany from './pages/ProfileCompany'; import ProfileCompany from './pages/ProfileCompany';
import Utenti from './pages/Utenti'; import Users from './pages/Users';
const routes = ({ role }) => { const routes = ({ role }) => {
return ( return (
@@ -81,7 +81,7 @@ const routes = ({ role }) => {
{'ROLE_BENEFICIARY' === role ? <ProfileCompany/> : null} {'ROLE_BENEFICIARY' === role ? <ProfileCompany/> : null}
</DefaultLayout>}/> </DefaultLayout>}/>
<Route path="/utenti" element={<DefaultLayout> <Route path="/utenti" element={<DefaultLayout>
{'ROLE_SUPER_ADMIN' === role ? <Utenti/> : null} {'ROLE_SUPER_ADMIN' === role ? <Users/> : null}
{'ROLE_BENEFICIARY' === role ? <PageNotFound/> : null} {'ROLE_BENEFICIARY' === role ? <PageNotFound/> : null}
</DefaultLayout>}/> </DefaultLayout>}/>
</Route> </Route>