diff --git a/src/modules/system/roles/RoleList.vue b/src/modules/system/roles/RoleList.vue
index 16cfb2abd..a7da6169c 100644
--- a/src/modules/system/roles/RoleList.vue
+++ b/src/modules/system/roles/RoleList.vue
@@ -137,6 +137,8 @@ const handleDelete = async (role: Role) => {
Toast.success("删除成功");
} catch (e) {
console.error("Failed to delete role", e);
+ } finally {
+ handleFetchRoles();
}
},
});
@@ -296,11 +298,6 @@ const handleDelete = async (role: Role) => {
>
-
-
-
-
-
@@ -310,6 +307,11 @@ const handleDelete = async (role: Role) => {
+
+
+
+
+
diff --git a/src/modules/system/roles/composables/use-role.ts b/src/modules/system/roles/composables/use-role.ts
index b71a3df1f..1eb908fd0 100644
--- a/src/modules/system/roles/composables/use-role.ts
+++ b/src/modules/system/roles/composables/use-role.ts
@@ -1,5 +1,5 @@
import type { Role } from "@halo-dev/api-client";
-import type { ComputedRef, Ref } from "vue";
+import { onUnmounted, type ComputedRef, type Ref } from "vue";
import { computed, onMounted, ref } from "vue";
import { roleLabels } from "@/constants/labels";
import { rbacAnnotations } from "@/constants/annotations";
@@ -55,16 +55,32 @@ interface useRoleTemplateSelectionReturn {
export function useFetchRole(): useFetchRoleReturn {
const roles = ref([]);
const loading = ref(false);
+ const refreshInterval = ref();
- const handleFetchRoles = async () => {
+ const handleFetchRoles = async (options?: { mute?: boolean }) => {
try {
- loading.value = true;
+ clearInterval(refreshInterval.value);
+
+ if (!options?.mute) {
+ loading.value = true;
+ }
+
const { data } = await apiClient.extension.role.listv1alpha1Role({
page: 0,
size: 0,
labelSelector: [`!${roleLabels.TEMPLATE}`],
});
roles.value = data.items;
+
+ const deletedRoles = roles.value.filter(
+ (role) => !!role.metadata.deletionTimestamp
+ );
+
+ if (deletedRoles.length) {
+ refreshInterval.value = setInterval(() => {
+ handleFetchRoles({ mute: true });
+ }, 3000);
+ }
} catch (e) {
console.error("Failed to fetch roles", e);
} finally {
@@ -74,6 +90,10 @@ export function useFetchRole(): useFetchRoleReturn {
onMounted(handleFetchRoles);
+ onUnmounted(() => {
+ clearInterval(refreshInterval.value);
+ });
+
return {
roles,
loading,
diff --git a/src/modules/system/users/UserList.vue b/src/modules/system/users/UserList.vue
index f25b4c2e5..a9e3b9c20 100644
--- a/src/modules/system/users/UserList.vue
+++ b/src/modules/system/users/UserList.vue
@@ -21,7 +21,7 @@ import {
import UserEditingModal from "./components/UserEditingModal.vue";
import UserPasswordChangeModal from "./components/UserPasswordChangeModal.vue";
import GrantPermissionModal from "./components/GrantPermissionModal.vue";
-import { computed, onMounted, ref, watch } from "vue";
+import { computed, onMounted, onUnmounted, ref, watch } from "vue";
import { apiClient } from "@/utils/api-client";
import type { User, UserList } from "@halo-dev/api-client";
import { rbacAnnotations } from "@/constants/annotations";
@@ -52,14 +52,19 @@ const users = ref({
const loading = ref(false);
const selectedUserNames = ref([]);
const selectedUser = ref();
+const refreshInterval = ref();
const userStore = useUserStore();
let fuse: Fuse | undefined = undefined;
-const handleFetchUsers = async () => {
+const handleFetchUsers = async (options?: { mute?: boolean }) => {
try {
- loading.value = true;
+ clearInterval(refreshInterval.value);
+
+ if (!options?.mute) {
+ loading.value = true;
+ }
const { data } = await apiClient.extension.user.listv1alpha1User({
page: users.value.page,
@@ -71,6 +76,16 @@ const handleFetchUsers = async () => {
keys: ["spec.displayName", "metadata.name", "spec.email"],
useExtendedSearch: true,
});
+
+ const deletedUsers = users.value.items.filter(
+ (user) => !!user.metadata.deletionTimestamp
+ );
+
+ if (deletedUsers.length) {
+ refreshInterval.value = setInterval(() => {
+ handleFetchUsers({ mute: true });
+ }, 3000);
+ }
} catch (e) {
console.error("Failed to fetch users", e);
} finally {
@@ -199,6 +214,10 @@ onMounted(() => {
handleFetchUsers();
});
+onUnmounted(() => {
+ clearInterval(refreshInterval.value);
+});
+
// Route query action
const routeQueryAction = useRouteQuery("action");