mirror of https://github.com/portainer/portainer
chore(notifications):improve performance [EE-4815] (#8475)
* chore(notifications):improve performance [EE-4815] Co-authored-by: testa113 <testa113>pull/8436/merge
parent
89dd72b4ac
commit
23f3008500
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -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) => ({
|
||||||
|
|
Loading…
Reference in New Issue