change(ui) - notifications count and list with mobx
This commit is contained in:
parent
d8911e93c1
commit
767376a8db
4 changed files with 88 additions and 52 deletions
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import { makeAutoObservable, runInAction, observable, action, reaction } from "mobx"
|
||||
import { DateTime } from 'luxon';
|
||||
|
||||
export default class Notification {
|
||||
|
|
|
|||
|
|
@ -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 || {});
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue