mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-09-18 20:32:30 +03:00
* feat(routing): add client picker to user rules Replace the free-text user criterion with a searchable multi-select backed by existing panel clients. Preserve saved values that no longer exist so editing legacy rules remains lossless. * feat(routing): polish user picker states Align the routing user selector with the inbound-tag multi-select, including search, clear, loading, empty, and error states. Localize the new copy across every supported locale and cover legacy saved users with a regression test. * fix(routing): keep custom user identifiers Use tags mode with comma tokenization so the user picker suggests panel clients without rejecting HTTP, Mixed, or raw-template identifiers. Restore the comma hint and cover custom entries with a regression test.
34 lines
1.0 KiB
TypeScript
34 lines
1.0 KiB
TypeScript
import { useQuery } from '@tanstack/react-query';
|
|
import { z } from 'zod';
|
|
|
|
import { HttpUtil } from '@/utils';
|
|
import { parseMsg } from '@/utils/zodValidate';
|
|
import { keys } from '@/api/queryKeys';
|
|
import { ClientRecordSchema, type ClientRecord } from '@/schemas/client';
|
|
|
|
const ClientRecordListSchema = z
|
|
.array(ClientRecordSchema)
|
|
.nullable()
|
|
.transform((value) => value ?? []);
|
|
|
|
async function fetchClients(): Promise<ClientRecord[]> {
|
|
const msg = await HttpUtil.get('/panel/api/clients/list', undefined, { silent: true });
|
|
if (!msg?.success) throw new Error(msg?.msg || 'Failed to load clients');
|
|
const validated = parseMsg(msg, ClientRecordListSchema, 'clients/list');
|
|
return validated.obj ?? [];
|
|
}
|
|
|
|
export function useClientOptions(enabled = true) {
|
|
return useQuery({
|
|
queryKey: keys.clients.all(),
|
|
queryFn: fetchClients,
|
|
enabled,
|
|
staleTime: 30_000,
|
|
select: (clients) =>
|
|
clients
|
|
.map((client) => client.email.trim())
|
|
.filter(Boolean)
|
|
.sort((a, b) => a.localeCompare(b)),
|
|
});
|
|
}
|