added notification drop down list and notification page

Merge branch 'PR78' into develop
pull/79/MERGE
13621160019@163.com 2021-11-06 14:16:37 +08:00
commit 4329569bb1
3 changed files with 113 additions and 58 deletions

View File

@ -62,7 +62,7 @@ const Notification = ({ setRedirect, setRedirectUrl, t }) => {
let isResponseOK = false; let isResponseOK = false;
if (!fetchSuccess) { if (!fetchSuccess) {
fetch(APIBaseURL + '/notifications?' + fetch(APIBaseURL + '/webmessagesnew?' +
'startdatetime=' + startDatetime.format('YYYY-MM-DDTHH:mm:ss') + 'startdatetime=' + startDatetime.format('YYYY-MM-DDTHH:mm:ss') +
'&enddatetime=' + endDatetime.format('YYYY-MM-DDTHH:mm:ss'), { '&enddatetime=' + endDatetime.format('YYYY-MM-DDTHH:mm:ss'), {
method: 'GET', method: 'GET',
@ -90,7 +90,8 @@ const Notification = ({ setRedirect, setRedirectUrl, t }) => {
let notification = {} let notification = {}
notification['id'] = json[index]['id']; notification['id'] = json[index]['id'];
notification['subject'] = json[index]['subject']; notification['subject'] = json[index]['subject'];
notification['created_datetime'] = json[index]['created_datetime']; notification['created_datetime'] = moment(parseInt(json[index]['created_datetime']))
.format("YYYY-MM-DD HH:mm:ss");
notification['message'] = json[index]['message']; notification['message'] = json[index]['message'];
notification['status'] = json[index]['status']; notification['status'] = json[index]['status'];
notification['url'] = json[index]['url']; notification['url'] = json[index]['url'];
@ -250,7 +251,7 @@ const Notification = ({ setRedirect, setRedirectUrl, t }) => {
const handleRead = (id, ) => { const handleRead = (id, ) => {
console.log('Mark As Read: ', id) console.log('Mark As Read: ', id)
let isResponseOK = false; let isResponseOK = false;
fetch(APIBaseURL + '/notifications/' + id, { fetch(APIBaseURL + '/webmessages/' + id, {
method: 'PUT', method: 'PUT',
headers: { headers: {
"Content-type": "application/json", "Content-type": "application/json",
@ -259,7 +260,8 @@ const Notification = ({ setRedirect, setRedirectUrl, t }) => {
}, },
body: JSON.stringify({ body: JSON.stringify({
"data": { "data": {
"status": 'read' "status": 'acknowledged',
"reply": 'ok'
} }
}), }),
}).then(response => { }).then(response => {

View File

@ -1,6 +1,6 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import classNames from 'classnames'; import classNames from 'classnames';
import React, { useState } from 'react'; import React, { useEffect, useState } from 'react';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { Card, Dropdown, DropdownMenu, DropdownToggle } from 'reactstrap'; import { Card, Dropdown, DropdownMenu, DropdownToggle } from 'reactstrap';
import ListGroup from 'reactstrap/es/ListGroup'; import ListGroup from 'reactstrap/es/ListGroup';
@ -11,14 +11,70 @@ import useFakeFetch from '../../hooks/useFakeFetch';
import FalconCardHeader from '../common/FalconCardHeader'; import FalconCardHeader from '../common/FalconCardHeader';
import Notification from '../notification/Notification'; import Notification from '../notification/Notification';
import { withTranslation } from 'react-i18next'; import { withTranslation } from 'react-i18next';
import { APIBaseURL } from "../../config";
import moment from 'moment';
import { toast } from "react-toastify";
import { getCookieValue } from '../../helpers/utils';
const NotificationDropdown = ({ t }) => { const NotificationDropdown = ({ t }) => {
// State // State
const { data: newNotifications, setData: setNewNotifications } = useFakeFetch(rawNewNotifications); const [rawNewNotificationschild, setRawNewNotificationschild] = useState([]);
const { data: earlierNotifications, setData: setEarlierNotifications } = useFakeFetch(rawEarlierNotifications);
const [isOpen, setIsOpen] = useState(false); const [isOpen, setIsOpen] = useState(false);
const [isAllRead, setIsAllRead] = useState(false); const [isAllRead, setIsAllRead] = useState(false);
useEffect(() => {
let isResponseOK = false;
fetch(APIBaseURL + '/webmessagesnew', {
method: 'GET',
headers: {
"Content-type": "application/json",
"User-UUID": getCookieValue('user_uuid'),
"Token": getCookieValue('token')
},
body: null,
}).then(response => {
console.log(response);
if (response.ok) {
isResponseOK = true;
}
return response.json();
}).then(json => {
console.log(json)
if (isResponseOK) {
let NewnotificationList = []
if (json.length > 0) {
json.forEach((currentValue, index) => {
let notification = {}
notification['id'] = json[index]['id'];
notification['status'] = json[index]['status'];
notification['subject'] = json[index]['subject']
notification['message'] = json[index]['message'];
notification['created_datetime'] = moment(parseInt(json[index]['created_datetime']))
.format("YYYY-MM-DD HH:mm:ss");
if (NewnotificationList.length > 3 ){
return true
}
if (notification['message'].length > 40){
notification['message'] = notification['message'].substring(0,30) + "...";
}
if (notification["status"] === "new"){
NewnotificationList.push(notification);
}
});
}
setRawNewNotificationschild(NewnotificationList);
}
}).catch(err => {
console.log(err);
});
}, [t,]);
console.log("test");
console.log(rawNewNotificationschild);
// Handler // Handler
const handleToggle = e => { const handleToggle = e => {
e.preventDefault(); e.preventDefault();
@ -27,30 +83,43 @@ const NotificationDropdown = ({ t }) => {
const markAsRead = e => { const markAsRead = e => {
e.preventDefault(); e.preventDefault();
const updatedNewNotifications = newNotifications.map(notification => { rawNewNotificationschild.map((notification,index) => {
if (notification.hasOwnProperty('unread')) { console.log('Mark As Read: ', notification["id"])
return { let isResponseOK = false;
...notification, fetch(APIBaseURL + '/webmessages/' + notification["id"], {
unread: false method: 'PUT',
}; headers: {
"Content-type": "application/json",
"User-UUID": getCookieValue('user_uuid'),
"Token": getCookieValue('token')
},
body: JSON.stringify({
"data": {
"status": 'acknowledged',
"reply": 'ok'
}
}),
}).then(response => {
if (response.ok) {
isResponseOK = true;
return null;
} else {
return response.json();
} }
return notification; }).then(json => {
}); console.log(isResponseOK);
const updatedEarlierNotifications = earlierNotifications.map(notification => { if (isResponseOK) {
if (notification.hasOwnProperty('unread')) {
return {
...notification,
unread: false
};
}
setIsAllRead(true);
return notification;
});
setNewNotifications(updatedNewNotifications); } else {
setEarlierNotifications(updatedEarlierNotifications); toast.error(json.description)
}
}).catch(err => {
console.log(err);
});
});
}; };
return ( return (
<Dropdown <Dropdown
nav nav
@ -83,19 +152,13 @@ const NotificationDropdown = ({ t }) => {
</FalconCardHeader> </FalconCardHeader>
<ListGroup flush className="font-weight-normal fs--1"> <ListGroup flush className="font-weight-normal fs--1">
<div className="list-group-title">{t('notification_NEW')}</div> <div className="list-group-title">{t('notification_NEW')}</div>
{isIterableArray(newNotifications) && {isIterableArray(rawNewNotificationschild) &&
newNotifications.map((notification, index) => ( rawNewNotificationschild.map((notification, index) => (
<ListGroupItem key={index} onClick={handleToggle}>
<Notification {...notification} flush />
</ListGroupItem>
))}
<div className="list-group-title">{t('notification_EARLIER')}</div>
{isIterableArray(earlierNotifications) &&
earlierNotifications.map((notification, index) => (
<ListGroupItem key={index} onClick={handleToggle}> <ListGroupItem key={index} onClick={handleToggle}>
<Notification {...notification} flush /> <Notification {...notification} flush />
</ListGroupItem> </ListGroupItem>
))} ))}
</ListGroup> </ListGroup>
<div className="card-footer text-center border-top-0" onClick={handleToggle}> <div className="card-footer text-center border-top-0" onClick={handleToggle}>
<Link className="card-link d-block" to="/notification"> <Link className="card-link d-block" to="/notification">

View File

@ -5,38 +5,28 @@ import { Link } from 'react-router-dom';
import Avatar from '../common/Avatar'; import Avatar from '../common/Avatar';
import createMarkup from '../../helpers/createMarkup'; import createMarkup from '../../helpers/createMarkup';
const Notification = ({ to, avatar, time, className, unread, flush, emoji, children }) => ( const Notification = ({ created_datetime, id, status, flush, message,subject}) => (
<Link className={classNames('notification', { 'bg-200': unread, 'notification-flush': flush }, className)} to={to}> <Link className={classNames('notification', { 'bg-200': status, 'notification-flush': flush }, id)}
{avatar && ( to="/notification">
<div className="notification-avatar">
<Avatar {...avatar} className="mr-3" />
</div>
)}
<div className="notification-body"> <div className="notification-body">
<p className={emoji ? 'mb-1' : 'mb-0'} dangerouslySetInnerHTML={createMarkup(children)} /> <h5>{subject}</h5><p>{status}</p>
<p className={'mb-0'} dangerouslySetInnerHTML={createMarkup(message)} />
<span className="notification-time"> <span className="notification-time">
{emoji && ( {created_datetime}
<span className="mr-1" role="img" aria-label="Emoji">
{emoji}
</span>
)}
{time}
</span> </span>
</div> </div>
</Link> </Link>
); );
Notification.propTypes = { Notification.propTypes = {
to: PropTypes.string.isRequired, created_datetime: PropTypes.string.isRequired,
avatar: PropTypes.shape(Avatar.propTypes), id: PropTypes.string,
time: PropTypes.string.isRequired, status: PropTypes.string,
className: PropTypes.string, subject: PropTypes.string,
unread: PropTypes.bool,
flush: PropTypes.bool, flush: PropTypes.bool,
emoji: PropTypes.string, message: PropTypes.node
children: PropTypes.node
}; };
Notification.defaultProps = { unread: false, flush: false }; Notification.defaultProps = { status: "acknowledged", flush: false };
export default Notification; export default Notification;