@arbidocs/blocks 0.5.115 → 0.5.117
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{ConnectedCallDock-WER7R222.cjs → ConnectedCallDock-OZBTU3IT.cjs} +20 -20
- package/dist/{ConnectedCallDock-WER7R222.cjs.map → ConnectedCallDock-OZBTU3IT.cjs.map} +1 -1
- package/dist/{ConnectedCallRoom-T7OBQTYP.cjs → ConnectedCallRoom-VMZE2NFP.cjs} +13 -13
- package/dist/{ConnectedCallRoom-T7OBQTYP.cjs.map → ConnectedCallRoom-VMZE2NFP.cjs.map} +1 -1
- package/dist/{ConnectedNativeDocxComparison-YXMYJWXY.cjs → ConnectedNativeDocxComparison-7OUKTKYP.cjs} +20 -20
- package/dist/{ConnectedNativeDocxComparison-YXMYJWXY.cjs.map → ConnectedNativeDocxComparison-7OUKTKYP.cjs.map} +1 -1
- package/dist/{ConnectedProductionSetDialog-LHB4VQWC.cjs → ConnectedProductionSetDialog-4EAY6KAZ.cjs} +3 -3
- package/dist/{ConnectedProductionSetDialog-LHB4VQWC.cjs.map → ConnectedProductionSetDialog-4EAY6KAZ.cjs.map} +1 -1
- package/dist/{ConnectedStreamedWordArtifact-2RTCHVPI.cjs → ConnectedStreamedWordArtifact-7V24ZDAC.cjs} +20 -20
- package/dist/{ConnectedStreamedWordArtifact-2RTCHVPI.cjs.map → ConnectedStreamedWordArtifact-7V24ZDAC.cjs.map} +1 -1
- package/dist/{DocumentReviewCard-ZSBZBGFK.cjs → DocumentReviewCard-OCPFVMLD.cjs} +15 -15
- package/dist/{DocumentReviewCard-ZSBZBGFK.cjs.map → DocumentReviewCard-OCPFVMLD.cjs.map} +1 -1
- package/dist/{FilesViewerDialog-I5QIHQZT.cjs → FilesViewerDialog-KLRDIYEH.cjs} +45 -45
- package/dist/{FilesViewerDialog-I5QIHQZT.cjs.map → FilesViewerDialog-KLRDIYEH.cjs.map} +1 -1
- package/dist/{NativeDocxEditor-H6TAEVGY.cjs → NativeDocxEditor-2LQY2CTV.cjs} +6 -6
- package/dist/{NativeDocxEditor-H6TAEVGY.cjs.map → NativeDocxEditor-2LQY2CTV.cjs.map} +1 -1
- package/dist/{WorkspaceTableView-J3C6VH4T.cjs → WorkspaceTableView-IMAZICIZ.cjs} +8 -8
- package/dist/{WorkspaceTableView-J3C6VH4T.cjs.map → WorkspaceTableView-IMAZICIZ.cjs.map} +1 -1
- package/dist/agents/index.cjs +297 -297
- package/dist/{ai-IM4A23YT.cjs → ai-7U4B4CVF.cjs} +24 -24
- package/dist/ai-7U4B4CVF.cjs.map +1 -0
- package/dist/calls/index.cjs +121 -121
- package/dist/chat/index.cjs +1 -1
- package/dist/{chunk-M6IKVKU5.cjs → chunk-2CSLFAGF.cjs} +392 -149
- package/dist/chunk-2CSLFAGF.cjs.map +1 -0
- package/dist/{chunk-SGYSDABK.cjs → chunk-2W5E62EY.cjs} +6 -6
- package/dist/{chunk-SGYSDABK.cjs.map → chunk-2W5E62EY.cjs.map} +1 -1
- package/dist/{chunk-P77YTTJ3.cjs → chunk-3ODEWSRO.cjs} +4 -4
- package/dist/{chunk-P77YTTJ3.cjs.map → chunk-3ODEWSRO.cjs.map} +1 -1
- package/dist/{chunk-DDIW4HLU.cjs → chunk-3U36VYMD.cjs} +27 -27
- package/dist/{chunk-DDIW4HLU.cjs.map → chunk-3U36VYMD.cjs.map} +1 -1
- package/dist/{chunk-TP5PGWIO.cjs → chunk-4IOYQLKG.cjs} +3 -3
- package/dist/{chunk-TP5PGWIO.cjs.map → chunk-4IOYQLKG.cjs.map} +1 -1
- package/dist/{chunk-NY3YUCOW.cjs → chunk-4NPCDS2X.cjs} +3 -3
- package/dist/{chunk-NY3YUCOW.cjs.map → chunk-4NPCDS2X.cjs.map} +1 -1
- package/dist/{chunk-BQ5RIWWT.cjs → chunk-4VZZWYEC.cjs} +3 -3
- package/dist/{chunk-BQ5RIWWT.cjs.map → chunk-4VZZWYEC.cjs.map} +1 -1
- package/dist/{chunk-Y24V6HPR.cjs → chunk-57EE6CMW.cjs} +15 -15
- package/dist/{chunk-Y24V6HPR.cjs.map → chunk-57EE6CMW.cjs.map} +1 -1
- package/dist/{chunk-NNUK5ZM7.cjs → chunk-5QUL5BZO.cjs} +4 -4
- package/dist/{chunk-NNUK5ZM7.cjs.map → chunk-5QUL5BZO.cjs.map} +1 -1
- package/dist/{chunk-OEREKAAP.cjs → chunk-6DCIZA3X.cjs} +75 -75
- package/dist/{chunk-OEREKAAP.cjs.map → chunk-6DCIZA3X.cjs.map} +1 -1
- package/dist/{chunk-YGXOKB5Z.cjs → chunk-7TEUGFIL.cjs} +4 -4
- package/dist/{chunk-YGXOKB5Z.cjs.map → chunk-7TEUGFIL.cjs.map} +1 -1
- package/dist/{chunk-TT4IF52H.cjs → chunk-7X3FS5HQ.cjs} +35 -35
- package/dist/{chunk-TT4IF52H.cjs.map → chunk-7X3FS5HQ.cjs.map} +1 -1
- package/dist/{chunk-CPR6EHG7.cjs → chunk-7XT5B2DZ.cjs} +47 -47
- package/dist/{chunk-CPR6EHG7.cjs.map → chunk-7XT5B2DZ.cjs.map} +1 -1
- package/dist/chunk-BKY2LAV2.cjs +18 -0
- package/dist/{chunk-CIHERNDO.cjs.map → chunk-BKY2LAV2.cjs.map} +1 -1
- package/dist/{chunk-XKVPSOKP.cjs → chunk-BW5MF464.cjs} +4 -4
- package/dist/{chunk-XKVPSOKP.cjs.map → chunk-BW5MF464.cjs.map} +1 -1
- package/dist/{chunk-IW7CDJTA.cjs → chunk-COD5ENHK.cjs} +4 -4
- package/dist/{chunk-IW7CDJTA.cjs.map → chunk-COD5ENHK.cjs.map} +1 -1
- package/dist/{chunk-A3T3IC3K.cjs → chunk-D7ICHGWM.cjs} +239 -85
- package/dist/chunk-D7ICHGWM.cjs.map +1 -0
- package/dist/{chunk-TDO5UWXF.cjs → chunk-E4BLRF2L.cjs} +5 -5
- package/dist/{chunk-TDO5UWXF.cjs.map → chunk-E4BLRF2L.cjs.map} +1 -1
- package/dist/{chunk-WR2SF44W.cjs → chunk-E4DUXU5K.cjs} +9 -9
- package/dist/{chunk-WR2SF44W.cjs.map → chunk-E4DUXU5K.cjs.map} +1 -1
- package/dist/{chunk-WAV762GP.cjs → chunk-GQXPNIRE.cjs} +6 -6
- package/dist/{chunk-WAV762GP.cjs.map → chunk-GQXPNIRE.cjs.map} +1 -1
- package/dist/{chunk-7OPOPYV6.cjs → chunk-H5OLHP2U.cjs} +3 -3
- package/dist/{chunk-7OPOPYV6.cjs.map → chunk-H5OLHP2U.cjs.map} +1 -1
- package/dist/{chunk-6UTKM5AB.cjs → chunk-JSQQV23D.cjs} +3 -3
- package/dist/{chunk-6UTKM5AB.cjs.map → chunk-JSQQV23D.cjs.map} +1 -1
- package/dist/{chunk-557MJ4IH.cjs → chunk-LFRNBT2I.cjs} +20 -20
- package/dist/{chunk-557MJ4IH.cjs.map → chunk-LFRNBT2I.cjs.map} +1 -1
- package/dist/{chunk-R7CJEIA5.cjs → chunk-LYTIQQQ2.cjs} +3 -3
- package/dist/{chunk-R7CJEIA5.cjs.map → chunk-LYTIQQQ2.cjs.map} +1 -1
- package/dist/{chunk-CPG7II4E.cjs → chunk-MC4F2URI.cjs} +28 -28
- package/dist/{chunk-CPG7II4E.cjs.map → chunk-MC4F2URI.cjs.map} +1 -1
- package/dist/{chunk-WXUU3COI.cjs → chunk-MZ2KZXNU.cjs} +3 -3
- package/dist/{chunk-WXUU3COI.cjs.map → chunk-MZ2KZXNU.cjs.map} +1 -1
- package/dist/{chunk-ZTXQIIFV.cjs → chunk-OZVDOAXG.cjs} +6 -6
- package/dist/{chunk-ZTXQIIFV.cjs.map → chunk-OZVDOAXG.cjs.map} +1 -1
- package/dist/{chunk-325GVZE6.cjs → chunk-Q6DQGGP4.cjs} +3 -3
- package/dist/{chunk-325GVZE6.cjs.map → chunk-Q6DQGGP4.cjs.map} +1 -1
- package/dist/{chunk-KTQOGT2L.cjs → chunk-TDN33HSK.cjs} +6 -6
- package/dist/{chunk-KTQOGT2L.cjs.map → chunk-TDN33HSK.cjs.map} +1 -1
- package/dist/{chunk-T23UTIRI.cjs → chunk-UNDQYTRF.cjs} +6 -6
- package/dist/{chunk-T23UTIRI.cjs.map → chunk-UNDQYTRF.cjs.map} +1 -1
- package/dist/{chunk-KXIRVKCJ.cjs → chunk-UUENH4BJ.cjs} +3 -3
- package/dist/{chunk-KXIRVKCJ.cjs.map → chunk-UUENH4BJ.cjs.map} +1 -1
- package/dist/{chunk-24EDG4PC.cjs → chunk-VBL3SHWX.cjs} +50 -50
- package/dist/{chunk-24EDG4PC.cjs.map → chunk-VBL3SHWX.cjs.map} +1 -1
- package/dist/{chunk-3A7QWUAW.cjs → chunk-VKH3BEZE.cjs} +3 -3
- package/dist/{chunk-3A7QWUAW.cjs.map → chunk-VKH3BEZE.cjs.map} +1 -1
- package/dist/{chunk-X5LANJDZ.cjs → chunk-VTYJAZDU.cjs} +23 -15
- package/dist/chunk-VTYJAZDU.cjs.map +1 -0
- package/dist/{chunk-B3LZITVF.cjs → chunk-WW6LXQY6.cjs} +12 -12
- package/dist/{chunk-B3LZITVF.cjs.map → chunk-WW6LXQY6.cjs.map} +1 -1
- package/dist/{chunk-NJCK6V6U.cjs → chunk-XKDUPU7B.cjs} +4 -4
- package/dist/{chunk-NJCK6V6U.cjs.map → chunk-XKDUPU7B.cjs.map} +1 -1
- package/dist/{chunk-42TURFHF.cjs → chunk-YGBHY67W.cjs} +5 -5
- package/dist/{chunk-42TURFHF.cjs.map → chunk-YGBHY67W.cjs.map} +1 -1
- package/dist/connect/docx.cjs +24 -24
- package/dist/connect/index.cjs +983 -983
- package/dist/connect/viewer.cjs +34 -34
- package/dist/connection/docx/ConnectedNativeDocxEditor.js +10 -2
- package/dist/connection/docx/ConnectedNativeDocxEditor.js.map +2 -2
- package/dist/connection/viewer/ConnectedDocumentViewer.js +124 -21
- package/dist/connection/viewer/ConnectedDocumentViewer.js.map +2 -2
- package/dist/connection/viewer/VersionDropdown.d.ts +9 -0
- package/dist/connection/viewer/VersionDropdown.js +39 -0
- package/dist/connection/viewer/VersionDropdown.js.map +7 -0
- package/dist/connection/viewer/ViewerPdfPane.js +4 -1
- package/dist/connection/viewer/ViewerPdfPane.js.map +2 -2
- package/dist/connection/viewer/useViewerBlobs.d.ts +3 -1
- package/dist/connection/viewer/useViewerBlobs.js +14 -8
- package/dist/connection/viewer/useViewerBlobs.js.map +2 -2
- package/dist/connection/viewer/useViewerTabs.js +10 -0
- package/dist/connection/viewer/useViewerTabs.js.map +2 -2
- package/dist/dashboards/index.cjs +1 -1
- package/dist/docx/DocxCommandMenu.d.ts +8 -0
- package/dist/docx/DocxCommandMenu.js +202 -0
- package/dist/docx/DocxCommandMenu.js.map +7 -0
- package/dist/docx/NativeDocxEditor.d.ts +4 -2
- package/dist/docx/NativeDocxEditor.js +51 -12
- package/dist/docx/NativeDocxEditor.js.map +2 -2
- package/dist/docx/RibbonMenu.d.ts +3 -1
- package/dist/docx/RibbonMenu.js +10 -3
- package/dist/docx/RibbonMenu.js.map +2 -2
- package/dist/docx/RibbonOverflow.d.ts +3 -0
- package/dist/docx/RibbonOverflow.js +24 -1
- package/dist/docx/RibbonOverflow.js.map +2 -2
- package/dist/docx/index.cjs +38 -38
- package/dist/docx/signatures/SignatureFields.d.ts +3 -1
- package/dist/docx/signatures/SignatureFields.js +17 -8
- package/dist/docx/signatures/SignatureFields.js.map +2 -2
- package/dist/embed/index.cjs +38 -38
- package/dist/files/index.cjs +224 -224
- package/dist/index.cjs +1590 -1590
- package/dist/settings/index.cjs +147 -147
- package/dist/shell/index.cjs +90 -90
- package/dist/studio/index.cjs +26 -26
- package/dist/styles.css +1 -1
- package/dist/workflow-canvas/index.cjs +55 -55
- package/node_modules/@arbidocs/coedit/package.json +1 -1
- package/package.json +5 -5
- package/src/docx/styles.css +94 -0
- package/dist/ai-IM4A23YT.cjs.map +0 -1
- package/dist/chunk-A3T3IC3K.cjs.map +0 -1
- package/dist/chunk-CIHERNDO.cjs +0 -18
- package/dist/chunk-M6IKVKU5.cjs.map +0 -1
- package/dist/chunk-X5LANJDZ.cjs.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/connection/viewer/useViewerTabs.tsx"],
|
|
4
|
-
"sourcesContent": ["/**\n * Tabs of the document viewer: which tabs a document has, the automatic switches when the\n * document's type or parsed content changes, and switching (which ends a comparison when leaving\n * the tab that hosts it). The open tab is the session state's, so whatever opens a document can\n * open it on a tab.\n */\n\nimport { useEffect, useRef } from 'react'\nimport { Code, FileText, History, MonitorPlay } from 'lucide-react'\nimport { friendlyFileType } from '@arbidocs/react/ui'\nimport {\n AudIcon,\n DocIcon,\n EmlIcon,\n HtmlIcon,\n ImgIcon,\n PdfIcon,\n VidIcon,\n XlsIcon,\n useArbiSessionState,\n useArbiSessionStore,\n type ArbiViewerTab,\n} from '@arbidocs/react'\nimport type { ViewerTab } from '../../files/ViewerParts'\nimport { useIsPhone } from '../../lib/use-media-query'\nimport type { ViewedDocument } from './useViewedDocument'\n\n/**\n * @param hasHistory The document has earlier versions (a signed copy, a re-upload): PDF and text\n * documents then get a Versions tab too. Artifacts and Word documents always have one.\n */\nexport function useViewerTabs(doc: ViewedDocument, isCompact: boolean, hasHistory = false) {\n const {\n documentData,\n isArtifact,\n isDocx,\n isXlsx,\n isEmail,\n isVideo,\n isAudio,\n isImage,\n liveKind,\n hasParsedContent,\n isParsedDocLoading,\n } = doc\n const session = useArbiSessionStore()\n const {\n tab: activeTab,\n compareId,\n tabRequest,\n phonePdfChosen,\n } = useArbiSessionState((s) => s.documentViewer)\n const setActiveTab = (tab: ArbiViewerTab) => session.setDocumentViewer({ tab })\n // A plain-text file is still shown as a generated PDF, but the tab names the file the user\n // opened (\"Text\", as the Fields panel does), not the rendering format.\n const isTextFile = friendlyFileType(documentData?.file_type, documentData?.file_name) === 'Text'\n const isPhone = useIsPhone()\n const phoneDefaultDecidedFor = useRef<string | null>(null)\n\n // Switch to the tab that fits the document type. Only on type changes: never over the user's own\n // choice. Keyed on the document and its kind, not on the record: a refreshed record (a new\n // version finishing processing) must not send a user on the PDF tab of a Word document back to\n // the editor.\n const hasDocumentData = !!documentData\n const documentKey = documentData?.external_id\n useEffect(() => {\n // A Word artifact (an AI draft, stored as .docx) has one Word tab, 'edit', not a DOCX tab.\n if (isArtifact && (activeTab === 'pdf' || (!liveKind && activeTab === 'docx'))) {\n setActiveTab(liveKind ? 'preview' : 'edit')\n } else if (isDocx && activeTab === 'pdf') {\n setActiveTab('docx')\n } else if (!liveKind && activeTab === 'preview') {\n setActiveTab(isArtifact ? 'edit' : 'pdf')\n } else if (!isArtifact && documentData && activeTab === 'edit') {\n setActiveTab(isDocx ? 'docx' : isXlsx ? 'xlsx' : 'pdf')\n } else if (\n !isArtifact &&\n !isDocx &&\n !isXlsx &&\n documentData &&\n (activeTab === 'docx' || activeTab === 'xlsx')\n ) {\n setActiveTab('pdf')\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [hasDocumentData, documentKey, isArtifact, isDocx, isXlsx, liveKind])\n\n // A tab asked for when the document was opened (a signature request opens on the PDF, where it\n // is signed) wins over the type's own tab once that document has loaded, and over the phone's\n // text default. Declared after the type switch above so it has the last word.\n useEffect(() => {\n if (!tabRequest || !documentKey || tabRequest.documentId !== documentKey) return\n phoneDefaultDecidedFor.current = documentKey\n session.setDocumentViewer({ tabRequest: null, tab: tabRequest.tab })\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [documentKey, tabRequest])\n\n // Versions of a PDF or text document exist only with history: leave the tab when there is none\n // (another document opened while it was active).\n const hasVersionsTab = isArtifact || isDocx || hasHistory\n useEffect(() => {\n if (activeTab === 'versions' && documentData && !hasVersionsTab) {\n setActiveTab(isXlsx ? 'xlsx' : 'pdf')\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [activeTab, documentData, hasVersionsTab])\n\n // The text tab exists only with parsed content. When it is open without any (a recording with\n // no transcript, a failed parse), fall back to the natural default once the parsed query\n // settles. Not during a comparison, which uses the text tab. Waits for the record: until it is\n // here the parsed query has not started, so it is not loading yet.\n useEffect(() => {\n if (\n activeTab === 'html' &&\n documentData !== undefined &&\n !isParsedDocLoading &&\n !hasParsedContent &&\n !compareId\n ) {\n setActiveTab(isArtifact ? 'edit' : isDocx ? 'docx' : isXlsx ? 'xlsx' : 'pdf')\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n activeTab,\n documentData,\n isParsedDocLoading,\n hasParsedContent,\n compareId,\n isArtifact,\n isDocx,\n isXlsx,\n ])\n\n // Phones open a document on the readable reflowed (text) view: a fit-width PDF on a 390px\n // screen is footnote-sized. Decided once per document, after the parsed query settles, and only\n // over the PDF default (Word, sheets, artifacts and media keep their own tab). A PDF the user\n // picked by hand this session wins.\n useEffect(() => {\n if (!isPhone || !documentKey || isParsedDocLoading) return\n if (phoneDefaultDecidedFor.current === documentKey) return\n phoneDefaultDecidedFor.current = documentKey\n const opensOnPdf =\n !isArtifact && !isDocx && !isXlsx && !isVideo && !isAudio && !isImage && !isEmail\n if (opensOnPdf && hasParsedContent && !compareId && !phonePdfChosen && activeTab === 'pdf') {\n setActiveTab('html')\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isPhone, documentKey, isParsedDocLoading, hasParsedContent])\n\n const handleTabChange = (tabId: string) => {\n // A comparison is shown on the text tab: leaving it ends the comparison.\n const change: Parameters<typeof session.setDocumentViewer>[0] = { tab: tabId as ArbiViewerTab }\n if (tabId !== 'html' && compareId) change.compareId = null\n // A phone user who goes back to the PDF wants it: stop opening documents on the text view\n // until they pick it again.\n if (isPhone && (tabId === 'pdf' || tabId === 'html')) change.phonePdfChosen = tabId === 'pdf'\n session.setDocumentViewer(change)\n }\n\n const mediaTab = isVideo\n ? { icon: <VidIcon size={20} />, tooltip: 'Video' }\n : isAudio\n ? { icon: <AudIcon size={20} />, tooltip: 'Audio' }\n : isImage\n ? { icon: <ImgIcon size={20} />, tooltip: 'Image' }\n : isEmail\n ? { icon: <EmlIcon size={20} />, tooltip: 'Email' }\n : isTextFile\n ? { icon: <FileText className=\"size-5\" />, tooltip: 'Text' }\n : documentData\n ? { icon: <PdfIcon size={20} />, tooltip: 'PDF' }\n : // The file type is unknown until the record loads: name no guess (a text file\n // would flip from PDF to Text once it arrives).\n { icon: <FileText className=\"size-5\" />, tooltip: 'Document' }\n // Tabs say what they are: in a narrow panel or on a phone only the open tab keeps its name, plus\n // the text view, whose icon is not recognisable. Labelling every tab there would crowd the header.\n const tabLabel = (id: string, label: string) =>\n !isCompact || activeTab === id || id === 'html' ? label : undefined\n\n const versionsTab: ViewerTab = {\n id: 'versions',\n icon: <History className=\"size-5\" />,\n tooltip: 'Versions',\n label: tabLabel('versions', 'Versions'),\n }\n const viewerTabs: ViewerTab[] = [\n ...(isArtifact\n ? [\n ...(liveKind\n ? [\n {\n id: 'preview',\n icon: <MonitorPlay className=\"size-5\" />,\n tooltip: 'Preview',\n label: tabLabel('preview', 'Preview'),\n },\n ]\n : []),\n {\n id: 'edit',\n icon: liveKind ? <Code className=\"size-5\" /> : <FileText className=\"size-5\" />,\n tooltip: liveKind ? 'Code' : 'Editor',\n label: tabLabel('edit', liveKind ? 'Code' : 'Document'),\n },\n versionsTab,\n ]\n : [\n ...(isDocx\n ? [\n {\n id: 'docx',\n icon: <DocIcon size={20} />,\n tooltip: 'DOCX (with track changes & comments)',\n label: tabLabel('docx', 'DOCX'),\n },\n ]\n : []),\n ...(isXlsx\n ? [\n {\n id: 'xlsx',\n icon: <XlsIcon size={20} />,\n tooltip: 'Spreadsheet',\n label: tabLabel('xlsx', 'Sheet'),\n },\n ]\n : []),\n { id: 'pdf', ...mediaTab, label: tabLabel('pdf', mediaTab.tooltip) },\n ...(hasVersionsTab ? [versionsTab] : []),\n ]),\n ...((hasParsedContent || compareId) && !liveKind\n ? [\n {\n id: 'html',\n icon: compareId ? <FileText className=\"size-5\" /> : <HtmlIcon size={20} />,\n tooltip: compareId ? 'Word redline' : 'HTML',\n label: tabLabel('html', compareId ? 'Compare' : 'HTML'),\n },\n ]\n : []),\n ]\n\n return { activeTab, handleTabChange, viewerTabs }\n}\n"],
|
|
5
|
-
"mappings": ";
|
|
4
|
+
"sourcesContent": ["/**\n * Tabs of the document viewer: which tabs a document has, the automatic switches when the\n * document's type or parsed content changes, and switching (which ends a comparison when leaving\n * the tab that hosts it). The open tab is the session state's, so whatever opens a document can\n * open it on a tab.\n */\n\nimport { useEffect, useRef } from 'react'\nimport { Code, FileText, History, MonitorPlay } from 'lucide-react'\nimport { friendlyFileType } from '@arbidocs/react/ui'\nimport {\n AudIcon,\n DocIcon,\n EmlIcon,\n HtmlIcon,\n ImgIcon,\n PdfIcon,\n VidIcon,\n XlsIcon,\n useArbiSessionState,\n useArbiSessionStore,\n type ArbiViewerTab,\n} from '@arbidocs/react'\nimport type { ViewerTab } from '../../files/ViewerParts'\nimport { useIsPhone } from '../../lib/use-media-query'\nimport type { ViewedDocument } from './useViewedDocument'\n\n/**\n * @param hasHistory The document has earlier versions (a signed copy, a re-upload): PDF and text\n * documents then get a Versions tab too. Artifacts and Word documents always have one.\n */\nexport function useViewerTabs(doc: ViewedDocument, isCompact: boolean, hasHistory = false) {\n const {\n documentData,\n isArtifact,\n isDraft,\n isStreaming,\n isDocx,\n isXlsx,\n isEmail,\n isVideo,\n isAudio,\n isImage,\n liveKind,\n hasParsedContent,\n isParsedDocLoading,\n } = doc\n const session = useArbiSessionStore()\n const {\n tab: activeTab,\n compareId,\n tabRequest,\n phonePdfChosen,\n } = useArbiSessionState((s) => s.documentViewer)\n const setActiveTab = (tab: ArbiViewerTab) => session.setDocumentViewer({ tab })\n // A plain-text file is still shown as a generated PDF, but the tab names the file the user\n // opened (\"Text\", as the Fields panel does), not the rendering format.\n const isTextFile = friendlyFileType(documentData?.file_type, documentData?.file_name) === 'Text'\n const isPhone = useIsPhone()\n const phoneDefaultDecidedFor = useRef<string | null>(null)\n\n // Switch to the tab that fits the document type. Only on type changes: never over the user's own\n // choice. Keyed on the document and its kind, not on the record: a refreshed record (a new\n // version finishing processing) must not send a user on the PDF tab of a Word document back to\n // the editor.\n const hasDocumentData = !!documentData\n const documentKey = documentData?.external_id\n useEffect(() => {\n // A Word artifact (an AI draft, stored as .docx) has one Word tab, 'edit', not a DOCX tab.\n if (isArtifact && (activeTab === 'pdf' || (!liveKind && activeTab === 'docx'))) {\n setActiveTab(liveKind ? 'preview' : 'edit')\n } else if (isDocx && activeTab === 'pdf') {\n setActiveTab('docx')\n } else if (!liveKind && activeTab === 'preview') {\n setActiveTab(isArtifact ? 'edit' : 'pdf')\n } else if (!isArtifact && documentData && activeTab === 'edit') {\n setActiveTab(isDocx ? 'docx' : isXlsx ? 'xlsx' : 'pdf')\n } else if (\n !isArtifact &&\n !isDocx &&\n !isXlsx &&\n documentData &&\n (activeTab === 'docx' || activeTab === 'xlsx')\n ) {\n setActiveTab('pdf')\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [hasDocumentData, documentKey, isArtifact, isDocx, isXlsx, liveKind])\n\n // A tab asked for when the document was opened (a signature request opens on the PDF, where it\n // is signed) wins over the type's own tab once that document has loaded, and over the phone's\n // text default. Declared after the type switch above so it has the last word.\n useEffect(() => {\n if (!tabRequest || !documentKey || tabRequest.documentId !== documentKey) return\n phoneDefaultDecidedFor.current = documentKey\n session.setDocumentViewer({ tabRequest: null, tab: tabRequest.tab })\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [documentKey, tabRequest])\n\n // Versions of a PDF or text document exist only with history: leave the tab when there is none\n // (another document opened while it was active).\n const hasVersionsTab = isArtifact || isDocx || hasHistory\n useEffect(() => {\n if (activeTab === 'versions' && documentData && !hasVersionsTab) {\n setActiveTab(isXlsx ? 'xlsx' : 'pdf')\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [activeTab, documentData, hasVersionsTab])\n\n // The text tab exists only with parsed content. When it is open without any (a recording with\n // no transcript, a failed parse), fall back to the natural default once the parsed query\n // settles. Not during a comparison, which uses the text tab. Waits for the record: until it is\n // here the parsed query has not started, so it is not loading yet.\n useEffect(() => {\n if (\n activeTab === 'html' &&\n documentData !== undefined &&\n !isParsedDocLoading &&\n !hasParsedContent &&\n !compareId\n ) {\n setActiveTab(isArtifact ? 'edit' : isDocx ? 'docx' : isXlsx ? 'xlsx' : 'pdf')\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n activeTab,\n documentData,\n isParsedDocLoading,\n hasParsedContent,\n compareId,\n isArtifact,\n isDocx,\n isXlsx,\n ])\n\n // Phones open a document on the readable reflowed (text) view: a fit-width PDF on a 390px\n // screen is footnote-sized. Decided once per document, after the parsed query settles, and only\n // over the PDF default (Word, sheets, artifacts and media keep their own tab). A PDF the user\n // picked by hand this session wins.\n useEffect(() => {\n if (!isPhone || !documentKey || isParsedDocLoading) return\n if (phoneDefaultDecidedFor.current === documentKey) return\n phoneDefaultDecidedFor.current = documentKey\n const opensOnPdf =\n !isArtifact && !isDocx && !isXlsx && !isVideo && !isAudio && !isImage && !isEmail\n if (opensOnPdf && hasParsedContent && !compareId && !phonePdfChosen && activeTab === 'pdf') {\n setActiveTab('html')\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isPhone, documentKey, isParsedDocLoading, hasParsedContent])\n\n const handleTabChange = (tabId: string) => {\n // A comparison is shown on the text tab: leaving it ends the comparison.\n const change: Parameters<typeof session.setDocumentViewer>[0] = { tab: tabId as ArbiViewerTab }\n if (tabId !== 'html' && compareId) change.compareId = null\n // A phone user who goes back to the PDF wants it: stop opening documents on the text view\n // until they pick it again.\n if (isPhone && (tabId === 'pdf' || tabId === 'html')) change.phonePdfChosen = tabId === 'pdf'\n session.setDocumentViewer(change)\n }\n\n const mediaTab = isVideo\n ? { icon: <VidIcon size={20} />, tooltip: 'Video' }\n : isAudio\n ? { icon: <AudIcon size={20} />, tooltip: 'Audio' }\n : isImage\n ? { icon: <ImgIcon size={20} />, tooltip: 'Image' }\n : isEmail\n ? { icon: <EmlIcon size={20} />, tooltip: 'Email' }\n : isTextFile\n ? { icon: <FileText className=\"size-5\" />, tooltip: 'Text' }\n : documentData\n ? { icon: <PdfIcon size={20} />, tooltip: 'PDF' }\n : // The file type is unknown until the record loads: name no guess (a text file\n // would flip from PDF to Text once it arrives).\n { icon: <FileText className=\"size-5\" />, tooltip: 'Document' }\n // Tabs say what they are: in a narrow panel or on a phone only the open tab keeps its name, plus\n // the text view, whose icon is not recognisable. Labelling every tab there would crowd the header.\n const tabLabel = (id: string, label: string) =>\n !isCompact || activeTab === id || id === 'html' ? label : undefined\n\n const versionsTab: ViewerTab = {\n id: 'versions',\n icon: <History className=\"size-5\" />,\n tooltip: 'Versions',\n label: tabLabel('versions', 'Versions'),\n }\n const viewerTabs: ViewerTab[] = [\n ...(isArtifact\n ? [\n ...(liveKind\n ? [\n {\n id: 'preview',\n icon: <MonitorPlay className=\"size-5\" />,\n tooltip: 'Preview',\n label: tabLabel('preview', 'Preview'),\n },\n ]\n : []),\n {\n id: 'edit',\n icon: liveKind ? <Code className=\"size-5\" /> : <FileText className=\"size-5\" />,\n tooltip: liveKind ? 'Code' : 'Editor',\n label: tabLabel('edit', liveKind ? 'Code' : 'Document'),\n },\n ...(!liveKind && !isDraft && !isStreaming && isDocx\n ? [\n {\n id: 'pdf',\n icon: <PdfIcon size={20} />,\n tooltip: 'PDF',\n label: tabLabel('pdf', 'PDF'),\n },\n ]\n : []),\n versionsTab,\n ]\n : [\n ...(isDocx\n ? [\n {\n id: 'docx',\n icon: <DocIcon size={20} />,\n tooltip: 'DOCX (with track changes & comments)',\n label: tabLabel('docx', 'DOCX'),\n },\n ]\n : []),\n ...(isXlsx\n ? [\n {\n id: 'xlsx',\n icon: <XlsIcon size={20} />,\n tooltip: 'Spreadsheet',\n label: tabLabel('xlsx', 'Sheet'),\n },\n ]\n : []),\n { id: 'pdf', ...mediaTab, label: tabLabel('pdf', mediaTab.tooltip) },\n ...(hasVersionsTab ? [versionsTab] : []),\n ]),\n ...((hasParsedContent || compareId) && !liveKind\n ? [\n {\n id: 'html',\n icon: compareId ? <FileText className=\"size-5\" /> : <HtmlIcon size={20} />,\n tooltip: compareId ? 'Word redline' : 'HTML',\n label: tabLabel('html', compareId ? 'Compare' : 'HTML'),\n },\n ]\n : []),\n ]\n\n return { activeTab, handleTabChange, viewerTabs }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -10,8 +10,8 @@ require('../chunk-ZU2B2RZK.cjs');
|
|
|
10
10
|
var chunkNSD37OF5_cjs = require('../chunk-NSD37OF5.cjs');
|
|
11
11
|
var chunkOEJQFPWO_cjs = require('../chunk-OEJQFPWO.cjs');
|
|
12
12
|
require('../chunk-JV5TVUOU.cjs');
|
|
13
|
-
var chunkZW6FPIFC_cjs = require('../chunk-ZW6FPIFC.cjs');
|
|
14
13
|
require('../chunk-IPSHAMO2.cjs');
|
|
14
|
+
var chunkZW6FPIFC_cjs = require('../chunk-ZW6FPIFC.cjs');
|
|
15
15
|
var chunkTKHCIHE2_cjs = require('../chunk-TKHCIHE2.cjs');
|
|
16
16
|
require('../chunk-JDFBEGQO.cjs');
|
|
17
17
|
require('../chunk-ULWRNGGE.cjs');
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { type DocxImageGeneration } from './layout/GenerateImage';
|
|
3
|
+
/** One editing menu, with named categories and the existing editor commands. */
|
|
4
|
+
export declare function DocxCommandMenu({ onSave, badge, imageGeneration, }: {
|
|
5
|
+
onSave: () => void;
|
|
6
|
+
badge?: React.ReactNode;
|
|
7
|
+
imageGeneration?: DocxImageGeneration;
|
|
8
|
+
}): React.JSX.Element;
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import { DocxEditor, useChromeTranslate } from "@docx-editor.dev/react";
|
|
5
|
+
import {
|
|
6
|
+
BookA,
|
|
7
|
+
ChevronDown,
|
|
8
|
+
FilePenLine,
|
|
9
|
+
Home,
|
|
10
|
+
Image,
|
|
11
|
+
LayoutGrid,
|
|
12
|
+
ListChecks,
|
|
13
|
+
Menu,
|
|
14
|
+
Plus,
|
|
15
|
+
Table,
|
|
16
|
+
UsersRound
|
|
17
|
+
} from "lucide-react";
|
|
18
|
+
import { useDefinedTerms } from "./definitions/DefinedTerms.js";
|
|
19
|
+
import { RibbonMenu } from "./RibbonMenu.js";
|
|
20
|
+
import { NamedCommandList, RibbonItem } from "./RibbonOverflow.js";
|
|
21
|
+
import { StyleGallery } from "./StyleGallery.js";
|
|
22
|
+
import { NoteButtons } from "./WordReferences.js";
|
|
23
|
+
import { CrossReferenceButton, UpdateCrossReferencesButton } from "./references/EditorMenus.js";
|
|
24
|
+
import { LayoutTabContent, LAYOUT_TAB, useContextualTabs } from "./layout/LayoutTabs.js";
|
|
25
|
+
import {
|
|
26
|
+
GenerateImageButton,
|
|
27
|
+
useGenerateImageTarget
|
|
28
|
+
} from "./layout/GenerateImage.js";
|
|
29
|
+
import { QuickParts } from "./template/QuickParts.js";
|
|
30
|
+
import { HouseTemplatePanel } from "./template/HouseTemplatePanel.js";
|
|
31
|
+
import { MySignatureMenu, SignatureFieldMenu } from "./signatures/SignatureFields.js";
|
|
32
|
+
function DefinedTermButton() {
|
|
33
|
+
const terms = useDefinedTerms();
|
|
34
|
+
if (!terms) return null;
|
|
35
|
+
return /* @__PURE__ */ jsx(
|
|
36
|
+
"button",
|
|
37
|
+
{
|
|
38
|
+
type: "button",
|
|
39
|
+
className: "native-docx-ribbon-trigger",
|
|
40
|
+
"aria-label": terms.labels.insert,
|
|
41
|
+
title: `${terms.labels.insert} (type @@)`,
|
|
42
|
+
"data-testid": "docx-insert-defined-term",
|
|
43
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
44
|
+
onClick: (event) => terms.openPicker(event.currentTarget),
|
|
45
|
+
children: /* @__PURE__ */ jsx(BookA, { size: 16 })
|
|
46
|
+
}
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
const categories = [
|
|
50
|
+
{ name: "Home", icon: Home },
|
|
51
|
+
{ name: "Insert", icon: Plus },
|
|
52
|
+
{ name: "Design", icon: FilePenLine },
|
|
53
|
+
{ name: LAYOUT_TAB, icon: LayoutGrid },
|
|
54
|
+
{ name: "References", icon: BookA },
|
|
55
|
+
{ name: "Review", icon: ListChecks }
|
|
56
|
+
];
|
|
57
|
+
function DocxCommandMenu({
|
|
58
|
+
onSave,
|
|
59
|
+
badge,
|
|
60
|
+
imageGeneration
|
|
61
|
+
}) {
|
|
62
|
+
const [selected, setSelected] = useState("Home");
|
|
63
|
+
const contextual = useContextualTabs(selected);
|
|
64
|
+
const tab = contextual.shown;
|
|
65
|
+
const t = useChromeTranslate();
|
|
66
|
+
useGenerateImageTarget();
|
|
67
|
+
const allCategories = [
|
|
68
|
+
...categories,
|
|
69
|
+
...contextual.tabs.map((name) => ({ name, icon: name === "Table" ? Table : Image }))
|
|
70
|
+
];
|
|
71
|
+
return /* @__PURE__ */ jsxs("div", { className: "native-docx-ribbon native-docx-command-menu", children: [
|
|
72
|
+
/* @__PURE__ */ jsxs(DocxEditor.Toolbar, { t, preset: false, onSave, children: [
|
|
73
|
+
/* @__PURE__ */ jsx(
|
|
74
|
+
RibbonMenu,
|
|
75
|
+
{
|
|
76
|
+
label: "Editing tools",
|
|
77
|
+
icon: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
78
|
+
/* @__PURE__ */ jsx(Menu, { size: 16 }),
|
|
79
|
+
/* @__PURE__ */ jsx("span", { children: "Editing tools" }),
|
|
80
|
+
/* @__PURE__ */ jsx(ChevronDown, { size: 14 })
|
|
81
|
+
] }),
|
|
82
|
+
className: "native-docx-command-trigger",
|
|
83
|
+
popoverClassName: "native-docx-command-panel",
|
|
84
|
+
keepMounted: true,
|
|
85
|
+
restoreFocus: true,
|
|
86
|
+
children: (close) => /* @__PURE__ */ jsxs("div", { className: "native-docx-command-layout", children: [
|
|
87
|
+
/* @__PURE__ */ jsx("nav", { className: "native-docx-command-categories", "aria-label": "Editing tool categories", children: allCategories.map(({ name, icon: Icon }) => /* @__PURE__ */ jsxs(
|
|
88
|
+
"button",
|
|
89
|
+
{
|
|
90
|
+
type: "button",
|
|
91
|
+
"aria-pressed": tab === name,
|
|
92
|
+
onClick: () => setSelected(name),
|
|
93
|
+
children: [
|
|
94
|
+
/* @__PURE__ */ jsx(Icon, { size: 16, "aria-hidden": "true" }),
|
|
95
|
+
/* @__PURE__ */ jsx("span", { children: name })
|
|
96
|
+
]
|
|
97
|
+
},
|
|
98
|
+
name
|
|
99
|
+
)) }),
|
|
100
|
+
/* @__PURE__ */ jsx(
|
|
101
|
+
"div",
|
|
102
|
+
{
|
|
103
|
+
className: "native-docx-command-list",
|
|
104
|
+
role: "group",
|
|
105
|
+
"aria-label": `${tab} commands`,
|
|
106
|
+
onClick: (event) => {
|
|
107
|
+
const target = event.target;
|
|
108
|
+
const button = target.closest("button");
|
|
109
|
+
const item = target.closest("[data-ribbon-item]")?.dataset.ribbonItem;
|
|
110
|
+
const direct = /* @__PURE__ */ new Set([
|
|
111
|
+
"home-undo",
|
|
112
|
+
"home-redo",
|
|
113
|
+
"home-save",
|
|
114
|
+
"home-bold",
|
|
115
|
+
"home-italic",
|
|
116
|
+
"home-underline",
|
|
117
|
+
"home-bullets",
|
|
118
|
+
"home-numbers",
|
|
119
|
+
"home-indent",
|
|
120
|
+
"home-outdent",
|
|
121
|
+
"home-strike",
|
|
122
|
+
"home-clear",
|
|
123
|
+
"references-footnote",
|
|
124
|
+
"references-endnote",
|
|
125
|
+
"references-update-cross-references",
|
|
126
|
+
"table-row-above",
|
|
127
|
+
"table-row-below",
|
|
128
|
+
"table-column-left",
|
|
129
|
+
"table-column-right"
|
|
130
|
+
]);
|
|
131
|
+
if ((!button || !button.disabled) && target.closest('[aria-disabled="true"]') === null && (button && item && direct.has(item) || target.closest('[role="gridcell"]') || target.closest('[role="menuitemradio"]') || target.closest('[data-testid="docx-insert-my-signature"]') || target.closest('[data-testid="docx-insert-my-initials"]') || target.closest('.native-docx-style-gallery [role="option"]') || button && button.closest(".native-docx-style-gallery"))) {
|
|
132
|
+
close();
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
children: /* @__PURE__ */ jsxs(NamedCommandList, { children: [
|
|
136
|
+
tab === "Home" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
137
|
+
/* @__PURE__ */ jsx(RibbonItem, { id: "home-undo", label: "Undo", children: /* @__PURE__ */ jsx(DocxEditor.Toolbar.Undo, {}) }),
|
|
138
|
+
/* @__PURE__ */ jsx(RibbonItem, { id: "home-redo", label: "Redo", children: /* @__PURE__ */ jsx(DocxEditor.Toolbar.Redo, {}) }),
|
|
139
|
+
/* @__PURE__ */ jsx(RibbonItem, { id: "home-save", label: "Save", children: /* @__PURE__ */ jsx(DocxEditor.Toolbar.Save, {}) }),
|
|
140
|
+
/* @__PURE__ */ jsx(RibbonItem, { id: "home-style", label: "Styles", children: /* @__PURE__ */ jsx(StyleGallery, {}) }),
|
|
141
|
+
/* @__PURE__ */ jsx(RibbonItem, { id: "home-bold", label: "Bold", children: /* @__PURE__ */ jsx(DocxEditor.Toolbar.Bold, {}) }),
|
|
142
|
+
/* @__PURE__ */ jsx(RibbonItem, { id: "home-italic", label: "Italic", children: /* @__PURE__ */ jsx(DocxEditor.Toolbar.Italic, {}) }),
|
|
143
|
+
/* @__PURE__ */ jsx(RibbonItem, { id: "home-underline", label: "Underline", children: /* @__PURE__ */ jsx(DocxEditor.Toolbar.Underline, {}) }),
|
|
144
|
+
/* @__PURE__ */ jsx(RibbonItem, { id: "home-font-family", label: "Font family", children: /* @__PURE__ */ jsx(DocxEditor.Toolbar.FontFamily, {}) }),
|
|
145
|
+
/* @__PURE__ */ jsx(RibbonItem, { id: "home-font-size", label: "Font size", children: /* @__PURE__ */ jsx(DocxEditor.Toolbar.FontSize, {}) }),
|
|
146
|
+
/* @__PURE__ */ jsx(RibbonItem, { id: "home-font-color", label: "Font color", children: /* @__PURE__ */ jsx(DocxEditor.Toolbar.FontColor, {}) }),
|
|
147
|
+
/* @__PURE__ */ jsx(RibbonItem, { id: "home-highlight", label: "Highlight", children: /* @__PURE__ */ jsx(DocxEditor.Toolbar.Highlight, {}) }),
|
|
148
|
+
/* @__PURE__ */ jsx(RibbonItem, { id: "home-alignment", label: "Alignment", children: /* @__PURE__ */ jsx(DocxEditor.Toolbar.Alignment, {}) }),
|
|
149
|
+
/* @__PURE__ */ jsx(RibbonItem, { id: "home-bullets", label: "Bulleted list", children: /* @__PURE__ */ jsx(DocxEditor.Toolbar.BulletList, {}) }),
|
|
150
|
+
/* @__PURE__ */ jsx(RibbonItem, { id: "home-numbers", label: "Numbered list", children: /* @__PURE__ */ jsx(DocxEditor.Toolbar.NumberedList, {}) }),
|
|
151
|
+
/* @__PURE__ */ jsx(RibbonItem, { id: "home-line-spacing", label: "Line spacing", children: /* @__PURE__ */ jsx(DocxEditor.Toolbar.LineSpacing, {}) }),
|
|
152
|
+
/* @__PURE__ */ jsx(RibbonItem, { id: "home-indent", label: "Increase indent", children: /* @__PURE__ */ jsx(DocxEditor.Toolbar.Indent, {}) }),
|
|
153
|
+
/* @__PURE__ */ jsx(RibbonItem, { id: "home-outdent", label: "Decrease indent", children: /* @__PURE__ */ jsx(DocxEditor.Toolbar.Outdent, {}) }),
|
|
154
|
+
/* @__PURE__ */ jsx(RibbonItem, { id: "home-strike", label: "Strikethrough", children: /* @__PURE__ */ jsx(DocxEditor.Toolbar.Strike, {}) }),
|
|
155
|
+
/* @__PURE__ */ jsx(RibbonItem, { id: "home-clear", label: "Clear formatting", children: /* @__PURE__ */ jsx(DocxEditor.Toolbar.ClearFormatting, {}) })
|
|
156
|
+
] }),
|
|
157
|
+
tab === "Insert" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
158
|
+
/* @__PURE__ */ jsx(RibbonItem, { id: "insert-table", label: "Table", children: /* @__PURE__ */ jsx(DocxEditor.Toolbar.TableInsert, {}) }),
|
|
159
|
+
/* @__PURE__ */ jsx(RibbonItem, { id: "insert-picture", label: "Picture", children: /* @__PURE__ */ jsx(DocxEditor.Toolbar.ImageInsert, {}) }),
|
|
160
|
+
imageGeneration && /* @__PURE__ */ jsx(RibbonItem, { id: "insert-generate-image", label: "Generate image", children: /* @__PURE__ */ jsx(GenerateImageButton, { generation: imageGeneration }) }),
|
|
161
|
+
/* @__PURE__ */ jsx(RibbonItem, { id: "insert-page-break", label: "Page break", children: /* @__PURE__ */ jsx(DocxEditor.Toolbar.Button, { slotId: "insert.pageBreak" }) }),
|
|
162
|
+
/* @__PURE__ */ jsx(RibbonItem, { id: "insert-link", label: "Link", children: /* @__PURE__ */ jsx(DocxEditor.Toolbar.Link, {}) }),
|
|
163
|
+
/* @__PURE__ */ jsx(RibbonItem, { id: "insert-defined-term", label: "Defined term", children: /* @__PURE__ */ jsx(DefinedTermButton, {}) }),
|
|
164
|
+
/* @__PURE__ */ jsx(RibbonItem, { id: "insert-quick-parts", label: "Quick Parts", children: /* @__PURE__ */ jsx(QuickParts, {}) }),
|
|
165
|
+
/* @__PURE__ */ jsx(RibbonItem, { id: "insert-signature-field", label: "Signature field", children: /* @__PURE__ */ jsx(SignatureFieldMenu, { onInserted: close }) }),
|
|
166
|
+
/* @__PURE__ */ jsx(RibbonItem, { id: "insert-my-signature", label: "My signature", children: /* @__PURE__ */ jsx(MySignatureMenu, {}) }),
|
|
167
|
+
/* @__PURE__ */ jsx(RibbonItem, { id: "insert-cross-reference", label: "Cross-reference", children: /* @__PURE__ */ jsx(CrossReferenceButton, {}) })
|
|
168
|
+
] }),
|
|
169
|
+
/* @__PURE__ */ jsx(LayoutTabContent, { tab }),
|
|
170
|
+
tab === "Design" && /* @__PURE__ */ jsx(RibbonItem, { id: "design-house-template", label: "House template", children: /* @__PURE__ */ jsx(HouseTemplatePanel, {}) }),
|
|
171
|
+
tab === "References" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
172
|
+
/* @__PURE__ */ jsx(NoteButtons, {}),
|
|
173
|
+
/* @__PURE__ */ jsx(RibbonItem, { id: "references-cross-reference", label: "Cross-reference", children: /* @__PURE__ */ jsx(CrossReferenceButton, {}) }),
|
|
174
|
+
/* @__PURE__ */ jsx(
|
|
175
|
+
RibbonItem,
|
|
176
|
+
{
|
|
177
|
+
id: "references-update-cross-references",
|
|
178
|
+
label: "Update cross-references",
|
|
179
|
+
children: /* @__PURE__ */ jsx(UpdateCrossReferencesButton, {})
|
|
180
|
+
}
|
|
181
|
+
)
|
|
182
|
+
] }),
|
|
183
|
+
tab === "Review" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
184
|
+
/* @__PURE__ */ jsx(RibbonItem, { id: "review-editing-mode", label: "Editing mode", children: /* @__PURE__ */ jsx(DocxEditor.Toolbar.EditingMode, {}) }),
|
|
185
|
+
/* @__PURE__ */ jsx(RibbonItem, { id: "review-comments", label: "Comments", children: /* @__PURE__ */ jsx(DocxEditor.Toolbar.Comments, {}) }),
|
|
186
|
+
/* @__PURE__ */ jsx(RibbonItem, { id: "review-options", label: "Review options", children: /* @__PURE__ */ jsx(RibbonMenu, { label: "Review options", icon: /* @__PURE__ */ jsx(UsersRound, { size: 16 }), children: /* @__PURE__ */ jsx(DocxEditor.Toolbar.Reviewers, {}) }) })
|
|
187
|
+
] })
|
|
188
|
+
] })
|
|
189
|
+
}
|
|
190
|
+
)
|
|
191
|
+
] })
|
|
192
|
+
}
|
|
193
|
+
),
|
|
194
|
+
/* @__PURE__ */ jsx(DocxEditor.Toolbar.TableCellFill, { hidden: true })
|
|
195
|
+
] }),
|
|
196
|
+
badge && /* @__PURE__ */ jsx("span", { className: "native-docx-ribbon-badge", "data-testid": "docx-ribbon-badge", children: badge })
|
|
197
|
+
] });
|
|
198
|
+
}
|
|
199
|
+
export {
|
|
200
|
+
DocxCommandMenu
|
|
201
|
+
};
|
|
202
|
+
//# sourceMappingURL=DocxCommandMenu.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/docx/DocxCommandMenu.tsx"],
|
|
4
|
+
"sourcesContent": ["import React, { useState } from 'react'\nimport { DocxEditor, useChromeTranslate } from '@docx-editor.dev/react'\nimport {\n BookA,\n ChevronDown,\n FilePenLine,\n Home,\n Image,\n LayoutGrid,\n ListChecks,\n Menu,\n Plus,\n Table,\n UsersRound,\n} from 'lucide-react'\nimport { useDefinedTerms } from './definitions/DefinedTerms'\nimport { RibbonMenu } from './RibbonMenu'\nimport { NamedCommandList, RibbonItem } from './RibbonOverflow'\nimport { StyleGallery } from './StyleGallery'\nimport { NoteButtons } from './WordReferences'\nimport { CrossReferenceButton, UpdateCrossReferencesButton } from './references/EditorMenus'\nimport { LayoutTabContent, LAYOUT_TAB, useContextualTabs } from './layout/LayoutTabs'\nimport {\n GenerateImageButton,\n useGenerateImageTarget,\n type DocxImageGeneration,\n} from './layout/GenerateImage'\nimport { QuickParts } from './template/QuickParts'\nimport { HouseTemplatePanel } from './template/HouseTemplatePanel'\nimport { MySignatureMenu, SignatureFieldMenu } from './signatures/SignatureFields'\n\nfunction DefinedTermButton() {\n const terms = useDefinedTerms()\n if (!terms) return null\n return (\n <button\n type=\"button\"\n className=\"native-docx-ribbon-trigger\"\n aria-label={terms.labels.insert}\n title={`${terms.labels.insert} (type @@)`}\n data-testid=\"docx-insert-defined-term\"\n onMouseDown={(event) => event.preventDefault()}\n onClick={(event) => terms.openPicker(event.currentTarget)}\n >\n <BookA size={16} />\n </button>\n )\n}\n\nconst categories = [\n { name: 'Home', icon: Home },\n { name: 'Insert', icon: Plus },\n { name: 'Design', icon: FilePenLine },\n { name: LAYOUT_TAB, icon: LayoutGrid },\n { name: 'References', icon: BookA },\n { name: 'Review', icon: ListChecks },\n] as const\n\n/** One editing menu, with named categories and the existing editor commands. */\nexport function DocxCommandMenu({\n onSave,\n badge,\n imageGeneration,\n}: {\n onSave: () => void\n badge?: React.ReactNode\n imageGeneration?: DocxImageGeneration\n}) {\n const [selected, setSelected] = useState('Home')\n const contextual = useContextualTabs(selected)\n const tab = contextual.shown\n const t = useChromeTranslate()\n useGenerateImageTarget()\n const allCategories = [\n ...categories,\n ...contextual.tabs.map((name) => ({ name, icon: name === 'Table' ? Table : Image })),\n ]\n return (\n <div className=\"native-docx-ribbon native-docx-command-menu\">\n <DocxEditor.Toolbar t={t} preset={false} onSave={onSave}>\n <RibbonMenu\n label=\"Editing tools\"\n icon={\n <>\n <Menu size={16} />\n <span>Editing tools</span>\n <ChevronDown size={14} />\n </>\n }\n className=\"native-docx-command-trigger\"\n popoverClassName=\"native-docx-command-panel\"\n keepMounted\n restoreFocus\n >\n {(close) => (\n <div className=\"native-docx-command-layout\">\n <nav className=\"native-docx-command-categories\" aria-label=\"Editing tool categories\">\n {allCategories.map(({ name, icon: Icon }) => (\n <button\n type=\"button\"\n key={name}\n aria-pressed={tab === name}\n onClick={() => setSelected(name)}\n >\n <Icon size={16} aria-hidden=\"true\" />\n <span>{name}</span>\n </button>\n ))}\n </nav>\n <div\n className=\"native-docx-command-list\"\n role=\"group\"\n aria-label={`${tab} commands`}\n onClick={(event) => {\n const target = event.target as HTMLElement\n const button = target.closest<HTMLButtonElement>('button')\n const item = target.closest<HTMLElement>('[data-ribbon-item]')?.dataset.ribbonItem\n const direct = new Set([\n 'home-undo',\n 'home-redo',\n 'home-save',\n 'home-bold',\n 'home-italic',\n 'home-underline',\n 'home-bullets',\n 'home-numbers',\n 'home-indent',\n 'home-outdent',\n 'home-strike',\n 'home-clear',\n 'references-footnote',\n 'references-endnote',\n 'references-update-cross-references',\n 'table-row-above',\n 'table-row-below',\n 'table-column-left',\n 'table-column-right',\n ])\n if (\n (!button || !button.disabled) &&\n target.closest('[aria-disabled=\"true\"]') === null &&\n ((button && item && direct.has(item)) ||\n target.closest('[role=\"gridcell\"]') ||\n target.closest('[role=\"menuitemradio\"]') ||\n target.closest('[data-testid=\"docx-insert-my-signature\"]') ||\n target.closest('[data-testid=\"docx-insert-my-initials\"]') ||\n target.closest('.native-docx-style-gallery [role=\"option\"]') ||\n (button && button.closest('.native-docx-style-gallery')))\n ) {\n close()\n }\n }}\n >\n <NamedCommandList>\n {tab === 'Home' && (\n <>\n <RibbonItem id=\"home-undo\" label=\"Undo\">\n <DocxEditor.Toolbar.Undo />\n </RibbonItem>\n <RibbonItem id=\"home-redo\" label=\"Redo\">\n <DocxEditor.Toolbar.Redo />\n </RibbonItem>\n <RibbonItem id=\"home-save\" label=\"Save\">\n <DocxEditor.Toolbar.Save />\n </RibbonItem>\n <RibbonItem id=\"home-style\" label=\"Styles\">\n <StyleGallery />\n </RibbonItem>\n <RibbonItem id=\"home-bold\" label=\"Bold\">\n <DocxEditor.Toolbar.Bold />\n </RibbonItem>\n <RibbonItem id=\"home-italic\" label=\"Italic\">\n <DocxEditor.Toolbar.Italic />\n </RibbonItem>\n <RibbonItem id=\"home-underline\" label=\"Underline\">\n <DocxEditor.Toolbar.Underline />\n </RibbonItem>\n <RibbonItem id=\"home-font-family\" label=\"Font family\">\n <DocxEditor.Toolbar.FontFamily />\n </RibbonItem>\n <RibbonItem id=\"home-font-size\" label=\"Font size\">\n <DocxEditor.Toolbar.FontSize />\n </RibbonItem>\n <RibbonItem id=\"home-font-color\" label=\"Font color\">\n <DocxEditor.Toolbar.FontColor />\n </RibbonItem>\n <RibbonItem id=\"home-highlight\" label=\"Highlight\">\n <DocxEditor.Toolbar.Highlight />\n </RibbonItem>\n <RibbonItem id=\"home-alignment\" label=\"Alignment\">\n <DocxEditor.Toolbar.Alignment />\n </RibbonItem>\n <RibbonItem id=\"home-bullets\" label=\"Bulleted list\">\n <DocxEditor.Toolbar.BulletList />\n </RibbonItem>\n <RibbonItem id=\"home-numbers\" label=\"Numbered list\">\n <DocxEditor.Toolbar.NumberedList />\n </RibbonItem>\n <RibbonItem id=\"home-line-spacing\" label=\"Line spacing\">\n <DocxEditor.Toolbar.LineSpacing />\n </RibbonItem>\n <RibbonItem id=\"home-indent\" label=\"Increase indent\">\n <DocxEditor.Toolbar.Indent />\n </RibbonItem>\n <RibbonItem id=\"home-outdent\" label=\"Decrease indent\">\n <DocxEditor.Toolbar.Outdent />\n </RibbonItem>\n <RibbonItem id=\"home-strike\" label=\"Strikethrough\">\n <DocxEditor.Toolbar.Strike />\n </RibbonItem>\n <RibbonItem id=\"home-clear\" label=\"Clear formatting\">\n <DocxEditor.Toolbar.ClearFormatting />\n </RibbonItem>\n </>\n )}\n {tab === 'Insert' && (\n <>\n <RibbonItem id=\"insert-table\" label=\"Table\">\n <DocxEditor.Toolbar.TableInsert />\n </RibbonItem>\n <RibbonItem id=\"insert-picture\" label=\"Picture\">\n <DocxEditor.Toolbar.ImageInsert />\n </RibbonItem>\n {imageGeneration && (\n <RibbonItem id=\"insert-generate-image\" label=\"Generate image\">\n <GenerateImageButton generation={imageGeneration} />\n </RibbonItem>\n )}\n <RibbonItem id=\"insert-page-break\" label=\"Page break\">\n <DocxEditor.Toolbar.Button slotId=\"insert.pageBreak\" />\n </RibbonItem>\n <RibbonItem id=\"insert-link\" label=\"Link\">\n <DocxEditor.Toolbar.Link />\n </RibbonItem>\n <RibbonItem id=\"insert-defined-term\" label=\"Defined term\">\n <DefinedTermButton />\n </RibbonItem>\n <RibbonItem id=\"insert-quick-parts\" label=\"Quick Parts\">\n <QuickParts />\n </RibbonItem>\n <RibbonItem id=\"insert-signature-field\" label=\"Signature field\">\n <SignatureFieldMenu onInserted={close} />\n </RibbonItem>\n <RibbonItem id=\"insert-my-signature\" label=\"My signature\">\n <MySignatureMenu />\n </RibbonItem>\n <RibbonItem id=\"insert-cross-reference\" label=\"Cross-reference\">\n <CrossReferenceButton />\n </RibbonItem>\n </>\n )}\n <LayoutTabContent tab={tab} />\n {tab === 'Design' && (\n <RibbonItem id=\"design-house-template\" label=\"House template\">\n <HouseTemplatePanel />\n </RibbonItem>\n )}\n {tab === 'References' && (\n <>\n <NoteButtons />\n <RibbonItem id=\"references-cross-reference\" label=\"Cross-reference\">\n <CrossReferenceButton />\n </RibbonItem>\n <RibbonItem\n id=\"references-update-cross-references\"\n label=\"Update cross-references\"\n >\n <UpdateCrossReferencesButton />\n </RibbonItem>\n </>\n )}\n {tab === 'Review' && (\n <>\n <RibbonItem id=\"review-editing-mode\" label=\"Editing mode\">\n <DocxEditor.Toolbar.EditingMode />\n </RibbonItem>\n <RibbonItem id=\"review-comments\" label=\"Comments\">\n <DocxEditor.Toolbar.Comments />\n </RibbonItem>\n <RibbonItem id=\"review-options\" label=\"Review options\">\n <RibbonMenu label=\"Review options\" icon={<UsersRound size={16} />}>\n <DocxEditor.Toolbar.Reviewers />\n </RibbonMenu>\n </RibbonItem>\n </>\n )}\n </NamedCommandList>\n </div>\n </div>\n )}\n </RibbonMenu>\n <DocxEditor.Toolbar.TableCellFill hidden />\n </DocxEditor.Toolbar>\n {badge && (\n <span className=\"native-docx-ribbon-badge\" data-testid=\"docx-ribbon-badge\">\n {badge}\n </span>\n )}\n </div>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -35,7 +35,7 @@ export interface NativeDocxAdapter {
|
|
|
35
35
|
author?: string;
|
|
36
36
|
subscribeTokenChanges?: (listener: () => void) => () => void;
|
|
37
37
|
onDirtyChange?: (dirty: boolean) => void;
|
|
38
|
-
onVersionSaved?: (documentId: string) => void | Promise<void>;
|
|
38
|
+
onVersionSaved?: (documentId: string, version?: number) => void | Promise<void>;
|
|
39
39
|
notify?: (message: string, kind: 'success' | 'error') => void;
|
|
40
40
|
mentions?: readonly DocxMention[];
|
|
41
41
|
requestAgent?: (documentId: string, request: DocxAgentCommentRequest) => Promise<DocxMentionDelivery | void>;
|
|
@@ -89,6 +89,8 @@ export interface NativeDocxEditorProps {
|
|
|
89
89
|
compact?: boolean;
|
|
90
90
|
/** Receives a reader of the live room's state, so the host's save can include the latest keystrokes. */
|
|
91
91
|
stateRef?: React.MutableRefObject<(() => string | undefined) | null>;
|
|
92
|
+
/** Save the current live room before leaving the editor; false means the caller must stay. */
|
|
93
|
+
saveRef?: React.MutableRefObject<(() => Promise<boolean | number>) | null>;
|
|
92
94
|
}
|
|
93
95
|
export declare function DocxParticipants({ session }: {
|
|
94
96
|
session?: DocxCollaborationSession;
|
|
@@ -100,4 +102,4 @@ export declare function DocxRibbon({ onSave, badge, imageGeneration, }: {
|
|
|
100
102
|
/** A short state label at the end of the row, such as "Co-editing". */
|
|
101
103
|
badge?: React.ReactNode;
|
|
102
104
|
}): React.JSX.Element;
|
|
103
|
-
export declare function NativeDocxEditor({ documentId, title, draftContent, initialCommentId, snapshot, onSaved, stream, adapter, compact, stateRef, }: NativeDocxEditorProps): React.JSX.Element;
|
|
105
|
+
export declare function NativeDocxEditor({ documentId, title, draftContent, initialCommentId, snapshot, onSaved, stream, adapter, compact, stateRef, saveRef, }: NativeDocxEditorProps): React.JSX.Element;
|
|
@@ -33,6 +33,7 @@ import {
|
|
|
33
33
|
} from "lucide-react";
|
|
34
34
|
import { DefinedTermsProvider, useDefinedTerms } from "./definitions/DefinedTerms.js";
|
|
35
35
|
import { RibbonMenu } from "./RibbonMenu.js";
|
|
36
|
+
import { DocxCommandMenu } from "./DocxCommandMenu.js";
|
|
36
37
|
import { RibbonItem, RibbonOverflow } from "./RibbonOverflow.js";
|
|
37
38
|
import { StyleGallery } from "./StyleGallery.js";
|
|
38
39
|
import { NoteButtons, WordShortcuts } from "./WordReferences.js";
|
|
@@ -100,12 +101,21 @@ class EditorBoundary extends React.Component {
|
|
|
100
101
|
] }) : this.props.children;
|
|
101
102
|
}
|
|
102
103
|
}
|
|
103
|
-
function RoomInputBinding({
|
|
104
|
+
function RoomInputBinding({
|
|
105
|
+
session,
|
|
106
|
+
flushRef
|
|
107
|
+
}) {
|
|
104
108
|
const editor = useDocxEditor();
|
|
105
109
|
useEffect(() => {
|
|
106
|
-
if (!editor
|
|
107
|
-
|
|
108
|
-
|
|
110
|
+
if (!editor) return;
|
|
111
|
+
const flush = () => editor.surface?.flushPendingInput();
|
|
112
|
+
flushRef.current = flush;
|
|
113
|
+
const unbind = session?.bindEditorInput(flush);
|
|
114
|
+
return () => {
|
|
115
|
+
if (flushRef.current === flush) flushRef.current = null;
|
|
116
|
+
unbind?.();
|
|
117
|
+
};
|
|
118
|
+
}, [editor, session, flushRef]);
|
|
109
119
|
return null;
|
|
110
120
|
}
|
|
111
121
|
function DocxParticipants({ session }) {
|
|
@@ -252,11 +262,14 @@ function NativeDocxEditor({
|
|
|
252
262
|
stream,
|
|
253
263
|
adapter,
|
|
254
264
|
compact = false,
|
|
255
|
-
stateRef
|
|
265
|
+
stateRef,
|
|
266
|
+
saveRef
|
|
256
267
|
}) {
|
|
257
268
|
const [ready, setReady] = useState(), [error, setError] = useState(""), [retry, setRetry] = useState(0);
|
|
258
269
|
const [status, setStatus] = useState("Connecting\u2026"), [dirty, setDirty] = useState(false), [saving, setSaving] = useState(false), [offline, setOffline] = useState(false);
|
|
259
270
|
const revision = useRef(0);
|
|
271
|
+
const savingRef = useRef(false);
|
|
272
|
+
const flushInputRef = useRef(null);
|
|
260
273
|
const stageRef = useRef(null), fitCleanup = useRef(void 0), refit = useRef(void 0);
|
|
261
274
|
const fitting = useRef(true), fitted = useRef(void 0);
|
|
262
275
|
const [fitWidth, setFitWidth] = useState(true), [zoomPercent, setZoomPercent] = useState(100);
|
|
@@ -480,11 +493,16 @@ function NativeDocxEditor({
|
|
|
480
493
|
};
|
|
481
494
|
}, [documentId, isDraft, ready]);
|
|
482
495
|
async function saveVersion() {
|
|
483
|
-
if (!ready ||
|
|
496
|
+
if (!ready || savingRef.current || stream) return false;
|
|
497
|
+
if (snapshot || !ready.canEdit) return true;
|
|
498
|
+
if (offline) return false;
|
|
499
|
+
savingRef.current = true;
|
|
484
500
|
setSaving(true);
|
|
485
|
-
runBeforeSave(ref.current);
|
|
486
|
-
const atRevision = revision.current;
|
|
487
501
|
try {
|
|
502
|
+
if (!flushInputRef.current) throw new Error("The editor is not ready to save yet.");
|
|
503
|
+
flushInputRef.current();
|
|
504
|
+
runBeforeSave(ref.current);
|
|
505
|
+
const atRevision = revision.current;
|
|
488
506
|
const result = isDraft ? await (async () => {
|
|
489
507
|
const bytes = await ref.current?.save();
|
|
490
508
|
if (!bytes) throw new Error("The editor is not ready.");
|
|
@@ -501,17 +519,32 @@ function NativeDocxEditor({
|
|
|
501
519
|
setDirty(false);
|
|
502
520
|
drafts.delete(documentId);
|
|
503
521
|
}
|
|
504
|
-
|
|
505
|
-
|
|
522
|
+
const savedVersion = "version" in result && typeof result.version === "number" ? result.version : void 0;
|
|
523
|
+
if (!isDraft && !savedVersion) throw new Error("Could not confirm the saved version.");
|
|
524
|
+
await adapter.onVersionSaved?.(result.document_ext_id, savedVersion);
|
|
506
525
|
onSaved?.(result.document_ext_id);
|
|
526
|
+
if (revision.current !== atRevision) {
|
|
527
|
+
adapter.notify?.("The document changed while saving. Please try again.", "error");
|
|
528
|
+
return false;
|
|
529
|
+
}
|
|
507
530
|
adapter.notify?.(isDraft ? "Word note saved" : "DOCX version saved", "success");
|
|
531
|
+
return savedVersion ?? true;
|
|
508
532
|
} catch (e) {
|
|
509
533
|
adapter.notify?.(e instanceof Error ? e.message : "Could not save this document.", "error");
|
|
510
534
|
setStatus("Save failed \xB7 your draft is retained");
|
|
535
|
+
return false;
|
|
511
536
|
} finally {
|
|
537
|
+
savingRef.current = false;
|
|
512
538
|
setSaving(false);
|
|
513
539
|
}
|
|
514
540
|
}
|
|
541
|
+
useEffect(() => {
|
|
542
|
+
if (!saveRef) return;
|
|
543
|
+
saveRef.current = saveVersion;
|
|
544
|
+
return () => {
|
|
545
|
+
saveRef.current = null;
|
|
546
|
+
};
|
|
547
|
+
});
|
|
515
548
|
function editorReady(editor) {
|
|
516
549
|
ref.current = editor;
|
|
517
550
|
if (streamRef.current) {
|
|
@@ -672,7 +705,7 @@ function NativeDocxEditor({
|
|
|
672
705
|
),
|
|
673
706
|
compact && !stream && /* @__PURE__ */ jsx(CompactToolbar, {}),
|
|
674
707
|
!compact && !stream && /* @__PURE__ */ jsx(
|
|
675
|
-
|
|
708
|
+
DocxCommandMenu,
|
|
676
709
|
{
|
|
677
710
|
onSave: () => void saveVersion(),
|
|
678
711
|
imageGeneration: adapter.imageGeneration && {
|
|
@@ -713,7 +746,13 @@ function NativeDocxEditor({
|
|
|
713
746
|
getAgentStatus: adapter.getAgentStatus,
|
|
714
747
|
requestAgent: adapter.requestAgent ? (request) => adapter.requestAgent(documentId, request) : void 0,
|
|
715
748
|
children: [
|
|
716
|
-
/* @__PURE__ */ jsx(
|
|
749
|
+
/* @__PURE__ */ jsx(
|
|
750
|
+
RoomInputBinding,
|
|
751
|
+
{
|
|
752
|
+
session: ready.room?.session,
|
|
753
|
+
flushRef: flushInputRef
|
|
754
|
+
}
|
|
755
|
+
),
|
|
717
756
|
/* @__PURE__ */ jsx(AgentUndoRoom.Provider, { value: ready.room?.ydoc ?? null, children: /* @__PURE__ */ jsx(DocxEditorReview, { children: () => /* @__PURE__ */ jsxs(DocxEditorReview.Card, { children: [
|
|
718
757
|
/* @__PURE__ */ jsx(DocxCommentActivity, {}),
|
|
719
758
|
/* @__PURE__ */ jsx(AgentUndo, {})
|