- added duplicate form from another call functionality;
- fixed styles; - added copy icon for user emails; - added hotkey to open loginadmin page quickly; - added modal for archiving document; - added modal for create appointment;
This commit is contained in:
5
.distignore
Normal file
5
.distignore
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
.git
|
||||||
|
node_modules
|
||||||
|
build
|
||||||
|
environments
|
||||||
|
public
|
||||||
@@ -14,9 +14,11 @@
|
|||||||
"@wordpress/react-i18n": "4.8.0",
|
"@wordpress/react-i18n": "4.8.0",
|
||||||
"@xyflow/react": "12.3.1",
|
"@xyflow/react": "12.3.1",
|
||||||
"codice-fiscale-js": "2.3.22",
|
"codice-fiscale-js": "2.3.22",
|
||||||
|
"copy-to-clipboard": "^3.3.3",
|
||||||
"deep-object-diff": "^1.1.9",
|
"deep-object-diff": "^1.1.9",
|
||||||
"dompurify": "3.1.7",
|
"dompurify": "3.1.7",
|
||||||
"fast-deep-equal": "3.1.3",
|
"fast-deep-equal": "3.1.3",
|
||||||
|
"hotkeys-js": "^3.13.7",
|
||||||
"html-react-parser": "5.1.16",
|
"html-react-parser": "5.1.16",
|
||||||
"jwt-decode": "4.0.0",
|
"jwt-decode": "4.0.0",
|
||||||
"klona": "2.0.6",
|
"klona": "2.0.6",
|
||||||
@@ -43,6 +45,7 @@
|
|||||||
"@babel/plugin-syntax-jsx": "7.24.7",
|
"@babel/plugin-syntax-jsx": "7.24.7",
|
||||||
"@wordpress/babel-plugin-makepot": "6.8.0",
|
"@wordpress/babel-plugin-makepot": "6.8.0",
|
||||||
"babel-plugin-macros": "3.1.0",
|
"babel-plugin-macros": "3.1.0",
|
||||||
|
"node-wp-i18n": "^1.2.7",
|
||||||
"sass": "1.79.3",
|
"sass": "1.79.3",
|
||||||
"sass-loader": "16.0.2"
|
"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: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",
|
"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",
|
"test": "react-scripts test",
|
||||||
"eject": "react-scripts eject"
|
"eject": "react-scripts eject",
|
||||||
|
"make-pot": "wpi18n makepot --domain-path=languages --domain=gepafin"
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
"extends": [
|
"extends": [
|
||||||
|
|||||||
@@ -167,6 +167,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
padding: 5px 0;
|
padding: 5px 0;
|
||||||
|
|
||||||
&.rowContent {
|
&.rowContent {
|
||||||
@@ -178,7 +179,7 @@
|
|||||||
|
|
||||||
p {
|
p {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
flex: 1 1 100%;
|
/*flex: 1 1 100%;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
ul, ol {
|
ul, ol {
|
||||||
|
|||||||
@@ -153,6 +153,16 @@ button[disabled] {
|
|||||||
filter: grayscale(1);
|
filter: grayscale(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.iconBtn {
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
color: var(--primary-text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 800px) {
|
@media (max-width: 800px) {
|
||||||
.inner {
|
.inner {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|||||||
@@ -3,31 +3,36 @@ import { __ } from '@wordpress/i18n';
|
|||||||
import { useParams, useNavigate } from 'react-router-dom';
|
import { useParams, useNavigate } from 'react-router-dom';
|
||||||
import { isEmpty } from 'ramda';
|
import { isEmpty } from 'ramda';
|
||||||
import { classNames } from 'primereact/utils';
|
import { classNames } from 'primereact/utils';
|
||||||
import { klona } from 'klona';
|
|
||||||
|
|
||||||
// components
|
// store
|
||||||
import { Button } from 'primereact/button';
|
import { storeSet } from '../../store';
|
||||||
import { Dropdown } from 'primereact/dropdown';
|
|
||||||
|
|
||||||
// service
|
// service
|
||||||
import FormsService from '../../service/forms-service';
|
import FormsService from '../../service/forms-service';
|
||||||
|
|
||||||
// store
|
// tools
|
||||||
import { storeSet } from '../../store';
|
|
||||||
import set404FromErrorResponse from '../../helpers/set404FromErrorResponse';
|
|
||||||
import BandoService from '../../service/bando-service';
|
|
||||||
import uniqid from '../../helpers/uniqid';
|
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';
|
import { Toast } from 'primereact/toast';
|
||||||
|
|
||||||
const BandoForms = () => {
|
const BandoForms = () => {
|
||||||
const { id } = useParams();
|
const { id } = useParams();
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
const [templates, setTemplates] = useState(null);
|
|
||||||
const [selectedTemplate, setSelectedTemplate] = useState(null);
|
|
||||||
const [selectedForm, setSelectedForm] = useState(null);
|
const [selectedForm, setSelectedForm] = useState(null);
|
||||||
const [selectedForDuplicateForm, setSelectedForDuplicateForm] = useState(null);
|
const [selectedForDuplicateForm, setSelectedForDuplicateForm] = useState(0);
|
||||||
const [forms, setForms] = useState([]);
|
const [forms, setForms] = useState([]);
|
||||||
const [bandoStatus, setBandoStatus] = 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 toast = useRef(null);
|
||||||
|
|
||||||
const doCreateNewForm = () => {
|
const doCreateNewForm = () => {
|
||||||
@@ -53,11 +58,11 @@ const BandoForms = () => {
|
|||||||
|
|
||||||
if (!isEmpty(selectedFormArr)) {
|
if (!isEmpty(selectedFormArr)) {
|
||||||
storeSet.main.setAsyncRequest();
|
storeSet.main.setAsyncRequest();
|
||||||
FormsService.getFormById(selectedForDuplicateForm, getFormCallback, errGetFormCallbacks);
|
FormsService.getFormById(selectedForDuplicateForm, getFormDuplicateCallback, errGetFormDuplicateCallbacks);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const getFormCallback = (data) => {
|
const getFormDuplicateCallback = (data) => {
|
||||||
if (data.status === 'SUCCESS') {
|
if (data.status === 'SUCCESS') {
|
||||||
const newLabel = `${data.data.label} (copy)`;
|
const newLabel = `${data.data.label} (copy)`;
|
||||||
|
|
||||||
@@ -76,9 +81,10 @@ const BandoForms = () => {
|
|||||||
errFormCreateCallback
|
errFormCreateCallback
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
storeSet.main.unsetAsyncRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
const errGetFormCallbacks = (data) => {
|
const errGetFormDuplicateCallbacks = (data) => {
|
||||||
set404FromErrorResponse(data);
|
set404FromErrorResponse(data);
|
||||||
storeSet.main.unsetAsyncRequest();
|
storeSet.main.unsetAsyncRequest();
|
||||||
}
|
}
|
||||||
@@ -141,17 +147,52 @@ const BandoForms = () => {
|
|||||||
storeSet.main.unsetAsyncRequest();
|
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(() => {
|
useEffect(() => {
|
||||||
const parsed = parseInt(id)
|
const parsed = parseInt(id)
|
||||||
const bandoId = !isNaN(parsed) ? parsed : 0;
|
const bandoId = !isNaN(parsed) ? parsed : 0;
|
||||||
|
|
||||||
setTemplates([
|
|
||||||
{ label: 'Form template', value: 11 }
|
|
||||||
])
|
|
||||||
|
|
||||||
storeSet.main.setAsyncRequest();
|
storeSet.main.setAsyncRequest();
|
||||||
BandoService.getBando(id, getCallback, errGetCallback);
|
BandoService.getBando(id, getCallback, errGetCallback);
|
||||||
FormsService.getFormsForCall(bandoId, getFormsCallback, errGetFormsCallback);
|
FormsService.getFormsForCall(bandoId, getFormsCallback, errGetFormsCallback);
|
||||||
|
|
||||||
|
setAllBandiIsLoading(true);
|
||||||
|
BandoService.getBandi(getAllBandiCallback, errGetAllBandiCallback);
|
||||||
}, [id]);
|
}, [id]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -164,7 +205,7 @@ const BandoForms = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="appPage__spacer"></div>
|
<div className="appPage__spacer"></div>
|
||||||
<Toast ref={toast} />
|
<Toast ref={toast}/>
|
||||||
|
|
||||||
<div className="appPage__content">
|
<div className="appPage__content">
|
||||||
|
|
||||||
@@ -191,7 +232,7 @@ const BandoForms = () => {
|
|||||||
</div>*/}
|
</div>*/}
|
||||||
|
|
||||||
<div className="appPageSection__withBorder">
|
<div className="appPageSection__withBorder">
|
||||||
<h2>{__('Crea un nuovo Form da Zero', 'gepafin')}</h2>
|
<h2>{__('Crea un nuovo Form o duplica', 'gepafin')}</h2>
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<p>{__('Inizia con un form completamente vuoto e personalizzabile', 'gepafin')}</p>
|
<p>{__('Inizia con un form completamente vuoto e personalizzabile', 'gepafin')}</p>
|
||||||
<Button
|
<Button
|
||||||
@@ -202,19 +243,46 @@ const BandoForms = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<p>{__('Duplica il form creato in precedenza', 'gepafin')}</p>
|
<p>{__('Duplica il form creato in precedenza', 'gepafin')}</p>
|
||||||
<Dropdown
|
<div className="row">
|
||||||
id="form"
|
<Dropdown
|
||||||
disabled={isEmpty(forms)}
|
id="form"
|
||||||
value={selectedForDuplicateForm}
|
disabled={isEmpty(forms)}
|
||||||
onChange={(e) => setSelectedForDuplicateForm(e.value)}
|
value={selectedForDuplicateForm}
|
||||||
options={forms}
|
onChange={(e) => setSelectedForDuplicateForm(e.value)}
|
||||||
optionLabel="label"
|
options={forms}
|
||||||
placeholder={__('Seleziona form', 'gepafin')}/>
|
optionLabel="label"
|
||||||
<Button
|
placeholder={__('Seleziona form', 'gepafin')}/>
|
||||||
type="button"
|
<Button
|
||||||
disabled={'PUBLISH' === bandoStatus || isEmpty(forms)}
|
type="button"
|
||||||
onClick={doDuplicateForm}
|
disabled={'PUBLISH' === bandoStatus || isEmpty(forms) || selectedForDuplicateForm === 0}
|
||||||
label={__('Duplicare', 'gepafin')}/>
|
onClick={doDuplicateForm}
|
||||||
|
label={__('Duplicare', 'gepafin')}/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="row">
|
||||||
|
<p>{__('Duplica il form dal altro bando', 'gepafin')}</p>
|
||||||
|
<div className="row">
|
||||||
|
<Dropdown
|
||||||
|
id="form"
|
||||||
|
disabled={allBandiIsLoading}
|
||||||
|
value={selectedBandoIdForDuplicate}
|
||||||
|
onChange={(e) => setSelectedBandoIdForDuplicate(e.value)}
|
||||||
|
options={allBandiOptions}
|
||||||
|
placeholder={__('Seleziona bando', 'gepafin')}/>
|
||||||
|
<Dropdown
|
||||||
|
id="form"
|
||||||
|
disabled={allFormsIsLoading}
|
||||||
|
value={selectedFormIdForDuplicate}
|
||||||
|
onChange={(e) => setSelectedFormIdForDuplicate(e.value)}
|
||||||
|
options={allFormsOptions}
|
||||||
|
placeholder={__('Seleziona form', 'gepafin')}/>
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
disabled={selectedBandoIdForDuplicate === 0 || selectedFormIdForDuplicate === 0}
|
||||||
|
onClick={doDuplicateFormOfAnotherBando}
|
||||||
|
label={__('Duplicare', 'gepafin')}/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ const ElementSettingTableColumns = ({
|
|||||||
</div>
|
</div>
|
||||||
})}
|
})}
|
||||||
<Button type="button" outlined
|
<Button type="button" outlined
|
||||||
label={__('Aggiungi una righa', 'gepafin')}
|
label={__('Aggiungi una riga', 'gepafin')}
|
||||||
onClick={() => addNewRow(findIndex(propEq(o.name, 'name'))(stateFieldData))}/>
|
onClick={() => addNewRow(findIndex(propEq(o.name, 'name'))(stateFieldData))}/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ const ElementSettingTableColumns = ({
|
|||||||
<Button type="button"
|
<Button type="button"
|
||||||
outlined
|
outlined
|
||||||
disabled={bandoStatus === 'PUBLISH'}
|
disabled={bandoStatus === 'PUBLISH'}
|
||||||
label={__('Aggiungi una righa', 'gepafin')}
|
label={__('Aggiungi una riga', 'gepafin')}
|
||||||
onClick={addNewRow}/>
|
onClick={addNewRow}/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1,106 @@
|
|||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import { __ } from '@wordpress/i18n';
|
||||||
|
import { isEmpty } from 'ramda';
|
||||||
|
import { wrap } from 'object-path-immutable';
|
||||||
|
|
||||||
|
// components
|
||||||
|
import { Button } from 'primereact/button';
|
||||||
|
import { Dialog } from 'primereact/dialog';
|
||||||
|
import { InputTextarea } from 'primereact/inputtextarea';
|
||||||
|
import { Dropdown } from 'primereact/dropdown';
|
||||||
|
import { classNames } from 'primereact/utils';
|
||||||
|
|
||||||
|
const ArchiveDocument = ({ ndg = '', fileId = 0 }) => {
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
const [isVisibleDialog, setIsVisibleDialog] = useState(false);
|
||||||
|
const [modalData, setModalData] = useState({});
|
||||||
|
const [categories, setCategories] = useState([]);
|
||||||
|
|
||||||
|
const openArchivationModal = () => {
|
||||||
|
setIsVisibleDialog(true);
|
||||||
|
setModalData({
|
||||||
|
description: '',
|
||||||
|
categoryId: 0,
|
||||||
|
fileId
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const headerDialog = () => {
|
||||||
|
return <span>{__('Archive document', 'gepafin')}</span>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const hideDialog = () => {
|
||||||
|
setIsVisibleDialog(false);
|
||||||
|
setModalData({});
|
||||||
|
}
|
||||||
|
|
||||||
|
const setValue = (name, value) => {
|
||||||
|
const newData = wrap(modalData).set(name, value).value();
|
||||||
|
setModalData(newData);
|
||||||
|
}
|
||||||
|
|
||||||
|
const footerDialog = () => {
|
||||||
|
return <div>
|
||||||
|
<Button type="button" label={__('Anulla', 'gepafin')} onClick={hideDialog} outlined/>
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
disabled={loading}
|
||||||
|
label={__('Invia', 'gepafin')} onClick={submitData}/>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
const submitData = () => {
|
||||||
|
console.log('submitData', modalData)
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setCategories([
|
||||||
|
{value: 1, label: 'Type 1'},
|
||||||
|
{value: 2, label: 'Type 2'},
|
||||||
|
])
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{!isEmpty(ndg)
|
||||||
|
? <Button icon="pi pi-file-export"
|
||||||
|
rounded
|
||||||
|
onClick={openArchivationModal}
|
||||||
|
outlined
|
||||||
|
severity="info"
|
||||||
|
aria-label={__('Mostra', 'gepafin')}/>
|
||||||
|
: null}
|
||||||
|
<Dialog
|
||||||
|
visible={isVisibleDialog}
|
||||||
|
modal
|
||||||
|
header={headerDialog}
|
||||||
|
footer={footerDialog}
|
||||||
|
style={{ maxWidth: '600px', width: '100%' }}
|
||||||
|
onHide={hideDialog}>
|
||||||
|
<div className="appForm__field">
|
||||||
|
<label className={classNames({ 'p-error': !modalData.categoryId || modalData.categoryId === 0 })}>
|
||||||
|
{__('Classificazione', 'gepafin')}*
|
||||||
|
</label>
|
||||||
|
<Dropdown
|
||||||
|
value={modalData.categoryId}
|
||||||
|
invalid={!modalData.categoryId || modalData.categoryId === 0}
|
||||||
|
onChange={(e) => setValue('categoryId', e.value)}
|
||||||
|
options={categories}/>
|
||||||
|
</div>
|
||||||
|
<div className="appForm__field">
|
||||||
|
<label className={classNames({ 'p-error': isEmpty(modalData.description) })}>
|
||||||
|
{__('Descrizione', 'gepafin')}
|
||||||
|
</label>
|
||||||
|
<InputTextarea
|
||||||
|
value={modalData.description}
|
||||||
|
invalid={isEmpty(modalData.description)}
|
||||||
|
onChange={(e) => setValue('description', e.target.value)}
|
||||||
|
rows={3}
|
||||||
|
cols={30}/>
|
||||||
|
</div>
|
||||||
|
</Dialog>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ArchiveDocument;
|
||||||
@@ -28,6 +28,10 @@ import BlockingOverlay from '../../components/BlockingOverlay';
|
|||||||
import { Toast } from 'primereact/toast';
|
import { Toast } from 'primereact/toast';
|
||||||
import HelpIcon from '../../icons/HelpIcon';
|
import HelpIcon from '../../icons/HelpIcon';
|
||||||
import { Dialog } from 'primereact/dialog';
|
import { Dialog } from 'primereact/dialog';
|
||||||
|
import ArchiveDocument from './components/ArchiveDocument';
|
||||||
|
import { classNames } from 'primereact/utils';
|
||||||
|
import { InputTextarea } from 'primereact/inputtextarea';
|
||||||
|
import { InputText } from 'primereact/inputtext';
|
||||||
|
|
||||||
const APP_EVALUATION_FLOW_ID = process.env.REACT_APP_EVALUATION_FLOW_ID;
|
const APP_EVALUATION_FLOW_ID = process.env.REACT_APP_EVALUATION_FLOW_ID;
|
||||||
|
|
||||||
@@ -46,6 +50,13 @@ const DomandaEditPreInstructor = () => {
|
|||||||
const [isVisibleCompleteDialog, setIsVisibleCompleteDialog] = useState(false);
|
const [isVisibleCompleteDialog, setIsVisibleCompleteDialog] = useState(false);
|
||||||
const [operationType, setOperationType] = useState('');
|
const [operationType, setOperationType] = useState('');
|
||||||
const [motivation, setMotivation] = useState('');
|
const [motivation, setMotivation] = useState('');
|
||||||
|
const [isVisibleAppointmentDialog, setIsVisibleAppointmentDialog] = useState(false);
|
||||||
|
const [appointmentData, setAppointmentData] = useState({
|
||||||
|
title: '',
|
||||||
|
text: '',
|
||||||
|
duration: 0,
|
||||||
|
amount: 0
|
||||||
|
});
|
||||||
|
|
||||||
const goToEvaluationsPage = () => {
|
const goToEvaluationsPage = () => {
|
||||||
navigate('/domande');
|
navigate('/domande');
|
||||||
@@ -322,10 +333,53 @@ const DomandaEditPreInstructor = () => {
|
|||||||
setIsVisibleCompleteDialog(true);
|
setIsVisibleCompleteDialog(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
const doCreateAppointment = () => {
|
const doCheckNDG = () => {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const doCreateAppointment = () => {
|
||||||
|
setAppointmentData({
|
||||||
|
title: '',
|
||||||
|
text: '',
|
||||||
|
duration: 0,
|
||||||
|
amount: 0
|
||||||
|
});
|
||||||
|
setIsVisibleAppointmentDialog(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
const setValue = (name, value) => {
|
||||||
|
const newData = wrap(appointmentData).set(name, value).value();
|
||||||
|
setAppointmentData(newData);
|
||||||
|
}
|
||||||
|
|
||||||
|
const headerAppointmentDialog = () => {
|
||||||
|
return <span>{__('Crea appuntamento', 'gepafin')}</span>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const hideAppointmentDialog = () => {
|
||||||
|
setIsVisibleAppointmentDialog(false);
|
||||||
|
setAppointmentData({});
|
||||||
|
}
|
||||||
|
|
||||||
|
const footerAppointmentDialog = () => {
|
||||||
|
return <div>
|
||||||
|
<Button type="button" label={__('Anulla', 'gepafin')} onClick={hideAppointmentDialog} outlined/>
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
disabled={loading}
|
||||||
|
label={__('Invia', 'gepafin')} onClick={doCreateAppointmentRequest}/>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
const doCreateAppointmentRequest = () => {
|
||||||
|
if (
|
||||||
|
!isEmpty(appointmentData.title) && !isEmpty(appointmentData.text) && !isEmpty(appointmentData.amount)
|
||||||
|
&& !isEmpty(appointmentData.duration) && appointmentData.duration !== 0 && appointmentData.amount !== 0
|
||||||
|
) {
|
||||||
|
console.log(appointmentData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const doMakeAdmisible = () => {
|
const doMakeAdmisible = () => {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
@@ -565,6 +619,7 @@ const DomandaEditPreInstructor = () => {
|
|||||||
}}>
|
}}>
|
||||||
<span>{k.name}</span>
|
<span>{k.name}</span>
|
||||||
<div className="appPageSection__iconActions">
|
<div className="appPageSection__iconActions">
|
||||||
|
<ArchiveDocument ndg={data.ndg} fileId={k.id}/>
|
||||||
<Button icon="pi pi-eye" rounded
|
<Button icon="pi pi-eye" rounded
|
||||||
onClick={() => window.open(k.filePath, '_blank').focus()}
|
onClick={() => window.open(k.filePath, '_blank').focus()}
|
||||||
outlined severity="info"
|
outlined severity="info"
|
||||||
@@ -615,6 +670,13 @@ const DomandaEditPreInstructor = () => {
|
|||||||
onClick={doSaveDraft}
|
onClick={doSaveDraft}
|
||||||
label={__('Crea valutazione', 'gepafin')}
|
label={__('Crea valutazione', 'gepafin')}
|
||||||
icon="pi pi-save" iconPos="right"/>}
|
icon="pi pi-save" iconPos="right"/>}
|
||||||
|
{APP_EVALUATION_FLOW_ID === '1' && ['EVALUATION'].includes(data.applicationStatus)
|
||||||
|
? <Button
|
||||||
|
type="button"
|
||||||
|
disabled={!data.id}
|
||||||
|
onClick={doCheckNDG}
|
||||||
|
label={__('Controlla NDG', 'gepafin')}
|
||||||
|
/> : null}
|
||||||
{APP_EVALUATION_FLOW_ID === '1' && ['EVALUATION'].includes(data.applicationStatus)
|
{APP_EVALUATION_FLOW_ID === '1' && ['EVALUATION'].includes(data.applicationStatus)
|
||||||
? <Button
|
? <Button
|
||||||
type="button"
|
type="button"
|
||||||
@@ -675,6 +737,55 @@ const DomandaEditPreInstructor = () => {
|
|||||||
</div>
|
</div>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
|
||||||
|
<Dialog
|
||||||
|
visible={isVisibleAppointmentDialog}
|
||||||
|
modal
|
||||||
|
header={headerAppointmentDialog}
|
||||||
|
footer={footerAppointmentDialog}
|
||||||
|
style={{ maxWidth: '600px', width: '100%' }}
|
||||||
|
onHide={hideAppointmentDialog}>
|
||||||
|
<div className="appForm__field">
|
||||||
|
<label className={classNames({ 'p-error': isEmpty(appointmentData.amount) || appointmentData.amount === 0})}>
|
||||||
|
{__('Importo', 'gepafin')}
|
||||||
|
</label>
|
||||||
|
<InputNumber
|
||||||
|
value={appointmentData.amount}
|
||||||
|
keyfilter="int"
|
||||||
|
invalid={isEmpty(appointmentData.amount) || appointmentData.amount === 0}
|
||||||
|
onChange={(e) => setValue('amount', e.value)}/>
|
||||||
|
</div>
|
||||||
|
<div className="appForm__field">
|
||||||
|
<label className={classNames({ 'p-error': isEmpty(appointmentData.duration) || appointmentData.duration === 0 })}>
|
||||||
|
{__('Durata', 'gepafin')}
|
||||||
|
</label>
|
||||||
|
<InputNumber
|
||||||
|
value={appointmentData.duration}
|
||||||
|
keyfilter="int"
|
||||||
|
invalid={isEmpty(appointmentData.duration) || appointmentData.duration === 0}
|
||||||
|
onChange={(e) => setValue('duration', e.value)}/>
|
||||||
|
</div>
|
||||||
|
<div className="appForm__field">
|
||||||
|
<label className={classNames({ 'p-error': isEmpty(appointmentData.title) })}>
|
||||||
|
{__('Titolo', 'gepafin')}
|
||||||
|
</label>
|
||||||
|
<InputText
|
||||||
|
value={appointmentData.title}
|
||||||
|
invalid={isEmpty(appointmentData.title)}
|
||||||
|
onChange={(e) => setValue('title', e.target.value)}/>
|
||||||
|
</div>
|
||||||
|
<div className="appForm__field">
|
||||||
|
<label className={classNames({ 'p-error': isEmpty(appointmentData.text) })}>
|
||||||
|
{__('Messaggio', 'gepafin')}
|
||||||
|
</label>
|
||||||
|
<InputTextarea
|
||||||
|
value={appointmentData.text}
|
||||||
|
invalid={isEmpty(appointmentData.text)}
|
||||||
|
onChange={(e) => setValue('text', e.target.value)}
|
||||||
|
rows={3}
|
||||||
|
cols={30}/>
|
||||||
|
</div>
|
||||||
|
</Dialog>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
: <>
|
: <>
|
||||||
<Skeleton width="20%" height="1rem" className="mb-2"></Skeleton>
|
<Skeleton width="20%" height="1rem" className="mb-2"></Skeleton>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import React, { useRef, useEffect, useState } from 'react';
|
|||||||
import { __, sprintf } from '@wordpress/i18n';
|
import { __, sprintf } from '@wordpress/i18n';
|
||||||
import { classNames } from 'primereact/utils';
|
import { classNames } from 'primereact/utils';
|
||||||
import { isEmpty, isNil } from 'ramda';
|
import { isEmpty, isNil } from 'ramda';
|
||||||
|
import hotkeys from 'hotkeys-js';
|
||||||
|
|
||||||
// store
|
// store
|
||||||
import { storeSet, useStore } from '../../store';
|
import { storeSet, useStore } from '../../store';
|
||||||
@@ -111,11 +112,14 @@ const Login = () => {
|
|||||||
}
|
}
|
||||||
}, [searchParams]);
|
}, [searchParams]);
|
||||||
|
|
||||||
/*useEffect(() => {
|
useEffect(() => {
|
||||||
if ('t7jh5wfg9QXylNaTZkPoE' === APP_HUB_ID) {
|
/*if ('t7jh5wfg9QXylNaTZkPoE' === APP_HUB_ID) {
|
||||||
setIsMaintenance(true);
|
setIsMaintenance(true);
|
||||||
}
|
}*/
|
||||||
}, [])*/
|
hotkeys('command+x', function(event, handler){
|
||||||
|
window.location.replace('/loginadmin')
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classNames(['appPage', 'appPageLogin'])}>
|
<div className={classNames(['appPage', 'appPageLogin'])}>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import { __ } from '@wordpress/i18n';
|
import { __ } from '@wordpress/i18n';
|
||||||
import { uniq } from 'ramda';
|
import { uniq } from 'ramda';
|
||||||
|
import copy from 'copy-to-clipboard';
|
||||||
|
|
||||||
// store
|
// store
|
||||||
import { useStore, storeSet } from '../../../../store';
|
import { useStore, storeSet } from '../../../../store';
|
||||||
@@ -116,6 +117,15 @@ const AllUsersTable = () => {
|
|||||||
return `${rowData.firstName} ${rowData.lastName}`;
|
return `${rowData.firstName} ${rowData.lastName}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const roleEmailTemplate = (rowData) => {
|
||||||
|
return <div className="appPageSection__tableActions lessGap">
|
||||||
|
<span className="truncatedText">{rowData.email}</span>
|
||||||
|
<button className="iconBtn" onClick={() => copy(rowData.email)}>
|
||||||
|
<i className="pi pi-copy"></i>
|
||||||
|
</button>
|
||||||
|
</div>;
|
||||||
|
};
|
||||||
|
|
||||||
const roleBodyTemplate = (rowData) => {
|
const roleBodyTemplate = (rowData) => {
|
||||||
return rowData.role.roleName;
|
return rowData.role.roleName;
|
||||||
};
|
};
|
||||||
@@ -157,7 +167,7 @@ const AllUsersTable = () => {
|
|||||||
header={__('Nome utente', 'gepafin')}
|
header={__('Nome utente', 'gepafin')}
|
||||||
filter filterPlaceholder={__('Cerca per nome', 'gepafin')}
|
filter filterPlaceholder={__('Cerca per nome', 'gepafin')}
|
||||||
style={{ minWidth: '12rem' }}/>
|
style={{ minWidth: '12rem' }}/>
|
||||||
<Column field="email" header={__('Email', 'gepafin')}
|
<Column body={roleEmailTemplate} header={__('Email', 'gepafin')}
|
||||||
filter filterPlaceholder={__('Cerca per email', 'gepafin')}
|
filter filterPlaceholder={__('Cerca per email', 'gepafin')}
|
||||||
style={{ minWidth: '12rem' }}/>
|
style={{ minWidth: '12rem' }}/>
|
||||||
<Column body={roleBodyTemplate} header={__('Ruolo', 'gepafin')}
|
<Column body={roleBodyTemplate} header={__('Ruolo', 'gepafin')}
|
||||||
|
|||||||
Reference in New Issue
Block a user