Refactor user batch enable/disable logic and update i18n (#7647)

pull/7650/head v2.21.4
Ryan Wang 2025-07-31 22:04:50 +08:00 committed by GitHub
parent 4119e36cd8
commit 87cb00a2f1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 62 additions and 88 deletions

View File

@ -138,70 +138,56 @@ const handleDeleteInBatch = async () => {
});
};
const handleUserBatchOperation = async ({
filterCondition,
apiMethod,
successMessageKey,
emptyMessageKey,
}) => {
const filteredUserNames = selectedUserNames.value.filter((name) => {
if (name === userStore.currentUser?.metadata.name) return false;
const user = users.value?.find((u) => u.user.metadata.name === name);
return user && filterCondition(user.user);
});
if (!filteredUserNames.length) {
Toast.info(t(emptyMessageKey));
return;
}
const chunks = chunk(filteredUserNames, 5);
for (const chunk of chunks) {
await Promise.all(chunk.map((name) => apiMethod(name)));
}
await refetch();
selectedUserNames.value.length = 0;
Toast.success(t(successMessageKey));
};
const handleEnableInBatch = async () => {
Dialog.warning({
title: t("core.user.operations.enable_in_batch.title"),
description: t("core.user.operations.enable_in_batch.description"),
confirmType: "primary",
confirmText: t("core.common.buttons.confirm"),
cancelText: t("core.common.buttons.cancel"),
onConfirm: async () => {
await handleUserBatchOperation({
filterCondition: (user) => !!user.spec.disabled,
apiMethod: (name) =>
consoleApiClient.user.enableUser({ username: name }),
successMessageKey: "core.common.toast.enable_success",
emptyMessageKey: "core.common.toast.no_users_to_enable",
});
function handleEnableOrDisableInBatch(operation: "enable" | "disable") {
const operations = {
enable: {
title: t("core.user.operations.enable_in_batch.title"),
description: t("core.user.operations.enable_in_batch.description"),
request: (name: string) =>
consoleApiClient.user.enableUser({ username: name }),
condition: (user: User) => user.spec.disabled,
message: t("core.common.toast.enable_success"),
},
});
};
disable: {
title: t("core.user.operations.disable_in_batch.title"),
description: t("core.user.operations.disable_in_batch.description"),
request: (name: string) =>
consoleApiClient.user.disableUser({ username: name }),
condition: (user: User) => !user.spec.disabled,
message: t("core.common.toast.disable_success"),
},
};
const operationConfig = operations[operation];
const handleDisableInBatch = async () => {
Dialog.warning({
title: t("core.user.operations.disable_in_batch.title"),
description: t("core.user.operations.disable_in_batch.description"),
title: operationConfig.title,
description: operationConfig.description,
confirmType: "danger",
confirmText: t("core.common.buttons.confirm"),
cancelText: t("core.common.buttons.cancel"),
onConfirm: async () => {
await handleUserBatchOperation({
filterCondition: (user) => !user.spec.disabled,
apiMethod: (name) =>
consoleApiClient.user.disableUser({ username: name }),
successMessageKey: "core.common.toast.disable_success",
emptyMessageKey: "core.common.toast.no_users_to_disable",
const filteredUserNames = selectedUserNames.value.filter((name) => {
if (name === userStore.currentUser?.metadata.name) return false;
const user = users.value?.find((u) => u.user.metadata.name === name);
return user && operationConfig.condition(user.user);
});
const chunks = chunk(filteredUserNames, 5);
for (const chunk of chunks) {
await Promise.all(chunk.map((name) => operationConfig.request(name)));
}
await refetch();
selectedUserNames.value.length = 0;
checkedAll.value = false;
Toast.success(operationConfig.message);
},
});
};
}
watch(selectedUserNames, (newValue) => {
checkedAll.value =
@ -308,10 +294,10 @@ function onCreationModalClose() {
<div class="flex w-full flex-1 items-center sm:w-auto">
<SearchInput v-if="!selectedUserNames.length" v-model="keyword" />
<VSpace v-else>
<VButton type="secondary" @click="handleDisableInBatch">
<VButton @click="handleEnableOrDisableInBatch('disable')">
{{ $t("core.common.buttons.disable") }}
</VButton>
<VButton type="secondary" @click="handleEnableInBatch">
<VButton @click="handleEnableOrDisableInBatch('enable')">
{{ $t("core.common.buttons.enable") }}
</VButton>
<VButton type="danger" @click="handleDeleteInBatch">

View File

@ -64,12 +64,16 @@ export function useUserEnableDisable() {
enable: {
title: t("core.user.operations.enable.title"),
description: t("core.user.operations.enable.description"),
value: false,
request: (name: string) =>
consoleApiClient.user.enableUser({ username: name }),
message: t("core.common.toast.enable_success"),
},
disable: {
title: t("core.user.operations.disable.title"),
description: t("core.user.operations.disable.description"),
value: true,
request: (name: string) =>
consoleApiClient.user.disableUser({ username: name }),
message: t("core.common.toast.disable_success"),
},
};
@ -83,17 +87,9 @@ export function useUserEnableDisable() {
cancelText: t("core.common.buttons.cancel"),
onConfirm: async () => {
try {
if (operation == "enable") {
await consoleApiClient.user.enableUser({
username: name,
});
} else {
await consoleApiClient.user.disableUser({
username: name,
});
}
await operationConfig.request(name);
Toast.success(t("core.common.toast.operation_success"));
Toast.success(operationConfig.message);
onSuccess?.();
} catch (e) {
console.error("Failed to enable or disable user", e);

View File

@ -1142,22 +1142,20 @@ core:
title: Grant permission
enable:
title: Enable
description: Are you sure you want to enable this user?
description: >-
Are you sure you want to enable this user? Once enabled, the user will be able to log back into the system.
enable_in_batch:
title: Enable
description: >-
Are you sure you want to enable the selected users? They will be able
to log in again after being enabled.
Are you sure you want to enable the selected users? Once enabled, these users will be able to log back into the system.
disable:
title: Disable
description: >-
Are you sure you want to disable this user? This user will not be able
to log in after being disabled
Are you sure you want to disable this user? Once disabled, the user will no longer be able to log in.
disable_in_batch:
title: Disable
description: >-
Are you sure you want to disable the selected users? They will no longer
be able to log in after being disabled.
Are you sure you want to disable the selected users? Once disabled, these users will no longer be able to log in.
filters:
role:
label: Role
@ -1981,8 +1979,6 @@ core:
unknown_error: Unknown error
disable_success: Disabled successfully
enable_success: Enabled successfully
no_users_to_enable: All selected users are already enabled
no_users_to_disable: All selected users are already disabled
dialog:
titles:
tip: Tip

View File

@ -1070,14 +1070,14 @@ core:
grant_permission:
title: 分配角色
enable:
title: 取消禁
description: 确定取消禁用该用户吗?
title:
description: 确定要启用该用户吗?启用之后该用户将可以重新登录系统
enable_in_batch:
title: 启用
description: 确定要启用所选用户吗?启用后用户将可以重新登录系统
description: 确定要启用所选用户吗?启用后这些用户将可以重新登录系统
disable:
title: 禁用
description: 确定禁用该用户吗?禁用后该用户将无法登录系统
description: 确定禁用该用户吗?禁用后该用户将无法登录系统
disable_in_batch:
title: 禁用
description: 确定要禁用所选用户吗?禁用后这些用户将无法登录系统
@ -1840,8 +1840,6 @@ core:
unknown_error: 未知错误
disable_success: 禁用成功
enable_success: 启用成功
no_users_to_enable: 所有选中的用户已启用
no_users_to_disable: 所有选中的用户已停用
dialog:
titles:
tip: 提示

View File

@ -1055,11 +1055,11 @@ core:
grant_permission:
title: 分配角色
enable:
title: 取消停
description: 確定要取消停用該用戶嗎?
title:
description: 確定要啟用該用戶嗎?啟用後該用戶將可以重新登入系統
enable_in_batch:
title: 启用
description: 確定要启用所選用戶嗎?啟用後該用戶將可以重新登入系統
description: 確定要啟用所選用戶嗎?啟用後這些用戶將可以重新登入系統
disable:
title: 停用
description: 確定要停用該用戶嗎?停用後該用戶將無法登入系統
@ -1825,8 +1825,6 @@ core:
unknown_error: 未知錯誤
disable_success: 禁用成功
enable_success: 啟用成功
no_users_to_enable: 所有選中的用戶都已啟用
no_users_to_disable: 所有選中的用戶都已停用
dialog:
titles:
tip: 提示