From fe8355776745574f115ff3ae2330789770a574f4 Mon Sep 17 00:00:00 2001 From: Philip Okugbe Date: Sat, 30 Nov 2024 19:47:22 +0000 Subject: [PATCH] feat: space export (#506) * wip * Space export * option to export pages with children * include attachments in exports * unified export UI * cleanup * fix: change export icon * add export button to space settings * cleanups * export name --- .../src/components/common/export-modal.tsx | 149 +++++++++++++ .../components/header/page-header-menu.tsx | 10 +- .../page/components/page-export-modal.tsx | 12 +- .../page/tree/components/space-tree.tsx | 126 ++++++----- .../src/features/page/types/page.types.ts | 1 + .../components/sidebar/space-sidebar.tsx | 62 ++++-- .../space/components/space-details.tsx | 29 ++- .../features/space/services/space-service.ts | 36 +++- .../src/features/space/types/space.types.ts | 7 + apps/client/src/lib/api-client.ts | 14 +- .../src/collaboration/collaboration.util.ts | 37 ++-- .../src/database/repos/page/page.repo.ts | 26 +++ .../src/integrations/export/dto/export-dto.ts | 16 +- .../integrations/export/export.controller.ts | 56 ++++- .../src/integrations/export/export.module.ts | 2 + .../src/integrations/export/export.service.ts | 195 +++++++++++++++++- apps/server/src/integrations/export/utils.ts | 175 ++++++++++++++++ package.json | 1 + packages/editor-ext/src/lib/link.ts | 19 ++ pnpm-lock.yaml | 70 +++++++ 20 files changed, 926 insertions(+), 117 deletions(-) create mode 100644 apps/client/src/components/common/export-modal.tsx diff --git a/apps/client/src/components/common/export-modal.tsx b/apps/client/src/components/common/export-modal.tsx new file mode 100644 index 00000000..1891849b --- /dev/null +++ b/apps/client/src/components/common/export-modal.tsx @@ -0,0 +1,149 @@ +import { + Modal, + Button, + Group, + Text, + Select, + Switch, + Divider, +} from "@mantine/core"; +import { exportPage } from "@/features/page/services/page-service.ts"; +import { useState } from "react"; +import { ExportFormat } from "@/features/page/types/page.types.ts"; +import { notifications } from "@mantine/notifications"; +import { exportSpace } from "@/features/space/services/space-service"; + +interface ExportModalProps { + id: string; + type: "space" | "page"; + open: boolean; + onClose: () => void; +} + +export default function ExportModal({ + id, + type, + open, + onClose, +}: ExportModalProps) { + const [format, setFormat] = useState(ExportFormat.Markdown); + const [includeChildren, setIncludeChildren] = useState(false); + const [includeAttachments, setIncludeAttachments] = useState(true); + + const handleExport = async () => { + try { + if (type === "page") { + await exportPage({ pageId: id, format, includeChildren }); + } + if (type === "space") { + await exportSpace({ spaceId: id, format, includeAttachments }); + } + setIncludeChildren(false); + setIncludeAttachments(true); + onClose(); + } catch (err) { + notifications.show({ + message: "Export failed:" + err.response?.data.message, + color: "red", + }); + console.error("export error", err); + } + }; + + const handleChange = (format: ExportFormat) => { + setFormat(format); + }; + + return ( + + + + + Export {type} + + + + +
+ Format +
+ +
+ + {type === "page" && ( + <> + + + +
+ Include subpages +
+ + setIncludeChildren(event.currentTarget.checked) + } + checked={includeChildren} + /> +
+ + )} + + {type === "space" && ( + <> + + + +
+ Include attachments +
+ + setIncludeAttachments(event.currentTarget.checked) + } + checked={includeAttachments} + /> +
+ + )} + + + + + +
+
+
+ ); +} + +interface ExportFormatSelection { + format: ExportFormat; + onChange: (value: string) => void; +} +function ExportFormatSelection({ format, onChange }: ExportFormatSelection) { + return ( +