✨ feat: Add queryNodeTag function and integrate tag retrieval in NodeForm and SubscribeForm components
This commit is contained in:
parent
9e01f4f590
commit
4563c570ac
@ -1,6 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import { filterServerList } from '@/services/admin/server';
|
||||
import { filterServerList, queryNodeTag } from '@/services/admin/server';
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { Button } from '@workspace/ui/components/button';
|
||||
@ -98,6 +98,15 @@ export default function NodeForm(props: {
|
||||
});
|
||||
const servers: ServerRow[] = data as ServerRow[];
|
||||
|
||||
const { data: tagsData } = useQuery({
|
||||
queryKey: ['queryNodeTag'],
|
||||
queryFn: async () => {
|
||||
const { data } = await queryNodeTag();
|
||||
return data?.data?.tags || [];
|
||||
},
|
||||
});
|
||||
const existingTags: string[] = tagsData as string[];
|
||||
|
||||
const currentServer = useMemo(() => servers?.find((s) => s.id === serverId), [servers, serverId]);
|
||||
|
||||
const availableProtocols = useMemo(() => {
|
||||
@ -298,6 +307,7 @@ export default function NodeForm(props: {
|
||||
placeholder={t('tags_placeholder')}
|
||||
value={field.value || []}
|
||||
onChange={(v) => form.setValue(field.name, v)}
|
||||
options={existingTags}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormDescription>{t('tags_description')}</FormDescription>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
'use client';
|
||||
|
||||
import { filterNodeList } from '@/services/admin/server';
|
||||
import { filterNodeList, queryNodeTag } from '@/services/admin/server';
|
||||
import { getSubscribeGroupList } from '@/services/admin/subscribe';
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
@ -245,7 +245,16 @@ export default function SubscribeForm<T extends Record<string, any>>({
|
||||
return (data.data?.list || []) as API.Node[];
|
||||
},
|
||||
});
|
||||
const tagGroups = Array.from(
|
||||
|
||||
const { data: allTagsData } = useQuery({
|
||||
queryKey: ['queryNodeTag'],
|
||||
queryFn: async () => {
|
||||
const { data } = await queryNodeTag();
|
||||
return data?.data?.tags || [];
|
||||
},
|
||||
});
|
||||
|
||||
const nodeExtractedTags = Array.from(
|
||||
new Set(
|
||||
((nodes as API.Node[]) || [])
|
||||
.flatMap((n) => (Array.isArray(n.tags) ? n.tags : []))
|
||||
@ -253,6 +262,12 @@ export default function SubscribeForm<T extends Record<string, any>>({
|
||||
),
|
||||
) as string[];
|
||||
|
||||
const allAvailableTags = (allTagsData as string[]) || [];
|
||||
|
||||
const tagGroups = Array.from(new Set([...allAvailableTags, ...nodeExtractedTags])).filter(
|
||||
Boolean,
|
||||
);
|
||||
|
||||
const unit_time = form.watch('unit_time');
|
||||
|
||||
return (
|
||||
@ -271,7 +286,7 @@ export default function SubscribeForm<T extends Record<string, any>>({
|
||||
<SheetHeader>
|
||||
<SheetTitle>{title}</SheetTitle>
|
||||
</SheetHeader>
|
||||
<ScrollArea className='h-[calc(100dvh-48px-36px-36px-env(safe-area-inset-top))]'>
|
||||
<ScrollArea className='-mx-6 h-[calc(100dvh-48px-36px-36px-env(safe-area-inset-top))] px-6'>
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(handleSubmit)} className='pt-4'>
|
||||
<Tabs defaultValue='basic' className='w-full'>
|
||||
@ -801,8 +816,12 @@ export default function SubscribeForm<T extends Record<string, any>>({
|
||||
<Accordion type='single' collapsible className='w-full'>
|
||||
{tagGroups.map((tag) => {
|
||||
const value = field.value || [];
|
||||
// Use a synthetic ID for tag grouping selection by name
|
||||
const tagId = tag;
|
||||
const nodesWithTag =
|
||||
(nodes as API.Node[])?.filter((n) =>
|
||||
(n.tags || []).includes(tag),
|
||||
) || [];
|
||||
|
||||
return (
|
||||
<AccordionItem key={tag} value={String(tag)}>
|
||||
<AccordionTrigger>
|
||||
@ -818,7 +837,12 @@ export default function SubscribeForm<T extends Record<string, any>>({
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<Label>{tag}</Label>
|
||||
<Label>
|
||||
{tag}
|
||||
<span className='text-muted-foreground ml-2 text-xs'>
|
||||
({nodesWithTag.length})
|
||||
</span>
|
||||
</Label>
|
||||
</div>
|
||||
</AccordionTrigger>
|
||||
<AccordionContent>
|
||||
@ -830,11 +854,13 @@ export default function SubscribeForm<T extends Record<string, any>>({
|
||||
key={node.id}
|
||||
className='flex items-center justify-between gap-3'
|
||||
>
|
||||
<span>{node.name}</span>
|
||||
<span>
|
||||
<span className='flex-1'>{node.name}</span>
|
||||
<span className='flex-1'>
|
||||
{node.address}:{node.port}
|
||||
</span>
|
||||
<span>{node.protocol}</span>
|
||||
<span className='flex-1 text-right'>
|
||||
{node.protocol}
|
||||
</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
@ -876,11 +902,11 @@ export default function SubscribeForm<T extends Record<string, any>>({
|
||||
}}
|
||||
/>
|
||||
<Label className='flex w-full items-center justify-between gap-3'>
|
||||
<span>{item.name}</span>
|
||||
<span>
|
||||
<span className='flex-1'>{item.name}</span>
|
||||
<span className='flex-1'>
|
||||
{item.address}:{item.port}
|
||||
</span>
|
||||
<span>{item.protocol}</span>
|
||||
<span className='flex-1 text-right'>{item.protocol}</span>
|
||||
</Label>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -141,6 +141,14 @@ export async function toggleNodeStatus(
|
||||
});
|
||||
}
|
||||
|
||||
/** Query all node tags GET /v1/admin/server/node/tags */
|
||||
export async function queryNodeTag(options?: { [key: string]: any }) {
|
||||
return request<API.Response & { data?: API.QueryNodeTagResponse }>('/v1/admin/server/node/tags', {
|
||||
method: 'GET',
|
||||
...(options || {}),
|
||||
});
|
||||
}
|
||||
|
||||
/** Update Node POST /v1/admin/server/node/update */
|
||||
export async function updateNode(body: API.UpdateNodeRequest, options?: { [key: string]: any }) {
|
||||
return request<API.Response & { data?: any }>('/v1/admin/server/node/update', {
|
||||
|
||||
4
apps/admin/services/admin/typings.d.ts
vendored
4
apps/admin/services/admin/typings.d.ts
vendored
@ -1551,6 +1551,10 @@ declare namespace API {
|
||||
list: Document[];
|
||||
};
|
||||
|
||||
type QueryNodeTagResponse = {
|
||||
tags: string[];
|
||||
};
|
||||
|
||||
type QueryOrderDetailRequest = {
|
||||
order_no: string;
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user