From d15933f04325eafb8a9ec3bea22b27ec2e46ceeb Mon Sep 17 00:00:00 2001 From: Vitalii Kiiko Date: Mon, 30 Dec 2024 15:03:32 +0100 Subject: [PATCH] - implemneted API for notifications; - added styles for notifications; - added email template to amendment page; --- src/assets/scss/components/appPage.scss | 9 ++ .../components/NotificationItem/index.js | 7 +- .../NotificationItemChosen/index.js | 12 +- src/components/NotificationsSidebar/index.js | 115 ++++++++++++++---- src/helpers/getStrippedHtmlBodyTags.js | 28 +++++ .../components/RepeaterFields/index.js | 2 +- src/pages/SoccorsoEditBeneficiario/index.js | 6 +- src/pages/SoccorsoEditPreInstructor/index.js | 35 +++--- src/service/notification-service.js | 12 ++ 9 files changed, 171 insertions(+), 55 deletions(-) create mode 100644 src/helpers/getStrippedHtmlBodyTags.js diff --git a/src/assets/scss/components/appPage.scss b/src/assets/scss/components/appPage.scss index 9d3de37..4f98387 100644 --- a/src/assets/scss/components/appPage.scss +++ b/src/assets/scss/components/appPage.scss @@ -434,6 +434,15 @@ } } +.appPageSection__emailTemplate { + > div { + max-width: 100%!important; + > div { + max-width: 100%!important; + } + } +} + @media (max-width: 700px) { .appPageSection { &.columns { diff --git a/src/components/NotificationsSidebar/components/NotificationItem/index.js b/src/components/NotificationsSidebar/components/NotificationItem/index.js index df13bc0..3d2efc5 100644 --- a/src/components/NotificationsSidebar/components/NotificationItem/index.js +++ b/src/components/NotificationsSidebar/components/NotificationItem/index.js @@ -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 (
  • - {item.title} - {item.createdDate} + {item.status === 'READ' + ?

    {item.title}

    + : {item.title}} + {getDateFromISOstring(item.createdDate)}
  • diff --git a/src/components/NotificationsSidebar/components/NotificationItemChosen/index.js b/src/components/NotificationsSidebar/components/NotificationItemChosen/index.js index 4821df3..4588de6 100644 --- a/src/components/NotificationsSidebar/components/NotificationItemChosen/index.js +++ b/src/components/NotificationsSidebar/components/NotificationItemChosen/index.js @@ -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 (
    ) } diff --git a/src/components/NotificationsSidebar/index.js b/src/components/NotificationsSidebar/index.js index 1a690ee..7e1d919 100644 --- a/src/components/NotificationsSidebar/index.js +++ b/src/components/NotificationsSidebar/index.js @@ -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 = () => { : !isEmpty(chosenMsg) - ? + ? : (notifications.length > 0 ?
      - {notifications.map(o => )} + {notifications.map(o => )}
    :
    @@ -111,11 +171,16 @@ const NotificationsSidebar = () => {
    : !isEmpty(chosenMsg) - ? + ? : (notificationsRead.length > 0 ?
      - {notificationsRead.map(o => )} + {notificationsRead.map(o => )}
    :
    diff --git a/src/helpers/getStrippedHtmlBodyTags.js b/src/helpers/getStrippedHtmlBodyTags.js new file mode 100644 index 0000000..59c4315 --- /dev/null +++ b/src/helpers/getStrippedHtmlBodyTags.js @@ -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 = `
    ${content}
    `; + 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; \ No newline at end of file diff --git a/src/pages/DomandaEditPreInstructor/components/RepeaterFields/index.js b/src/pages/DomandaEditPreInstructor/components/RepeaterFields/index.js index d6249d9..36564c5 100644 --- a/src/pages/DomandaEditPreInstructor/components/RepeaterFields/index.js +++ b/src/pages/DomandaEditPreInstructor/components/RepeaterFields/index.js @@ -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')} /> diff --git a/src/pages/SoccorsoEditBeneficiario/index.js b/src/pages/SoccorsoEditBeneficiario/index.js index 21da492..4a88264 100644 --- a/src/pages/SoccorsoEditBeneficiario/index.js +++ b/src/pages/SoccorsoEditBeneficiario/index.js @@ -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 = () => { ?

    {__('Dettagli Richiesta', 'gepafin')}

    {__('Note e spiegazioni', 'gepafin')}

    -
    - {renderHtmlContent(data.note)} -
    +
    {getEmailTemplateForSoccorso(data.emailTemplate, data.note)}
    : null} {data.id diff --git a/src/pages/SoccorsoEditPreInstructor/index.js b/src/pages/SoccorsoEditPreInstructor/index.js index 54922dc..f6aad62 100644 --- a/src/pages/SoccorsoEditPreInstructor/index.js +++ b/src/pages/SoccorsoEditPreInstructor/index.js @@ -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 = () => {

    {__('Dettagli Richiesta', 'gepafin')}

    -
    -
    -

    {__('Documenti Richiesti', 'gepafin')}

    -
      - {data.formFields - ? data.formFields.map((o, i) =>
    1. - {o.label} -
    2. ) : null} -
    -
    -
    -

    {__('Note e spiegazioni', 'gepafin')}

    -
    - {renderHtmlContent(data.note)} -
    -
    - -
    +

    {__('Note e spiegazioni', 'gepafin')}

    +
    {getEmailTemplateForSoccorso(data.emailTemplate, data.note)}
    +
    +
    +

    {__('Documenti Richiesti', 'gepafin')}

    +
      + {data.formFields + ? data.formFields.map((o, i) =>
    1. + {o.label} +
    2. ) : null} +
    diff --git a/src/service/notification-service.js b/src/service/notification-service.js index cd33e34..c3457b2 100644 --- a/src/service/notification-service.js +++ b/src/service/notification-service.js @@ -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'] + ]); + }; }