feat: add permission settings to dashboard widgets (#4112)

#### What type of PR is this?

/kind improvement
/area console
/milestone 2.7.x

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

为仪表板内置的小组件添加权限设置,解决部分没有权限的用户访问仪表盘提示异常的问题。

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

Fixes #4111 

#### Special notes for your reviewer:

测试方式:

1. 创建一个访客角色的用户。
2. 访问仪表盘,观察是否有异常提示,以及是否出现没有权限的小组件。

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

```release-note
Console 端仪表盘的内置小组件添加权限设置。
```
pull/4114/head^2
Ryan Wang 2023-06-26 12:12:16 +08:00 committed by GitHub
parent 96225e4040
commit ac47942a04
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 108 additions and 48 deletions

View File

@ -38,23 +38,24 @@
:use-css-transforms="true"
:vertical-compact="true"
>
<grid-item
v-for="(item, index) in layout"
:key="index"
:h="item.h"
:i="item.i"
:w="item.w"
:x="item.x"
:y="item.y"
>
<component :is="item.widget" />
<div v-if="settings" class="absolute right-2 top-2">
<IconCloseCircle
class="cursor-pointer text-lg text-gray-500 hover:text-gray-900"
@click="handleRemove(item)"
/>
</div>
</grid-item>
<template v-for="(item, index) in layout" :key="index">
<grid-item
v-if="currentUserHasPermission(item.permissions)"
:h="item.h"
:i="item.i"
:w="item.w"
:x="item.x"
:y="item.y"
>
<component :is="item.widget" />
<div v-if="settings" class="absolute right-2 top-2">
<IconCloseCircle
class="cursor-pointer text-lg text-gray-500 hover:text-gray-900"
@click="handleRemove(item)"
/>
</div>
</grid-item>
</template>
</grid-layout>
</div>
@ -88,19 +89,20 @@
:use-css-transforms="true"
:vertical-compact="true"
>
<grid-item
v-for="(item, index) in group.widgets"
:key="index"
:h="item.h"
:i="item.i"
:w="item.w"
:x="item.x"
:y="item.y"
class="cursor-pointer"
@click="handleAddWidget(item)"
>
<component :is="item.widget" />
</grid-item>
<template v-for="(item, index) in group.widgets" :key="index">
<grid-item
v-if="currentUserHasPermission(item.permissions)"
:h="item.h"
:i="item.i"
:w="item.w"
:x="item.x"
:y="item.y"
class="cursor-pointer"
@click="handleAddWidget(item)"
>
<component :is="item.widget" />
</grid-item>
</template>
</grid-layout>
</template>
</div>
@ -125,23 +127,48 @@ import cloneDeep from "lodash.clonedeep";
import { apiClient } from "@/utils/api-client";
import type { DashboardStats } from "@halo-dev/api-client";
import { useI18n } from "vue-i18n";
import { usePermission } from "@/utils/permission";
const { t } = useI18n();
const { currentUserHasPermission } = usePermission();
const widgetsGroup = [
{
id: "post",
label: t("core.dashboard.widgets.groups.post"),
widgets: [
{ x: 0, y: 0, w: 3, h: 3, i: 0, widget: "PostStatsWidget" },
{ x: 0, y: 0, w: 6, h: 10, i: 1, widget: "RecentPublishedWidget" },
{
x: 0,
y: 0,
w: 3,
h: 3,
i: 0,
widget: "PostStatsWidget",
},
{
x: 0,
y: 0,
w: 6,
h: 10,
i: 1,
widget: "RecentPublishedWidget",
permissions: ["system:posts:view"],
},
],
},
{
id: "page",
label: t("core.dashboard.widgets.groups.page"),
widgets: [
{ x: 0, y: 0, w: 3, h: 3, i: 0, widget: "SinglePageStatsWidget" },
{
x: 0,
y: 0,
w: 3,
h: 3,
i: 0,
widget: "SinglePageStatsWidget",
permissions: ["system:singlepages:view"],
},
],
},
{
@ -152,10 +179,7 @@ const widgetsGroup = [
{
id: "user",
label: t("core.dashboard.widgets.groups.user"),
widgets: [
{ x: 0, y: 0, w: 3, h: 3, i: 0, widget: "UserStatsWidget" },
{ x: 0, y: 0, w: 3, h: 3, i: 1, widget: "UserProfileWidget" },
],
widgets: [{ x: 0, y: 0, w: 3, h: 3, i: 0, widget: "UserStatsWidget" }],
},
{
id: "other",
@ -172,18 +196,54 @@ const widgetsModal = ref(false);
const activeId = ref(widgetsGroup[0].id);
const layout = useStorage("widgets", [
{ x: 0, y: 0, w: 3, h: 3, i: 0, widget: "PostStatsWidget" },
{ x: 3, y: 0, w: 3, h: 3, i: 1, widget: "UserStatsWidget" },
{ x: 6, y: 0, w: 3, h: 3, i: 2, widget: "CommentStatsWidget" },
{ x: 9, y: 0, w: 3, h: 3, i: 3, widget: "ViewsStatsWidget" },
{ x: 0, y: 3, w: 4, h: 10, i: 4, widget: "QuickLinkWidget" },
{
x: 4,
x: 0,
y: 0,
w: 3,
h: 3,
i: 0,
widget: "PostStatsWidget",
},
{
x: 3,
y: 0,
w: 3,
h: 3,
i: 1,
widget: "UserStatsWidget",
},
{
x: 6,
y: 0,
w: 3,
h: 3,
i: 2,
widget: "CommentStatsWidget",
},
{
x: 9,
y: 0,
w: 3,
h: 3,
i: 3,
widget: "ViewsStatsWidget",
},
{
x: 0,
y: 3,
w: 4,
h: 10,
w: 6,
h: 12,
i: 4,
widget: "QuickLinkWidget",
},
{
x: 6,
y: 3,
w: 6,
h: 12,
i: 5,
widget: "RecentPublishedWidget",
permissions: ["system:posts:view"],
},
]);

View File

@ -36,7 +36,7 @@ export function hasPermission(
}
interface usePermissionReturn {
currentUserHasPermission: (targetPermissions: Array<string>) => boolean;
currentUserHasPermission: (targetPermissions?: Array<string>) => boolean;
}
/**
@ -49,9 +49,9 @@ export function usePermission(): usePermissionReturn {
const { uiPermissions } = roleStore.permissions;
const currentUserHasPermission = (
targetPermissions: Array<string>
targetPermissions?: Array<string>
): boolean => {
return hasPermission(uiPermissions, targetPermissions, true);
return hasPermission(uiPermissions, targetPermissions || [], true);
};
return {