- merged develop;

This commit is contained in:
Vitalii Kiiko
2024-12-11 11:37:36 +01:00
34 changed files with 917 additions and 456 deletions

View File

@@ -1,4 +1,4 @@
import React, { useEffect, useState } from 'react';
import React, { useEffect, useRef, useState } from 'react';
import { __ } from '@wordpress/i18n';
import { isEmpty } from 'ramda';
import { wrap } from 'object-path-immutable';
@@ -9,24 +9,37 @@ import { Dialog } from 'primereact/dialog';
import { InputTextarea } from 'primereact/inputtextarea';
import { Dropdown } from 'primereact/dropdown';
import { classNames } from 'primereact/utils';
import { InputSwitch } from 'primereact/inputswitch';
import { InputText } from 'primereact/inputtext';
const ArchiveDocument = ({ ndg = '', fileId = 0 }) => {
import { classificationType, protocolType } from '../../../../configData';
import AppointmentService from '../../../../service/appointment-service';
import set404FromErrorResponse from '../../../../helpers/set404FromErrorResponse';
import { storeSet } from '../../../../store';
import { Toast } from 'primereact/toast';
const ArchiveDocument = ({ applicationId, ndg = '', fileId = 0 }) => {
const [loading, setLoading] = useState(false);
const [isVisibleDialog, setIsVisibleDialog] = useState(false);
const [modalData, setModalData] = useState({});
const [types, setTypes] = useState([]);
const [categories, setCategories] = useState([]);
const toast = useRef(null);
const openArchivationModal = () => {
setIsVisibleDialog(true);
setModalData({
description: '',
categoryId: 0,
descrizione: '',
idTipoProtocollo: 0,
idClassificazione: 0,
flagDaFirmare: false,
email: '',
fileId
});
}
const headerDialog = () => {
return <span>{__('Archive document', 'gepafin')}</span>;
return <span>{__('Archiviazione del documento', 'gepafin')}</span>;
}
const hideDialog = () => {
@@ -50,57 +63,141 @@ const ArchiveDocument = ({ ndg = '', fileId = 0 }) => {
}
const submitData = () => {
console.log('submitData', modalData);
//setLoading(true);
if (
modalData.idTipoProtocollo !== 0 && modalData.idClassificazione !== 0
&& !isEmpty(modalData.descrizione) && !isEmpty(modalData.email)
) {
setLoading(true);
const submitData = {
'input': {
'idTipoProtocollo': modalData.idTipoProtocollo,
'idClassificazione': modalData.idClassificazione,
'flagDaFirmare': modalData.flagDaFirmare,
'descrizione': modalData.descrizione,
'attributes': {
'ndg': ndg,
'email': modalData.email
}
}
}
AppointmentService.archiveDocument(applicationId, fileId, submitData, submitCallback, errSubmitCallback)
}
}
const submitCallback = (data) => {
if (data.status === 'SUCCESS') {
console.log(data.data);
}
setLoading(false);
}
const errSubmitCallback = (data) => {
if (toast.current && data.message) {
toast.current.show({
severity: 'error',
summary: '',
detail: data.message
});
}
set404FromErrorResponse(data);
setLoading(false);
}
useEffect(() => {
setCategories([
{value: 1, label: 'Type 1'},
{value: 2, label: 'Type 2'},
])
const newModalData = {
...modalData,
idClassificazione: 0
};
setModalData(newModalData);
setCategories(classificationType
.filter(o => o.idTipoprotocollo === modalData.idTipoProtocollo)
.map(o => ({ value: o.idClassificazione, label: o.name })));
}, [modalData.idTipoProtocollo])
useEffect(() => {
setTypes(protocolType.map(o => ({ value: o.id, label: o.name })));
}, []);
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>
</>
return (!isEmpty(ndg)
? <>
<Toast ref={toast}/>
<Button icon="pi pi-file-export"
rounded
onClick={openArchivationModal}
outlined
severity="info"
aria-label={__('Mostra', 'gepafin')}/>
<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.idTipoProtocollo || modalData.idTipoProtocollo === 0 })}>
{__('Tipo di protocollo', 'gepafin')}*
</label>
<Dropdown
value={modalData.idTipoProtocollo}
invalid={!modalData.idTipoProtocollo || modalData.idTipoProtocollo === 0}
onChange={(e) => setValue('idTipoProtocollo', e.value)}
options={types}/>
</div>
<div className="appForm__field">
<label
className={classNames({ 'p-error': !modalData.idClassificazione || modalData.idClassificazione === 0 })}>
{__('Classificazione', 'gepafin')}*
</label>
<Dropdown
value={modalData.idClassificazione}
invalid={!modalData.idClassificazione || modalData.idClassificazione === 0}
onChange={(e) => setValue('idClassificazione', e.value)}
options={categories}/>
</div>
<div className="appForm__field">
<label>
{__('Da firmare?', 'gepafin')}
</label>
<InputSwitch
checked={modalData.flagDaFirmare}
onChange={(e) => setValue('flagDaFirmare', e.value)}/>
</div>
<div className="appForm__field">
<label className={classNames({ 'p-error': isEmpty(modalData.descrizione) })}>
{__('Descrizione', 'gepafin')}*
</label>
<InputTextarea
value={modalData.descrizione}
invalid={isEmpty(modalData.descrizione)}
onChange={(e) => setValue('descrizione', e.target.value)}
rows={3}
cols={30}/>
</div>
<div className="appForm__field">
<label>
{__('NDG', 'gepafin')}*
</label>
<InputText
value={ndg}
disabled
onChange={() => {
}}/>
</div>
<div className="appForm__field">
<label className={classNames({ 'p-error': isEmpty(modalData.email) })}>
{__('Email', 'gepafin')}*
</label>
<InputText
value={modalData.email}
keyfilter="email"
invalid={isEmpty(modalData.email)}
onChange={(e) => setValue('email', e.target.value)}/>
</div>
</Dialog>
</> : null
)
}

View File

@@ -0,0 +1,49 @@
import React, { useState } from 'react';
import { __ } from '@wordpress/i18n';
// tools
import set404FromErrorResponse from '../../../../helpers/set404FromErrorResponse';
// api
import ApplicationService from '../../../../service/application-service';
// components
import { Button } from 'primereact/button';
const DownloadApplicationArchive = ({ applicationId = 0 }) => {
const [loading, setLoading] = useState(false);
const onClickDownload = () => {
setLoading(true);
ApplicationService.downloadCompleteZip(applicationId, getCompleteZipCallback, errCompleteZipCallback);
}
const getCompleteZipCallback = (data) => {
const file = new Blob([data], { type: 'application/zip' });
const url = window.URL.createObjectURL(file);
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', `application-${applicationId}.zip`);
document.body.appendChild(link);
link.click();
link.remove();
setLoading(false);
}
const errCompleteZipCallback = (data) => {
set404FromErrorResponse(data);
setLoading(false);
}
return (applicationId && applicationId !== 0
? <Button
type="button"
disabled={loading}
onClick={onClickDownload}
label={__('Scarica ZIP', 'gepafin')}
icon="pi pi-download"
iconPos="right"/> : null
)
}
export default DownloadApplicationArchive;

View File

@@ -0,0 +1,51 @@
import React, { useState, useEffect } from 'react';
import { __ } from '@wordpress/i18n';
import { isEmpty } from 'ramda';
// api
import CompanyService from '../../../../service/company-service';
// components
import { Button } from 'primereact/button';
const DownloadCompanyDelegation = ({ applicationId = 0 }) => {
const [loading, setLoading] = useState(false);
const [delega, setDelega] = useState({});
const onClickDownload = () => {
if (delega.filePath) {
window.open(encodeURI(delega.filePath), '_blank').focus()
}
}
const getDellegaCallback = (data) => {
if (data.data) {
setDelega(data.data);
}
setLoading(false);
}
const errDellegaCallback = () => {
setDelega([]);
setLoading(false);
}
useEffect(() => {
setLoading(true);
CompanyService.getCompanyDelega(getDellegaCallback, errDellegaCallback, [
['applicationId', applicationId]
]);
}, [])
return (applicationId && applicationId !== 0
? <Button
type="button"
disabled={loading || isEmpty(delega)}
onClick={onClickDownload}
label={__('Scarica la delega', 'gepafin')}
icon="pi pi-download"
iconPos="right"/> : null
)
}
export default DownloadCompanyDelegation;

