diff --git a/src/layouts/BasicLayout.vue b/src/layouts/BasicLayout.vue
index 9092c952d..cc2629e70 100644
--- a/src/layouts/BasicLayout.vue
+++ b/src/layouts/BasicLayout.vue
@@ -27,6 +27,7 @@ import sortBy from "lodash.sortby";
import { useRoleStore } from "@/stores/role";
import { hasPermission } from "@/utils/permission";
import { useUserStore } from "@/stores/user";
+import { rbacAnnotations } from "@/constants/annotations";
const route = useRoute();
const router = useRouter();
@@ -56,11 +57,16 @@ const handleLogout = () => {
};
const currentRole = computed(() => {
- return JSON.parse(
- userStore.currentUser?.metadata.annotations?.[
- "rbac.authorization.halo.run/role-names"
- ] || "[]"
- )[0];
+ const names = JSON.parse(
+ userStore.currentUser?.metadata.annotations?.[rbacAnnotations.ROLE_NAMES] ||
+ "[]"
+ );
+
+ if (names.length === 0) {
+ return;
+ }
+
+ return roleStore.getRoleDisplayName(names[0]);
});
// Global Search
@@ -228,7 +234,7 @@ onMounted(generateMenus);
+
diff --git a/src/main.ts b/src/main.ts
index d76759bfd..1809e970b 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -240,6 +240,9 @@ async function initApp() {
await loadUserPermissions();
+ const roleStore = useRoleStore();
+ await roleStore.fetchRoles();
+
try {
await loadPluginModules();
} catch (e) {
diff --git a/src/modules/system/roles/RoleList.vue b/src/modules/system/roles/RoleList.vue
index a7da6169c..78e608f3f 100644
--- a/src/modules/system/roles/RoleList.vue
+++ b/src/modules/system/roles/RoleList.vue
@@ -36,7 +36,9 @@ import Fuse from "fuse.js";
import { usePermission } from "@/utils/permission";
import { roleLabels } from "@/constants/labels";
import { SUPER_ROLE_NAME } from "@/constants/constants";
+import { useRoleStore } from "@/stores/role";
+const roleStore = useRoleStore();
const { currentUserHasPermission } = usePermission();
const editingModal = ref(false);
@@ -90,6 +92,7 @@ const handleOpenEditingModal = (role: Role) => {
const onEditingModalClose = () => {
selectedRole.value = undefined;
handleFetchRoles();
+ roleStore.fetchRoles();
};
const handleCloneRole = async (role: Role) => {
@@ -139,6 +142,7 @@ const handleDelete = async (role: Role) => {
console.error("Failed to delete role", e);
} finally {
handleFetchRoles();
+ roleStore.fetchRoles();
}
},
});
diff --git a/src/modules/system/users/UserDetail.vue b/src/modules/system/users/UserDetail.vue
index 0410e496a..fd710a1a5 100644
--- a/src/modules/system/users/UserDetail.vue
+++ b/src/modules/system/users/UserDetail.vue
@@ -6,13 +6,20 @@ import { useRouter } from "vue-router";
import type { User } from "@halo-dev/api-client";
import { rbacAnnotations } from "@/constants/annotations";
import { formatDatetime } from "@/utils/date";
+import { useRoleStore } from "@/stores/role";
const user = inject[>("user");
+const roleStore = useRoleStore();
+
const roles = computed(() => {
- return JSON.parse(
+ const names = JSON.parse(
user?.value?.metadata?.annotations?.[rbacAnnotations.ROLE_NAMES] || "[]"
);
+
+ return names.map((name: string) => {
+ return roleStore.getRoleDisplayName(name);
+ });
});
const router = useRouter();
diff --git a/src/modules/system/users/UserList.vue b/src/modules/system/users/UserList.vue
index e1883c3b6..a316eb2b4 100644
--- a/src/modules/system/users/UserList.vue
+++ b/src/modules/system/users/UserList.vue
@@ -30,6 +30,7 @@ import { useRouteQuery } from "@vueuse/router";
import Fuse from "fuse.js";
import { usePermission } from "@/utils/permission";
import { useUserStore } from "@/stores/user";
+import { useRoleStore } from "@/stores/role";
const { currentUserHasPermission } = usePermission();
@@ -55,6 +56,7 @@ const selectedUser = ref();
const refreshInterval = ref();
const userStore = useUserStore();
+const roleStore = useRoleStore();
let fuse: Fuse | undefined = undefined;
@@ -208,9 +210,13 @@ const handleOpenGrantPermissionModal = (user: User) => {
};
const getRoles = (user: User) => {
- return JSON.parse(
+ const names = JSON.parse(
user.metadata.annotations?.[rbacAnnotations.ROLE_NAMES] || "[]"
);
+
+ return names.map((name: string) => {
+ return roleStore.getRoleDisplayName(name);
+ });
};
onMounted(() => {
diff --git a/src/stores/role.ts b/src/stores/role.ts
index c4265ae37..2ce4546e1 100644
--- a/src/stores/role.ts
+++ b/src/stores/role.ts
@@ -1,18 +1,34 @@
import { defineStore } from "pinia";
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 {
- roles: Role[]; // all roles
- permissions: UserPermission; // current user's permissions
-}
-
-export const useRoleStore = defineStore({
- id: "role",
- state: (): RoleStoreState => ({
+export const useRoleStore = defineStore("role", () => {
+ const roles = ref([]);
+ const permissions = ref({
roles: [],
- permissions: {
- roles: [],
- uiPermissions: [],
- },
- }),
+ 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 };
});
]