chore(notifications):improve performance [EE-4815] (#8475)

* chore(notifications):improve performance [EE-4815]

Co-authored-by: testa113 <testa113>
pull/8436/merge
Ali 2023-02-17 12:51:00 +13:00 committed by GitHub
parent 89dd72b4ac
commit 23f3008500
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 27 additions and 29 deletions

View File

@ -7,7 +7,6 @@ import {
} from '@reach/menu-button'; } from '@reach/menu-button';
import { UISrefProps, useSref } from '@uirouter/react'; import { UISrefProps, useSref } from '@uirouter/react';
import Moment from 'moment'; import Moment from 'moment';
import { useEffect, useState } from 'react';
import { useStore } from 'zustand'; import { useStore } from 'zustand';
import { AlertCircle, Bell, CheckCircle, Trash2 } from 'lucide-react'; import { AlertCircle, Bell, CheckCircle, Trash2 } from 'lucide-react';
@ -35,23 +34,6 @@ export function NotificationsMenu() {
(state) => state.userNotifications[user.Id] (state) => state.userNotifications[user.Id]
); );
if (userNotifications && userNotifications.length > 1) {
userNotifications.sort(
(a, b) =>
new Date(b.timeStamp).getTime() - new Date(a.timeStamp).getTime()
);
}
const [badge, setBadge] = useState(false);
useEffect(() => {
if (userNotifications?.length > 0) {
setBadge(true);
} else {
setBadge(false);
}
}, [userNotifications]);
return ( return (
<Menu> <Menu>
<MenuButton <MenuButton
@ -71,7 +53,11 @@ export function NotificationsMenu() {
)} )}
> >
<Icon icon={Bell} /> <Icon icon={Bell} />
<span className={badge ? notificationStyles.badge : ''} /> <span
className={
userNotifications?.length > 0 ? notificationStyles.badge : ''
}
/>
</div> </div>
</MenuButton> </MenuButton>

View File

@ -2,11 +2,12 @@ import create from 'zustand/vanilla';
import { persist } from 'zustand/middleware'; import { persist } from 'zustand/middleware';
import { keyBuilder } from '@/react/hooks/useLocalStorage'; import { keyBuilder } from '@/react/hooks/useLocalStorage';
import { UserId } from '@/portainer/users/types';
import { ToastNotification } from './types'; import { ToastNotification } from './types';
interface NotificationsState { interface NotificationsState {
userNotifications: Record<string, ToastNotification[]>; userNotifications: Record<UserId, ToastNotification[]>;
addNotification: (userId: number, notification: ToastNotification) => void; addNotification: (userId: number, notification: ToastNotification) => void;
removeNotification: (userId: number, notificationId: string) => void; removeNotification: (userId: number, notificationId: string) => void;
removeNotifications: (userId: number, notifications: string[]) => void; removeNotifications: (userId: number, notifications: string[]) => void;
@ -18,15 +19,26 @@ export const notificationsStore = create<NotificationsState>()(
(set) => ({ (set) => ({
userNotifications: {}, userNotifications: {},
addNotification: (userId: number, notification: ToastNotification) => { addNotification: (userId: number, notification: ToastNotification) => {
set((state) => ({ set((state) => {
userNotifications: { const currentUserNotifications =
...state.userNotifications, state.userNotifications[userId] || [];
[userId]: [ // keep the new notification at the start of the list, so sorting by newest time isn't required
...(state.userNotifications[userId] || []), const newUserNotifications = [
notification, notification,
], ...currentUserNotifications,
}, ];
})); const maxNotifications = 50;
const reducedNotifications = newUserNotifications.slice(
0,
maxNotifications
);
return {
userNotifications: {
...state.userNotifications,
[userId]: reducedNotifications,
},
};
});
}, },
removeNotification: (userId: number, notificationId: string) => { removeNotification: (userId: number, notificationId: string) => {
set((state) => ({ set((state) => ({