View File

@@ -0,0 +1,45 @@
import React, { useState } from 'react';
import { __ } from '@wordpress/i18n';
// api
import ApplicationService from '../../../../service/application-service';
// components
import { Button } from 'primereact/button';
const DownloadSignedApplication = ({ applicationId = 0 }) => {
const [loading, setLoading] = useState(false);
const [, setDocument] = useState({});
const onClickDownload = () => {
setLoading(true);
ApplicationService.getApplicationSignedPdf(applicationId, getSignedPdfCallback, errSignedPdfCallbacks);
}
const getSignedPdfCallback = (data) => {
if (data.data) {
setDocument([data.data]);
if (data.data.filePath) {
window.open(encodeURI(data.data.filePath), '_blank').focus()
}
}
setLoading(false);
}
const errSignedPdfCallbacks = () => {
setDocument([]);
setLoading(false);
}
return (applicationId && applicationId !== 0
? <Button
type="button"
disabled={loading}
onClick={onClickDownload}
label={__('Scarica PDF firmato', 'gepafin')}
icon="pi pi-download"
iconPos="right"/> : null
)
}
export default DownloadSignedApplication;

View File

@@ -0,0 +1,72 @@
import React from 'react';
import { Button } from 'primereact/button';
import { __ } from '@wordpress/i18n';
import { isNil } from 'ramda';
import ArchiveDocument from '../ArchiveDocument';
const ListOfFiles = ({ files, updateFn, shouldDisableFieldFn, name, ndg, applicationId }) => {
return (
<ol className="appPageSection__list">
{files.map((o, i) => <li key={o.id} className="appPageSection__listItem">
<div className="appPageSection__listItemRow">
<span>{o.label}</span>
<div className="appPageSection__iconActions">
{o.fileDetail && o.fileDetail.length === 1
? <Button icon="pi pi-eye" rounded
onClick={() => {
window.open(o.fileDetail[0].filePath, '_blank').focus()
}}
outlined severity="info"
aria-label={__('Mostra', 'gepafin')}/> : null}
<Button icon="pi pi-thumbs-up" rounded outlined
disabled={shouldDisableFieldFn(name)}
severity={!isNil(o.valid) && o.valid ? 'success' : 'secondary'}
onClick={() => updateFn(
true,
[name, i, 'valid']
)}
aria-label={__('Su', 'gepafin')}/>
<Button icon="pi pi-thumbs-down" rounded outlined
disabled={shouldDisableFieldFn(name)}
severity={!isNil(o.valid) && !o.valid ? 'danger' : 'secondary'}
onClick={() => updateFn(
false,
[name, i, 'valid']
)}
aria-label={__('Giu', 'gepafin')}/>
</div>
</div>
{o.fileDetail && o.fileDetail.length > 1
? <ul style={{
width: '100%',
paddingLeft: '15px',
display: 'flex',
flexDirection: 'column',
gap: '10px'
}}>
{o.fileDetail.map((k) => <li key={k.id} style={{
display: 'flex',
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between'
}}>
<span>{k.name}</span>
<div className="appPageSection__iconActions">
<ArchiveDocument ndg={ndg} applicationId={applicationId} fileId={k.id}/>
<Button icon="pi pi-eye" rounded
onClick={() => {
window.open(k.filePath, '_blank').focus()
}}
outlined severity="info"
aria-label={__('Mostra', 'gepafin')}/>
</div>
</li>)}
</ul>
: null}
</li>)}
</ol>
)
}
export default ListOfFiles;