feat: add pages extension points

Signed-off-by: Ryan Wang <i@ryanc.cc>
pull/588/head
Ryan Wang 2022-06-23 15:31:32 +08:00
parent 4ef9f0cf5d
commit c97a3c8836
8 changed files with 71 additions and 58 deletions

View File

@ -1,3 +1,4 @@
export * from "./types/plugin";
export * from "./types/menus";
export * from "./core/plugins";
export * from "./states/pages";

View File

@ -0,0 +1,9 @@
export interface PagesPublicState {
functionalPages: FunctionalPagesState[];
}
export interface FunctionalPagesState {
name: string;
path: string;
url?: string;
}

View File

@ -1,15 +1,11 @@
import type { Component } from "vue";
import type { Component, Ref } from "vue";
import type { RouteRecordRaw } from "vue-router";
import type { MenuGroupType } from "./menus";
import type { PagesPublicState } from "@/states/pages";
export type ExtensionPointName =
| "POSTS"
| "POST_EDITOR"
| "DASHBOARD"
| "USER_SETTINGS";
export type ExtensionPointName = "PAGES" | "POSTS";
// TODO define extension point state
export type ExtensionPointState = Record<string, unknown>;
export type ExtensionPointState = PagesPublicState;
export interface Plugin {
name: string;
@ -33,8 +29,7 @@ export interface Plugin {
menus?: MenuGroupType[];
extensionPoints?: Record<
ExtensionPointName,
(state: ExtensionPointState) => void
>;
extensionPoints?: {
[key in ExtensionPointName]?: (state: Ref<ExtensionPointState>) => void;
};
}

View File

@ -0,0 +1,21 @@
import { usePluginStore } from "@/stores/plugin";
import type {
ExtensionPointName,
ExtensionPointState,
} from "@halo-dev/admin-shared";
import type { Plugin } from "@/types/extension";
import type { Ref } from "vue";
export function useExtensionPointsState(
point: ExtensionPointName,
state: Ref<ExtensionPointState>
) {
const { plugins } = usePluginStore();
plugins.forEach((plugin: Plugin) => {
if (!plugin.spec.module?.extensionPoints?.[point]) {
return;
}
plugin.spec.module.extensionPoints[point]?.(state);
});
}

View File

@ -14,9 +14,10 @@ import {
} from "@halo-dev/components";
import { ref } from "vue";
import { users } from "@/modules/system/users/users-mock";
import halo from "@/assets/logo.svg";
import type { PagesPublicState } from "@halo-dev/admin-shared";
import { useExtensionPointsState } from "@/composables/usePlugins";
const sheetsRef = ref([
const pagesRef = ref([
{
title: "关于我们",
url: "/about",
@ -37,29 +38,13 @@ const sheetsRef = ref([
},
]);
const advancedSheets = ref([
{
name: "友情链接",
author: "halo-dev",
logo: halo,
url: "/links",
},
{
name: "图库",
author: "halo-dev",
logo: halo,
url: "/photos",
},
{
name: "社区",
author: "halo-dev",
logo: halo,
url: "/community",
},
]);
const activeId = ref("functional");
const checkAll = ref(false);
const activeId = ref("advanced");
const pagesPublicState = ref<PagesPublicState>({
functionalPages: [],
});
useExtensionPointsState("PAGES", pagesPublicState);
</script>
<template>
<VPageHeader title="页面">
@ -82,19 +67,23 @@ const activeId = ref("advanced");
<VTabbar
v-model:active-id="activeId"
:items="[
{ id: 'advanced', label: '功能页面' },
{ id: 'functional', label: '功能页面' },
{ id: 'custom', label: '自定义页面' },
]"
class="w-full !rounded-none"
type="outline"
></VTabbar>
</template>
<div v-if="activeId === 'advanced'">
<div v-if="activeId === 'functional'">
<ul
class="box-border h-full w-full divide-y divide-gray-100"
role="list"
>
<li v-for="(sheet, index) in advancedSheets" :key="index">
<li
v-for="(page, index) in pagesPublicState.functionalPages"
:key="index"
@click="$router.push({ path: page.path })"
>
<div
class="relative block cursor-pointer px-4 py-3 transition-all hover:bg-gray-50"
>
@ -104,20 +93,15 @@ const activeId = ref("advanced");
<span
class="mr-0 truncate text-sm font-medium text-gray-900 sm:mr-2"
>
{{ sheet.name }}
{{ page.name }}
</span>
<VTag>{{ sheet.url }}</VTag>
<VTag>{{ page.url }}</VTag>
</div>
</div>
<div class="flex">
<div
class="inline-flex flex-col flex-col-reverse items-end gap-4 sm:flex-row sm:items-center sm:gap-6"
>
<img
v-tooltip="`由${sheet.name}插件提供`"
:src="sheet.logo"
class="hidden h-6 w-6 rounded-full ring-2 ring-white sm:inline-block"
/>
<span class="cursor-pointer">
<IconSettings />
</span>
@ -269,7 +253,7 @@ const activeId = ref("advanced");
class="box-border h-full w-full divide-y divide-gray-100"
role="list"
>
<li v-for="(sheet, index) in sheetsRef" :key="index">
<li v-for="(page, index) in pagesRef" :key="index">
<div
:class="{
'bg-gray-100': checkAll,
@ -293,17 +277,17 @@ const activeId = ref("advanced");
<span
class="mr-0 truncate text-sm font-medium text-gray-900 sm:mr-2"
>
{{ sheet.title }}
{{ page.title }}
</span>
<VTag>{{ sheet.url }}</VTag>
<VTag>{{ page.url }}</VTag>
</div>
<div class="mt-1 flex">
<VSpace>
<span class="text-xs text-gray-500">
访问量 {{ sheet.views }}
访问量 {{ page.views }}
</span>
<span class="text-xs text-gray-500">
评论 {{ sheet.commentCount }}
评论 {{ page.commentCount }}
</span>
</VSpace>
</div>

View File

@ -1,19 +1,19 @@
import { definePlugin } from "@halo-dev/admin-shared";
import { BasicLayout } from "@/layouts";
import SheetList from "./SheetList.vue";
import SheetList from "./PageList.vue";
import { IconPages } from "@halo-dev/components";
export default definePlugin({
name: "sheetModule",
name: "pageModule",
components: [],
routes: [
{
path: "/sheets",
path: "/pages",
component: BasicLayout,
children: [
{
path: "",
name: "Sheets",
name: "Pages",
component: SheetList,
},
],
@ -25,7 +25,7 @@ export default definePlugin({
items: [
{
name: "页面",
path: "/sheets",
path: "/pages",
icon: IconPages,
},
],

View File

@ -1,6 +1,6 @@
import dashboardModule from "./dashboard/module";
import postModule from "./contents/posts/module";
import sheetModule from "./contents/sheets/module";
import pageModule from "./contents/pages/module";
import commentModule from "./contents/comments/module";
import attachmentModule from "./contents/attachments/module";
import themeModule from "./interface/themes/module";
@ -13,7 +13,7 @@ import settingModule from "./system/settings/module";
const coreModules = [
dashboardModule,
postModule,
sheetModule,
pageModule,
commentModule,
attachmentModule,
themeModule,

View File

@ -1,3 +1,5 @@
import type { Plugin as PluginModule } from "@halo-dev/admin-shared";
export interface License {
name?: string;
url?: string;
@ -44,6 +46,7 @@ export interface PluginSpec {
requires?: string;
pluginClass?: string;
enabled?: boolean;
module?: PluginModule;
}
export interface PluginStatus {