mirror of https://github.com/halo-dev/halo-admin
perf: automatic refresh of the list of users and roles (#797)
#### What type of PR is this? /kind improvement /milestone 2.1.x #### What this PR does / why we need it: 优化用户和角色列表,如果包含正在删除的内容会自动刷新。 #### Which issue(s) this PR fixes: Fixes https://github.com/halo-dev/halo/issues/3036 #### Special notes for your reviewer: 测试方式: 1. 创建若干角色和用户。 2. 测试删除之后是否会自动刷新列表。 #### Does this PR introduce a user-facing change? ```release-note 优化 Console 端的用户和角色列表,如果包含正在删除的内容会自动刷新。 ```pull/784/head^2
parent
f7ece9135a
commit
da06195d08
|
@ -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) => {
|
|||
></VEntityField>
|
||||
</template>
|
||||
<template #end>
|
||||
<VEntityField v-if="role.metadata.deletionTimestamp">
|
||||
<template #description>
|
||||
<VStatusDot v-tooltip="`删除中`" state="warning" animate />
|
||||
</template>
|
||||
</VEntityField>
|
||||
<!-- TODO: 支持显示用户数量 -->
|
||||
<VEntityField v-if="false" description="0 个用户" />
|
||||
<VEntityField>
|
||||
|
@ -310,6 +307,11 @@ const handleDelete = async (role: Role) => {
|
|||
</VTag>
|
||||
</template>
|
||||
</VEntityField>
|
||||
<VEntityField v-if="role.metadata.deletionTimestamp">
|
||||
<template #description>
|
||||
<VStatusDot v-tooltip="`删除中`" state="warning" animate />
|
||||
</template>
|
||||
</VEntityField>
|
||||
<VEntityField>
|
||||
<template #description>
|
||||
<span class="truncate text-xs tabular-nums text-gray-500">
|
||||
|
|
|
@ -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<Role[]>([]);
|
||||
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,
|
||||
|
|
|
@ -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<UserList>({
|
|||
const loading = ref(false);
|
||||
const selectedUserNames = ref<string[]>([]);
|
||||
const selectedUser = ref<User>();
|
||||
const refreshInterval = ref();
|
||||
|
||||
const userStore = useUserStore();
|
||||
|
||||
let fuse: Fuse<User> | 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<string | undefined>("action");
|
||||
|
||||
|
|
Loading…
Reference in New Issue