Files
3x-ui/frontend/src/api/queries/useHostMutations.ts
T
Hamed 136c1c4d50 feat(hosts): add drag-and-drop and global subscription ordering (#6895)
Hosts already had one saved order on the Hosts page, but subscriptions honoured
it only inside each inbound, so a host of a later inbound could never come before
one of an earlier inbound (#6894). A new opt-in setting makes raw/base64,
Clash/Mihomo and JSON subscriptions follow the Hosts page order across inbounds;
the default keeps today's inbound-first output unchanged. The Hosts table gains
drag-and-drop reordering next to the Up/Down buttons, on a pointer-reorder hook
the Routing Rules table now shares.
2026-10-24 07:27:47 +02:00

80 lines
2.8 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/${groupId}`, payload, JSON_HEADERS),
onSuccess: (msg) => {
if (msg?.success) invalidate();
},
});
const removeMut = useMutation({
mutationFn: (groupId: string) => HttpUtil.post(`/panel/api/hosts/del/${groupId}`),
onSuccess: (msg) => {
if (msg?.success) invalidate();
},
});
const setEnableMut = useMutation({
mutationFn: ({ groupId, enable }: { groupId: string; enable: boolean }) =>
HttpUtil.post(`/panel/api/hosts/setEnable/${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),
};
}