Files
3x-ui/frontend/src/api/queries/useHostMutations.ts
T
MHSanaei d3df3e9ea7 fix(frontend): keep node-reported values one URL path segment
InboundInfoModal put a client's email into /panel/api/clients/ips and
clearIps unencoded, and the host mutations did the same with a host
group id. Both values reach the master from a node's sync without the
panel's own character rules, so "../" and "?" in them chose the route
and query of the admin's authenticated POST; the IP-log request fires as
soon as the window opens. Encode them as every other client route in
the SPA already does.
2026-11-01 00:08:35 +01:00

85 lines
2.9 KiB
TypeScript

import { useMutation, useQueryClient } from '@tanstack/react-query';
import { HttpUtil } from '@/utils';
import { keys } from '@/api/queryKeys';
import type { BulkAddHostValues } from '@/schemas/api/host';
const JSON_HEADERS = { headers: { 'Content-Type': 'application/json' } };
export function useHostMutations() {
const queryClient = useQueryClient();
const invalidate = () => queryClient.invalidateQueries({ queryKey: keys.hosts.root() });
const bulkCreateMut = useMutation({
mutationFn: (payload: BulkAddHostValues) =>
HttpUtil.post('/panel/api/hosts/bulk/add', payload, JSON_HEADERS),
onSuccess: (msg) => {
if (msg?.success) invalidate();
},
});
const updateMut = useMutation({
mutationFn: ({ groupId, payload }: { groupId: string; payload: BulkAddHostValues }) =>
HttpUtil.post(
`/panel/api/hosts/update/${encodeURIComponent(groupId)}`,
payload,
JSON_HEADERS,
),
onSuccess: (msg) => {
if (msg?.success) invalidate();
},
});
const removeMut = useMutation({
mutationFn: (groupId: string) =>
HttpUtil.post(`/panel/api/hosts/del/${encodeURIComponent(groupId)}`),
onSuccess: (msg) => {
if (msg?.success) invalidate();
},
});
const setEnableMut = useMutation({
mutationFn: ({ groupId, enable }: { groupId: string; enable: boolean }) =>
HttpUtil.post(`/panel/api/hosts/setEnable/${encodeURIComponent(groupId)}`, { enable }),
onSuccess: (msg) => {
if (msg?.success) invalidate();
},
});
const reorderMut = useMutation({
mutationFn: (groupIds: string[]) =>
HttpUtil.post('/panel/api/hosts/reorder', { ids: groupIds }, JSON_HEADERS),
onSuccess: (msg) => {
if (msg?.success) return invalidate();
},
});
const bulkEnableMut = useMutation({
mutationFn: ({ groupIds, enable }: { groupIds: string[]; enable: boolean }) =>
HttpUtil.post('/panel/api/hosts/bulk/setEnable', { ids: groupIds, enable }, JSON_HEADERS),
onSuccess: (msg) => {
if (msg?.success) invalidate();
},
});
const bulkDelMut = useMutation({
mutationFn: (groupIds: string[]) =>
HttpUtil.post('/panel/api/hosts/bulk/del', { ids: groupIds }, JSON_HEADERS),
onSuccess: (msg) => {
if (msg?.success) invalidate();
},
});
return {
bulkCreate: (payload: BulkAddHostValues) => bulkCreateMut.mutateAsync(payload),
update: (groupId: string, payload: BulkAddHostValues) =>
updateMut.mutateAsync({ groupId, payload }),
remove: (groupId: string) => removeMut.mutateAsync(groupId),
setEnable: (groupId: string, enable: boolean) => setEnableMut.mutateAsync({ groupId, enable }),
reorder: (groupIds: string[]) => reorderMut.mutateAsync(groupIds),
bulkSetEnable: (groupIds: string[], enable: boolean) =>
bulkEnableMut.mutateAsync({ groupIds, enable }),
bulkDel: (groupIds: string[]) => bulkDelMut.mutateAsync(groupIds),
};
}