@arbidocs/blocks 0.5.120 → 0.5.122

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.
Files changed (417) hide show
  1. package/dist/ClippingMediaViewer-IEIBT74X.cjs +156 -0
  2. package/dist/ClippingMediaViewer-IEIBT74X.cjs.map +1 -0
  3. package/dist/ClippingPdfViewer-OGYLMVCE.cjs +79 -0
  4. package/dist/ClippingPdfViewer-OGYLMVCE.cjs.map +1 -0
  5. package/dist/{ConnectedCallDock-WER7R222.cjs → ConnectedCallDock-XJOYVVAH.cjs} +9 -7
  6. package/dist/ConnectedCallDock-XJOYVVAH.cjs.map +1 -0
  7. package/dist/{ConnectedCallRoom-T7OBQTYP.cjs → ConnectedCallRoom-CUDYAPQK.cjs} +9 -7
  8. package/dist/{ConnectedCallRoom-T7OBQTYP.cjs.map → ConnectedCallRoom-CUDYAPQK.cjs.map} +1 -1
  9. package/dist/{ConnectedNativeDocxComparison-SGE4R3M4.cjs → ConnectedNativeDocxComparison-QKHCYD6W.cjs} +7 -7
  10. package/dist/{ConnectedNativeDocxComparison-SGE4R3M4.cjs.map → ConnectedNativeDocxComparison-QKHCYD6W.cjs.map} +1 -1
  11. package/dist/ConnectedPresentation-AU25OW25.cjs +321 -0
  12. package/dist/ConnectedPresentation-AU25OW25.cjs.map +1 -0
  13. package/dist/ConnectedSlidesTab-I75LKKN7.cjs +236 -0
  14. package/dist/ConnectedSlidesTab-I75LKKN7.cjs.map +1 -0
  15. package/dist/{ConnectedStreamedWordArtifact-6MCLJRIT.cjs → ConnectedStreamedWordArtifact-AG62232A.cjs} +7 -7
  16. package/dist/{ConnectedStreamedWordArtifact-6MCLJRIT.cjs.map → ConnectedStreamedWordArtifact-AG62232A.cjs.map} +1 -1
  17. package/dist/{DocumentReviewCard-BPIAJJED.cjs → DocumentReviewCard-M53XFLI2.cjs} +15 -14
  18. package/dist/DocumentReviewCard-M53XFLI2.cjs.map +1 -0
  19. package/dist/{FilesViewerDialog-67WK3TZC.cjs → FilesViewerDialog-4352KIOG.cjs} +30 -22
  20. package/dist/FilesViewerDialog-4352KIOG.cjs.map +1 -0
  21. package/dist/{GridViewImpl-ZMJJWTOM.cjs → GridViewImpl-LTYET77Q.cjs} +3 -3
  22. package/dist/GridViewImpl-LTYET77Q.cjs.map +1 -0
  23. package/dist/{WorkspaceTableView-J3C6VH4T.cjs → WorkspaceTableView-3XYAV4BV.cjs} +9 -8
  24. package/dist/WorkspaceTableView-3XYAV4BV.cjs.map +1 -0
  25. package/dist/agents/index.cjs +186 -186
  26. package/dist/{ai-IM4A23YT.cjs → ai-IEIR7SC2.cjs} +17 -15
  27. package/dist/ai-IEIR7SC2.cjs.map +1 -0
  28. package/dist/calls/connected/CallControls.d.ts +2 -0
  29. package/dist/calls/connected/CallControls.js +71 -9
  30. package/dist/calls/connected/CallControls.js.map +2 -2
  31. package/dist/calls/connected/ShareDocumentDialog.d.ts +14 -0
  32. package/dist/calls/connected/ShareDocumentDialog.js +77 -0
  33. package/dist/calls/connected/ShareDocumentDialog.js.map +7 -0
  34. package/dist/calls/index.cjs +2 -2
  35. package/dist/chat/index.cjs +8 -7
  36. package/dist/{chunk-557MJ4IH.cjs → chunk-2F57IO7S.cjs} +9 -146
  37. package/dist/chunk-2F57IO7S.cjs.map +1 -0
  38. package/dist/chunk-2RLA6QO2.cjs +174 -0
  39. package/dist/chunk-2RLA6QO2.cjs.map +1 -0
  40. package/dist/chunk-4TTX6ZNS.cjs +1374 -0
  41. package/dist/chunk-4TTX6ZNS.cjs.map +1 -0
  42. package/dist/chunk-5GCCUXMT.cjs +63 -0
  43. package/dist/chunk-5GCCUXMT.cjs.map +1 -0
  44. package/dist/{chunk-BUVIBHFU.cjs → chunk-5QERK4PK.cjs} +38 -38
  45. package/dist/chunk-5QERK4PK.cjs.map +1 -0
  46. package/dist/chunk-6OK7ESTL.cjs +134 -0
  47. package/dist/chunk-6OK7ESTL.cjs.map +1 -0
  48. package/dist/{chunk-ECLUFKYR.cjs → chunk-7557LDAN.cjs} +4 -4
  49. package/dist/{chunk-ECLUFKYR.cjs.map → chunk-7557LDAN.cjs.map} +1 -1
  50. package/dist/{chunk-KTQOGT2L.cjs → chunk-7L4X6QN2.cjs} +7 -7
  51. package/dist/{chunk-KTQOGT2L.cjs.map → chunk-7L4X6QN2.cjs.map} +1 -1
  52. package/dist/{chunk-BP3IJ34D.cjs → chunk-7NLO7ASW.cjs} +4 -4
  53. package/dist/{chunk-BP3IJ34D.cjs.map → chunk-7NLO7ASW.cjs.map} +1 -1
  54. package/dist/{chunk-3GWWOYGS.cjs → chunk-7PN3YENO.cjs} +4 -4
  55. package/dist/{chunk-3GWWOYGS.cjs.map → chunk-7PN3YENO.cjs.map} +1 -1
  56. package/dist/{chunk-DFBDQKGE.cjs → chunk-ADDQKZ5I.cjs} +4 -4
  57. package/dist/{chunk-DFBDQKGE.cjs.map → chunk-ADDQKZ5I.cjs.map} +1 -1
  58. package/dist/chunk-AFQTQC7A.cjs +35 -0
  59. package/dist/chunk-AFQTQC7A.cjs.map +1 -0
  60. package/dist/{chunk-NLSWDP42.cjs → chunk-ALK3PUUB.cjs} +21 -11
  61. package/dist/chunk-ALK3PUUB.cjs.map +1 -0
  62. package/dist/{chunk-775S43W7.cjs → chunk-CQQQIZU4.cjs} +8 -8
  63. package/dist/{chunk-775S43W7.cjs.map → chunk-CQQQIZU4.cjs.map} +1 -1
  64. package/dist/{chunk-TDO5UWXF.cjs → chunk-E3L5DB5F.cjs} +5 -5
  65. package/dist/{chunk-TDO5UWXF.cjs.map → chunk-E3L5DB5F.cjs.map} +1 -1
  66. package/dist/chunk-GFUOCGY6.cjs +32 -0
  67. package/dist/chunk-GFUOCGY6.cjs.map +1 -0
  68. package/dist/chunk-HYUKPHCT.cjs +66 -0
  69. package/dist/chunk-HYUKPHCT.cjs.map +1 -0
  70. package/dist/{chunk-QQWHG3KF.cjs → chunk-JJZOL5MG.cjs} +4 -4
  71. package/dist/{chunk-QQWHG3KF.cjs.map → chunk-JJZOL5MG.cjs.map} +1 -1
  72. package/dist/chunk-K4763GD5.cjs +301 -0
  73. package/dist/chunk-K4763GD5.cjs.map +1 -0
  74. package/dist/{chunk-B3LZITVF.cjs → chunk-KA3F6TIH.cjs} +2 -442
  75. package/dist/chunk-KA3F6TIH.cjs.map +1 -0
  76. package/dist/{chunk-PGJYD67F.cjs → chunk-KNGZZC4O.cjs} +7 -6
  77. package/dist/chunk-KNGZZC4O.cjs.map +1 -0
  78. package/dist/{chunk-YYPZOEED.cjs → chunk-LHWOKOMP.cjs} +23 -2
  79. package/dist/chunk-LHWOKOMP.cjs.map +1 -0
  80. package/dist/{chunk-HA66DHW6.cjs → chunk-MLA2BJ2Y.cjs} +28 -28
  81. package/dist/chunk-MLA2BJ2Y.cjs.map +1 -0
  82. package/dist/{chunk-CPR6EHG7.cjs → chunk-NG2EE7HR.cjs} +134 -10
  83. package/dist/chunk-NG2EE7HR.cjs.map +1 -0
  84. package/dist/{chunk-CKCG4NDB.cjs → chunk-OHHKBURG.cjs} +29 -29
  85. package/dist/chunk-OHHKBURG.cjs.map +1 -0
  86. package/dist/{chunk-4XJEHKVZ.cjs → chunk-PIYYBPHH.cjs} +4 -4
  87. package/dist/{chunk-4XJEHKVZ.cjs.map → chunk-PIYYBPHH.cjs.map} +1 -1
  88. package/dist/{chunk-YYSBWMDJ.cjs → chunk-QG2U2JGX.cjs} +4 -4
  89. package/dist/{chunk-YYSBWMDJ.cjs.map → chunk-QG2U2JGX.cjs.map} +1 -1
  90. package/dist/{chunk-5IZFSAEZ.cjs → chunk-SDRYSLOX.cjs} +4 -4
  91. package/dist/{chunk-5IZFSAEZ.cjs.map → chunk-SDRYSLOX.cjs.map} +1 -1
  92. package/dist/{chunk-NJCK6V6U.cjs → chunk-T73BHNQX.cjs} +2 -58
  93. package/dist/chunk-T73BHNQX.cjs.map +1 -0
  94. package/dist/{chunk-EOG6OT5I.cjs → chunk-TXP2N3DC.cjs} +4 -4
  95. package/dist/{chunk-EOG6OT5I.cjs.map → chunk-TXP2N3DC.cjs.map} +1 -1
  96. package/dist/{chunk-6UTKM5AB.cjs → chunk-UFT22LAB.cjs} +75 -75
  97. package/dist/chunk-UFT22LAB.cjs.map +1 -0
  98. package/dist/chunk-USNTRL22.cjs +4790 -0
  99. package/dist/chunk-USNTRL22.cjs.map +1 -0
  100. package/dist/{chunk-X36UR4A7.cjs → chunk-UTJ223TI.cjs} +413 -90
  101. package/dist/chunk-UTJ223TI.cjs.map +1 -0
  102. package/dist/{chunk-VZCPMXWC.cjs → chunk-V6MW7B4B.cjs} +4 -4
  103. package/dist/{chunk-VZCPMXWC.cjs.map → chunk-V6MW7B4B.cjs.map} +1 -1
  104. package/dist/{chunk-T23UTIRI.cjs → chunk-VWBYE3XY.cjs} +5 -5
  105. package/dist/{chunk-T23UTIRI.cjs.map → chunk-VWBYE3XY.cjs.map} +1 -1
  106. package/dist/chunk-WFMWKPGY.cjs +102 -0
  107. package/dist/chunk-WFMWKPGY.cjs.map +1 -0
  108. package/dist/chunk-WOOOMTTA.cjs +19 -0
  109. package/dist/chunk-WOOOMTTA.cjs.map +1 -0
  110. package/dist/{chunk-W6INT5GS.cjs → chunk-WRLGLZIA.cjs} +8 -8
  111. package/dist/{chunk-W6INT5GS.cjs.map → chunk-WRLGLZIA.cjs.map} +1 -1
  112. package/dist/{chunk-CJYWHUZR.cjs → chunk-XCKHOXRP.cjs} +4 -4
  113. package/dist/{chunk-CJYWHUZR.cjs.map → chunk-XCKHOXRP.cjs.map} +1 -1
  114. package/dist/chunk-XF355M7O.cjs +154 -0
  115. package/dist/chunk-XF355M7O.cjs.map +1 -0
  116. package/dist/{chunk-Q6CLWOP2.cjs → chunk-XGM4VVNV.cjs} +34 -34
  117. package/dist/{chunk-Q6CLWOP2.cjs.map → chunk-XGM4VVNV.cjs.map} +1 -1
  118. package/dist/{chunk-6WMMZLEV.cjs → chunk-XJEXFEWG.cjs} +2 -27
  119. package/dist/chunk-XJEXFEWG.cjs.map +1 -0
  120. package/dist/chunk-XK4TVJKD.cjs +73 -0
  121. package/dist/chunk-XK4TVJKD.cjs.map +1 -0
  122. package/dist/{chunk-E7TE2WVT.cjs → chunk-ZVEW3JBT.cjs} +3 -3
  123. package/dist/{chunk-E7TE2WVT.cjs.map → chunk-ZVEW3JBT.cjs.map} +1 -1
  124. package/dist/collaboration/index.cjs +70 -70
  125. package/dist/components/ZoomSlider.d.ts +25 -0
  126. package/dist/components/ZoomSlider.js +59 -0
  127. package/dist/components/ZoomSlider.js.map +7 -0
  128. package/dist/connect/docx.cjs +10 -10
  129. package/dist/connect/index.cjs +1066 -1147
  130. package/dist/connect/index.cjs.map +1 -1
  131. package/dist/connect/viewer.cjs +19 -12
  132. package/dist/connection/ai.d.ts +1 -1
  133. package/dist/connection/conversation/ConnectedMessage.js +1 -1
  134. package/dist/connection/conversation/ConnectedMessage.js.map +2 -2
  135. package/dist/connection/files/ConnectedNewFileMenu.d.ts +2 -1
  136. package/dist/connection/files/ConnectedNewFileMenu.js +9 -3
  137. package/dist/connection/files/ConnectedNewFileMenu.js.map +2 -2
  138. package/dist/connection/files/explorer/ConnectedFilesExplorer.js +1 -1
  139. package/dist/connection/files/explorer/ConnectedFilesExplorer.js.map +2 -2
  140. package/dist/connection/files/explorer/FileTiles.js +1 -1
  141. package/dist/connection/files/explorer/FileTiles.js.map +2 -2
  142. package/dist/connection/files/fields/documentField.js +1 -1
  143. package/dist/connection/files/fields/documentField.js.map +2 -2
  144. package/dist/connection/files/grid/documentColumns.js +1 -1
  145. package/dist/connection/files/grid/documentColumns.js.map +2 -2
  146. package/dist/connection/files/page/DocumentsFilterBarActions.js +17 -28
  147. package/dist/connection/files/page/DocumentsFilterBarActions.js.map +2 -2
  148. package/dist/connection/mail/useMailboxDefaults.js +1 -1
  149. package/dist/connection/mail/useMailboxDefaults.js.map +2 -2
  150. package/dist/connection/panels/useSessionPanelMode.js +3 -2
  151. package/dist/connection/panels/useSessionPanelMode.js.map +2 -2
  152. package/dist/connection/presentation/ClippingMediaViewer.d.ts +12 -0
  153. package/dist/connection/presentation/ClippingMediaViewer.js +153 -0
  154. package/dist/connection/presentation/ClippingMediaViewer.js.map +7 -0
  155. package/dist/connection/presentation/ClippingPdfViewer.d.ts +22 -0
  156. package/dist/connection/presentation/ClippingPdfViewer.js +75 -0
  157. package/dist/connection/presentation/ClippingPdfViewer.js.map +7 -0
  158. package/dist/connection/presentation/ConnectedPresentation.d.ts +12 -0
  159. package/dist/connection/presentation/ConnectedPresentation.js +100 -0
  160. package/dist/connection/presentation/ConnectedPresentation.js.map +7 -0
  161. package/dist/connection/presentation/ConnectedSlidesTab.d.ts +20 -0
  162. package/dist/connection/presentation/ConnectedSlidesTab.js +222 -0
  163. package/dist/connection/presentation/ConnectedSlidesTab.js.map +7 -0
  164. package/dist/connection/presentation/CropClipDialog.d.ts +11 -0
  165. package/dist/connection/presentation/CropClipDialog.js +86 -0
  166. package/dist/connection/presentation/CropClipDialog.js.map +7 -0
  167. package/dist/connection/presentation/GenerateTile.d.ts +4 -0
  168. package/dist/connection/presentation/GenerateTile.js +24 -0
  169. package/dist/connection/presentation/GenerateTile.js.map +7 -0
  170. package/dist/connection/presentation/LabelColumnMenu.d.ts +8 -0
  171. package/dist/connection/presentation/LabelColumnMenu.js +38 -0
  172. package/dist/connection/presentation/LabelColumnMenu.js.map +7 -0
  173. package/dist/connection/presentation/PresentationDialogs.d.ts +39 -0
  174. package/dist/connection/presentation/PresentationDialogs.js +295 -0
  175. package/dist/connection/presentation/PresentationDialogs.js.map +7 -0
  176. package/dist/connection/presentation/PresentationFileCard.d.ts +10 -0
  177. package/dist/connection/presentation/PresentationFileCard.js +35 -0
  178. package/dist/connection/presentation/PresentationFileCard.js.map +7 -0
  179. package/dist/connection/presentation/PresentationPill.d.ts +8 -0
  180. package/dist/connection/presentation/PresentationPill.js +39 -0
  181. package/dist/connection/presentation/PresentationPill.js.map +7 -0
  182. package/dist/connection/presentation/PresentationSlot.d.ts +7 -0
  183. package/dist/connection/presentation/PresentationSlot.js +35 -0
  184. package/dist/connection/presentation/PresentationSlot.js.map +7 -0
  185. package/dist/connection/presentation/requests.d.ts +21 -0
  186. package/dist/connection/presentation/requests.js +27 -0
  187. package/dist/connection/presentation/requests.js.map +7 -0
  188. package/dist/connection/presentation/useImageGeneration.d.ts +11 -0
  189. package/dist/connection/presentation/useImageGeneration.js +66 -0
  190. package/dist/connection/presentation/useImageGeneration.js.map +7 -0
  191. package/dist/connection/presentation/useLabelColumns.d.ts +15 -0
  192. package/dist/connection/presentation/useLabelColumns.js +33 -0
  193. package/dist/connection/presentation/useLabelColumns.js.map +7 -0
  194. package/dist/connection/presentation/usePresentationController.d.ts +15 -0
  195. package/dist/connection/presentation/usePresentationController.js +118 -0
  196. package/dist/connection/presentation/usePresentationController.js.map +7 -0
  197. package/dist/connection/presentation/usePresentationFiles.d.ts +44 -0
  198. package/dist/connection/presentation/usePresentationFiles.js +307 -0
  199. package/dist/connection/presentation/usePresentationFiles.js.map +7 -0
  200. package/dist/connection/presentation/useViewerClipping.d.ts +14 -0
  201. package/dist/connection/presentation/useViewerClipping.js +18 -0
  202. package/dist/connection/presentation/useViewerClipping.js.map +7 -0
  203. package/dist/connection/shell/ConnectedAppShell.js +5 -1
  204. package/dist/connection/shell/ConnectedAppShell.js.map +2 -2
  205. package/dist/connection/viewer/CleanViewControl.d.ts +8 -0
  206. package/dist/connection/viewer/CleanViewControl.js +76 -0
  207. package/dist/connection/viewer/CleanViewControl.js.map +7 -0
  208. package/dist/connection/viewer/ConnectedDocumentViewer.js +28 -29
  209. package/dist/connection/viewer/ConnectedDocumentViewer.js.map +2 -2
  210. package/dist/connection/viewer/ViewerCropModal.d.ts +5 -0
  211. package/dist/connection/viewer/ViewerCropModal.js +22 -0
  212. package/dist/connection/viewer/ViewerCropModal.js.map +7 -0
  213. package/dist/connection/viewer/ViewerPdfPane.d.ts +3 -1
  214. package/dist/connection/viewer/ViewerPdfPane.js +41 -1
  215. package/dist/connection/viewer/ViewerPdfPane.js.map +2 -2
  216. package/dist/connection/viewer/documentPlace.d.ts +5 -4
  217. package/dist/connection/viewer/documentPlace.js +2 -2
  218. package/dist/connection/viewer/documentPlace.js.map +2 -2
  219. package/dist/connection/viewer/drafts.js +6 -4
  220. package/dist/connection/viewer/drafts.js.map +2 -2
  221. package/dist/connection/viewer/pdf/PdfClipOutlines.d.ts +11 -0
  222. package/dist/connection/viewer/pdf/PdfClipOutlines.js +42 -0
  223. package/dist/connection/viewer/pdf/PdfClipOutlines.js.map +7 -0
  224. package/dist/connection/viewer/pdf/clipOutlines.d.ts +17 -0
  225. package/dist/connection/viewer/pdf/clipOutlines.js +24 -0
  226. package/dist/connection/viewer/pdf/clipOutlines.js.map +7 -0
  227. package/dist/connection/viewer/pdf/passageHighlights.d.ts +2 -0
  228. package/dist/connection/viewer/pdf/passageHighlights.js +12 -1
  229. package/dist/connection/viewer/pdf/passageHighlights.js.map +2 -2
  230. package/dist/connection/viewer/pdf/usePdfClipOutlines.d.ts +7 -0
  231. package/dist/connection/viewer/pdf/usePdfClipOutlines.js +36 -0
  232. package/dist/connection/viewer/pdf/usePdfClipOutlines.js.map +7 -0
  233. package/dist/connection/viewer/pdf/usePdfPassageHighlights.js +11 -2
  234. package/dist/connection/viewer/pdf/usePdfPassageHighlights.js.map +2 -2
  235. package/dist/connection/viewer/shareDocument.d.ts +11 -0
  236. package/dist/connection/viewer/shareDocument.js +11 -0
  237. package/dist/connection/viewer/shareDocument.js.map +7 -0
  238. package/dist/connection/viewer/slidesTabChunk.d.ts +2 -0
  239. package/dist/connection/viewer/slidesTabChunk.js +9 -0
  240. package/dist/connection/viewer/slidesTabChunk.js.map +7 -0
  241. package/dist/connection/viewer/useCleanView.d.ts +14 -0
  242. package/dist/connection/viewer/useCleanView.js +29 -0
  243. package/dist/connection/viewer/useCleanView.js.map +7 -0
  244. package/dist/connection/viewer/useViewedDocument.d.ts +1 -0
  245. package/dist/connection/viewer/useViewedDocument.js +9 -1
  246. package/dist/connection/viewer/useViewedDocument.js.map +2 -2
  247. package/dist/connection/viewer/useViewerTabs.js +18 -4
  248. package/dist/connection/viewer/useViewerTabs.js.map +2 -2
  249. package/dist/connection/workflows/ConnectedWorkflowStart.d.ts +14 -2
  250. package/dist/connection/workflows/ConnectedWorkflowStart.js +5 -2
  251. package/dist/connection/workflows/ConnectedWorkflowStart.js.map +2 -2
  252. package/dist/databases/index.cjs +49 -49
  253. package/dist/document-tools/DocumentToolButtons.d.ts +2 -0
  254. package/dist/document-tools/DocumentToolButtons.js +22 -1
  255. package/dist/document-tools/DocumentToolButtons.js.map +2 -2
  256. package/dist/document-tools/index.cjs +16 -12
  257. package/dist/document-tools/index.d.ts +1 -1
  258. package/dist/document-tools/index.js +2 -0
  259. package/dist/document-tools/index.js.map +2 -2
  260. package/dist/embed/index.cjs +17 -15
  261. package/dist/files/GridViewImpl.js +1 -1
  262. package/dist/files/GridViewImpl.js.map +2 -2
  263. package/dist/files/ViewerChrome.d.ts +5 -1
  264. package/dist/files/ViewerChrome.js +16 -6
  265. package/dist/files/ViewerChrome.js.map +2 -2
  266. package/dist/files/index.cjs +224 -224
  267. package/dist/files/navigator/DocumentSearchList.js +1 -1
  268. package/dist/files/navigator/DocumentSearchList.js.map +2 -2
  269. package/dist/index.cjs +359 -356
  270. package/dist/index.cjs.map +1 -1
  271. package/dist/presentation/BoxActionBar.d.ts +11 -0
  272. package/dist/presentation/BoxActionBar.js +182 -0
  273. package/dist/presentation/BoxActionBar.js.map +7 -0
  274. package/dist/presentation/ClipActionBar.d.ts +26 -0
  275. package/dist/presentation/ClipActionBar.js +103 -0
  276. package/dist/presentation/ClipActionBar.js.map +7 -0
  277. package/dist/presentation/ClipCaptureOverlay.d.ts +14 -0
  278. package/dist/presentation/ClipCaptureOverlay.js +69 -0
  279. package/dist/presentation/ClipCaptureOverlay.js.map +7 -0
  280. package/dist/presentation/ClipImage.d.ts +21 -0
  281. package/dist/presentation/ClipImage.js +119 -0
  282. package/dist/presentation/ClipImage.js.map +7 -0
  283. package/dist/presentation/ClipTray.d.ts +11 -0
  284. package/dist/presentation/ClipTray.js +152 -0
  285. package/dist/presentation/ClipTray.js.map +7 -0
  286. package/dist/presentation/ClipViewControls.d.ts +11 -0
  287. package/dist/presentation/ClipViewControls.js +142 -0
  288. package/dist/presentation/ClipViewControls.js.map +7 -0
  289. package/dist/presentation/DesignMenu.d.ts +8 -0
  290. package/dist/presentation/DesignMenu.js +199 -0
  291. package/dist/presentation/DesignMenu.js.map +7 -0
  292. package/dist/presentation/LayoutMenu.d.ts +17 -0
  293. package/dist/presentation/LayoutMenu.js +122 -0
  294. package/dist/presentation/LayoutMenu.js.map +7 -0
  295. package/dist/presentation/MediaClip.d.ts +15 -0
  296. package/dist/presentation/MediaClip.js +67 -0
  297. package/dist/presentation/MediaClip.js.map +7 -0
  298. package/dist/presentation/Notice.d.ts +6 -0
  299. package/dist/presentation/Notice.js +43 -0
  300. package/dist/presentation/Notice.js.map +7 -0
  301. package/dist/presentation/PresentControls.d.ts +11 -0
  302. package/dist/presentation/PresentControls.js +117 -0
  303. package/dist/presentation/PresentControls.js.map +7 -0
  304. package/dist/presentation/PresentationStage.d.ts +32 -0
  305. package/dist/presentation/PresentationStage.js +232 -0
  306. package/dist/presentation/PresentationStage.js.map +7 -0
  307. package/dist/presentation/PresenterView.d.ts +16 -0
  308. package/dist/presentation/PresenterView.js +100 -0
  309. package/dist/presentation/PresenterView.js.map +7 -0
  310. package/dist/presentation/SlideDecor.d.ts +25 -0
  311. package/dist/presentation/SlideDecor.js +189 -0
  312. package/dist/presentation/SlideDecor.js.map +7 -0
  313. package/dist/presentation/SlidesEditor.d.ts +25 -0
  314. package/dist/presentation/SlidesEditor.js +375 -0
  315. package/dist/presentation/SlidesEditor.js.map +7 -0
  316. package/dist/presentation/StageBox.d.ts +30 -0
  317. package/dist/presentation/StageBox.js +281 -0
  318. package/dist/presentation/StageBox.js.map +7 -0
  319. package/dist/presentation/StageItem.d.ts +37 -0
  320. package/dist/presentation/StageItem.js +211 -0
  321. package/dist/presentation/StageItem.js.map +7 -0
  322. package/dist/presentation/box-style.d.ts +6 -0
  323. package/dist/presentation/box-style.js +19 -0
  324. package/dist/presentation/box-style.js.map +7 -0
  325. package/dist/presentation/boxes.d.ts +105 -0
  326. package/dist/presentation/boxes.js +103 -0
  327. package/dist/presentation/boxes.js.map +7 -0
  328. package/dist/presentation/draw-boxes.d.ts +8 -0
  329. package/dist/presentation/draw-boxes.js +130 -0
  330. package/dist/presentation/draw-boxes.js.map +7 -0
  331. package/dist/presentation/export-boxes.d.ts +10 -0
  332. package/dist/presentation/export-boxes.js +74 -0
  333. package/dist/presentation/export-boxes.js.map +7 -0
  334. package/dist/presentation/export-pptx.d.ts +16 -0
  335. package/dist/presentation/export-pptx.js +194 -0
  336. package/dist/presentation/export-pptx.js.map +7 -0
  337. package/dist/presentation/import-pptx.d.ts +35 -0
  338. package/dist/presentation/import-pptx.js +659 -0
  339. package/dist/presentation/import-pptx.js.map +7 -0
  340. package/dist/presentation/merge-outside-edits.d.ts +12 -0
  341. package/dist/presentation/merge-outside-edits.js +35 -0
  342. package/dist/presentation/merge-outside-edits.js.map +7 -0
  343. package/dist/presentation/model.d.ts +201 -0
  344. package/dist/presentation/model.js +271 -0
  345. package/dist/presentation/model.js.map +7 -0
  346. package/dist/presentation/panel-id.d.ts +44 -0
  347. package/dist/presentation/panel-id.js +29 -0
  348. package/dist/presentation/panel-id.js.map +7 -0
  349. package/dist/presentation/persistence.d.ts +121 -0
  350. package/dist/presentation/persistence.js +141 -0
  351. package/dist/presentation/persistence.js.map +7 -0
  352. package/dist/presentation/pptx-data.d.ts +22 -0
  353. package/dist/presentation/pptx-data.js +83 -0
  354. package/dist/presentation/pptx-data.js.map +7 -0
  355. package/dist/presentation/pptx-xml.d.ts +90 -0
  356. package/dist/presentation/pptx-xml.js +333 -0
  357. package/dist/presentation/pptx-xml.js.map +7 -0
  358. package/dist/presentation/render-slides.d.ts +58 -0
  359. package/dist/presentation/render-slides.js +309 -0
  360. package/dist/presentation/render-slides.js.map +7 -0
  361. package/dist/presentation/saved-boxes.d.ts +11 -0
  362. package/dist/presentation/saved-boxes.js +80 -0
  363. package/dist/presentation/saved-boxes.js.map +7 -0
  364. package/dist/presentation/slide-layout.d.ts +58 -0
  365. package/dist/presentation/slide-layout.js +133 -0
  366. package/dist/presentation/slide-layout.js.map +7 -0
  367. package/dist/presentation/stage-videos.d.ts +5 -0
  368. package/dist/presentation/stage-videos.js +19 -0
  369. package/dist/presentation/stage-videos.js.map +7 -0
  370. package/dist/presentation/store.d.ts +203 -0
  371. package/dist/presentation/store.js +429 -0
  372. package/dist/presentation/store.js.map +7 -0
  373. package/dist/presentation/theme.d.ts +102 -0
  374. package/dist/presentation/theme.js +276 -0
  375. package/dist/presentation/theme.js.map +7 -0
  376. package/dist/presentation/useClipDrag.d.ts +26 -0
  377. package/dist/presentation/useClipDrag.js +65 -0
  378. package/dist/presentation/useClipDrag.js.map +7 -0
  379. package/dist/presentation/useObjectUrl.d.ts +6 -0
  380. package/dist/presentation/useObjectUrl.js +15 -0
  381. package/dist/presentation/useObjectUrl.js.map +7 -0
  382. package/dist/presentation/usePresenterKeys.d.ts +13 -0
  383. package/dist/presentation/usePresenterKeys.js +62 -0
  384. package/dist/presentation/usePresenterKeys.js.map +7 -0
  385. package/dist/settings/index.cjs +149 -148
  386. package/dist/shell/PanelPortal.js +13 -3
  387. package/dist/shell/PanelPortal.js.map +2 -2
  388. package/dist/shell/index.cjs +49 -46
  389. package/dist/shell/panel-windows.d.ts +2 -0
  390. package/dist/shell/panel-windows.js +8 -2
  391. package/dist/shell/panel-windows.js.map +2 -2
  392. package/dist/studio/index.cjs +8 -6
  393. package/dist/studio/index.cjs.map +1 -1
  394. package/dist/styles.css +1 -1
  395. package/dist/workflow-canvas/index.cjs +26 -25
  396. package/dist/workflow-canvas/index.cjs.map +1 -1
  397. package/node_modules/@arbidocs/coedit/package.json +1 -1
  398. package/package.json +6 -5
  399. package/dist/ConnectedCallDock-WER7R222.cjs.map +0 -1
  400. package/dist/DocumentReviewCard-BPIAJJED.cjs.map +0 -1
  401. package/dist/FilesViewerDialog-67WK3TZC.cjs.map +0 -1
  402. package/dist/GridViewImpl-ZMJJWTOM.cjs.map +0 -1
  403. package/dist/WorkspaceTableView-J3C6VH4T.cjs.map +0 -1
  404. package/dist/ai-IM4A23YT.cjs.map +0 -1
  405. package/dist/chunk-557MJ4IH.cjs.map +0 -1
  406. package/dist/chunk-6UTKM5AB.cjs.map +0 -1
  407. package/dist/chunk-6WMMZLEV.cjs.map +0 -1
  408. package/dist/chunk-B3LZITVF.cjs.map +0 -1
  409. package/dist/chunk-BUVIBHFU.cjs.map +0 -1
  410. package/dist/chunk-CKCG4NDB.cjs.map +0 -1
  411. package/dist/chunk-CPR6EHG7.cjs.map +0 -1
  412. package/dist/chunk-HA66DHW6.cjs.map +0 -1
  413. package/dist/chunk-NJCK6V6U.cjs.map +0 -1
  414. package/dist/chunk-NLSWDP42.cjs.map +0 -1
  415. package/dist/chunk-PGJYD67F.cjs.map +0 -1
  416. package/dist/chunk-X36UR4A7.cjs.map +0 -1
  417. package/dist/chunk-YYPZOEED.cjs.map +0 -1
