fix: the issue that role display name (#847)

#### What type of PR is this?

/kind improvement

#### What this PR does / why we need it:

为系统初始化的角色添加显示名称

#### Which issue(s) this PR fixes:

Fixes https://github.com/halo-dev/halo/issues/3257

#### Screenshots:

<img width="1668" alt="image" src="https://user-images.githubusercontent.com/21301288/218020794-696420c4-69bb-4422-9409-482bb2aff708.png">


#### Special notes for your reviewer:

测试方式:

1. Halo 需要切换到:https://github.com/halo-dev/halo/pull/3280
2. 检查 Console 端显示的系统角色是否正常。
3. 新建若干自定义角色,检查名称是否正常。

#### Does this PR introduce a user-facing change?

```release-note
优化 Console 端用户角色标识的显示名称。
```
pull/857/head
Ryan Wang 2023-02-15 13:58:12 +08:00 committed by GitHub
parent 381c3e2484
commit aca67f683c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 63 additions and 21 deletions

View File

@ -27,6 +27,7 @@ import sortBy from "lodash.sortby";
import { useRoleStore } from "@/stores/role"; import { useRoleStore } from "@/stores/role";
import { hasPermission } from "@/utils/permission"; import { hasPermission } from "@/utils/permission";
import { useUserStore } from "@/stores/user"; import { useUserStore } from "@/stores/user";
import { rbacAnnotations } from "@/constants/annotations";
const route = useRoute(); const route = useRoute();
const router = useRouter(); const router = useRouter();
@ -56,11 +57,16 @@ const handleLogout = () => {
}; };
const currentRole = computed(() => { const currentRole = computed(() => {
return JSON.parse( const names = JSON.parse(
userStore.currentUser?.metadata.annotations?.[ userStore.currentUser?.metadata.annotations?.[rbacAnnotations.ROLE_NAMES] ||
"rbac.authorization.halo.run/role-names" "[]"
] || "[]" );
)[0];
if (names.length === 0) {
return;
}
return roleStore.getRoleDisplayName(names[0]);
}); });
// Global Search // Global Search
@ -228,7 +234,7 @@ onMounted(generateMenus);
<div class="flex text-sm font-medium"> <div class="flex text-sm font-medium">
{{ userStore.currentUser?.spec.displayName }} {{ userStore.currentUser?.spec.displayName }}
</div> </div>
<div class="flex"> <div v-if="currentRole" class="flex">
<VTag> <VTag>
<template #leftIcon> <template #leftIcon>
<IconUserSettings /> <IconUserSettings />

View File

@ -240,6 +240,9 @@ async function initApp() {
await loadUserPermissions(); await loadUserPermissions();
const roleStore = useRoleStore();
await roleStore.fetchRoles();
try { try {
await loadPluginModules(); await loadPluginModules();
} catch (e) { } catch (e) {

View File

@ -36,7 +36,9 @@ import Fuse from "fuse.js";
import { usePermission } from "@/utils/permission"; import { usePermission } from "@/utils/permission";
import { roleLabels } from "@/constants/labels"; import { roleLabels } from "@/constants/labels";
import { SUPER_ROLE_NAME } from "@/constants/constants"; import { SUPER_ROLE_NAME } from "@/constants/constants";
import { useRoleStore } from "@/stores/role";
const roleStore = useRoleStore();
const { currentUserHasPermission } = usePermission(); const { currentUserHasPermission } = usePermission();
const editingModal = ref<boolean>(false); const editingModal = ref<boolean>(false);
@ -91,6 +93,7 @@ const handleOpenEditingModal = (role: Role) => {
const onEditingModalClose = () => { const onEditingModalClose = () => {
selectedRole.value = undefined; selectedRole.value = undefined;
handleFetchRoles(); handleFetchRoles();
roleStore.fetchRoles();
}; };
const handleCloneRole = async (role: Role) => { const handleCloneRole = async (role: Role) => {
@ -140,6 +143,7 @@ const handleDelete = async (role: Role) => {
console.error("Failed to delete role", e); console.error("Failed to delete role", e);
} finally { } finally {
handleFetchRoles(); handleFetchRoles();
roleStore.fetchRoles();
} }
}, },
}); });

