fix(frontend): serialize bulk client delete + drop deprecated Alert.message

useClients.removeMany was firing all DELETEs in parallel via Promise.all.
The 3x-ui backend mutates a single config JSON per request (read /
modify / write), so 20 concurrent deletes raced on the same file: every
request reported success, but only the last writer's copy stuck — about
half the selected clients reappeared after the toast. Replace the
parallel fan-out with a sequential for-of loop so each delete sees the
committed state of the previous one. The trade-off is total latency
(20 * ~250ms = ~5s) which is the correct behavior until the backend
grows a proper /bulkDel endpoint.

Also rename the Alert `message` prop to `title` in
ClientBulkAdjustModal to clear the AntD v6 deprecation warning.
This commit is contained in:
MHSanaei
2026-05-26 23:53:54 +02:00
parent a6a3ef8e64
commit 989333b0b1
2 changed files with 6 additions and 4 deletions

View File

@@ -212,10 +212,12 @@ export function useClients() {
const removeManyMut = useMutation({
mutationFn: async ({ emails, keepTraffic }: { emails: string[]; keepTraffic?: boolean }) => {
const suffix = keepTraffic ? '?keepTraffic=1' : '';
const results = await Promise.all(emails.map((email) => {
const results: Msg<unknown>[] = [];
for (const email of emails) {
const url = `/panel/api/clients/del/${encodeURIComponent(email)}${suffix}`;
return HttpUtil.post(url, undefined, { silent: true });
}));
const res = await HttpUtil.post(url, undefined, { silent: true });
results.push(res);
}
return results;
},
onSuccess: () => invalidateAll(),

View File

@@ -75,7 +75,7 @@ export default function ClientBulkAdjustModal({ open, count, onOpenChange, onSub
type="info"
showIcon
style={{ marginBottom: 16 }}
message={t('pages.clients.bulkAdjustHint')}
title={t('pages.clients.bulkAdjustHint')}
/>
<Form layout="vertical">
<Form.Item label={t('pages.clients.addDays')}>