@@ -1,11 +1,11 @@
1
1
  "use client";
2
2
  import { jsx } from "react/jsx-runtime";
3
3
  import { useCallback, useEffect, useMemo, useRef } from "react";
4
- import { useArbiSessionState, useParsedDocument } from "@arbidocs/react";
4
+ import { useArbiSessionState, useArbiSessionStore, useParsedDocument } from "@arbidocs/react";
5
5
  import { useProcessedChunks } from "@arbidocs/react/viewers";
6
6
  import { useViewerPassageCitation } from "../support.js";
7
7
  import { PdfPassageHighlights } from "./PdfPassageHighlights.js";
8
- import { passageBoxesByPage } from "./passageHighlights.js";
8
+ import { passageBoxesByPage, passagePlaced } from "./passageHighlights.js";
9
9
  const NONE = [];
10
10
  const NO_FOOTNOTES = {};
11
11
  function usePdfPassageHighlights(documentId) {
@@ -20,6 +20,15 @@ function usePdfPassageHighlights(documentId) {
20
20
  () => passageBoxesByPage(processedChunks, { cited, active }),
21
21
  [processedChunks, cited, active]
22
22
  );
23
+ const session = useArbiSessionStore();
24
+ const fellBackFor = useRef(null);
25
+ useEffect(() => {
26
+ if (!active || !parsed || !documentId) return;
27
+ const key = `${documentId}:${active}`;
28
+ if (fellBackFor.current === key || passagePlaced(processedChunks, active)) return;
29
+ fellBackFor.current = key;
30
+ session.setDocumentViewer({ tab: "html" });
31
+ }, [active, parsed, processedChunks, documentId, session]);
23
32
  const centredFor = useRef(null);
24
33
  const activeKey = active ? `${documentId}:${active}` : null;
25
34
  useEffect(() => {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/connection/viewer/pdf/usePdfPassageHighlights.tsx"],
4
- "sourcesContent": ["/**\n * The passages a citation lights, drawn over the PDF page by page: a fact's cited passages (its\n * Citation popover is open) and the passage a citation opened the document at, as the parsed view\n * lights them. Nothing is fetched until one is lit; the parsed chunks are the parsed view's own\n * query, so opening that tab afterwards costs nothing more.\n */\n\nimport { useCallback, useEffect, useMemo, useRef, type ReactNode } from 'react'\nimport { useArbiSessionState, useParsedDocument } from '@arbidocs/react'\nimport { useProcessedChunks } from '@arbidocs/react/viewers'\nimport { useViewerPassageCitation } from '../support'\nimport { PdfPassageHighlights } from './PdfPassageHighlights'\nimport { passageBoxesByPage } from './passageHighlights'\n\nconst NONE: readonly string[] = []\nconst NO_FOOTNOTES: Record<string, string> = {}\n\n/** A PDF viewer's page overlay for the document being viewed: `(page) => highlights | null`. */\nexport function usePdfPassageHighlights(\n documentId: string | undefined\n): (pageNumber: number) => ReactNode {\n const citedIds = useViewerPassageCitation()?.highlighted ?? NONE\n const cited = useMemo(() => new Set(citedIds), [citedIds])\n const active = useArbiSessionState((s) => s.viewingDocument?.passageId ?? null)\n\n const { data: parsed } = useParsedDocument(documentId, 'final', {\n enabled: cited.size > 0 || !!active,\n })\n const { processedChunks } = useProcessedChunks(parsed?.chunks, NO_FOOTNOTES)\n const boxesByPage = useMemo(\n () => passageBoxesByPage(processedChunks, { cited, active }),\n [processedChunks, cited, active]\n )\n\n // The passage being read is brought into view once, when its page first draws it: the viewer\n // opens the page, this centres the passage on it, and scrolling away is then left alone.\n const centredFor = useRef<string | null>(null)\n const activeKey = active ? `${documentId}:${active}` : null\n useEffect(() => {\n if (!activeKey) centredFor.current = null\n }, [activeKey])\n const centre = useCallback(\n (element: HTMLElement) => {\n if (!activeKey || centredFor.current === activeKey) return\n centredFor.current = activeKey\n element.scrollIntoView?.({ block: 'center', behavior: 'smooth' })\n },\n [activeKey]\n )\n\n return useCallback(\n (pageNumber: number) => {\n const boxes = boxesByPage.get(pageNumber)\n return boxes ? (\n <PdfPassageHighlights boxes={boxes} activeId={active} onActiveDrawn={centre} />\n ) : null\n },\n [boxesByPage, active, centre]\n )\n}\n"],
5
- "mappings": ";AAsDQ;AA/CR,SAAS,aAAa,WAAW,SAAS,cAA8B;AACxE,SAAS,qBAAqB,yBAAyB;AACvD,SAAS,0BAA0B;AACnC,SAAS,gCAAgC;AACzC,SAAS,4BAA4B;AACrC,SAAS,0BAA0B;AAEnC,MAAM,OAA0B,CAAC;AACjC,MAAM,eAAuC,CAAC;AAGvC,SAAS,wBACd,YACmC;AACnC,QAAM,WAAW,yBAAyB,GAAG,eAAe;AAC5D,QAAM,QAAQ,QAAQ,MAAM,IAAI,IAAI,QAAQ,GAAG,CAAC,QAAQ,CAAC;AACzD,QAAM,SAAS,oBAAoB,CAAC,MAAM,EAAE,iBAAiB,aAAa,IAAI;AAE9E,QAAM,EAAE,MAAM,OAAO,IAAI,kBAAkB,YAAY,SAAS;AAAA,IAC9D,SAAS,MAAM,OAAO,KAAK,CAAC,CAAC;AAAA,EAC/B,CAAC;AACD,QAAM,EAAE,gBAAgB,IAAI,mBAAmB,QAAQ,QAAQ,YAAY;AAC3E,QAAM,cAAc;AAAA,IAClB,MAAM,mBAAmB,iBAAiB,EAAE,OAAO,OAAO,CAAC;AAAA,IAC3D,CAAC,iBAAiB,OAAO,MAAM;AAAA,EACjC;AAIA,QAAM,aAAa,OAAsB,IAAI;AAC7C,QAAM,YAAY,SAAS,GAAG,UAAU,IAAI,MAAM,KAAK;AACvD,YAAU,MAAM;AACd,QAAI,CAAC,UAAW,YAAW,UAAU;AAAA,EACvC,GAAG,CAAC,SAAS,CAAC;AACd,QAAM,SAAS;AAAA,IACb,CAAC,YAAyB;AACxB,UAAI,CAAC,aAAa,WAAW,YAAY,UAAW;AACpD,iBAAW,UAAU;AACrB,cAAQ,iBAAiB,EAAE,OAAO,UAAU,UAAU,SAAS,CAAC;AAAA,IAClE;AAAA,IACA,CAAC,SAAS;AAAA,EACZ;AAEA,SAAO;AAAA,IACL,CAAC,eAAuB;AACtB,YAAM,QAAQ,YAAY,IAAI,UAAU;AACxC,aAAO,QACL,oBAAC,wBAAqB,OAAc,UAAU,QAAQ,eAAe,QAAQ,IAC3E;AAAA,IACN;AAAA,IACA,CAAC,aAAa,QAAQ,MAAM;AAAA,EAC9B;AACF;",
4
+ "sourcesContent": ["/**\n * The passages a citation lights, drawn over the PDF page by page: a fact's cited passages (its\n * Citation popover is open) and the passage a citation opened the document at, as the parsed view\n * lights them. Nothing is fetched until one is lit; the parsed chunks are the parsed view's own\n * query, so opening that tab afterwards costs nothing more.\n */\n\nimport { useCallback, useEffect, useMemo, useRef, type ReactNode } from 'react'\nimport { useArbiSessionState, useArbiSessionStore, useParsedDocument } from '@arbidocs/react'\nimport { useProcessedChunks } from '@arbidocs/react/viewers'\nimport { useViewerPassageCitation } from '../support'\nimport { PdfPassageHighlights } from './PdfPassageHighlights'\nimport { passageBoxesByPage, passagePlaced } from './passageHighlights'\n\nconst NONE: readonly string[] = []\nconst NO_FOOTNOTES: Record<string, string> = {}\n\n/** A PDF viewer's page overlay for the document being viewed: `(page) => highlights | null`. */\nexport function usePdfPassageHighlights(\n documentId: string | undefined\n): (pageNumber: number) => ReactNode {\n const citedIds = useViewerPassageCitation()?.highlighted ?? NONE\n const cited = useMemo(() => new Set(citedIds), [citedIds])\n const active = useArbiSessionState((s) => s.viewingDocument?.passageId ?? null)\n\n const { data: parsed } = useParsedDocument(documentId, 'final', {\n enabled: cited.size > 0 || !!active,\n })\n const { processedChunks } = useProcessedChunks(parsed?.chunks, NO_FOOTNOTES)\n const boxesByPage = useMemo(\n () => passageBoxesByPage(processedChunks, { cited, active }),\n [processedChunks, cited, active]\n )\n\n // The passage being read could not be placed on its page (a document parsed before passages had\n // boxes): the text view marks it instead.\n const session = useArbiSessionStore()\n const fellBackFor = useRef<string | null>(null)\n useEffect(() => {\n if (!active || !parsed || !documentId) return\n const key = `${documentId}:${active}`\n if (fellBackFor.current === key || passagePlaced(processedChunks, active)) return\n fellBackFor.current = key\n session.setDocumentViewer({ tab: 'html' })\n }, [active, parsed, processedChunks, documentId, session])\n\n // The passage being read is brought into view once, when its page first draws it: the viewer\n // opens the page, this centres the passage on it, and scrolling away is then left alone.\n const centredFor = useRef<string | null>(null)\n const activeKey = active ? `${documentId}:${active}` : null\n useEffect(() => {\n if (!activeKey) centredFor.current = null\n }, [activeKey])\n const centre = useCallback(\n (element: HTMLElement) => {\n if (!activeKey || centredFor.current === activeKey) return\n centredFor.current = activeKey\n element.scrollIntoView?.({ block: 'center', behavior: 'smooth' })\n },\n [activeKey]\n )\n\n return useCallback(\n (pageNumber: number) => {\n const boxes = boxesByPage.get(pageNumber)\n return boxes ? (\n <PdfPassageHighlights boxes={boxes} activeId={active} onActiveDrawn={centre} />\n ) : null\n },\n [boxesByPage, active, centre]\n )\n}\n"],
5
+ "mappings": ";AAkEQ;AA3DR,SAAS,aAAa,WAAW,SAAS,cAA8B;AACxE,SAAS,qBAAqB,qBAAqB,yBAAyB;AAC5E,SAAS,0BAA0B;AACnC,SAAS,gCAAgC;AACzC,SAAS,4BAA4B;AACrC,SAAS,oBAAoB,qBAAqB;AAElD,MAAM,OAA0B,CAAC;AACjC,MAAM,eAAuC,CAAC;AAGvC,SAAS,wBACd,YACmC;AACnC,QAAM,WAAW,yBAAyB,GAAG,eAAe;AAC5D,QAAM,QAAQ,QAAQ,MAAM,IAAI,IAAI,QAAQ,GAAG,CAAC,QAAQ,CAAC;AACzD,QAAM,SAAS,oBAAoB,CAAC,MAAM,EAAE,iBAAiB,aAAa,IAAI;AAE9E,QAAM,EAAE,MAAM,OAAO,IAAI,kBAAkB,YAAY,SAAS;AAAA,IAC9D,SAAS,MAAM,OAAO,KAAK,CAAC,CAAC;AAAA,EAC/B,CAAC;AACD,QAAM,EAAE,gBAAgB,IAAI,mBAAmB,QAAQ,QAAQ,YAAY;AAC3E,QAAM,cAAc;AAAA,IAClB,MAAM,mBAAmB,iBAAiB,EAAE,OAAO,OAAO,CAAC;AAAA,IAC3D,CAAC,iBAAiB,OAAO,MAAM;AAAA,EACjC;AAIA,QAAM,UAAU,oBAAoB;AACpC,QAAM,cAAc,OAAsB,IAAI;AAC9C,YAAU,MAAM;AACd,QAAI,CAAC,UAAU,CAAC,UAAU,CAAC,WAAY;AACvC,UAAM,MAAM,GAAG,UAAU,IAAI,MAAM;AACnC,QAAI,YAAY,YAAY,OAAO,cAAc,iBAAiB,MAAM,EAAG;AAC3E,gBAAY,UAAU;AACtB,YAAQ,kBAAkB,EAAE,KAAK,OAAO,CAAC;AAAA,EAC3C,GAAG,CAAC,QAAQ,QAAQ,iBAAiB,YAAY,OAAO,CAAC;AAIzD,QAAM,aAAa,OAAsB,IAAI;AAC7C,QAAM,YAAY,SAAS,GAAG,UAAU,IAAI,MAAM,KAAK;AACvD,YAAU,MAAM;AACd,QAAI,CAAC,UAAW,YAAW,UAAU;AAAA,EACvC,GAAG,CAAC,SAAS,CAAC;AACd,QAAM,SAAS;AAAA,IACb,CAAC,YAAyB;AACxB,UAAI,CAAC,aAAa,WAAW,YAAY,UAAW;AACpD,iBAAW,UAAU;AACrB,cAAQ,iBAAiB,EAAE,OAAO,UAAU,UAAU,SAAS,CAAC;AAAA,IAClE;AAAA,IACA,CAAC,SAAS;AAAA,EACZ;AAEA,SAAO;AAAA,IACL,CAAC,eAAuB;AACtB,YAAM,QAAQ,YAAY,IAAI,UAAU;AACxC,aAAO,QACL,oBAAC,wBAAqB,OAAc,UAAU,QAAQ,eAAe,QAAQ,IAC3E;AAAA,IACN;AAAA,IACA,CAAC,aAAa,QAAQ,MAAM;AAAA,EAC9B;AACF;",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,11 @@
1
+ import { type ArbiSessionStore } from '@arbidocs/react';
2
+ type Session = Pick<ArbiSessionStore, 'setViewingDocument' | 'setDocumentViewer' | 'openPanel'>;
3
+ /**
4
+ * Open a document in a window of its own, to be shared in a call (Share screen/tab): the viewer's
5
+ * clean view, only its pages (a presentation's are its slides). Call it from a click: the browser
6
+ * opens a window only for one.
7
+ */
8
+ export declare function openDocumentToShare(session: Session, doc: {
9
+ id: string;
10
+ }): void;
11
+ export {};
@@ -0,0 +1,11 @@
1
+ "use client";
2
+ import { DOCUMENT_VIEWER_PANEL } from "@arbidocs/react";
3
+ function openDocumentToShare(session, doc) {
4
+ session.setViewingDocument({ id: doc.id, page: null });
5
+ session.setDocumentViewer({ presenting: true, tab: "pdf" });
6
+ session.openPanel(DOCUMENT_VIEWER_PANEL, "popout");
7
+ }
8
+ export {
9
+ openDocumentToShare
10
+ };
11
+ //# sourceMappingURL=shareDocument.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/connection/viewer/shareDocument.ts"],
4
+ "sourcesContent": ["import { DOCUMENT_VIEWER_PANEL, type ArbiSessionStore } from '@arbidocs/react'\n\ntype Session = Pick<ArbiSessionStore, 'setViewingDocument' | 'setDocumentViewer' | 'openPanel'>\n\n/**\n * Open a document in a window of its own, to be shared in a call (Share screen/tab): the viewer's\n * clean view, only its pages (a presentation's are its slides). Call it from a click: the browser\n * opens a window only for one.\n */\nexport function openDocumentToShare(session: Session, doc: { id: string }): void {\n session.setViewingDocument({ id: doc.id, page: null })\n session.setDocumentViewer({ presenting: true, tab: 'pdf' })\n session.openPanel(DOCUMENT_VIEWER_PANEL, 'popout')\n}\n"],
5
+ "mappings": ";AAAA,SAAS,6BAAoD;AAStD,SAAS,oBAAoB,SAAkB,KAA2B;AAC/E,UAAQ,mBAAmB,EAAE,IAAI,IAAI,IAAI,MAAM,KAAK,CAAC;AACrD,UAAQ,kBAAkB,EAAE,YAAY,MAAM,KAAK,MAAM,CAAC;AAC1D,UAAQ,UAAU,uBAAuB,QAAQ;AACnD;",
6
+ "names": []
7
+ }
@@ -0,0 +1,2 @@
1
+ /** A presentation's slides tab: its own chunk, loaded when a presentation shows. */
2
+ export declare const SlidesTab: import("react").LazyExoticComponent<typeof import("../presentation/ConnectedSlidesTab").ConnectedSlidesTab>;
@@ -0,0 +1,9 @@
1
+ "use client";
2
+ import { lazy } from "react";
3
+ const SlidesTab = lazy(
4
+ () => import("../presentation/ConnectedSlidesTab.js").then((m) => ({ default: m.ConnectedSlidesTab }))
5
+ );
6
+ export {
7
+ SlidesTab
8
+ };
9
+ //# sourceMappingURL=slidesTabChunk.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/connection/viewer/slidesTabChunk.ts"],
4
+ "sourcesContent": ["import { lazy } from 'react'\n\n/** A presentation's slides tab: its own chunk, loaded when a presentation shows. */\nexport const SlidesTab = lazy(() =>\n import('../presentation/ConnectedSlidesTab').then((m) => ({ default: m.ConnectedSlidesTab }))\n)\n"],
5
+ "mappings": ";AAAA,SAAS,YAAY;AAGd,MAAM,YAAY;AAAA,EAAK,MAC5B,OAAO,oCAAoC,EAAE,KAAK,CAAC,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE;AAC9F;",
6
+ "names": []
7
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * The viewer's clean view: popped out with `documentViewer.presenting`, it shows only the document
3
+ * on black (no header, bars or controls), to share in a call or put full screen. Its one control
4
+ * (`CleanViewControl`: full screen, show the controls again) shows while the pointer moves. Popping
5
+ * the viewer back in ends the clean view.
6
+ */
7
+ import { type ReactNode } from 'react';
8
+ export declare function useCleanView(): {
9
+ on: boolean;
10
+ frame: {
11
+ bare: boolean;
12
+ overlay: ReactNode;
13
+ };
14
+ };
@@ -0,0 +1,29 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { useEffect, useRef } from "react";
4
+ import { useArbiSessionState, useArbiSessionStore } from "@arbidocs/react";
5
+ import { CleanViewControl } from "./CleanViewControl.js";
6
+ function useCleanView() {
7
+ const session = useArbiSessionStore();
8
+ const detached = useArbiSessionState((s) => s.documentViewer.detached);
9
+ const presenting = useArbiSessionState((s) => s.documentViewer.presenting);
10
+ const on = detached && presenting;
11
+ const wasDetached = useRef(detached);
12
+ useEffect(() => {
13
+ if (wasDetached.current && !detached && presenting) {
14
+ session.setDocumentViewer({ presenting: false });
15
+ }
16
+ wasDetached.current = detached;
17
+ }, [detached, presenting, session]);
18
+ return {
19
+ on,
20
+ frame: {
21
+ bare: on,
22
+ overlay: on ? /* @__PURE__ */ jsx(CleanViewControl, { onExit: () => session.setDocumentViewer({ presenting: false }) }) : null
23
+ }
24
+ };
25
+ }
26
+ export {
27
+ useCleanView
28
+ };
29
+ //# sourceMappingURL=useCleanView.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/connection/viewer/useCleanView.tsx"],
4
+ "sourcesContent": ["/**\n * The viewer's clean view: popped out with `documentViewer.presenting`, it shows only the document\n * on black (no header, bars or controls), to share in a call or put full screen. Its one control\n * (`CleanViewControl`: full screen, show the controls again) shows while the pointer moves. Popping\n * the viewer back in ends the clean view.\n */\n\nimport { useEffect, useRef, type ReactNode } from 'react'\nimport { useArbiSessionState, useArbiSessionStore } from '@arbidocs/react'\nimport { CleanViewControl } from './CleanViewControl'\n\nexport function useCleanView(): { on: boolean; frame: { bare: boolean; overlay: ReactNode } } {\n const session = useArbiSessionStore()\n const detached = useArbiSessionState((s) => s.documentViewer.detached)\n const presenting = useArbiSessionState((s) => s.documentViewer.presenting)\n const on = detached && presenting\n\n // Back in the app's window: the next pop-out shows the controls as usual.\n const wasDetached = useRef(detached)\n useEffect(() => {\n if (wasDetached.current && !detached && presenting) {\n session.setDocumentViewer({ presenting: false })\n }\n wasDetached.current = detached\n }, [detached, presenting, session])\n\n return {\n on,\n frame: {\n bare: on,\n overlay: on ? (\n <CleanViewControl onExit={() => session.setDocumentViewer({ presenting: false })} />\n ) : null,\n },\n }\n}\n"],
5
+ "mappings": ";AA+BQ;AAxBR,SAAS,WAAW,cAA8B;AAClD,SAAS,qBAAqB,2BAA2B;AACzD,SAAS,wBAAwB;AAE1B,SAAS,eAA8E;AAC5F,QAAM,UAAU,oBAAoB;AACpC,QAAM,WAAW,oBAAoB,CAAC,MAAM,EAAE,eAAe,QAAQ;AACrE,QAAM,aAAa,oBAAoB,CAAC,MAAM,EAAE,eAAe,UAAU;AACzE,QAAM,KAAK,YAAY;AAGvB,QAAM,cAAc,OAAO,QAAQ;AACnC,YAAU,MAAM;AACd,QAAI,YAAY,WAAW,CAAC,YAAY,YAAY;AAClD,cAAQ,kBAAkB,EAAE,YAAY,MAAM,CAAC;AAAA,IACjD;AACA,gBAAY,UAAU;AAAA,EACxB,GAAG,CAAC,UAAU,YAAY,OAAO,CAAC;AAElC,SAAO;AAAA,IACL;AAAA,IACA,OAAO;AAAA,MACL,MAAM;AAAA,MACN,SAAS,KACP,oBAAC,oBAAiB,QAAQ,MAAM,QAAQ,kBAAkB,EAAE,YAAY,MAAM,CAAC,GAAG,IAChF;AAAA,IACN;AAAA,EACF;AACF;",
6
+ "names": []
7
+ }
@@ -60,6 +60,7 @@ export declare function useViewedDocument(documentId: string): {
60
60
  isBlobArtifact: boolean;
61
61
  savedDocumentId: string | null;
62
62
  isArtifact: boolean;
63
+ isPresentation: boolean;
63
64
  liveKind: import("@arbidocs/react/artifacts").ArtifactPreviewKind | null;
64
65
  liveSource: string;
65
66
  isDocx: boolean;
@@ -10,7 +10,13 @@ import {
10
10
  artifactKindFromMode,
11
11
  useArtifactSource
12
12
  } from "@arbidocs/react/artifacts";
13
- import { isAudioFile, isDownloadOnlyFile, isImageFile, isVideoFile } from "@arbidocs/react/ui";
13
+ import {
14
+ isAudioFile,
15
+ isDownloadOnlyFile,
16
+ isImageFile,
17
+ isPresentationFileName,
18
+ isVideoFile
19
+ } from "@arbidocs/react/ui";
14
20
  import { savedDocumentIdFor } from "@arbidocs/react/shell";
15
21
  import { isDocumentLabel, summariseDocTags } from "../../files/doc-labels.js";
16
22
  import { useConnectedWorkspace } from "../ConnectionProvider.js";
@@ -55,6 +61,7 @@ function useViewedDocument(documentId) {
55
61
  const isAudio = isWebmFile && webmHasVideoTrack === false ? true : isAudioFile(fileName);
56
62
  const isBlobArtifact = streamingDoc?.mode === "image" || documentData?.wp_type === "artifact" && (isImage || isVideo || isAudio);
57
63
  const isArtifact = (!!streamingDoc || isTextDraft || documentData?.wp_type === "artifact" || isMarkdown) && !isBlobArtifact;
64
+ const isPresentation = draftDoc?.kind === "presentation" || isPresentationFileName(documentData?.file_name, documentData?.folder);
58
65
  const liveKind = isArtifact ? artifactKindFromMode(streamingDoc?.mode ?? void 0) ?? artifactKindFromFileName(fileName) : null;
59
66
  const savedDocumentId = savedDocumentIdFor({
60
67
  documentId,
@@ -96,6 +103,7 @@ function useViewedDocument(documentId) {
96
103
  isBlobArtifact,
97
104
  savedDocumentId,
98
105
  isArtifact,
106
+ isPresentation,
99
107
  liveKind,
100
108
  liveSource,
101
109
  isDocx: DOCX_EXTENSIONS.has(fileExtension(fileName)),
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/connection/viewer/useViewedDocument.ts"],
4
- "sourcesContent": ["/**\n * What the document viewer is looking at: the document record, the streaming / draft overlay,\n * the kind of content (artifact, live artifact, media, Word, sheet, ...) and whether it has parsed\n * text.\n */\n\nimport { useEffect, useMemo, useState } from 'react'\nimport {\n useArbiSessionState,\n useDocument,\n useParsedDocument,\n type ArbiDraftDocument,\n} from '@arbidocs/react'\nimport {\n artifactKindFromFileName,\n artifactKindFromMode,\n useArtifactSource,\n} from '@arbidocs/react/artifacts'\nimport { isAudioFile, isDownloadOnlyFile, isImageFile, isVideoFile } from '@arbidocs/react/ui'\nimport { savedDocumentIdFor } from '@arbidocs/react/shell'\nimport { isDocumentLabel, summariseDocTags } from '../../files/doc-labels'\nimport { useConnectedWorkspace } from '../ConnectionProvider'\nimport { useConnectedTags } from '../workspaceData'\nimport { useViewerStreamingDocument } from './support'\n\nconst DOCX_EXTENSIONS = new Set(['.docx', '.doc'])\nconst XLSX_EXTENSIONS = new Set(['.xlsx', '.xls'])\nconst EMAIL_EXTENSIONS = new Set(['.eml', '.msg'])\n\n/** Lower-cased extension with its dot (`.pdf`), or `''`. */\nexport function fileExtension(fileName: string | null | undefined): string {\n if (!fileName) return ''\n return fileName.substring(fileName.lastIndexOf('.')).toLowerCase()\n}\n\nexport function useViewedDocument(documentId: string) {\n // `.webm` is ambiguous by extension alone (audio-only recordings use the same container as\n // video). Resolved once the bytes are here; null = not yet, and the extension's guess stands.\n const [webmHasVideoTrack, setWebmHasVideoTrack] = useState<boolean | null>(null)\n useEffect(() => setWebmHasVideoTrack(null), [documentId])\n\n // An artifact being generated in a chat.\n const streamingDoc = useViewerStreamingDocument(documentId)\n const isStreaming = !!streamingDoc && !streamingDoc.isComplete\n // A draft the user started (blank document, voice note) with no backend record yet.\n const draftDoc = useArbiSessionState<ArbiDraftDocument | undefined>(\n (state) => state.draftDocuments[documentId]\n )\n const isDraft = !!draftDoc\n // A capture draft (photo/video/audio) is its recorder; a text draft opens in the Word editor.\n const isCaptureDraft =\n draftDoc?.kind === 'audio' || draftDoc?.kind === 'photo' || draftDoc?.kind === 'video'\n const isTextDraft = draftDoc?.kind === 'text'\n\n const { workspaceId, live } = useConnectedWorkspace()\n const { data: record } = useDocument(documentId, {\n enabled: live && !!workspaceId && !isStreaming && !isDraft,\n // A new version (Save version, a signed copy) is processed before its PDF exists: keep\n // re-reading until it is done, so the PDF tab and the signing tools come back on their own.\n pollWhileProcessing: true,\n })\n // A record of the previously viewed document is not this one.\n const documentData = record?.external_id === documentId ? record : undefined\n\n // Labels for the bar the PDF view carries (the text view derives its own).\n const { data: tags } = useConnectedTags()\n const labelSummaries = useMemo(\n () => summariseDocTags(documentData?.doctags ?? [], tags.filter(isDocumentLabel)),\n [documentData, tags]\n )\n\n // A document renders on the artifact path (Word editor or live preview, and Versions) rather\n // than the PDF path when (1) an artifact is streaming, (2) it is an artifact (AI drafts are\n // stored as .docx, html/react artifacts as .html/.jsx), or (3) it is an uploaded `*.md` (editing\n // and history are its own view; the PDF is a fallback).\n const fileName = documentData?.file_name\n const isMarkdown = fileExtension(fileName) === '.md'\n const isImage = isImageFile(fileName)\n const isWebmFile = fileExtension(fileName) === '.webm'\n // A resolved \"no video track\" wins over the extension's guess (always video for .webm).\n const isVideo = isWebmFile && webmHasVideoTrack === false ? false : isVideoFile(fileName)\n const isAudio = isWebmFile && webmHasVideoTrack === false ? true : isAudioFile(fileName)\n // Generated artifacts carried as a blob (image/audio/video) render in the media viewer.\n const isBlobArtifact =\n streamingDoc?.mode === 'image' ||\n (documentData?.wp_type === 'artifact' && (isImage || isVideo || isAudio))\n const isArtifact =\n (!!streamingDoc || isTextDraft || documentData?.wp_type === 'artifact' || isMarkdown) &&\n !isBlobArtifact\n // html/react artifacts render live in a sandbox; the streaming mode or the saved extension says.\n const liveKind = isArtifact\n ? (artifactKindFromMode(streamingDoc?.mode ?? undefined) ?? artifactKindFromFileName(fileName))\n : null\n\n // The saved document a chat drafts in while it is open here: a saved artifact or Word document.\n const savedDocumentId = savedDocumentIdFor({\n documentId,\n isDraft,\n isStreaming,\n isBlobArtifact,\n documentData,\n })\n\n // Parsed text is stripped of markup: a live artifact needs its stored source.\n const { data: liveSourceFetched } = useArtifactSource(\n documentId,\n !!liveKind && !streamingDoc && !!documentData && !isDraft\n )\n const liveSource = streamingDoc ? streamingDoc.content : (liveSourceFetched ?? '')\n\n // The text view exists whenever there is parsed content, for any file (a recording's\n // transcript too). `low-content` is a terminal status with indexed passages, just sparse.\n const hasParsedDocStatus =\n documentData?.status === 'completed' || documentData?.status === 'low-content'\n const wantsParsedDoc =\n !!documentId && live && !isStreaming && !isDraft && !isBlobArtifact && hasParsedDocStatus\n const { data: parsedDoc, isPending: isParsedDocPending } = useParsedDocument(\n documentId,\n 'final',\n { enabled: wantsParsedDoc }\n )\n // Loading until the text is read, including while the query still waits for the workspace to\n // open: on a reload the record comes back from the saved query cache before the session has\n // opened the workspace, and the text view a passage link asked for must not be given up then.\n // A document with no text to read (or no workspace at all) is settled at once.\n const isParsedDocLoading = wantsParsedDoc && !!workspaceId && isParsedDocPending\n const hasParsedContent =\n ((parsedDoc as { chunks?: unknown[] } | undefined)?.chunks?.length ?? 0) > 0\n\n return {\n workspaceId,\n documentData,\n streamingDoc,\n isStreaming,\n draftDoc,\n isDraft,\n isCaptureDraft,\n isTextDraft,\n labelSummaries,\n isImage,\n isWebmFile,\n setWebmHasVideoTrack,\n isVideo,\n isAudio,\n isMedia: isVideo || isAudio,\n isBlobArtifact,\n savedDocumentId,\n isArtifact,\n liveKind,\n liveSource,\n isDocx: DOCX_EXTENSIONS.has(fileExtension(fileName)),\n isXlsx: XLSX_EXTENSIONS.has(fileExtension(fileName)),\n isEmail: EMAIL_EXTENSIONS.has(fileExtension(fileName)),\n isDownloadOnly: isDownloadOnlyFile(fileName),\n isParsedDocLoading,\n hasParsedContent,\n }\n}\n\nexport type ViewedDocument = ReturnType<typeof useViewedDocument>\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * What the document viewer is looking at: the document record, the streaming / draft overlay,\n * the kind of content (artifact, live artifact, media, Word, sheet, ...) and whether it has parsed\n * text.\n */\n\nimport { useEffect, useMemo, useState } from 'react'\nimport {\n useArbiSessionState,\n useDocument,\n useParsedDocument,\n type ArbiDraftDocument,\n} from '@arbidocs/react'\nimport {\n artifactKindFromFileName,\n artifactKindFromMode,\n useArtifactSource,\n} from '@arbidocs/react/artifacts'\nimport {\n isAudioFile,\n isDownloadOnlyFile,\n isImageFile,\n isPresentationFileName,\n isVideoFile,\n} from '@arbidocs/react/ui'\nimport { savedDocumentIdFor } from '@arbidocs/react/shell'\nimport { isDocumentLabel, summariseDocTags } from '../../files/doc-labels'\nimport { useConnectedWorkspace } from '../ConnectionProvider'\nimport { useConnectedTags } from '../workspaceData'\nimport { useViewerStreamingDocument } from './support'\n\nconst DOCX_EXTENSIONS = new Set(['.docx', '.doc'])\nconst XLSX_EXTENSIONS = new Set(['.xlsx', '.xls'])\nconst EMAIL_EXTENSIONS = new Set(['.eml', '.msg'])\n\n/** Lower-cased extension with its dot (`.pdf`), or `''`. */\nexport function fileExtension(fileName: string | null | undefined): string {\n if (!fileName) return ''\n return fileName.substring(fileName.lastIndexOf('.')).toLowerCase()\n}\n\nexport function useViewedDocument(documentId: string) {\n // `.webm` is ambiguous by extension alone (audio-only recordings use the same container as\n // video). Resolved once the bytes are here; null = not yet, and the extension's guess stands.\n const [webmHasVideoTrack, setWebmHasVideoTrack] = useState<boolean | null>(null)\n useEffect(() => setWebmHasVideoTrack(null), [documentId])\n\n // An artifact being generated in a chat.\n const streamingDoc = useViewerStreamingDocument(documentId)\n const isStreaming = !!streamingDoc && !streamingDoc.isComplete\n // A draft the user started (blank document, voice note) with no backend record yet.\n const draftDoc = useArbiSessionState<ArbiDraftDocument | undefined>(\n (state) => state.draftDocuments[documentId]\n )\n const isDraft = !!draftDoc\n // A capture draft (photo/video/audio) is its recorder; a text draft opens in the Word editor.\n const isCaptureDraft =\n draftDoc?.kind === 'audio' || draftDoc?.kind === 'photo' || draftDoc?.kind === 'video'\n const isTextDraft = draftDoc?.kind === 'text'\n\n const { workspaceId, live } = useConnectedWorkspace()\n const { data: record } = useDocument(documentId, {\n enabled: live && !!workspaceId && !isStreaming && !isDraft,\n // A new version (Save version, a signed copy) is processed before its PDF exists: keep\n // re-reading until it is done, so the PDF tab and the signing tools come back on their own.\n pollWhileProcessing: true,\n })\n // A record of the previously viewed document is not this one.\n const documentData = record?.external_id === documentId ? record : undefined\n\n // Labels for the bar the PDF view carries (the text view derives its own).\n const { data: tags } = useConnectedTags()\n const labelSummaries = useMemo(\n () => summariseDocTags(documentData?.doctags ?? [], tags.filter(isDocumentLabel)),\n [documentData, tags]\n )\n\n // A document renders on the artifact path (Word editor or live preview, and Versions) rather\n // than the PDF path when (1) an artifact is streaming, (2) it is an artifact (AI drafts are\n // stored as .docx, html/react artifacts as .html/.jsx), or (3) it is an uploaded `*.md` (editing\n // and history are its own view; the PDF is a fallback).\n const fileName = documentData?.file_name\n const isMarkdown = fileExtension(fileName) === '.md'\n const isImage = isImageFile(fileName)\n const isWebmFile = fileExtension(fileName) === '.webm'\n // A resolved \"no video track\" wins over the extension's guess (always video for .webm).\n const isVideo = isWebmFile && webmHasVideoTrack === false ? false : isVideoFile(fileName)\n const isAudio = isWebmFile && webmHasVideoTrack === false ? true : isAudioFile(fileName)\n // Generated artifacts carried as a blob (image/audio/video) render in the media viewer.\n const isBlobArtifact =\n streamingDoc?.mode === 'image' ||\n (documentData?.wp_type === 'artifact' && (isImage || isVideo || isAudio))\n const isArtifact =\n (!!streamingDoc || isTextDraft || documentData?.wp_type === 'artifact' || isMarkdown) &&\n !isBlobArtifact\n // A presentation (saved, or a new one): edited on its slides tab; its PDF is its slides.\n const isPresentation =\n draftDoc?.kind === 'presentation' ||\n isPresentationFileName(documentData?.file_name, documentData?.folder)\n // html/react artifacts render live in a sandbox; the streaming mode or the saved extension says.\n const liveKind = isArtifact\n ? (artifactKindFromMode(streamingDoc?.mode ?? undefined) ?? artifactKindFromFileName(fileName))\n : null\n\n // The saved document a chat drafts in while it is open here: a saved artifact or Word document.\n const savedDocumentId = savedDocumentIdFor({\n documentId,\n isDraft,\n isStreaming,\n isBlobArtifact,\n documentData,\n })\n\n // Parsed text is stripped of markup: a live artifact needs its stored source.\n const { data: liveSourceFetched } = useArtifactSource(\n documentId,\n !!liveKind && !streamingDoc && !!documentData && !isDraft\n )\n const liveSource = streamingDoc ? streamingDoc.content : (liveSourceFetched ?? '')\n\n // The text view exists whenever there is parsed content, for any file (a recording's\n // transcript too). `low-content` is a terminal status with indexed passages, just sparse.\n const hasParsedDocStatus =\n documentData?.status === 'completed' || documentData?.status === 'low-content'\n const wantsParsedDoc =\n !!documentId && live && !isStreaming && !isDraft && !isBlobArtifact && hasParsedDocStatus\n const { data: parsedDoc, isPending: isParsedDocPending } = useParsedDocument(\n documentId,\n 'final',\n { enabled: wantsParsedDoc }\n )\n // Loading until the text is read, including while the query still waits for the workspace to\n // open: on a reload the record comes back from the saved query cache before the session has\n // opened the workspace, and the text view a passage link asked for must not be given up then.\n // A document with no text to read (or no workspace at all) is settled at once.\n const isParsedDocLoading = wantsParsedDoc && !!workspaceId && isParsedDocPending\n const hasParsedContent =\n ((parsedDoc as { chunks?: unknown[] } | undefined)?.chunks?.length ?? 0) > 0\n\n return {\n workspaceId,\n documentData,\n streamingDoc,\n isStreaming,\n draftDoc,\n isDraft,\n isCaptureDraft,\n isTextDraft,\n labelSummaries,\n isImage,\n isWebmFile,\n setWebmHasVideoTrack,\n isVideo,\n isAudio,\n isMedia: isVideo || isAudio,\n isBlobArtifact,\n savedDocumentId,\n isArtifact,\n isPresentation,\n liveKind,\n liveSource,\n isDocx: DOCX_EXTENSIONS.has(fileExtension(fileName)),\n isXlsx: XLSX_EXTENSIONS.has(fileExtension(fileName)),\n isEmail: EMAIL_EXTENSIONS.has(fileExtension(fileName)),\n isDownloadOnly: isDownloadOnlyFile(fileName),\n isParsedDocLoading,\n hasParsedContent,\n }\n}\n\nexport type ViewedDocument = ReturnType<typeof useViewedDocument>\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { jsx } from "react/jsx-runtime";
3
3
  import { useEffect, useRef } from "react";
4
- import { Code, FileText, History, MonitorPlay } from "lucide-react";
4
+ import { Code, FileText, History, MonitorPlay, Presentation } from "lucide-react";
5
5
  import { friendlyFileType } from "@arbidocs/react/ui";
6
6
  import {
7
7
  AudIcon,
@@ -20,6 +20,7 @@ function useViewerTabs(doc, isCompact, hasHistory = false) {
20
20
  const {
21
21
  documentData,
22
22
  isArtifact,
23
+ isPresentation,
23
24
  isDraft,
24
25
  isStreaming,
25
26
  isDocx,
@@ -46,7 +47,11 @@ function useViewerTabs(doc, isCompact, hasHistory = false) {
46
47
  const hasDocumentData = !!documentData;
47
48
  const documentKey = documentData?.external_id;
48
49
  useEffect(() => {
49
- if (isArtifact && (activeTab === "pdf" || !liveKind && activeTab === "docx")) {
50
+ if (isPresentation && hasDocumentData && activeTab === "pdf") {
51
+ setActiveTab("slides");
52
+ } else if (!isPresentation && documentData && activeTab === "slides") {
53
+ setActiveTab(isDocx ? "docx" : isXlsx ? "xlsx" : "pdf");
54
+ } else if (isArtifact && (activeTab === "pdf" || !liveKind && activeTab === "docx")) {
50
55
  setActiveTab(liveKind ? "preview" : "edit");
51
56
  } else if (isDocx && activeTab === "pdf") {
52
57
  setActiveTab("docx");
@@ -57,7 +62,7 @@ function useViewerTabs(doc, isCompact, hasHistory = false) {
57
62
  } else if (!isArtifact && !isDocx && !isXlsx && documentData && (activeTab === "docx" || activeTab === "xlsx")) {
58
63
  setActiveTab("pdf");
59
64
  }
60
- }, [hasDocumentData, documentKey, isArtifact, isDocx, isXlsx, liveKind]);
65
+ }, [hasDocumentData, documentKey, isArtifact, isDocx, isXlsx, liveKind, isPresentation]);
61
66
  useEffect(() => {
62
67
  if (!tabRequest || !documentKey || tabRequest.documentId !== documentKey) return;
63
68
  phoneDefaultDecidedFor.current = documentKey;
@@ -111,6 +116,15 @@ function useViewerTabs(doc, isCompact, hasHistory = false) {
111
116
  label: tabLabel("versions", "Versions")
112
117
  };
113
118
  const viewerTabs = [
119
+ // A presentation's slides, edited; then its PDF (the slides as saved), once it has one.
120
+ ...isPresentation ? [
121
+ {
122
+ id: "slides",
123
+ icon: /* @__PURE__ */ jsx(Presentation, { className: "size-5" }),
124
+ tooltip: "Slides",
125
+ label: tabLabel("slides", "Slides")
126
+ }
127
+ ] : [],
114
128
  ...isArtifact ? [
115
129
  ...liveKind ? [
116
130
  {
@@ -152,7 +166,7 @@ function useViewerTabs(doc, isCompact, hasHistory = false) {
152
166
  label: tabLabel("xlsx", "Sheet")
153
167
  }
154
168
  ] : [],
155
- { id: "pdf", ...mediaTab, label: tabLabel("pdf", mediaTab.tooltip) },
169
+ ...isPresentation && isDraft ? [] : [{ id: "pdf", ...mediaTab, label: tabLabel("pdf", mediaTab.tooltip) }],
156
170
  ...hasVersionsTab ? [versionsTab] : []
157
171
  ],
158
172
  ...(hasParsedContent || compareId) && !liveKind ? [
@@ -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 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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",
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, Presentation } 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 isPresentation,\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 presentation opens on its slides; another document never shows that tab.\n if (isPresentation && hasDocumentData && activeTab === 'pdf') {\n setActiveTab('slides')\n } else if (!isPresentation && documentData && activeTab === 'slides') {\n setActiveTab(isDocx ? 'docx' : isXlsx ? 'xlsx' : 'pdf')\n }\n // A Word artifact (an AI draft, stored as .docx) has one Word tab, 'edit', not a DOCX tab.\n else 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, isPresentation])\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 // A presentation's slides, edited; then its PDF (the slides as saved), once it has one.\n ...(isPresentation\n ? [\n {\n id: 'slides',\n icon: <Presentation className=\"size-5\" />,\n tooltip: 'Slides',\n label: tabLabel('slides', 'Slides'),\n },\n ]\n : []),\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 ...(isPresentation && isDraft\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
  }
@@ -8,7 +8,7 @@
8
8
  * The dashboard's Start band, Files ("Create new") and, headless, the slash menu use it.
9
9
  */
10
10
  import { type ReactNode } from 'react';
11
- import { type WorkflowDefinition, type WorkflowInputs, type WorkflowLanding } from '../../agents/workflows/types';
11
+ import { type OnWorkflowLaunch, type WorkflowDefinition, type WorkflowInputs, type WorkflowLanding } from '../../agents/workflows/types';
12
12
  import { type StartTile } from '../../home/StartTiles';
13
13
  export interface ConnectedWorkflowStartProps {
14
14
  workflows: WorkflowDefinition[];
@@ -29,9 +29,21 @@ export interface ConnectedWorkflowStartProps {
29
29
  landing?: WorkflowLanding;
30
30
  /** A prompt run's own send (a chat that is not the session's conversation). See `useLaunchWorkflow`. */
31
31
  send?: (prompt: string) => void;
32
+ /**
33
+ * Run a launch here instead of the usual way (`useLaunchWorkflow`): a surface that wants the
34
+ * result itself, e.g. the presentation, which adds a generated image to its clips. The dialog
35
+ * shows it running until it resolves, closes then, and stays open if it throws.
36
+ */
37
+ onLaunch?: OnWorkflowLaunch;
38
+ /**
39
+ * Files added from a `documents` field are uploaded right in the field instead of through the
40
+ * host's upload dialog: for a dialog in a popped-out window, where the host's dialog would open
41
+ * in the app's window, out of sight, and block this one.
42
+ */
43
+ uploadInPlace?: boolean;
32
44
  /** The host's own "Add" control, offered when a workflow needs files and there are none. */
33
45
  addFilesAction?: ReactNode;
34
46
  tileTestId?: (workflow: WorkflowDefinition) => string | undefined;
35
47
  disabledReason?: (workflow: WorkflowDefinition) => string | undefined;
36
48
  }
37
- export declare function ConnectedWorkflowStart({ workflows, landing, send, addFilesAction, ...rest }: ConnectedWorkflowStartProps): import("react").JSX.Element;
49
+ export declare function ConnectedWorkflowStart({ workflows, landing, send, addFilesAction, onLaunch: launchHere, uploadInPlace, ...rest }: ConnectedWorkflowStartProps): import("react").JSX.Element;
@@ -16,9 +16,12 @@ function ConnectedWorkflowStart({
16
16
  landing,
17
17
  send,
18
18
  addFilesAction,
19
+ onLaunch: launchHere,
20
+ uploadInPlace = false,
19
21
  ...rest
20
22
  }) {
21
- const onLaunch = useLaunchWorkflow({ landing, send });
23
+ const launchUsually = useLaunchWorkflow({ landing, send });
24
+ const onLaunch = launchHere ?? launchUsually;
22
25
  const hostIcon = useHost().workflows?.renderIcon;
23
26
  const renderIcon = useCallback(
24
27
  (key) => hostIcon?.(key) ?? renderWorkflowIcon(key) ?? renderWorkflowIcon("skill"),
@@ -42,7 +45,7 @@ function ConnectedWorkflowStart({
42
45
  workflows,
43
46
  onLaunch,
44
47
  renderIcon,
45
- onAddFiles: openUpload,
48
+ onAddFiles: uploadInPlace ? void 0 : openUpload,
46
49
  agentLabels: AGENT_LABELS,
47
50
  addFilesAction,
48
51
  fieldPlaceholder,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/connection/workflows/ConnectedWorkflowStart.tsx"],
4
- "sourcesContent": ["/**\n * The workflow launcher, wired to run what it launches: `ConnectedWorkflowLauncher` (the\n * workspace's files behind scope and file fields, the user's agents behind \"Run as\") with the one\n * launch handler (`useLaunchWorkflow`), the host's upload dialog for adding files\n * (`environment.openUpload`), and the touches of the annotation operation (its derived name and\n * overwrite warning, \"Annotate N documents\").\n *\n * The dashboard's Start band, Files (\"Create new\") and, headless, the slash menu use it.\n */\n\nimport { useTags } from '@arbidocs/react'\nimport { useCallback, useMemo, type ReactNode } from 'react'\nimport { TriangleAlert } from 'lucide-react'\nimport { documentScopeLabels } from '../../agents/workflows/workspaceScope'\nimport {\n type WorkflowDefinition,\n type WorkflowField,\n type WorkflowInputs,\n type WorkflowLanding,\n} from '../../agents/workflows/types'\nimport { ConnectedWorkflowLauncher } from '../ConnectedWorkflowLauncher'\nimport { type StartTile } from '../../home/StartTiles'\nimport { useBlocksEnvironment } from '../../provider/environment'\nimport { useHost } from '../../provider/host'\nimport { deriveAnnotationName } from '../../agents/workflows/catalogue/annotation-name'\nimport { ANNOTATE_ID, renderWorkflowIcon } from '../../agents/workflows/catalogue/seed'\nimport { useLaunchWorkflow } from './useLaunchWorkflow'\n\n// The agent picker names the person it hands the work to: the default \"Run as\" / \"My assistant\"\n// copy did not say who an assistant is.\nconst AGENT_LABELS = { label: 'Who this runs for', myAssistant: 'Me (your own assistant)' }\n\nexport interface ConnectedWorkflowStartProps {\n workflows: WorkflowDefinition[]\n /** Which of `workflows` get a tile (a filtered or capped view). */\n tileWorkflows?: WorkflowDefinition[]\n /** Render the Start band (off when another surface opens the dialog). */\n showTiles?: boolean\n caption?: string\n captionTestId?: string\n testId?: string\n /** Plain tiles appended to the band (e.g. the \"Create a file\" menu). */\n extraTiles?: StartTile[]\n /** Controlled open workflow id. */\n activeId?: string | null\n onActiveIdChange?: (id: string | null) => void\n initialInputsFor?: (workflow: WorkflowDefinition) => Partial<WorkflowInputs> | undefined\n /** Where launches land, over each workflow's default (`current-chat` = the chat on screen). */\n landing?: WorkflowLanding\n /** A prompt run's own send (a chat that is not the session's conversation). See `useLaunchWorkflow`. */\n send?: (prompt: string) => void\n /** The host's own \"Add\" control, offered when a workflow needs files and there are none. */\n addFilesAction?: ReactNode\n tileTestId?: (workflow: WorkflowDefinition) => string | undefined\n disabledReason?: (workflow: WorkflowDefinition) => string | undefined\n}\n\nexport function ConnectedWorkflowStart({\n workflows,\n landing,\n send,\n addFilesAction,\n ...rest\n}: ConnectedWorkflowStartProps) {\n const onLaunch = useLaunchWorkflow({ landing, send })\n // The host's icons first (a skill pack names its own), then the kit's, then the skill icon.\n const hostIcon = useHost().workflows?.renderIcon\n const renderIcon = useCallback(\n (key: string) => hostIcon?.(key) ?? renderWorkflowIcon(key) ?? renderWorkflowIcon('skill'),\n [hostIcon]\n )\n const { openUpload } = useBlocksEnvironment()\n const { data: workspaceTags = [] } = useTags()\n const tags = useMemo(() => documentScopeLabels(workspaceTags), [workspaceTags])\n\n // The annotation's name is optional: left blank it is taken from the question, which the\n // field's placeholder shows before anything runs.\n const fieldPlaceholder = useCallback(\n (field: WorkflowField, inputs: WorkflowInputs, workflow: WorkflowDefinition) => {\n if (workflow.id !== ANNOTATE_ID || field.name !== 'name') return undefined\n const derived = deriveAnnotationName(String(inputs.description ?? ''))\n return derived ? `Otherwise \u201C${derived}\u201D` : 'Taken from the description'\n },\n []\n )\n\n return (\n <ConnectedWorkflowLauncher\n {...rest}\n workflows={workflows}\n onLaunch={onLaunch}\n renderIcon={renderIcon}\n onAddFiles={openUpload}\n agentLabels={AGENT_LABELS}\n addFilesAction={addFilesAction}\n fieldPlaceholder={fieldPlaceholder}\n submitLabel={({ workflow, matchedCount }) =>\n workflow.id === ANNOTATE_ID && matchedCount !== null\n ? `Annotate ${matchedCount} document${matchedCount !== 1 ? 's' : ''}`\n : undefined\n }\n renderNotice={({ workflow, inputs }) => {\n if (workflow.id !== ANNOTATE_ID) return null\n // A same-named label is reused: warn that this overwrites its stored description and the\n // cell values for the selected documents.\n const name =\n String(inputs.name ?? '').trim() || deriveAnnotationName(String(inputs.description ?? ''))\n const existing = name\n ? tags.find((t) => t.name.toLowerCase() === name.toLowerCase())\n : undefined\n if (!existing) return null\n return (\n <div\n className=\"flex items-start gap-2 rounded-md border border-amber-500/40 bg-amber-500/10 px-3 py-2 text-sm text-amber-800 dark:text-amber-200\"\n role=\"status\"\n data-testid=\"workflow-existing-label-warning\"\n >\n <TriangleAlert className=\"mt-0.5 size-4 shrink-0 text-amber-500\" />\n <span>\n An annotation called <span className=\"font-medium\">{existing.name}</span> already\n exists. Annotating will overwrite its description and the current cell values for the\n selected files.\n </span>\n </div>\n )\n }}\n />\n )\n}\n"],
5
- "mappings": ";AAqHY,cACA,YADA;AA3GZ,SAAS,eAAe;AACxB,SAAS,aAAa,eAA+B;AACrD,SAAS,qBAAqB;AAC9B,SAAS,2BAA2B;AAOpC,SAAS,iCAAiC;AAE1C,SAAS,4BAA4B;AACrC,SAAS,eAAe;AACxB,SAAS,4BAA4B;AACrC,SAAS,aAAa,0BAA0B;AAChD,SAAS,yBAAyB;AAIlC,MAAM,eAAe,EAAE,OAAO,qBAAqB,aAAa,0BAA0B;AA2BnF,SAAS,uBAAuB;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAgC;AAC9B,QAAM,WAAW,kBAAkB,EAAE,SAAS,KAAK,CAAC;AAEpD,QAAM,WAAW,QAAQ,EAAE,WAAW;AACtC,QAAM,aAAa;AAAA,IACjB,CAAC,QAAgB,WAAW,GAAG,KAAK,mBAAmB,GAAG,KAAK,mBAAmB,OAAO;AAAA,IACzF,CAAC,QAAQ;AAAA,EACX;AACA,QAAM,EAAE,WAAW,IAAI,qBAAqB;AAC5C,QAAM,EAAE,MAAM,gBAAgB,CAAC,EAAE,IAAI,QAAQ;AAC7C,QAAM,OAAO,QAAQ,MAAM,oBAAoB,aAAa,GAAG,CAAC,aAAa,CAAC;AAI9E,QAAM,mBAAmB;AAAA,IACvB,CAAC,OAAsB,QAAwB,aAAiC;AAC9E,UAAI,SAAS,OAAO,eAAe,MAAM,SAAS,OAAQ,QAAO;AACjE,YAAM,UAAU,qBAAqB,OAAO,OAAO,eAAe,EAAE,CAAC;AACrE,aAAO,UAAU,mBAAc,OAAO,WAAM;AAAA,IAC9C;AAAA,IACA,CAAC;AAAA,EACH;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA,YAAY;AAAA,MACZ,aAAa;AAAA,MACb;AAAA,MACA;AAAA,MACA,aAAa,CAAC,EAAE,UAAU,aAAa,MACrC,SAAS,OAAO,eAAe,iBAAiB,OAC5C,YAAY,YAAY,YAAY,iBAAiB,IAAI,MAAM,EAAE,KACjE;AAAA,MAEN,cAAc,CAAC,EAAE,UAAU,OAAO,MAAM;AACtC,YAAI,SAAS,OAAO,YAAa,QAAO;AAGxC,cAAM,OACJ,OAAO,OAAO,QAAQ,EAAE,EAAE,KAAK,KAAK,qBAAqB,OAAO,OAAO,eAAe,EAAE,CAAC;AAC3F,cAAM,WAAW,OACb,KAAK,KAAK,CAAC,MAAM,EAAE,KAAK,YAAY,MAAM,KAAK,YAAY,CAAC,IAC5D;AACJ,YAAI,CAAC,SAAU,QAAO;AACtB,eACE;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA,YACV,MAAK;AAAA,YACL,eAAY;AAAA,YAEZ;AAAA,kCAAC,iBAAc,WAAU,yCAAwC;AAAA,cACjE,qBAAC,UAAK;AAAA;AAAA,gBACiB,oBAAC,UAAK,WAAU,eAAe,mBAAS,MAAK;AAAA,gBAAO;AAAA,iBAG3E;AAAA;AAAA;AAAA,QACF;AAAA,MAEJ;AAAA;AAAA,EACF;AAEJ;",
4
+ "sourcesContent": ["/**\n * The workflow launcher, wired to run what it launches: `ConnectedWorkflowLauncher` (the\n * workspace's files behind scope and file fields, the user's agents behind \"Run as\") with the one\n * launch handler (`useLaunchWorkflow`), the host's upload dialog for adding files\n * (`environment.openUpload`), and the touches of the annotation operation (its derived name and\n * overwrite warning, \"Annotate N documents\").\n *\n * The dashboard's Start band, Files (\"Create new\") and, headless, the slash menu use it.\n */\n\nimport { useTags } from '@arbidocs/react'\nimport { useCallback, useMemo, type ReactNode } from 'react'\nimport { TriangleAlert } from 'lucide-react'\nimport { documentScopeLabels } from '../../agents/workflows/workspaceScope'\nimport {\n type OnWorkflowLaunch,\n type WorkflowDefinition,\n type WorkflowField,\n type WorkflowInputs,\n type WorkflowLanding,\n} from '../../agents/workflows/types'\nimport { ConnectedWorkflowLauncher } from '../ConnectedWorkflowLauncher'\nimport { type StartTile } from '../../home/StartTiles'\nimport { useBlocksEnvironment } from '../../provider/environment'\nimport { useHost } from '../../provider/host'\nimport { deriveAnnotationName } from '../../agents/workflows/catalogue/annotation-name'\nimport { ANNOTATE_ID, renderWorkflowIcon } from '../../agents/workflows/catalogue/seed'\nimport { useLaunchWorkflow } from './useLaunchWorkflow'\n\n// The agent picker names the person it hands the work to: the default \"Run as\" / \"My assistant\"\n// copy did not say who an assistant is.\nconst AGENT_LABELS = { label: 'Who this runs for', myAssistant: 'Me (your own assistant)' }\n\nexport interface ConnectedWorkflowStartProps {\n workflows: WorkflowDefinition[]\n /** Which of `workflows` get a tile (a filtered or capped view). */\n tileWorkflows?: WorkflowDefinition[]\n /** Render the Start band (off when another surface opens the dialog). */\n showTiles?: boolean\n caption?: string\n captionTestId?: string\n testId?: string\n /** Plain tiles appended to the band (e.g. the \"Create a file\" menu). */\n extraTiles?: StartTile[]\n /** Controlled open workflow id. */\n activeId?: string | null\n onActiveIdChange?: (id: string | null) => void\n initialInputsFor?: (workflow: WorkflowDefinition) => Partial<WorkflowInputs> | undefined\n /** Where launches land, over each workflow's default (`current-chat` = the chat on screen). */\n landing?: WorkflowLanding\n /** A prompt run's own send (a chat that is not the session's conversation). See `useLaunchWorkflow`. */\n send?: (prompt: string) => void\n /**\n * Run a launch here instead of the usual way (`useLaunchWorkflow`): a surface that wants the\n * result itself, e.g. the presentation, which adds a generated image to its clips. The dialog\n * shows it running until it resolves, closes then, and stays open if it throws.\n */\n onLaunch?: OnWorkflowLaunch\n /**\n * Files added from a `documents` field are uploaded right in the field instead of through the\n * host's upload dialog: for a dialog in a popped-out window, where the host's dialog would open\n * in the app's window, out of sight, and block this one.\n */\n uploadInPlace?: boolean\n /** The host's own \"Add\" control, offered when a workflow needs files and there are none. */\n addFilesAction?: ReactNode\n tileTestId?: (workflow: WorkflowDefinition) => string | undefined\n disabledReason?: (workflow: WorkflowDefinition) => string | undefined\n}\n\nexport function ConnectedWorkflowStart({\n workflows,\n landing,\n send,\n addFilesAction,\n onLaunch: launchHere,\n uploadInPlace = false,\n ...rest\n}: ConnectedWorkflowStartProps) {\n const launchUsually = useLaunchWorkflow({ landing, send })\n const onLaunch = launchHere ?? launchUsually\n // The host's icons first (a skill pack names its own), then the kit's, then the skill icon.\n const hostIcon = useHost().workflows?.renderIcon\n const renderIcon = useCallback(\n (key: string) => hostIcon?.(key) ?? renderWorkflowIcon(key) ?? renderWorkflowIcon('skill'),\n [hostIcon]\n )\n const { openUpload } = useBlocksEnvironment()\n const { data: workspaceTags = [] } = useTags()\n const tags = useMemo(() => documentScopeLabels(workspaceTags), [workspaceTags])\n\n // The annotation's name is optional: left blank it is taken from the question, which the\n // field's placeholder shows before anything runs.\n const fieldPlaceholder = useCallback(\n (field: WorkflowField, inputs: WorkflowInputs, workflow: WorkflowDefinition) => {\n if (workflow.id !== ANNOTATE_ID || field.name !== 'name') return undefined\n const derived = deriveAnnotationName(String(inputs.description ?? ''))\n return derived ? `Otherwise \u201C${derived}\u201D` : 'Taken from the description'\n },\n []\n )\n\n return (\n <ConnectedWorkflowLauncher\n {...rest}\n workflows={workflows}\n onLaunch={onLaunch}\n renderIcon={renderIcon}\n onAddFiles={uploadInPlace ? undefined : openUpload}\n agentLabels={AGENT_LABELS}\n addFilesAction={addFilesAction}\n fieldPlaceholder={fieldPlaceholder}\n submitLabel={({ workflow, matchedCount }) =>\n workflow.id === ANNOTATE_ID && matchedCount !== null\n ? `Annotate ${matchedCount} document${matchedCount !== 1 ? 's' : ''}`\n : undefined\n }\n renderNotice={({ workflow, inputs }) => {\n if (workflow.id !== ANNOTATE_ID) return null\n // A same-named label is reused: warn that this overwrites its stored description and the\n // cell values for the selected documents.\n const name =\n String(inputs.name ?? '').trim() || deriveAnnotationName(String(inputs.description ?? ''))\n const existing = name\n ? tags.find((t) => t.name.toLowerCase() === name.toLowerCase())\n : undefined\n if (!existing) return null\n return (\n <div\n className=\"flex items-start gap-2 rounded-md border border-amber-500/40 bg-amber-500/10 px-3 py-2 text-sm text-amber-800 dark:text-amber-200\"\n role=\"status\"\n data-testid=\"workflow-existing-label-warning\"\n >\n <TriangleAlert className=\"mt-0.5 size-4 shrink-0 text-amber-500\" />\n <span>\n An annotation called <span className=\"font-medium\">{existing.name}</span> already\n exists. Annotating will overwrite its description and the current cell values for the\n selected files.\n </span>\n </div>\n )\n }}\n />\n )\n}\n"],
5
+ "mappings": ";AAqIY,cACA,YADA;AA3HZ,SAAS,eAAe;AACxB,SAAS,aAAa,eAA+B;AACrD,SAAS,qBAAqB;AAC9B,SAAS,2BAA2B;AAQpC,SAAS,iCAAiC;AAE1C,SAAS,4BAA4B;AACrC,SAAS,eAAe;AACxB,SAAS,4BAA4B;AACrC,SAAS,aAAa,0BAA0B;AAChD,SAAS,yBAAyB;AAIlC,MAAM,eAAe,EAAE,OAAO,qBAAqB,aAAa,0BAA0B;AAuCnF,SAAS,uBAAuB;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,gBAAgB;AAAA,EAChB,GAAG;AACL,GAAgC;AAC9B,QAAM,gBAAgB,kBAAkB,EAAE,SAAS,KAAK,CAAC;AACzD,QAAM,WAAW,cAAc;AAE/B,QAAM,WAAW,QAAQ,EAAE,WAAW;AACtC,QAAM,aAAa;AAAA,IACjB,CAAC,QAAgB,WAAW,GAAG,KAAK,mBAAmB,GAAG,KAAK,mBAAmB,OAAO;AAAA,IACzF,CAAC,QAAQ;AAAA,EACX;AACA,QAAM,EAAE,WAAW,IAAI,qBAAqB;AAC5C,QAAM,EAAE,MAAM,gBAAgB,CAAC,EAAE,IAAI,QAAQ;AAC7C,QAAM,OAAO,QAAQ,MAAM,oBAAoB,aAAa,GAAG,CAAC,aAAa,CAAC;AAI9E,QAAM,mBAAmB;AAAA,IACvB,CAAC,OAAsB,QAAwB,aAAiC;AAC9E,UAAI,SAAS,OAAO,eAAe,MAAM,SAAS,OAAQ,QAAO;AACjE,YAAM,UAAU,qBAAqB,OAAO,OAAO,eAAe,EAAE,CAAC;AACrE,aAAO,UAAU,mBAAc,OAAO,WAAM;AAAA,IAC9C;AAAA,IACA,CAAC;AAAA,EACH;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA,YAAY,gBAAgB,SAAY;AAAA,MACxC,aAAa;AAAA,MACb;AAAA,MACA;AAAA,MACA,aAAa,CAAC,EAAE,UAAU,aAAa,MACrC,SAAS,OAAO,eAAe,iBAAiB,OAC5C,YAAY,YAAY,YAAY,iBAAiB,IAAI,MAAM,EAAE,KACjE;AAAA,MAEN,cAAc,CAAC,EAAE,UAAU,OAAO,MAAM;AACtC,YAAI,SAAS,OAAO,YAAa,QAAO;AAGxC,cAAM,OACJ,OAAO,OAAO,QAAQ,EAAE,EAAE,KAAK,KAAK,qBAAqB,OAAO,OAAO,eAAe,EAAE,CAAC;AAC3F,cAAM,WAAW,OACb,KAAK,KAAK,CAAC,MAAM,EAAE,KAAK,YAAY,MAAM,KAAK,YAAY,CAAC,IAC5D;AACJ,YAAI,CAAC,SAAU,QAAO;AACtB,eACE;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA,YACV,MAAK;AAAA,YACL,eAAY;AAAA,YAEZ;AAAA,kCAAC,iBAAc,WAAU,yCAAwC;AAAA,cACjE,qBAAC,UAAK;AAAA;AAAA,gBACiB,oBAAC,UAAK,WAAU,eAAe,mBAAS,MAAK;AAAA,gBAAO;AAAA,iBAG3E;AAAA;AAAA;AAAA,QACF;AAAA,MAEJ;AAAA;AAAA,EACF;AAEJ;",
6
6
  "names": []
7
7
  }