From bb6671c14f17fcbaadd497d2ac1dcd787bd79f41 Mon Sep 17 00:00:00 2001 From: web Date: Wed, 24 Sep 2025 03:00:37 -0700 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20fix:=20Add=20DynamicMultiplier?= =?UTF-8?q?=20component=20for=20managing=20node=20multipliers=20and=20upda?= =?UTF-8?q?te=20ServersPage=20layout?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 47 ++++--- .../dashboard/servers/dynamic-multiplier.tsx | 115 ++++++++++++++++++ apps/admin/app/dashboard/servers/page.tsx | 11 +- .../app/dashboard/servers/server-config.tsx | 102 +++------------- apps/admin/locales/en-US/servers.json | 2 +- apps/admin/locales/zh-CN/servers.json | 2 +- 6 files changed, 163 insertions(+), 116 deletions(-) create mode 100644 apps/admin/app/dashboard/servers/dynamic-multiplier.tsx diff --git a/CHANGELOG.md b/CHANGELOG.md index 294dcc0..989d51c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,57 +1,52 @@ + # Changelog ## [1.4.8](https://github.com/perfect-panel/ppanel-web/compare/v1.4.7...v1.4.8) (2025-09-23) - ### ๐Ÿ› Bug Fixes -* Rename 'server_id' to 'protocol' in NodesPage and clean up unused imports and code in ServerConfig ([70b3484](https://github.com/perfect-panel/ppanel-web/commit/70b3484)) -* Update announcement page to display timeline of announcements with Markdown content ([3c036eb](https://github.com/perfect-panel/ppanel-web/commit/3c036eb)) -* Update Empty component to support border prop and adjust usage in various pages ([ce9ab89](https://github.com/perfect-panel/ppanel-web/commit/ce9ab89)) +- Rename 'server_id' to 'protocol' in NodesPage and clean up unused imports and code in ServerConfig ([70b3484](https://github.com/perfect-panel/ppanel-web/commit/70b3484)) +- Update announcement page to display timeline of announcements with Markdown content ([3c036eb](https://github.com/perfect-panel/ppanel-web/commit/3c036eb)) +- Update Empty component to support border prop and adjust usage in various pages ([ce9ab89](https://github.com/perfect-panel/ppanel-web/commit/ce9ab89)) ## [1.4.7](https://github.com/perfect-panel/ppanel-web/compare/v1.4.6...v1.4.7) (2025-09-23) - ### ๐Ÿ› Bug Fixes -* Add unique key to ProTable for improved rendering with user ID filters ([2bff15f](https://github.com/perfect-panel/ppanel-web/commit/2bff15f)) -* Adjust layout spacing and chart aspect ratio in ServerConfig component ([05a61d8](https://github.com/perfect-panel/ppanel-web/commit/05a61d8)) -* Refactor server ID cell rendering for improved readability and consistency ([0345b7c](https://github.com/perfect-panel/ppanel-web/commit/0345b7c)) -* Update announcement page to format creation date and enhance content display ([8445e30](https://github.com/perfect-panel/ppanel-web/commit/8445e30)) -* Update OnlineUsersCell to display user count with icon instead of badge ([7a4ebdf](https://github.com/perfect-panel/ppanel-web/commit/7a4ebdf)) -* Update subscribe name fallback to return '--' instead of 'Unknown' ([0a07d25](https://github.com/perfect-panel/ppanel-web/commit/0a07d25)) +- Add unique key to ProTable for improved rendering with user ID filters ([2bff15f](https://github.com/perfect-panel/ppanel-web/commit/2bff15f)) +- Adjust layout spacing and chart aspect ratio in ServerConfig component ([05a61d8](https://github.com/perfect-panel/ppanel-web/commit/05a61d8)) +- Refactor server ID cell rendering for improved readability and consistency ([0345b7c](https://github.com/perfect-panel/ppanel-web/commit/0345b7c)) +- Update announcement page to format creation date and enhance content display ([8445e30](https://github.com/perfect-panel/ppanel-web/commit/8445e30)) +- Update OnlineUsersCell to display user count with icon instead of badge ([7a4ebdf](https://github.com/perfect-panel/ppanel-web/commit/7a4ebdf)) +- Update subscribe name fallback to return '--' instead of 'Unknown' ([0a07d25](https://github.com/perfect-panel/ppanel-web/commit/0a07d25)) ## [1.4.6](https://github.com/perfect-panel/ppanel-web/compare/v1.4.5...v1.4.6) (2025-09-17) - ### ๐ŸŽซ Chores -* Merge branch 'main' into develop ([41f06bf](https://github.com/perfect-panel/ppanel-web/commit/41f06bf)) - +- Merge branch 'main' into develop ([41f06bf](https://github.com/perfect-panel/ppanel-web/commit/41f06bf)) ### ๐Ÿ› Bug Fixes -* Add loaded state to node, server, and subscribe stores for better loading management ([13dce0c](https://github.com/perfect-panel/ppanel-web/commit/13dce0c)) -* Removed node metadata fields in subscription schema to simplify structure ([0cadd83](https://github.com/perfect-panel/ppanel-web/commit/0cadd83)) +- Add loaded state to node, server, and subscribe stores for better loading management ([13dce0c](https://github.com/perfect-panel/ppanel-web/commit/13dce0c)) +- Removed node metadata fields in subscription schema to simplify structure ([0cadd83](https://github.com/perfect-panel/ppanel-web/commit/0cadd83)) ## [1.4.5](https://github.com/perfect-panel/ppanel-web/compare/v1.4.4...v1.4.5) (2025-09-17) - ### โ™ป Code Refactoring -* Replace useQuery with Zustand store for subscription and node data management ([c6dd0b6](https://github.com/perfect-panel/ppanel-web/commit/c6dd0b6)) -* Simplify TemplatePreview component structure by consolidating Sheet and Button elements ([1b715c5](https://github.com/perfect-panel/ppanel-web/commit/1b715c5)) - +- Replace useQuery with Zustand store for subscription and node data management ([c6dd0b6](https://github.com/perfect-panel/ppanel-web/commit/c6dd0b6)) +- Simplify TemplatePreview component structure by consolidating Sheet and Button elements ([1b715c5](https://github.com/perfect-panel/ppanel-web/commit/1b715c5)) ### ๐Ÿ› Bug Fixes -* Add showLineNumbers prop handling in MonacoEditor for improved placeholder positioning ([bd67ece](https://github.com/perfect-panel/ppanel-web/commit/bd67ece)) -* Add fetchTags method to NodesPage and ensure tags are fetched alongside nodes ([a3c5e31](https://github.com/perfect-panel/ppanel-web/commit/a3c5e31)) -* Add NEXT_PUBLIC_HIDDEN_TUTORIAL_DOCUMENT to control tutorial visibility and update page query accordingly ([e94405d](https://github.com/perfect-panel/ppanel-web/commit/e94405d)) -* Add subscribeSchema for subscription management with detailed proxy and user information ([49b3dcc](https://github.com/perfect-panel/ppanel-web/commit/49b3dcc)) -* Enhance server ID display in ServerTrafficLogPage with badges and server ratio ([6dfac27](https://github.com/perfect-panel/ppanel-web/commit/6dfac27)) -* Update platform handling in Content component to ensure available platforms are correctly filtered and displayed ([1dde708](https://github.com/perfect-panel/ppanel-web/commit/1dde708)) +- Add showLineNumbers prop handling in MonacoEditor for improved placeholder positioning ([bd67ece](https://github.com/perfect-panel/ppanel-web/commit/bd67ece)) +- Add fetchTags method to NodesPage and ensure tags are fetched alongside nodes ([a3c5e31](https://github.com/perfect-panel/ppanel-web/commit/a3c5e31)) +- Add NEXT_PUBLIC_HIDDEN_TUTORIAL_DOCUMENT to control tutorial visibility and update page query accordingly ([e94405d](https://github.com/perfect-panel/ppanel-web/commit/e94405d)) +- Add subscribeSchema for subscription management with detailed proxy and user information ([49b3dcc](https://github.com/perfect-panel/ppanel-web/commit/49b3dcc)) +- Enhance server ID display in ServerTrafficLogPage with badges and server ratio ([6dfac27](https://github.com/perfect-panel/ppanel-web/commit/6dfac27)) +- Update platform handling in Content component to ensure available platforms are correctly filtered and displayed ([1dde708](https://github.com/perfect-panel/ppanel-web/commit/1dde708)) diff --git a/apps/admin/app/dashboard/servers/dynamic-multiplier.tsx b/apps/admin/app/dashboard/servers/dynamic-multiplier.tsx new file mode 100644 index 0000000..c26dcf2 --- /dev/null +++ b/apps/admin/app/dashboard/servers/dynamic-multiplier.tsx @@ -0,0 +1,115 @@ +'use client'; + +import { getNodeMultiplier, setNodeMultiplier } from '@/services/admin/system'; +import { useQuery } from '@tanstack/react-query'; +import { Button } from '@workspace/ui/components/button'; +import { Card, CardContent } from '@workspace/ui/components/card'; +import { ScrollArea } from '@workspace/ui/components/scroll-area'; +import { + Sheet, + SheetContent, + SheetDescription, + SheetFooter, + SheetHeader, + SheetTitle, + SheetTrigger, +} from '@workspace/ui/components/sheet'; +import { ArrayInput } from '@workspace/ui/custom-components/dynamic-Inputs'; +import { Icon } from '@workspace/ui/custom-components/icon'; +import { useTranslations } from 'next-intl'; +import { useEffect, useState } from 'react'; +import { toast } from 'sonner'; + +export default function DynamicMultiplier() { + const t = useTranslations('servers'); + const [open, setOpen] = useState(false); + const [timeSlots, setTimeSlots] = useState([]); + + const { data: periodsResp, refetch: refetchPeriods } = useQuery({ + queryKey: ['getNodeMultiplier'], + queryFn: async () => { + const { data } = await getNodeMultiplier(); + return (data.data?.periods || []) as API.TimePeriod[]; + }, + enabled: open, + }); + + useEffect(() => { + if (periodsResp) { + setTimeSlots(periodsResp); + } + }, [periodsResp]); + + async function savePeriods() { + try { + await setNodeMultiplier({ periods: timeSlots }); + await refetchPeriods(); + toast.success(t('config.saveSuccess')); + setOpen(false); + } catch (error) { + toast.error(t('config.saveError')); + } + } + + return ( + + + + +
+
+
+ +
+
+

