feat: add multi-role assignment support for users (#7037)

#### What type of PR is this?

/area ui
/kind feature
/milestone 2.20.x

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

支持为用户分配多个角色。

<img width="634" alt="image" src="https://github.com/user-attachments/assets/caa40327-518a-4bef-afc3-75a020018d3d">
<img width="764" alt="image" src="https://github.com/user-attachments/assets/8b4b807e-6c72-45d9-9368-75e70bb12dcc">

TODO:

- [x] Console / UC 侧边栏显示多个角色
- [x] 支持在管理端查看用户聚合的角色模板列表,或者在分配时显示所选角色其下的角色模板列表,能够让管理员清楚的知道用户具体权限。

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

Fixes #

#### Special notes for your reviewer:

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

```release-note
支持为用户分配多个角色。
```
This commit is contained in:
Ryan Wang
2024-11-24 23:48:21 +08:00
committed by GitHub
parent 964bc28052
commit 391aac62d3
14 changed files with 403 additions and 90 deletions

View File

@@ -9,11 +9,13 @@ import { coreMenuGroups } from "@console/router/constant";
import {
Dialog,
IconAccountCircleLine,
IconArrowDownLine,
IconLogoutCircleRLine,
IconMore,
IconSearch,
IconUserSettings,
IconShieldUser,
VAvatar,
VDropdown,
VTag,
} from "@halo-dev/components";
import { useEventListener } from "@vueuse/core";
@@ -152,10 +154,10 @@ onMounted(() => {
>
{{ currentUser?.spec.displayName }}
</div>
<div v-if="currentRoles?.[0]" class="flex">
<VTag>
<div v-if="currentRoles?.length" class="flex mt-1">
<VTag v-if="currentRoles.length === 1">
<template #leftIcon>
<IconUserSettings />
<IconShieldUser />
</template>
{{
currentRoles[0].metadata.annotations?.[
@@ -163,6 +165,41 @@ onMounted(() => {
] || currentRoles[0].metadata.name
}}
</VTag>
<VDropdown v-else>
<div class="flex gap-1">
<VTag>
<template #leftIcon>
<IconShieldUser />
</template>
{{ $t("core.sidebar.profile.aggregate_role") }}
</VTag>
<IconArrowDownLine />
</div>
<template #popper>
<div class="p-1">
<h2
class="text-gray-600 text-sm font-semibold border-b border-gray-100 pb-1.5"
>
{{ $t("core.sidebar.profile.aggregate_role") }}
</h2>
<div class="flex gap-2 flex-wrap mt-2">
<VTag
v-for="role in currentRoles"
:key="role.metadata.name"
>
<template #leftIcon>
<IconShieldUser />
</template>
{{
role.metadata.annotations?.[
rbacAnnotations.DISPLAY_NAME
] || role.metadata.name
}}
</VTag>
</div>
</div>
</template>
</VDropdown>
</div>
</div>
@@ -299,6 +336,7 @@ onMounted(() => {
.profile-placeholder {
height: 70px;
flex: none;
.current-profile {
height: 70px;