mirror of https://github.com/halo-dev/halo
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
parent
96225e4040
commit
ac47942a04
|
@ -38,23 +38,24 @@
|
||||||
:use-css-transforms="true"
|
:use-css-transforms="true"
|
||||||
:vertical-compact="true"
|
:vertical-compact="true"
|
||||||
>
|
>
|
||||||
<grid-item
|
<template v-for="(item, index) in layout" :key="index">
|
||||||
v-for="(item, index) in layout"
|
<grid-item
|
||||||
:key="index"
|
v-if="currentUserHasPermission(item.permissions)"
|
||||||
:h="item.h"
|
:h="item.h"
|
||||||
:i="item.i"
|
:i="item.i"
|
||||||
:w="item.w"
|
:w="item.w"
|
||||||
:x="item.x"
|
:x="item.x"
|
||||||
:y="item.y"
|
:y="item.y"
|
||||||
>
|
>
|
||||||
<component :is="item.widget" />
|
<component :is="item.widget" />
|
||||||
<div v-if="settings" class="absolute right-2 top-2">
|
<div v-if="settings" class="absolute right-2 top-2">
|
||||||
<IconCloseCircle
|
<IconCloseCircle
|
||||||
class="cursor-pointer text-lg text-gray-500 hover:text-gray-900"
|
class="cursor-pointer text-lg text-gray-500 hover:text-gray-900"
|
||||||
@click="handleRemove(item)"
|
@click="handleRemove(item)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</grid-item>
|
</grid-item>
|
||||||
|
</template>
|
||||||
</grid-layout>
|
</grid-layout>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -88,19 +89,20 @@
|
||||||
:use-css-transforms="true"
|
:use-css-transforms="true"
|
||||||
:vertical-compact="true"
|
:vertical-compact="true"
|
||||||
>
|
>
|
||||||
<grid-item
|
<template v-for="(item, index) in group.widgets" :key="index">
|
||||||
v-for="(item, index) in group.widgets"
|
<grid-item
|
||||||
:key="index"
|
v-if="currentUserHasPermission(item.permissions)"
|
||||||
:h="item.h"
|
:h="item.h"
|
||||||
:i="item.i"
|
:i="item.i"
|
||||||
:w="item.w"
|
:w="item.w"
|
||||||
:x="item.x"
|
:x="item.x"
|
||||||
:y="item.y"
|
:y="item.y"
|
||||||
class="cursor-pointer"
|
class="cursor-pointer"
|
||||||
@click="handleAddWidget(item)"
|
@click="handleAddWidget(item)"
|
||||||
>
|
>
|
||||||
<component :is="item.widget" />
|
<component :is="item.widget" />
|
||||||
</grid-item>
|
</grid-item>
|
||||||
|
</template>
|
||||||
</grid-layout>
|
</grid-layout>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
@ -125,23 +127,48 @@ import cloneDeep from "lodash.clonedeep";
|
||||||
import { apiClient } from "@/utils/api-client";
|
import { apiClient } from "@/utils/api-client";
|
||||||
import type { DashboardStats } from "@halo-dev/api-client";
|
import type { DashboardStats } from "@halo-dev/api-client";
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
|
import { usePermission } from "@/utils/permission";
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
const { currentUserHasPermission } = usePermission();
|
||||||
|
|
||||||
const widgetsGroup = [
|
const widgetsGroup = [
|
||||||
{
|
{
|
||||||
id: "post",
|
id: "post",
|
||||||
label: t("core.dashboard.widgets.groups.post"),
|
label: t("core.dashboard.widgets.groups.post"),
|
||||||
widgets: [
|
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",
|
id: "page",
|
||||||
label: t("core.dashboard.widgets.groups.page"),
|
label: t("core.dashboard.widgets.groups.page"),
|
||||||
widgets: [
|
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",
|
id: "user",
|
||||||
label: t("core.dashboard.widgets.groups.user"),
|
label: t("core.dashboard.widgets.groups.user"),
|
||||||
widgets: [
|
widgets: [{ x: 0, y: 0, w: 3, h: 3, i: 0, widget: "UserStatsWidget" }],
|
||||||
{ x: 0, y: 0, w: 3, h: 3, i: 0, widget: "UserStatsWidget" },
|
|
||||||
{ x: 0, y: 0, w: 3, h: 3, i: 1, widget: "UserProfileWidget" },
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "other",
|
id: "other",
|
||||||
|
@ -172,18 +196,54 @@ const widgetsModal = ref(false);
|
||||||
const activeId = ref(widgetsGroup[0].id);
|
const activeId = ref(widgetsGroup[0].id);
|
||||||
|
|
||||||
const layout = useStorage("widgets", [
|
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,
|
y: 3,
|
||||||
w: 4,
|
w: 6,
|
||||||
h: 10,
|
h: 12,
|
||||||
|
i: 4,
|
||||||
|
widget: "QuickLinkWidget",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
x: 6,
|
||||||
|
y: 3,
|
||||||
|
w: 6,
|
||||||
|
h: 12,
|
||||||
i: 5,
|
i: 5,
|
||||||
widget: "RecentPublishedWidget",
|
widget: "RecentPublishedWidget",
|
||||||
|
permissions: ["system:posts:view"],
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ export function hasPermission(
|
||||||
}
|
}
|
||||||
|
|
||||||
interface usePermissionReturn {
|
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 { uiPermissions } = roleStore.permissions;
|
||||||
|
|
||||||
const currentUserHasPermission = (
|
const currentUserHasPermission = (
|
||||||
targetPermissions: Array<string>
|
targetPermissions?: Array<string>
|
||||||
): boolean => {
|
): boolean => {
|
||||||
return hasPermission(uiPermissions, targetPermissions, true);
|
return hasPermission(uiPermissions, targetPermissions || [], true);
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
Loading…
Reference in New Issue