{t('config.dynamicMultiplier')}

+

+ {t('config.dynamicMultiplierDescription')} +

+
+
+ +
+
+
+
+ + + + {t('config.dynamicMultiplier')} + {t('config.dynamicMultiplierDescription')} + + +
+ + fields={[ + { name: 'start_time', prefix: t('config.startTime'), type: 'time' }, + { name: 'end_time', prefix: t('config.endTime'), type: 'time' }, + { + name: 'multiplier', + prefix: t('config.multiplier'), + type: 'number', + placeholder: '0', + }, + ]} + value={timeSlots} + onChange={setTimeSlots} + /> +
+
+ + + +
+ + +
+
+
+
+ ); +} diff --git a/apps/admin/app/dashboard/servers/page.tsx b/apps/admin/app/dashboard/servers/page.tsx index 182bc1f..158eb77 100644 --- a/apps/admin/app/dashboard/servers/page.tsx +++ b/apps/admin/app/dashboard/servers/page.tsx @@ -15,12 +15,12 @@ import { useServer } from '@/store/server'; import { useQuery } from '@tanstack/react-query'; import { Badge } from '@workspace/ui/components/badge'; import { Button } from '@workspace/ui/components/button'; -import { Card, CardContent } from '@workspace/ui/components/card'; import { ConfirmButton } from '@workspace/ui/custom-components/confirm-button'; import { cn } from '@workspace/ui/lib/utils'; import { useTranslations } from 'next-intl'; import { useRef, useState } from 'react'; import { toast } from 'sonner'; +import DynamicMultiplier from './dynamic-multiplier'; import OnlineUsersCell from './online-users-cell'; import ServerConfig from './server-config'; import ServerForm from './server-form'; @@ -95,11 +95,10 @@ export default function ServersPage() { return (
- - - - - +
+ + +
action={ref} header={{ diff --git a/apps/admin/app/dashboard/servers/server-config.tsx b/apps/admin/app/dashboard/servers/server-config.tsx index 0d75559..6f06810 100644 --- a/apps/admin/app/dashboard/servers/server-config.tsx +++ b/apps/admin/app/dashboard/servers/server-config.tsx @@ -1,15 +1,10 @@ 'use client'; -import { - getNodeConfig, - getNodeMultiplier, - setNodeMultiplier, - updateNodeConfig, -} from '@/services/admin/system'; +import { getNodeConfig, updateNodeConfig } from '@/services/admin/system'; import { zodResolver } from '@hookform/resolvers/zod'; import { useQuery } from '@tanstack/react-query'; import { Button } from '@workspace/ui/components/button'; - +import { Card, CardContent } from '@workspace/ui/components/card'; import { Form, FormControl, @@ -19,7 +14,6 @@ import { FormLabel, FormMessage, } from '@workspace/ui/components/form'; -import { Label } from '@workspace/ui/components/label'; import { ScrollArea } from '@workspace/ui/components/scroll-area'; import { Sheet, @@ -29,7 +23,6 @@ import { SheetTitle, SheetTrigger, } from '@workspace/ui/components/sheet'; -import { ArrayInput } from '@workspace/ui/custom-components/dynamic-Inputs'; import { EnhancedInput } from '@workspace/ui/custom-components/enhanced-input'; import { Icon } from '@workspace/ui/custom-components/icon'; import { DicesIcon } from 'lucide-react'; @@ -51,7 +44,6 @@ export default function ServerConfig() { const t = useTranslations('servers'); const [open, setOpen] = useState(false); const [saving, setSaving] = useState(false); - const [timeSlots, setTimeSlots] = useState([]); const { data: cfgResp, refetch: refetchCfg } = useQuery({ queryKey: ['getNodeConfig'], @@ -62,15 +54,6 @@ export default function ServerConfig() { enabled: open, }); - const { data: periodsResp, refetch: refetchPeriods } = useQuery({ - queryKey: ['getNodeMultiplier'], - queryFn: async () => { - const { data } = await getNodeMultiplier(); - return (data.data?.periods || []) as API.TimePeriod[]; - }, - enabled: open, - }); - const form = useForm({ resolver: zodResolver(nodeConfigSchema), defaultValues: { @@ -90,12 +73,6 @@ export default function ServerConfig() { } }, [cfgResp, form]); - useEffect(() => { - if (periodsResp) { - setTimeSlots(periodsResp); - } - }, [periodsResp]); - async function onSubmit(values: NodeConfigFormData) { setSaving(true); try { @@ -108,32 +85,32 @@ export default function ServerConfig() { } } - async function savePeriods() { - await setNodeMultiplier({ periods: timeSlots }); - await refetchPeriods(); - toast.success(t('config.saveSuccess')); - } - return ( -
-
-
- + + +
+
+
+ +
+
+

{t('config.title')}

+

+ {t('config.description')} +

+
+
+
-
-

{t('config.title')}

-

{t('config.description')}

-
-
- -
+ + - {t('config.title')} + ่Š‚็‚น้…็ฝฎ @@ -218,45 +195,6 @@ export default function ServerConfig() { )} /> - -
- -

- {t('config.dynamicMultiplierDescription')} -

- -
-
- - fields={[ - { name: 'start_time', prefix: t('config.startTime'), type: 'time' }, - { name: 'end_time', prefix: t('config.endTime'), type: 'time' }, - { - name: 'multiplier', - prefix: t('config.multiplier'), - type: 'number', - placeholder: '0', - }, - ]} - value={timeSlots} - onChange={setTimeSlots} - /> -
- - -
-
-
-
diff --git a/apps/admin/locales/en-US/servers.json b/apps/admin/locales/en-US/servers.json index df9c99b..ff3c577 100644 --- a/apps/admin/locales/en-US/servers.json +++ b/apps/admin/locales/en-US/servers.json @@ -8,7 +8,7 @@ "city": "City", "config": { "title": "Node configuration", - "description": "Manage node communication keys, pull/push intervals, and dynamic multipliers.", + "description": "Manage node communication keys, pull/push intervals.", "saveSuccess": "Saved successfully", "communicationKey": "Communication key", "inputPlaceholder": "Please enter", diff --git a/apps/admin/locales/zh-CN/servers.json b/apps/admin/locales/zh-CN/servers.json index 682df68..9e66187 100644 --- a/apps/admin/locales/zh-CN/servers.json +++ b/apps/admin/locales/zh-CN/servers.json @@ -13,7 +13,7 @@ }, "communicationKey": "้€šไฟกๅฏ†้’ฅ", "communicationKeyDescription": "็”จไบŽ่Š‚็‚น้‰ดๆƒใ€‚", - "description": "็ฎก็†่Š‚็‚น้€šไฟกๅฏ†้’ฅใ€ๆ‹‰ๅ–/ๆŽจ้€้—ด้š”ไธŽๅŠจๆ€ๅ€็އใ€‚", + "description": "็ฎก็†่Š‚็‚น้€šไฟกๅฏ†้’ฅใ€ๆ‹‰ๅ–/ๆŽจ้€้—ด้š”ใ€‚", "dynamicMultiplier": "ๅŠจๆ€ๅ€็އ", "dynamicMultiplierDescription": "ๆŒ‰ๆ—ถ้—ดๆฎต่ฎพ็ฝฎๅ€็އ๏ผŒ็”จไบŽ่ฐƒ่Š‚ๆต้‡ๆˆ–่ฎก่ดนใ€‚", "endTime": "็ป“ๆŸๆ—ถ้—ด",