diff --git a/frontend/app/components/shared/AlertTriggersModal/AlertTriggersModal.tsx b/frontend/app/components/shared/AlertTriggersModal/AlertTriggersModal.tsx index e36d03ab1..4d748687d 100644 --- a/frontend/app/components/shared/AlertTriggersModal/AlertTriggersModal.tsx +++ b/frontend/app/components/shared/AlertTriggersModal/AlertTriggersModal.tsx @@ -1,8 +1,5 @@ import React, { useEffect } from 'react'; -import { Button, NoContent } from 'UI'; -import { connect } from 'react-redux'; -import { fetchList, setViewed, clearAll } from 'Duck/notifications'; -import { setLastRead } from 'Duck/announcements'; +import { Button, NoContent, Loader } from 'UI'; import cn from 'classnames'; import AnimatedSVG, { ICONS } from 'Shared/AnimatedSVG/AnimatedSVG'; import ListItem from './ListItem' @@ -10,51 +7,42 @@ import { useStore } from 'App/mstore'; import { useObserver } from 'mobx-react-lite'; interface Props { - setLastRead: Function; - clearingAll: boolean; - loading: boolean; - clearing: boolean; - - list: any; - clearAll: Function; - setViewed: Function; } function AlertTriggersModal(props: Props) { - const { loading, clearingAll, clearing } = props; const { notificationStore } = useStore(); const count = useObserver(() => notificationStore.notificationsCount); const list = useObserver(() => notificationStore.notifications); + const loading = useObserver(() => notificationStore.loading); + const markingAsRead = useObserver(() => notificationStore.markingAsRead); const onClearAll = () => { - const { list } = props; - const firstItem = list.first(); - props.clearAll({ endTimestamp: firstItem.createdAt.ts }); + const firstItem = list[0]; + if (!firstItem) return; + notificationStore.ignoreAllNotifications({ endTimestamp: firstItem.createdAt.ts }); } const onClear = (notification: any) => { - props.setViewed(notification.notificationId) + notificationStore.ignoreNotification(notification.notificationId); } useEffect(() => { notificationStore.fetchNotifications(); }, []) - return ( + return useObserver(() => (
Alerts
{ count > 0 && (
@@ -63,35 +51,27 @@ function AlertTriggersModal(props: Props) {
- - -
- } - subtext="There are no alerts to show." - show={ !loading && count === 0 } - size="small" - > - {list.map((item: any, i: any) => ( -
- onClear(item)} loading={false} /> -
- ))} - + + + +
+ } + subtext="There are no alerts to show." + show={ !loading && list.length === 0 } + size="small" + > + {list.map((item: any, i: any) => ( +
+ onClear(item)} loading={markingAsRead} /> +
+ ))} + +
- ); + )); } -export default connect((state: any) => ({ - loading: state.getIn(['notifications', 'fetchRequest', 'loading']), - clearing: state.getIn(['notifications', 'setViewed', 'loading']), - clearingAll: state.getIn(['notifications', 'clearAll', 'loading']), - list: state.getIn(['notifications', 'list']), -}), { - fetchList, - setLastRead, - setViewed, - clearAll, -})(AlertTriggersModal); \ No newline at end of file +export default AlertTriggersModal; \ No newline at end of file diff --git a/frontend/app/mstore/notificationStore.ts b/frontend/app/mstore/notificationStore.ts index 7afaecfd2..e2e4fbe5e 100644 --- a/frontend/app/mstore/notificationStore.ts +++ b/frontend/app/mstore/notificationStore.ts @@ -3,20 +3,26 @@ import { userService } from 'App/services'; import Notification from './types/notification'; export default class NotificationStore { + loading: boolean = false; + markingAsRead: boolean = false; notificationsCount: any = 0; notifications: any = []; constructor() { makeAutoObservable(this, { + loading: observable, notificationsCount: observable, notifications: observable, fetchNotificationsCount: action, fetchNotifications: action, + ignoreAllNotifications: action, + ignoreNotification: action, }); } fetchNotifications(): Promise { + this.loading = true; return new Promise((resolve, reject) => { userService.getNotifications() .then((response: any) => { @@ -24,6 +30,44 @@ export default class NotificationStore { resolve(response); }).catch((error: any) => { reject(error); + }).finally(() => { + this.loading = false; + }); + }); + } + + ignoreAllNotifications(params: any): Promise { + return new Promise((resolve, reject) => { + userService.ignoreAllNotifications(params) + .then((response: any) => { + this.notifications = this.notifications.map((notification: any) => { + notification.viewed = true; + return notification; + }); + resolve(response); + }).catch((error: any) => { + reject(error); + }); + }); + } + + ignoreNotification(notificationId: number): Promise { + this.markingAsRead = true; + return new Promise((resolve, reject) => { + userService.ignoreNotification(notificationId) + .then((response: any) => { + // updates notifications item + this.notifications = this.notifications.map((notification: any) => { + if (notification.notificationId === notificationId) { + notification.viewed = true; + } + return notification; + }); + resolve(response); + }).catch((error: any) => { + reject(error); + }).finally(() => { + this.markingAsRead = false; }); }); } diff --git a/frontend/app/mstore/types/notification.ts b/frontend/app/mstore/types/notification.ts index 09061b210..3a47f90ed 100644 --- a/frontend/app/mstore/types/notification.ts +++ b/frontend/app/mstore/types/notification.ts @@ -1,4 +1,3 @@ -import { makeAutoObservable, runInAction, observable, action, reaction } from "mobx" import { DateTime } from 'luxon'; export default class Notification { diff --git a/frontend/app/services/UserService.ts b/frontend/app/services/UserService.ts index 7df24cf01..43c6350f2 100644 --- a/frontend/app/services/UserService.ts +++ b/frontend/app/services/UserService.ts @@ -72,4 +72,17 @@ export default class UserService { .then((response: { json: () => any; }) => response.json()) .then((response: { data: any; }) => response.data || {}); } + + ignoreNotification(notificationId: string) { + return this.client.get(`/notifications/${notificationId}/view`) + .then((response: { json: () => any; }) => response.json()) + .then((response: { data: any; }) => response.data || {}); + } + + ignoreAllNotifications(params: any) { + return this.client.post(`/notifications/view`, params) + .then((response: { json: () => any; }) => response.json()) + .then((response: { data: any; }) => response.data || {}); + } + } \ No newline at end of file