change(ui) - notifications count and list with mobx

This commit is contained in:
Shekar Siri 2022-06-08 15:50:19 +02:00
parent d8911e93c1
commit 767376a8db
4 changed files with 88 additions and 52 deletions

View file

@ -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(() => (
<div className="bg-white box-shadow h-screen overflow-y-auto" style={{ width: '450px'}}>
<div className="flex items-center justify-between p-5 text-2xl">
<div>Alerts</div>
{ count > 0 && (
<div className="">
<Button
loading={clearingAll}
loading={loading}
variant="text"
onClick={props.setLastRead}
onClick={onClearAll}
disabled={count === 0}
>
<span
className={ cn("text-sm color-gray-medium", { 'invisible' : clearingAll })}
onClick={onClearAll}>
<span className={ cn("text-sm color-gray-medium")} >
IGNORE ALL
</span>
</Button>
@ -63,35 +51,27 @@ function AlertTriggersModal(props: Props) {
</div>
<div className="pb-5">
<NoContent
title={
<div className="flex items-center justify-between">
<AnimatedSVG name={ICONS.EMPTY_STATE} size="100" />
</div>
}
subtext="There are no alerts to show."
show={ !loading && count === 0 }
size="small"
>
{list.map((item: any, i: any) => (
<div className="border-b" key={i}>
<ListItem alert={item} onClear={() => onClear(item)} loading={false} />
</div>
))}
</NoContent>
<Loader loading={loading}>
<NoContent
title={
<div className="flex items-center justify-between">
<AnimatedSVG name={ICONS.EMPTY_STATE} size="100" />
</div>
}
subtext="There are no alerts to show."
show={ !loading && list.length === 0 }
size="small"
>
{list.map((item: any, i: any) => (
<div className="border-b" key={i}>
<ListItem alert={item} onClear={() => onClear(item)} loading={markingAsRead} />
</div>
))}
</NoContent>
</Loader>
</div>
</div>
);
));
}
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);
export default AlertTriggersModal;

View file

@ -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<any> {
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<any> {
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<any> {
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;
});
});
}

View file

@ -1,4 +1,3 @@
import { makeAutoObservable, runInAction, observable, action, reaction } from "mobx"
import { DateTime } from 'luxon';
export default class Notification {

View file

@ -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 || {});
}
}