View File

@ -6,13 +6,20 @@ import { useRouter } from "vue-router";
import type { User } from "@halo-dev/api-client"; import type { User } from "@halo-dev/api-client";
import { rbacAnnotations } from "@/constants/annotations"; import { rbacAnnotations } from "@/constants/annotations";
import { formatDatetime } from "@/utils/date"; import { formatDatetime } from "@/utils/date";
import { useRoleStore } from "@/stores/role";
const user = inject<Ref<User>>("user"); const user = inject<Ref<User>>("user");
const roleStore = useRoleStore();
const roles = computed(() => { const roles = computed(() => {
return JSON.parse( const names = JSON.parse(
user?.value?.metadata?.annotations?.[rbacAnnotations.ROLE_NAMES] || "[]" user?.value?.metadata?.annotations?.[rbacAnnotations.ROLE_NAMES] || "[]"
); );
return names.map((name: string) => {
return roleStore.getRoleDisplayName(name);
});
}); });
const router = useRouter(); const router = useRouter();

View File

@ -30,6 +30,7 @@ import { useRouteQuery } from "@vueuse/router";
import Fuse from "fuse.js"; import Fuse from "fuse.js";
import { usePermission } from "@/utils/permission"; import { usePermission } from "@/utils/permission";
import { useUserStore } from "@/stores/user"; import { useUserStore } from "@/stores/user";
import { useRoleStore } from "@/stores/role";
const { currentUserHasPermission } = usePermission(); const { currentUserHasPermission } = usePermission();
@ -55,6 +56,7 @@ const selectedUser = ref<User>();
const refreshInterval = ref(); const refreshInterval = ref();
const userStore = useUserStore(); const userStore = useUserStore();
const roleStore = useRoleStore();
let fuse: Fuse<User> | undefined = undefined; let fuse: Fuse<User> | undefined = undefined;
@ -209,9 +211,13 @@ const handleOpenGrantPermissionModal = (user: User) => {
}; };
const getRoles = (user: User) => { const getRoles = (user: User) => {
return JSON.parse( const names = JSON.parse(
user.metadata.annotations?.[rbacAnnotations.ROLE_NAMES] || "[]" user.metadata.annotations?.[rbacAnnotations.ROLE_NAMES] || "[]"
); );
return names.map((name: string) => {
return roleStore.getRoleDisplayName(name);
});
}; };
onMounted(() => { onMounted(() => {

View File

@ -1,18 +1,34 @@
import { defineStore } from "pinia"; import { defineStore } from "pinia";
import type { Role, UserPermission } from "@halo-dev/api-client"; import type { Role, UserPermission } from "@halo-dev/api-client";
import { ref } from "vue";
import { apiClient } from "@/utils/api-client";
import { roleLabels } from "@/constants/labels";
import { rbacAnnotations } from "@/constants/annotations";
interface RoleStoreState { export const useRoleStore = defineStore("role", () => {
roles: Role[]; // all roles const roles = ref<Role[]>([]);
permissions: UserPermission; // current user's permissions const permissions = ref<UserPermission>({
}
export const useRoleStore = defineStore({
id: "role",
state: (): RoleStoreState => ({
roles: [], roles: [],
permissions: { uiPermissions: [],
roles: [], });
uiPermissions: [],
}, async function fetchRoles() {
}), try {
const { data } = await apiClient.extension.role.listv1alpha1Role({
page: 0,
size: 0,
labelSelector: [`!${roleLabels.TEMPLATE}`],
});
roles.value = data.items;
} catch (error) {
console.error("Failed to fetch roles", error);
}
}
function getRoleDisplayName(name: string) {
const role = roles.value.find((role) => role.metadata.name === name);
return role?.metadata.annotations?.[rbacAnnotations.DISPLAY_NAME] || name;
}
return { roles, permissions, fetchRoles, getRoleDisplayName };
}); });