diff --git a/package.json b/package.json index a7537a329..80cee73d0 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "@formkit/themes": "1.0.0-beta.10", "@formkit/vue": "1.0.0-beta.10", "@halo-dev/admin-shared": "workspace:*", - "@halo-dev/api-client": "^0.0.15", + "@halo-dev/api-client": "^0.0.17", "@halo-dev/components": "workspace:*", "@halo-dev/richtext-editor": "^0.0.0-alpha.6", "@tiptap/extension-character-count": "2.0.0-beta.31", diff --git a/packages/shared/package.json b/packages/shared/package.json index 3919a8451..4c9a267d1 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -38,7 +38,7 @@ "homepage": "https://github.com/halo-dev/halo-admin/tree/next/shared/components#readme", "license": "MIT", "dependencies": { - "@halo-dev/api-client": "^0.0.15", + "@halo-dev/api-client": "^0.0.17", "@halo-dev/components": "workspace:*", "axios": "^0.27.2", "lodash.merge": "^4.6.2" diff --git a/packages/shared/src/utils/api-client.ts b/packages/shared/src/utils/api-client.ts index 0051a8b68..a569c7f7c 100644 --- a/packages/shared/src/utils/api-client.ts +++ b/packages/shared/src/utils/api-client.ts @@ -10,6 +10,7 @@ import { ContentHaloRunV1alpha1ReplyApi, ContentHaloRunV1alpha1SnapshotApi, ContentHaloRunV1alpha1TagApi, + ContentHaloRunV1alpha1SinglePageApi, PluginHaloRunV1alpha1PluginApi, PluginHaloRunV1alpha1ReverseProxyApi, StorageHaloRunV1alpha1AttachmentApi, @@ -78,6 +79,11 @@ function setupApiClient(axios: AxiosInstance) { menu: new V1alpha1MenuApi(undefined, apiUrl, axios), menuItem: new V1alpha1MenuItemApi(undefined, apiUrl, axios), post: new ContentHaloRunV1alpha1PostApi(undefined, apiUrl, axios), + singlePage: new ContentHaloRunV1alpha1SinglePageApi( + undefined, + apiUrl, + axios + ), category: new ContentHaloRunV1alpha1CategoryApi(undefined, apiUrl, axios), tag: new ContentHaloRunV1alpha1TagApi(undefined, apiUrl, axios), snapshot: new ContentHaloRunV1alpha1SnapshotApi(undefined, apiUrl, axios), diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8bb37bf65..33bcdc306 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -13,7 +13,7 @@ importers: '@formkit/themes': 1.0.0-beta.10 '@formkit/vue': 1.0.0-beta.10 '@halo-dev/admin-shared': workspace:* - '@halo-dev/api-client': ^0.0.15 + '@halo-dev/api-client': ^0.0.17 '@halo-dev/components': workspace:* '@halo-dev/richtext-editor': ^0.0.0-alpha.6 '@iconify-json/vscode-icons': ^1.1.11 @@ -92,7 +92,7 @@ importers: '@formkit/themes': 1.0.0-beta.10_tailwindcss@3.1.8 '@formkit/vue': 1.0.0-beta.10_wwmyxdjqen5bmh3tr2meig5lki '@halo-dev/admin-shared': link:packages/shared - '@halo-dev/api-client': 0.0.15 + '@halo-dev/api-client': 0.0.17 '@halo-dev/components': link:packages/components '@halo-dev/richtext-editor': 0.0.0-alpha.6_vue@3.2.37 '@tiptap/extension-character-count': 2.0.0-beta.31 @@ -194,14 +194,14 @@ importers: packages/shared: specifiers: - '@halo-dev/api-client': ^0.0.15 + '@halo-dev/api-client': ^0.0.17 '@halo-dev/components': workspace:* '@types/lodash.merge': ^4.6.7 axios: ^0.27.2 lodash.merge: ^4.6.2 vite-plugin-dts: ^1.4.1 dependencies: - '@halo-dev/api-client': 0.0.15 + '@halo-dev/api-client': 0.0.17 '@halo-dev/components': link:../components axios: 0.27.2 lodash.merge: 4.6.2 @@ -2129,8 +2129,8 @@ packages: - windicss dev: false - /@halo-dev/api-client/0.0.15: - resolution: {integrity: sha512-RCQXU2s5IJJ3pUORg0n2b/CYbDox/Jm4aXB2J9ZbKod3vdS3HM6X33iVXc/pyuxRjucijly3WyLkiTZ0bkwLbg==} + /@halo-dev/api-client/0.0.17: + resolution: {integrity: sha512-+OCYSioOxkaxN71t1mHOACw/pkF84nGd04jtS5Ak4FbrtBb4T2sJ+P76r8BwwG2uCk3lss1PkeDdP9/QxfUfxQ==} dev: false /@halo-dev/richtext-editor/0.0.0-alpha.6_vue@3.2.37: diff --git a/src/modules/contents/attachments/composables/use-attachment.ts b/src/modules/contents/attachments/composables/use-attachment.ts index 5d5e90f1e..8c8bff8eb 100644 --- a/src/modules/contents/attachments/composables/use-attachment.ts +++ b/src/modules/contents/attachments/composables/use-attachment.ts @@ -7,8 +7,9 @@ import type { } from "@halo-dev/api-client"; import type { Ref } from "vue"; import { ref, watch } from "vue"; -import { apiClient } from "@halo-dev/admin-shared"; +import { apiClient, type AttachmentLike } from "@halo-dev/admin-shared"; import { useDialog } from "@halo-dev/components"; +import type { Content, Editor } from "@halo-dev/richtext-editor"; interface useAttachmentControlReturn { attachments: Ref; @@ -33,6 +34,10 @@ interface useAttachmentControlReturn { handleReset: () => void; } +interface useAttachmentSelectReturn { + onAttachmentSelect: (attachments: AttachmentLike[]) => void; +} + export function useAttachmentControl(filterOptions?: { policy?: Ref; group?: Ref; @@ -212,3 +217,41 @@ export function useAttachmentControl(filterOptions?: { handleReset, }; } + +export function useAttachmentSelect( + editor: Ref +): useAttachmentSelectReturn { + const onAttachmentSelect = (attachments: AttachmentLike[]) => { + const images: Content[] = attachments.map((attachment) => { + const attrs: { src?: string; alt?: string } = {}; + if (typeof attachment === "string") { + attrs.src = attachment; + return { + type: "image", + attrs, + }; + } + if ("url" in attachment) { + attrs.src = attachment.url; + attrs.alt = attachment.type; + } + if ("spec" in attachment) { + attrs.src = attachment.status?.permalink; + attrs.alt = attachment.spec.displayName; + } + return { + type: "image", + attrs, + }; + }); + editor.value + ?.chain() + .focus() + .insertContent([...images, { type: "paragraph", content: "" }]) + .run(); + }; + + return { + onAttachmentSelect, + }; +} diff --git a/src/modules/contents/pages/FunctionalPageList.vue b/src/modules/contents/pages/FunctionalPageList.vue new file mode 100644 index 000000000..8d56d6526 --- /dev/null +++ b/src/modules/contents/pages/FunctionalPageList.vue @@ -0,0 +1,76 @@ + + + diff --git a/src/modules/contents/pages/PageList.vue b/src/modules/contents/pages/PageList.vue deleted file mode 100644 index e125a0646..000000000 --- a/src/modules/contents/pages/PageList.vue +++ /dev/null @@ -1,351 +0,0 @@ - - diff --git a/src/modules/contents/pages/SinglePageEditor.vue b/src/modules/contents/pages/SinglePageEditor.vue new file mode 100644 index 000000000..9189fc023 --- /dev/null +++ b/src/modules/contents/pages/SinglePageEditor.vue @@ -0,0 +1,209 @@ + + + diff --git a/src/modules/contents/pages/SinglePageList.vue b/src/modules/contents/pages/SinglePageList.vue new file mode 100644 index 000000000..05853b956 --- /dev/null +++ b/src/modules/contents/pages/SinglePageList.vue @@ -0,0 +1,488 @@ + + + diff --git a/src/modules/contents/pages/components/SinglePageSettingModal.vue b/src/modules/contents/pages/components/SinglePageSettingModal.vue new file mode 100644 index 000000000..435c12f71 --- /dev/null +++ b/src/modules/contents/pages/components/SinglePageSettingModal.vue @@ -0,0 +1,292 @@ + + + diff --git a/src/modules/contents/pages/layouts/PageLayout.vue b/src/modules/contents/pages/layouts/PageLayout.vue new file mode 100644 index 000000000..b1cc2ac4a --- /dev/null +++ b/src/modules/contents/pages/layouts/PageLayout.vue @@ -0,0 +1,99 @@ + + + diff --git a/src/modules/contents/pages/module.ts b/src/modules/contents/pages/module.ts index 2f02737a5..128f65f3b 100644 --- a/src/modules/contents/pages/module.ts +++ b/src/modules/contents/pages/module.ts @@ -1,5 +1,8 @@ -import { BasicLayout, definePlugin } from "@halo-dev/admin-shared"; -import PageList from "./PageList.vue"; +import { BasicLayout, BlankLayout, definePlugin } from "@halo-dev/admin-shared"; +import PageLayout from "./layouts/PageLayout.vue"; +import FunctionalPageList from "./FunctionalPageList.vue"; +import SinglePageList from "./SinglePageList.vue"; +import SinglePageEditor from "./SinglePageEditor.vue"; import { IconPages } from "@halo-dev/components"; export default definePlugin({ @@ -8,13 +11,50 @@ export default definePlugin({ routes: [ { path: "/pages", - component: BasicLayout, + component: BlankLayout, name: "BasePages", + redirect: { + name: "FunctionalPages", + }, children: [ { - path: "", - name: "Pages", - component: PageList, + path: "functional", + component: PageLayout, + children: [ + { + path: "", + name: "FunctionalPages", + component: FunctionalPageList, + }, + ], + }, + { + path: "single", + component: BlankLayout, + children: [ + { + path: "", + component: PageLayout, + children: [ + { + path: "", + name: "SinglePages", + component: SinglePageList, + }, + ], + }, + { + path: "editor", + component: BasicLayout, + children: [ + { + path: "", + name: "SinglePageEditor", + component: SinglePageEditor, + }, + ], + }, + ], }, ], }, diff --git a/src/modules/contents/posts/PostEditor.vue b/src/modules/contents/posts/PostEditor.vue index e4d992b5a..926bc2235 100644 --- a/src/modules/contents/posts/PostEditor.vue +++ b/src/modules/contents/posts/PostEditor.vue @@ -18,17 +18,17 @@ import AttachmentSelectorModal from "../attachments/components/AttachmentSelecto import type { PostRequest } from "@halo-dev/api-client"; import { computed, onMounted, ref, watch } from "vue"; import cloneDeep from "lodash.clonedeep"; -import { apiClient, type AttachmentLike } from "@halo-dev/admin-shared"; +import { apiClient } from "@halo-dev/admin-shared"; import { useRouteQuery } from "@vueuse/router"; import { v4 as uuid } from "uuid"; import { allExtensions, RichTextEditor, useEditor, - type Content, } from "@halo-dev/richtext-editor"; import ExtensionCharacterCount from "@tiptap/extension-character-count"; import { formatDatetime } from "@/utils/date"; +import { useAttachmentSelect } from "../attachments/composables/use-attachment"; const initialFormState: PostRequest = { post: { @@ -107,35 +107,7 @@ watch( } ); -const onAttachmentSelect = (attachments: AttachmentLike[]) => { - const images: Content[] = attachments.map((attachment) => { - const attrs: { src?: string; alt?: string } = {}; - if (typeof attachment === "string") { - attrs.src = attachment; - return { - type: "image", - attrs, - }; - } - if ("url" in attachment) { - attrs.src = attachment.url; - attrs.alt = attachment.type; - } - if ("spec" in attachment) { - attrs.src = attachment.status?.permalink; - attrs.alt = attachment.spec.displayName; - } - return { - type: "image", - attrs, - }; - }); - editor.value - ?.chain() - .focus() - .insertContent([...images, { type: "paragraph", content: "" }]) - .run(); -}; +const { onAttachmentSelect } = useAttachmentSelect(editor); const handleGenerateTableOfContent = () => { if (!editor.value) {