- implemneted API for notifications;

- added styles for notifications;
- added email template to amendment page;
This commit is contained in:
Vitalii Kiiko
2024-12-30 15:03:32 +01:00
parent 0fddd87190
commit d15933f043
9 changed files with 171 additions and 55 deletions

View File

@@ -434,6 +434,15 @@
}
}
.appPageSection__emailTemplate {
> div {
max-width: 100%!important;
> div {
max-width: 100%!important;
}
}
}
@media (max-width: 700px) {
.appPageSection {
&.columns {

View File

@@ -1,4 +1,5 @@
import React from 'react';
import getDateFromISOstring from '../../../../helpers/getDateFromISOstring';
const NotificationItem = ({ item, clickFn }) => {
const handleClick = () => {
@@ -8,8 +9,10 @@ const NotificationItem = ({ item, clickFn }) => {
return (
<li className="notificationsSidebar__listItem" onClick={handleClick}>
<div className="notificationsSidebar__listItemContent">
<strong>{item.title}</strong>
<span>{item.createdDate}</span>
{item.status === 'READ'
? <p>{item.title}</p>
: <strong>{item.title}</strong>}
<span>{getDateFromISOstring(item.createdDate)}</span>
</div>
<i className="pi pi-angle-right"></i>
</li>

View File

@@ -1,8 +1,9 @@
import React from 'react';
import { __ } from '@wordpress/i18n';
import { Button } from 'primereact/button';
import getDateFromISOstring from '../../../../helpers/getDateFromISOstring';
const NotificationItemChosen = ({ item, closeFn }) => {
const NotificationItemChosen = ({ item, closeFn, markReadFn }) => {
return (
<div className="notificationsSidebar__listItemChosen">
<Button
@@ -13,8 +14,15 @@ const NotificationItemChosen = ({ item, closeFn }) => {
label={__('Indietro', 'gepafin')}
icon="pi pi-arrow-left" iconPos="left"/>
<strong>{item.title}</strong>
<span>{item.createdDate}</span>
<span>{getDateFromISOstring(item.createdDate)}</span>
{item.message}
<Button
style={{marginTop: '20px'}}
type="button"
outlined
onClick={() => markReadFn(item.id)}
label={__('Letto', 'gepafin')}/>
</div>
)
}

View File

@@ -8,6 +8,9 @@ import { storeGet, useStore } from '../../store';
// api
import NotificationService from '../../service/notification-service';
// tools
import set404FromErrorResponse from '../../helpers/set404FromErrorResponse';
// components
import { Badge } from 'primereact/badge';
import { Sidebar } from 'primereact/sidebar';
@@ -33,11 +36,12 @@ const NotificationsSidebar = () => {
const fetchTabData = (index) => {
setChosenMsg({});
console.log('fetchTabData', index);
setLoading(true);
setTimeout(() => {
setLoading(false);
}, 7000)
if (0 === index) {
fetchMessages();
} else {
fetchMessages('READ');
}
}
const chooseNotification = (id) => {
@@ -52,28 +56,79 @@ const NotificationsSidebar = () => {
setChosenMsg({});
}
const fetchMessages = (status = 'UNREAD') => {
const chosenCompanyId = storeGet.main.chosenCompanyId();
const userData = storeGet.main.userData();
const role = pathOr('', ['role', 'roleType'], userData);
if (userData.id && chosenCompanyId !== 0 && role === 'ROLE_BENEFICIARY') {
setLoading(true);
NotificationService.getNotifications(
userData.id,
status === 'UNREAD' ? getNotifications : getNotificationsRead,
errGetNotifications,
[
['status', status],
['companyId', chosenCompanyId]
]
);
} else if (userData.id && role !== 'ROLE_BENEFICIARY') {
setLoading(true);
NotificationService.getNotifications(
userData.id,
status === 'UNREAD' ? getNotifications : getNotificationsRead,
errGetNotifications,
[
['status', status]
]
);
}
}
const getNotifications = (resp) => {
console.log('resp', resp);
if (resp.status === 'SUCCESS') {
setNotifications(resp.data);
}
set404FromErrorResponse(resp);
setLoading(false);
}
const getNotificationsRead = (resp) => {
if (resp.status === 'SUCCESS') {
setNotificationsRead(resp.data);
}
set404FromErrorResponse(resp);
setLoading(false);
}
const errGetNotifications = (resp) => {
set404FromErrorResponse(resp);
setLoading(false);
}
const makeNotificationRead = (id) => {
NotificationService.notificationMakeRead(id, makeReadCallback, makeReadErrorCallback)
}
const makeReadCallback = (resp) => {
if (resp.status === 'SUCCESS') {
if (0 === activeIndex) {
const msgs = notifications.map(o => o.id === resp.data.id ? resp.data : o);
setNotifications(msgs);
} else {
const msgs = notificationsRead.map(o => o.id === resp.data.id ? resp.data : o);
setNotificationsRead(msgs);
}
}
set404FromErrorResponse(resp);
}
const makeReadErrorCallback = (resp) => {
set404FromErrorResponse(resp);
}
useEffect(() => {
const role = pathOr('', ['role', 'roleType'], userData);
console.log('chosenCompanyId', chosenCompanyId, role)
if (userData.id && chosenCompanyId !== 0 && role === 'ROLE_BENEFICIARY') {
NotificationService.getNotifications(userData.id, getNotifications, errGetNotifications, [
['status', 'UNREAD'],
['companyId', chosenCompanyId]
]);
} else if (userData.id && role !== 'ROLE_BENEFICIARY') {
NotificationService.getNotifications(userData.id, getNotifications, errGetNotifications, [
['status', 'UNREAD']
]);
}
fetchMessages();
}, [chosenCompanyId, userData.id]);
return (
@@ -94,11 +149,16 @@ const NotificationsSidebar = () => {
<i className="pi pi-spin pi-spinner" style={{ fontSize: '2rem' }}></i>
</div>
: !isEmpty(chosenMsg)
? <NotificationItemChosen item={chosenMsg} closeFn={closeChosenMsg}/>
? <NotificationItemChosen
item={chosenMsg}
closeFn={closeChosenMsg}
markReadFn={makeNotificationRead}/>
: (notifications.length > 0
? <ul className="notificationsSidebar__list">
{notifications.map(o => <NotificationItem key={o.id} item={o}
clickFn={chooseNotification}/>)}
{notifications.map(o => <NotificationItem
key={o.id}
item={o}
clickFn={chooseNotification}/>)}
</ul>
: <div className="notificationsSidebar__loading">
<i className="pi pi-megaphone" style={{ fontSize: '2rem' }}></i>
@@ -111,11 +171,16 @@ const NotificationsSidebar = () => {
<i className="pi pi-spin pi-spinner" style={{ fontSize: '2rem' }}></i>
</div>
: !isEmpty(chosenMsg)
? <NotificationItemChosen item={chosenMsg} closeFn={closeChosenMsg}/>
? <NotificationItemChosen
item={chosenMsg}
closeFn={closeChosenMsg}
markReadFn={makeNotificationRead}/>
: (notificationsRead.length > 0
? <ul className="notificationsSidebar__list">
{notificationsRead.map(o => <NotificationItem key={o.id} item={o}
clickFn={chooseNotification}/>)}
{notificationsRead.map(o => <NotificationItem
key={o.id}
item={o}
clickFn={chooseNotification}/>)}
</ul>
:
<div className="notificationsSidebar__loading">

View File

@@ -0,0 +1,28 @@
import parse from 'html-react-parser';
import DOMPurify from 'dompurify';
const getEmailTemplateForSoccorso = (content = '', fallback = '') => {
const config = {
FORBID_TAGS: ['html', 'body'],
WHOLE_DOCUMENT: false,
RETURN_DOM: false,
RETURN_DOM_FRAGMENT: false,
RETURN_DOM_IMPORT: false,
FORCE_BODY: false,
ADD_TAGS: ['*'],
ADD_ATTR: ['*']
};
try {
const wrappedHtml = `<div>${content}</div>`;
const cleaned = DOMPurify.sanitize(wrappedHtml, config);
const tempDiv = document.createElement('div');
tempDiv.innerHTML = cleaned;
return parse(tempDiv.innerHTML);
} catch (error) {
console.error('DOMPurify cleaning error:', error);
return fallback;
}
}
export default getEmailTemplateForSoccorso;

View File

@@ -138,7 +138,7 @@ const RepeaterFields = ({
className="fieldsRepeater__addNew"
outlined
type="button"
disabled={watchFields && watchFields.filter(o => isEmpty(o.nameValue) || isEmpty(o.fileValue)).length > 0 || shouldDisable}
disabled={(watchFields && watchFields.filter(o => isEmpty(o.nameValue) || isEmpty(o.fileValue)).length > 0) || shouldDisable}
onClick={addNew}
label={__('Aggiungi nuovo file', 'gepafin')}
/>

View File

@@ -27,6 +27,7 @@ import { Dialog } from 'primereact/dialog';
import FormField from '../../components/FormField';
import SoccorsoComunications from '../SoccorsoEditPreInstructor/components/SoccorsoComunications';
import { Editor } from 'primereact/editor';
import getEmailTemplateForSoccorso from '../../helpers/getStrippedHtmlBodyTags';
const SoccorsoEditBeneficiario = () => {
const isAsyncRequest = useStore().main.isAsyncRequest();
@@ -327,10 +328,7 @@ const SoccorsoEditBeneficiario = () => {
? <div className="appPageSection">
<h2>{__('Dettagli Richiesta', 'gepafin')}</h2>
<h3>{__('Note e spiegazioni', 'gepafin')}</h3>
<div className="appPageSection__withBorder grey ql-editor"
style={{ minHeight: '100px' }}>
{renderHtmlContent(data.note)}
</div>
<div>{getEmailTemplateForSoccorso(data.emailTemplate, data.note)}</div>
</div> : null}
{data.id

View File

@@ -16,7 +16,7 @@ import AmendmentsService from '../../service/amendments-service';
import set404FromErrorResponse from '../../helpers/set404FromErrorResponse';
import getBandoLabel from '../../helpers/getBandoLabel';
import getDateFromISOstring from '../../helpers/getDateFromISOstring';
import renderHtmlContent from '../../helpers/renderHtmlContent';
import getEmailTemplateForSoccorso from '../../helpers/getStrippedHtmlBodyTags';
// components
import { Button } from 'primereact/button';
@@ -411,26 +411,19 @@ const SoccorsoEditPreInstructor = () => {
<div className="appPageSection">
<h2>{__('Dettagli Richiesta', 'gepafin')}</h2>
<div className="appPageSection columns">
<div>
<h3>{__('Documenti Richiesti', 'gepafin')}</h3>
<ol className="appPageSection__list">
{data.formFields
? data.formFields.map((o, i) => <li key={o.fieldId}
style={{ flexDirection: 'row' }}>
<span>{o.label}</span>
</li>) : null}
</ol>
</div>
<div>
<h3>{__('Note e spiegazioni', 'gepafin')}</h3>
<div className="appPageSection__withBorder grey ql-editor"
style={{ minHeight: '200px' }}>
{renderHtmlContent(data.note)}
</div>
</div>
</div>
<h3>{__('Note e spiegazioni', 'gepafin')}</h3>
<div
className="appPageSection__emailTemplate">{getEmailTemplateForSoccorso(data.emailTemplate, data.note)}</div>
</div>
<div className="appPageSection">
<h3>{__('Documenti Richiesti', 'gepafin')}</h3>
<ol className="appPageSection__list">
{data.formFields
? data.formFields.map((o, i) => <li key={o.fieldId}
style={{ flexDirection: 'row' }}>
<span>{o.label}</span>
</li>) : null}
</ol>
</div>
<div className="appPageSection">

View File

@@ -7,4 +7,16 @@ export default class NotificationService {
static getNotifications = (id, callback, errCallback, queryParams) => {
NetworkService.get(`${API_BASE_URL}/notification/user/${id}`, callback, errCallback, queryParams);
};
static notificationMakeRead = (id, callback, errCallback) => {
NetworkService.put(`${API_BASE_URL}/notification/${id}`, {}, callback, errCallback, [
['status', 'READ']
]);
};
static notificationMakeUnread = (id, callback, errCallback) => {
NetworkService.put(`${API_BASE_URL}/notification/${id}`, {}, callback, errCallback, [
['status', 'UNREAD']
]);
};
}