diff --git a/frontend/desktop/src/components/notification/index.tsx b/frontend/desktop/src/components/notification/index.tsx index fac65496e..782936f16 100644 --- a/frontend/desktop/src/components/notification/index.tsx +++ b/frontend/desktop/src/components/notification/index.tsx @@ -3,12 +3,12 @@ import request from '@/services/request'; import useAppStore from '@/stores/app'; import { formatTime } from '@/utils/tools'; import { Box, Button, Flex, Text, UseDisclosureReturn } from '@chakra-ui/react'; -import { ClearOutlineIcon, CloseIcon, WarnIcon } from '@sealos/ui'; +import { ClearOutlineIcon, CloseIcon, WarnIcon, useMessage } from '@sealos/ui'; import { useMutation, useQuery } from '@tanstack/react-query'; import clsx from 'clsx'; import { produce } from 'immer'; import { useTranslation } from 'next-i18next'; -import { useEffect, useState } from 'react'; +import { useEffect, useRef, useState } from 'react'; import styles from './index.module.scss'; import { NotificationItem } from '@/types'; @@ -23,6 +23,8 @@ export default function Notification(props: TNotification) { const { installedApps, openApp } = useAppStore(); const [readNotes, setReadNotes] = useState([]); const [unReadNotes, setUnReadNotes] = useState([]); + const { message } = useMessage(); + const isForbiddenRef = useRef(false); const [MessageConfig, setMessageConfig] = useState<{ activeTab: 'read' | 'unread'; @@ -46,7 +48,8 @@ export default function Notification(props: TNotification) { handleNotificationData(messages); } }, - refetchInterval: 5 * 60 * 1000 + refetchInterval: 5 * 60 * 1000, + staleTime: 5 * 60 * 1000 } ); @@ -63,7 +66,7 @@ export default function Notification(props: TNotification) { unReadMessage.sort(compareByTimestamp); readMessage.sort(compareByTimestamp); - if (unReadMessage?.[0]?.spec?.desktopPopup) { + if (unReadMessage?.[0]?.spec?.desktopPopup && !isForbiddenRef.current) { setMessageConfig( produce((draft) => { draft.popupMessage = unReadMessage[0]; @@ -79,8 +82,23 @@ export default function Notification(props: TNotification) { const notifications = MessageConfig.activeTab === 'unread' ? unReadNotes : readNotes; const readMsgMutation = useMutation({ - mutationFn: (name: string[]) => request.post('/api/notification/read', { name }), - onSettled: () => refetch() + mutationFn: (name: string[]) => + request.post<{ code: number; reason: string }>('/api/notification/read', { name }), + onSettled: () => refetch(), + onSuccess: (data) => { + if (data.data.code === 403) { + isForbiddenRef.current = true; + message({ + status: 'warning', + title: data.data.reason + }); + setMessageConfig( + produce((draft) => { + draft.popupMessage = undefined; + }) + ); + } + } }); const goMsgDetail = (item: NotificationItem) => { diff --git a/frontend/desktop/src/pages/api/desktop/getInstalledApps.ts b/frontend/desktop/src/pages/api/desktop/getInstalledApps.ts index 9968b70ae..360146f8b 100644 --- a/frontend/desktop/src/pages/api/desktop/getInstalledApps.ts +++ b/frontend/desktop/src/pages/api/desktop/getInstalledApps.ts @@ -25,9 +25,19 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) const getRawAppList = async (meta: CRDMeta) => ((await ListCRD(kc, meta)).body as TAppCRList).items || []; - const defaultArr = (await getRawAppList(getMeta())).map((item) => { - return { key: `system-${item.metadata.name}`, ...item.spec }; - }); + const defaultArr = (await getRawAppList(getMeta())) + .map((item) => { + return { key: `system-${item.metadata.name}`, ...item.spec }; + }) + .sort((a, b) => { + if (a.displayType === 'more' && b.displayType !== 'more') { + return 1; + } else if (a.displayType !== 'more' && b.displayType === 'more') { + return -1; + } else { + return 0; + } + }); const userArr = (await getRawAppList(getMeta(payload.workspaceId))).map((item) => { return { key: `user-${item.metadata.name}`, ...item.spec, displayType: 'normal' }; diff --git a/frontend/desktop/src/pages/api/desktop/getResource.ts b/frontend/desktop/src/pages/api/desktop/getResource.ts index 09bd9f00d..98bb1771d 100644 --- a/frontend/desktop/src/pages/api/desktop/getResource.ts +++ b/frontend/desktop/src/pages/api/desktop/getResource.ts @@ -25,9 +25,12 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) let totalMemoryLimits = 0; let totalStorageRequests = 0; let runningPodCount = 0; - let totalPodCount = result.body.items.length; + let totalPodCount = 0; for (const pod of result.body.items) { + if (pod.status?.phase === 'Succeeded') continue; + totalPodCount++; + if (pod.status?.phase === 'Running') { runningPodCount++; } diff --git a/frontend/desktop/src/pages/api/notification/read.ts b/frontend/desktop/src/pages/api/notification/read.ts index 2678ce5c7..7460d2609 100644 --- a/frontend/desktop/src/pages/api/notification/read.ts +++ b/frontend/desktop/src/pages/api/notification/read.ts @@ -37,8 +37,23 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) let result = []; for (const n of name) { - let temp = await UpdateCRD(kc, meta, n, patch); - result.push(temp?.body); + try { + let temp = await UpdateCRD(kc, meta, n, patch); + result.push(temp?.body); + } catch (err: any) { + if (err?.body?.code === 403) { + const temp = { + name: n, + reason: err?.body?.reason, + message: err?.body?.message, + code: 403 + }; + + jsonRes(res, { data: temp }); + } else { + throw err; + } + } } jsonRes(res, { data: result }); } catch (err) { diff --git a/frontend/desktop/src/types/app.ts b/frontend/desktop/src/types/app.ts index fcf526445..6017f987e 100644 --- a/frontend/desktop/src/types/app.ts +++ b/frontend/desktop/src/types/app.ts @@ -8,7 +8,8 @@ export enum APPTYPE { } export type WindowSize = 'maximize' | 'maxmin' | 'minimize'; -export type displayType = 'normal' | 'hidden' | 'more '; +export type displayType = 'normal' | 'hidden' | 'more'; + export type TAppFront = { isShow: boolean; zIndex: number;