mirror of https://github.com/halo-dev/halo
feat: add tools page for console (#5252)
#### What type of PR is this? /area console /kind feature /milestone 2.12.x #### What this PR does / why we need it: 为 Console 提供工具页面和菜单项,方便插件集成。 <img width="1920" alt="image" src="https://github.com/halo-dev/halo/assets/21301288/9b63284f-7bdb-4eed-bc6e-cbe2c78359db"> #### Which issue(s) this PR fixes: Fixes https://github.com/halo-dev/halo/issues/5249 #### Special notes for your reviewer: 可以使用以下插件进行测试: 1. [plugin-umami-1.0.0-SNAPSHOT.jar.zip](https://github.com/halo-dev/halo/files/14049119/plugin-umami-1.0.0-SNAPSHOT.jar.zip) 2. [plugin-metrics-graph-1.0.0-beta.1.jar.zip](https://github.com/halo-dev/halo/files/14049127/plugin-metrics-graph-1.0.0-beta.1.jar.zip) 3. [NotifyMe-1.1.0.jar.zip](https://github.com/halo-dev/halo/files/14049131/NotifyMe-1.1.0.jar.zip) #### Does this PR introduce a user-facing change? ```release-note 为 Console 提供工具页面和菜单项,方便插件集成。 ```pull/5256/head
parent
3f27f6f262
commit
22104fe636
|
@ -0,0 +1,98 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { useRoleStore } from "@/stores/role";
|
||||||
|
import { hasPermission } from "@/utils/permission";
|
||||||
|
import {
|
||||||
|
VPageHeader,
|
||||||
|
IconToolsFill,
|
||||||
|
VCard,
|
||||||
|
VEntity,
|
||||||
|
VEntityField,
|
||||||
|
VButton,
|
||||||
|
VEmpty,
|
||||||
|
} from "@halo-dev/components";
|
||||||
|
import { computed } from "vue";
|
||||||
|
import type { RouteRecordRaw } from "vue-router";
|
||||||
|
import { useRouter } from "vue-router";
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
const roleStore = useRoleStore();
|
||||||
|
|
||||||
|
const { uiPermissions } = roleStore.permissions;
|
||||||
|
|
||||||
|
function isRouteValid(route?: RouteRecordRaw) {
|
||||||
|
if (!route) return false;
|
||||||
|
const { meta } = route;
|
||||||
|
if (!meta?.menu) return false;
|
||||||
|
return (
|
||||||
|
!meta.permissions || hasPermission(uiPermissions, meta.permissions, true)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const routes = computed(() => {
|
||||||
|
const matchedRoute = router.currentRoute.value.matched[0];
|
||||||
|
|
||||||
|
return router
|
||||||
|
.getRoutes()
|
||||||
|
.find((route) => route.name === matchedRoute.name)
|
||||||
|
?.children.filter((route) => route.path !== "")
|
||||||
|
.filter((route) => isRouteValid(route));
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<VPageHeader :title="$t('core.tool.title')">
|
||||||
|
<template #icon>
|
||||||
|
<IconToolsFill class="mr-2 self-center" />
|
||||||
|
</template>
|
||||||
|
</VPageHeader>
|
||||||
|
|
||||||
|
<div class="m-0 md:m-4">
|
||||||
|
<VCard :body-class="['!p-0']">
|
||||||
|
<VEmpty
|
||||||
|
v-if="!routes?.length"
|
||||||
|
:title="$t('core.tool.empty.title')"
|
||||||
|
:message="$t('core.tool.empty.message')"
|
||||||
|
></VEmpty>
|
||||||
|
<ul
|
||||||
|
v-else
|
||||||
|
class="box-border h-full w-full divide-y divide-gray-100"
|
||||||
|
role="list"
|
||||||
|
>
|
||||||
|
<li v-for="route in routes" :key="route.name">
|
||||||
|
<VEntity>
|
||||||
|
<template #start>
|
||||||
|
<VEntityField>
|
||||||
|
<template #description>
|
||||||
|
<component
|
||||||
|
:is="route.meta?.menu?.icon"
|
||||||
|
v-if="route.meta?.menu?.icon"
|
||||||
|
class="text-lg"
|
||||||
|
/>
|
||||||
|
<IconToolsFill v-else class="text-lg" />
|
||||||
|
</template>
|
||||||
|
</VEntityField>
|
||||||
|
<VEntityField
|
||||||
|
:route="{ name: route.name }"
|
||||||
|
:title="route.meta?.menu?.name"
|
||||||
|
:description="route.meta?.description"
|
||||||
|
></VEntityField>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #end>
|
||||||
|
<VEntityField>
|
||||||
|
<template #description>
|
||||||
|
<VButton
|
||||||
|
size="sm"
|
||||||
|
@click="$router.push({ name: route.name })"
|
||||||
|
>
|
||||||
|
{{ $t("core.common.buttons.access") }}
|
||||||
|
</VButton>
|
||||||
|
</template>
|
||||||
|
</VEntityField>
|
||||||
|
</template>
|
||||||
|
</VEntity>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</VCard>
|
||||||
|
</div>
|
||||||
|
</template>
|
|
@ -0,0 +1,32 @@
|
||||||
|
import { definePlugin } from "@halo-dev/console-shared";
|
||||||
|
import Tools from "./Tools.vue";
|
||||||
|
import { markRaw } from "vue";
|
||||||
|
import BasicLayout from "@console/layouts/BasicLayout.vue";
|
||||||
|
import { IconToolsFill } from "@halo-dev/components";
|
||||||
|
|
||||||
|
export default definePlugin({
|
||||||
|
components: {},
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
path: "/tools",
|
||||||
|
name: "ToolsRoot",
|
||||||
|
component: BasicLayout,
|
||||||
|
meta: {
|
||||||
|
title: "core.tool.title",
|
||||||
|
menu: {
|
||||||
|
name: "core.sidebar.menu.items.tools",
|
||||||
|
group: "system",
|
||||||
|
icon: markRaw(IconToolsFill),
|
||||||
|
priority: 5,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: "",
|
||||||
|
name: "Tools",
|
||||||
|
component: Tools,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
|
@ -71,6 +71,7 @@ import IconLogoutCircleRLine from "~icons/ri/logout-circle-r-line";
|
||||||
import IconAccountCircleLine from "~icons/ri/account-circle-line";
|
import IconAccountCircleLine from "~icons/ri/account-circle-line";
|
||||||
import IconSettings3Line from "~icons/ri/settings-3-line";
|
import IconSettings3Line from "~icons/ri/settings-3-line";
|
||||||
import IconImageAddLine from "~icons/ri/image-add-line";
|
import IconImageAddLine from "~icons/ri/image-add-line";
|
||||||
|
import IconToolsFill from "~icons/ri/tools-fill";
|
||||||
|
|
||||||
export {
|
export {
|
||||||
IconDashboard,
|
IconDashboard,
|
||||||
|
@ -146,4 +147,5 @@ export {
|
||||||
IconAccountCircleLine,
|
IconAccountCircleLine,
|
||||||
IconSettings3Line,
|
IconSettings3Line,
|
||||||
IconImageAddLine,
|
IconImageAddLine,
|
||||||
|
IconToolsFill,
|
||||||
};
|
};
|
||||||
|
|
|
@ -77,6 +77,7 @@ core:
|
||||||
settings: Settings
|
settings: Settings
|
||||||
actuator: Actuator
|
actuator: Actuator
|
||||||
backup: Backup
|
backup: Backup
|
||||||
|
tools: Tools
|
||||||
operations:
|
operations:
|
||||||
logout:
|
logout:
|
||||||
tooltip: Logout
|
tooltip: Logout
|
||||||
|
@ -1495,6 +1496,7 @@ core:
|
||||||
view_all: View all
|
view_all: View all
|
||||||
verify: Verify
|
verify: Verify
|
||||||
modify: Modify
|
modify: Modify
|
||||||
|
access: Access
|
||||||
radio:
|
radio:
|
||||||
"yes": "Yes"
|
"yes": "Yes"
|
||||||
"no": "No"
|
"no": "No"
|
||||||
|
@ -1601,3 +1603,10 @@ core:
|
||||||
toast_success: >-
|
toast_success: >-
|
||||||
If your username and email address match, we will send an email to
|
If your username and email address match, we will send an email to
|
||||||
your email address.
|
your email address.
|
||||||
|
tool:
|
||||||
|
title: Tools
|
||||||
|
empty:
|
||||||
|
title: There are no tools available
|
||||||
|
message: >-
|
||||||
|
There are currently no tools available, and system tools may be provided
|
||||||
|
by plugins
|
||||||
|
|
|
@ -75,6 +75,7 @@ core:
|
||||||
settings: 设置
|
settings: 设置
|
||||||
actuator: 概览
|
actuator: 概览
|
||||||
backup: 备份
|
backup: 备份
|
||||||
|
tools: 工具
|
||||||
operations:
|
operations:
|
||||||
logout:
|
logout:
|
||||||
tooltip: 退出登录
|
tooltip: 退出登录
|
||||||
|
@ -1441,6 +1442,7 @@ core:
|
||||||
view_all: 查看全部
|
view_all: 查看全部
|
||||||
verify: 验证
|
verify: 验证
|
||||||
modify: 修改
|
modify: 修改
|
||||||
|
access: 访问
|
||||||
radio:
|
radio:
|
||||||
"yes": 是
|
"yes": 是
|
||||||
"no": 否
|
"no": 否
|
||||||
|
@ -1509,3 +1511,8 @@ core:
|
||||||
recovering: 恢复中
|
recovering: 恢复中
|
||||||
fields:
|
fields:
|
||||||
post_count: "{count} 篇文章"
|
post_count: "{count} 篇文章"
|
||||||
|
tool:
|
||||||
|
title: 工具
|
||||||
|
empty:
|
||||||
|
title: 没有可用工具
|
||||||
|
message: 当前没有可用的工具,系统工具可能由插件提供
|
||||||
|
|
|
@ -75,6 +75,7 @@ core:
|
||||||
settings: 設置
|
settings: 設置
|
||||||
actuator: 概覽
|
actuator: 概覽
|
||||||
backup: 備份
|
backup: 備份
|
||||||
|
tools: 工具
|
||||||
operations:
|
operations:
|
||||||
logout:
|
logout:
|
||||||
tooltip: 登出
|
tooltip: 登出
|
||||||
|
@ -1407,6 +1408,7 @@ core:
|
||||||
view_all: 查看全部
|
view_all: 查看全部
|
||||||
modify: 修改
|
modify: 修改
|
||||||
verify: 驗證
|
verify: 驗證
|
||||||
|
access: 访问
|
||||||
radio:
|
radio:
|
||||||
"yes": 是
|
"yes": 是
|
||||||
"no": 否
|
"no": 否
|
||||||
|
@ -1509,3 +1511,8 @@ core:
|
||||||
send:
|
send:
|
||||||
label: 發送驗證郵件
|
label: 發送驗證郵件
|
||||||
toast_success: 如果你的用戶名和郵箱地址匹配,我們將會發送一封郵件到你的郵箱。
|
toast_success: 如果你的用戶名和郵箱地址匹配,我們將會發送一封郵件到你的郵箱。
|
||||||
|
tool:
|
||||||
|
title: 工具
|
||||||
|
empty:
|
||||||
|
title: 沒有可用工具
|
||||||
|
message: 目前沒有可用的工具,系統工具可能由外掛提供
|
||||||
|
|
Loading…
Reference in New Issue