diff --git a/apps/client/package.json b/apps/client/package.json index 430b151b7..46c076520 100644 --- a/apps/client/package.json +++ b/apps/client/package.json @@ -21,20 +21,20 @@ "@docmost/base-formula": "workspace:*", "@docmost/editor-ext": "workspace:*", "@excalidraw/excalidraw": "0.18.0-3a5ef40", - "@mantine/core": "8.3.18", - "@mantine/dates": "8.3.18", - "@mantine/form": "8.3.18", - "@mantine/hooks": "8.3.18", - "@mantine/modals": "8.3.18", - "@mantine/notifications": "8.3.18", - "@mantine/spotlight": "8.3.18", + "@mantine/core": "9.3.2", + "@mantine/dates": "9.3.2", + "@mantine/form": "9.3.2", + "@mantine/hooks": "9.3.2", + "@mantine/modals": "9.3.2", + "@mantine/notifications": "9.3.2", + "@mantine/spotlight": "9.3.2", "@slidoapp/emoji-mart": "5.8.7", "@slidoapp/emoji-mart-data": "1.2.4", "@slidoapp/emoji-mart-react": "1.1.5", "@tabler/icons-react": "3.40.0", "@tanstack/react-query": "5.90.17", "@tanstack/react-table": "8.21.3", - "@tanstack/react-virtual": "3.14.2", + "@tanstack/react-virtual": "3.14.3", "alfaaz": "1.1.0", "axios": "1.16.0", "blueimp-load-image": "5.16.0", @@ -43,7 +43,7 @@ "highlightjs-sap-abap": "0.3.0", "i18next": "25.10.1", "i18next-http-backend": "3.0.6", - "jotai": "2.18.1", + "jotai": "2.20.1", "jotai-optics": "0.4.0", "js-cookie": "3.0.7", "jwt-decode": "4.0.0", @@ -52,16 +52,16 @@ "mantine-form-zod-resolver": "1.3.0", "mermaid": "11.15.0", "mitt": "3.0.1", - "nanoid": "^3.3.8", - "posthog-js": "1.372.2", - "react": "18.3.1", + "nanoid": "3.3.8", + "posthog-js": "1.391.2", + "react": "19.2.7", "react-clear-modal": "^2.0.18", - "react-dom": "^18.3.1", + "react-dom": "19.2.7", "react-drawio": "1.0.7", "react-error-boundary": "6.1.1", "react-helmet-async": "3.0.0", "react-i18next": "16.5.8", - "react-router-dom": "7.13.1", + "react-router-dom": "7.18.0", "semver": "7.7.4", "socket.io-client": "4.8.3", "zod": "4.3.6" @@ -76,8 +76,8 @@ "@types/js-cookie": "3.0.6", "@types/katex": "0.16.8", "@types/node": "22.19.1", - "@types/react": "18.3.12", - "@types/react-dom": "18.3.1", + "@types/react": "19.2.17", + "@types/react-dom": "19.2.3", "@vitejs/plugin-react": "6.0.1", "eslint": "9.28.0", "eslint-plugin-react": "7.37.5", @@ -92,7 +92,7 @@ "prettier": "3.8.1", "typescript": "5.9.3", "typescript-eslint": "8.57.1", - "vite": "8.0.5", + "vite": "8.0.16", "vitest": "4.1.6" } } diff --git a/apps/client/public/locales/en-US/translation.json b/apps/client/public/locales/en-US/translation.json index 7017eba70..392fae178 100644 --- a/apps/client/public/locales/en-US/translation.json +++ b/apps/client/public/locales/en-US/translation.json @@ -418,6 +418,8 @@ "Insert mermaid diagram": "Insert mermaid diagram", "Insert and design Drawio diagrams": "Insert and design Drawio diagrams", "Insert current date": "Insert current date", + "Time": "Time", + "Insert current time": "Insert current time", "Draw and sketch excalidraw diagrams": "Draw and sketch excalidraw diagrams", "Multiple": "Multiple", "Turn into": "Turn into", @@ -1108,6 +1110,12 @@ "Removed {{name}} from favorites": "Removed {{name}} from favorites", "Page menu for {{name}}": "Page menu for {{name}}", "Create subpage of {{name}}": "Create subpage of {{name}}", + "Allow personal spaces": "Allow personal spaces", + "Members can create their own personal space.": "Members can create their own personal space.", + "Toggle allow personal spaces": "Toggle allow personal spaces", + "Create personal space": "Create personal space", + "Personal space": "Personal space", + "{{name}}'s space": "{{name}}'s space", "Apply": "Apply", "Cells that aren't already a page reference will be cleared.": "Cells that aren't already a page reference will be cleared.", "Cells that aren't a valid URL will be cleared.": "Cells that aren't a valid URL will be cleared.", diff --git a/apps/client/src/components/common/export-modal.tsx b/apps/client/src/components/common/export-modal.tsx index 2a83debf9..bbd58b64d 100644 --- a/apps/client/src/components/common/export-modal.tsx +++ b/apps/client/src/components/common/export-modal.tsx @@ -6,13 +6,21 @@ import { Select, Switch, Divider, + Tooltip, + Badge, } from "@mantine/core"; -import { exportPage } from "@/features/page/services/page-service.ts"; +import { + exportPage, + exportPageToDocx, +} 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"; import { useTranslation } from "react-i18next"; +import { Feature } from "@/ee/features"; +import { useHasFeature } from "@/ee/hooks/use-feature"; +import { useUpgradeLabel } from "@/ee/hooks/use-upgrade-label"; interface ExportModalProps { id: string; @@ -32,17 +40,25 @@ export default function ExportModal({ const [includeAttachments, setIncludeAttachments] = useState(false); const [isExporting, setIsExporting] = useState(false); const { t } = useTranslation(); + const upgradeLabel = useUpgradeLabel(); + const isDocx = format === ExportFormat.Docx; + const docxEntitled = useHasFeature(Feature.DOCX_EXPORT); + const blockedByLicense = isDocx && !docxEntitled; const handleExport = async () => { setIsExporting(true); try { if (type === "page") { - await exportPage({ - pageId: id, - format, - includeChildren, - includeAttachments, - }); + if (format === ExportFormat.Docx) { + await exportPageToDocx({ pageId: id }); + } else { + await exportPage({ + pageId: id, + format, + includeChildren, + includeAttachments, + }); + } } if (type === "space") { await exportSpace({ spaceId: id, format, includeAttachments }); @@ -88,10 +104,15 @@ export default function ExportModal({
{t("Format")}
- + - {type === "page" && ( + {type === "page" && !isDocx && ( <> @@ -143,7 +164,16 @@ export default function ExportModal({ - + + + @@ -154,23 +184,49 @@ export default function ExportModal({ interface ExportFormatSelection { format: ExportFormat; onChange: (value: string) => void; + includeDocx?: boolean; + docxEntitled?: boolean; } -function ExportFormatSelection({ format, onChange }: ExportFormatSelection) { +function ExportFormatSelection({ + format, + onChange, + includeDocx, + docxEntitled, +}: ExportFormatSelection) { const { t } = useTranslation(); + const data = [ + { value: "markdown", label: "Markdown" }, + { value: "html", label: "HTML" }, + ...(includeDocx + ? [{ value: "docx", label: "Word (.docx)", disabled: !docxEntitled }] + : []), + ]; + return (