@docyrus/ui-pro-ai-assistant 0.0.1

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 (308) hide show
  1. package/dist/index.js +26161 -0
  2. package/dist/index.js.map +1 -0
  3. package/package.json +155 -0
  4. package/src/components/assistant-animations.tsx +29 -0
  5. package/src/components/assistant-dialogs.tsx +235 -0
  6. package/src/components/code-view.tsx +278 -0
  7. package/src/components/create-agent-task.tsx +104 -0
  8. package/src/components/create-new-work-version.tsx +30 -0
  9. package/src/components/extract-web.tsx +160 -0
  10. package/src/components/forward-to-agent.tsx +90 -0
  11. package/src/components/generate-chart.tsx +101 -0
  12. package/src/components/generative-action-button.tsx +122 -0
  13. package/src/components/generative-tool.tsx +685 -0
  14. package/src/components/generative-ui-object.tsx +210 -0
  15. package/src/components/input-area.tsx +1209 -0
  16. package/src/components/json-schema-layout.tsx +326 -0
  17. package/src/components/list-item-card.tsx +92 -0
  18. package/src/components/mermaid-diagram.tsx +192 -0
  19. package/src/components/preview-image.tsx +47 -0
  20. package/src/components/request-approval.tsx +48 -0
  21. package/src/components/request-user-input.tsx +270 -0
  22. package/src/components/search-web.tsx +319 -0
  23. package/src/components/sheet-command.tsx +88 -0
  24. package/src/components/shell-canvas.tsx +122 -0
  25. package/src/components/show-advanced-data-table.tsx +352 -0
  26. package/src/components/show-generated-content-options.tsx +93 -0
  27. package/src/components/show-people-cards.tsx +180 -0
  28. package/src/components/subagent-tool.tsx +180 -0
  29. package/src/components/text-editor-tool.tsx +328 -0
  30. package/src/components/work-canvas.tsx +88 -0
  31. package/src/components/work-card.tsx +42 -0
  32. package/src/declarations.d.ts +1 -0
  33. package/src/docy-assistant.tsx +1962 -0
  34. package/src/hooks/index.ts +7 -0
  35. package/src/hooks/use-assistant-api.ts +507 -0
  36. package/src/hooks/use-deployment-data.ts +162 -0
  37. package/src/hooks/use-project-state.ts +347 -0
  38. package/src/hooks/use-session-state.ts +207 -0
  39. package/src/hooks/use-speech-recognition.ts +137 -0
  40. package/src/hooks/use-ui-state.ts +185 -0
  41. package/src/hooks/use-works-state.ts +146 -0
  42. package/src/i18n/context.tsx +253 -0
  43. package/src/i18n/index.ts +19 -0
  44. package/src/i18n/locales/de.json +198 -0
  45. package/src/i18n/locales/el.json +198 -0
  46. package/src/i18n/locales/en.json +226 -0
  47. package/src/i18n/locales/es.json +198 -0
  48. package/src/i18n/locales/fr.json +198 -0
  49. package/src/i18n/locales/it.json +198 -0
  50. package/src/i18n/locales/pt.json +198 -0
  51. package/src/i18n/locales/sl.json +198 -0
  52. package/src/i18n/locales/tr.json +211 -0
  53. package/src/i18n/types.ts +23 -0
  54. package/src/i18n/use-translation.ts +17 -0
  55. package/src/index.ts +18 -0
  56. package/src/internal/plate-editor/editor/auth-context.ts +11 -0
  57. package/src/internal/plate-editor/editor/editor-base-kit.tsx +39 -0
  58. package/src/internal/plate-editor/editor/editor-kit.tsx +89 -0
  59. package/src/internal/plate-editor/editor/plate-editor.tsx +75 -0
  60. package/src/internal/plate-editor/editor/plate-types.ts +126 -0
  61. package/src/internal/plate-editor/editor/plugins/ai-kit.tsx +172 -0
  62. package/src/internal/plate-editor/editor/plugins/autoformat-kit.tsx +211 -0
  63. package/src/internal/plate-editor/editor/plugins/basic-blocks-base-kit.tsx +26 -0
  64. package/src/internal/plate-editor/editor/plugins/basic-blocks-kit.tsx +51 -0
  65. package/src/internal/plate-editor/editor/plugins/basic-marks-base-kit.tsx +24 -0
  66. package/src/internal/plate-editor/editor/plugins/basic-marks-kit.tsx +38 -0
  67. package/src/internal/plate-editor/editor/plugins/basic-nodes-kit.tsx +6 -0
  68. package/src/internal/plate-editor/editor/plugins/block-menu-kit.tsx +14 -0
  69. package/src/internal/plate-editor/editor/plugins/block-placeholder-kit.tsx +17 -0
  70. package/src/internal/plate-editor/editor/plugins/block-selection-kit.tsx +31 -0
  71. package/src/internal/plate-editor/editor/plugins/callout-base-kit.tsx +5 -0
  72. package/src/internal/plate-editor/editor/plugins/callout-kit.tsx +7 -0
  73. package/src/internal/plate-editor/editor/plugins/code-block-base-kit.tsx +23 -0
  74. package/src/internal/plate-editor/editor/plugins/code-block-kit.tsx +26 -0
  75. package/src/internal/plate-editor/editor/plugins/column-base-kit.tsx +8 -0
  76. package/src/internal/plate-editor/editor/plugins/column-kit.tsx +7 -0
  77. package/src/internal/plate-editor/editor/plugins/comment-base-kit.tsx +5 -0
  78. package/src/internal/plate-editor/editor/plugins/comment-kit.tsx +174 -0
  79. package/src/internal/plate-editor/editor/plugins/copilot-kit.tsx +68 -0
  80. package/src/internal/plate-editor/editor/plugins/cursor-overlay-kit.tsx +13 -0
  81. package/src/internal/plate-editor/editor/plugins/date-base-kit.tsx +5 -0
  82. package/src/internal/plate-editor/editor/plugins/date-kit.tsx +7 -0
  83. package/src/internal/plate-editor/editor/plugins/discussion-kit.tsx +36 -0
  84. package/src/internal/plate-editor/editor/plugins/dnd-kit.tsx +27 -0
  85. package/src/internal/plate-editor/editor/plugins/docx-export-kit.tsx +43 -0
  86. package/src/internal/plate-editor/editor/plugins/docx-kit.tsx +6 -0
  87. package/src/internal/plate-editor/editor/plugins/emoji-kit.tsx +15 -0
  88. package/src/internal/plate-editor/editor/plugins/exit-break-kit.tsx +12 -0
  89. package/src/internal/plate-editor/editor/plugins/floating-toolbar-kit.tsx +19 -0
  90. package/src/internal/plate-editor/editor/plugins/font-base-kit.tsx +36 -0
  91. package/src/internal/plate-editor/editor/plugins/font-kit.tsx +47 -0
  92. package/src/internal/plate-editor/editor/plugins/indent-base-kit.tsx +19 -0
  93. package/src/internal/plate-editor/editor/plugins/indent-kit.tsx +22 -0
  94. package/src/internal/plate-editor/editor/plugins/link-base-kit.tsx +5 -0
  95. package/src/internal/plate-editor/editor/plugins/link-kit.tsx +35 -0
  96. package/src/internal/plate-editor/editor/plugins/list-base-kit.tsx +24 -0
  97. package/src/internal/plate-editor/editor/plugins/list-kit.tsx +27 -0
  98. package/src/internal/plate-editor/editor/plugins/markdown-kit.tsx +18 -0
  99. package/src/internal/plate-editor/editor/plugins/math-base-kit.tsx +8 -0
  100. package/src/internal/plate-editor/editor/plugins/math-kit.tsx +10 -0
  101. package/src/internal/plate-editor/editor/plugins/media-base-kit.tsx +37 -0
  102. package/src/internal/plate-editor/editor/plugins/media-kit.tsx +53 -0
  103. package/src/internal/plate-editor/editor/plugins/mention-base-kit.tsx +5 -0
  104. package/src/internal/plate-editor/editor/plugins/mention-kit.tsx +36 -0
  105. package/src/internal/plate-editor/editor/plugins/slash-kit.tsx +17 -0
  106. package/src/internal/plate-editor/editor/plugins/suggestion-base-kit.tsx +5 -0
  107. package/src/internal/plate-editor/editor/plugins/suggestion-kit.tsx +95 -0
  108. package/src/internal/plate-editor/editor/plugins/table-base-kit.tsx +20 -0
  109. package/src/internal/plate-editor/editor/plugins/table-kit.tsx +22 -0
  110. package/src/internal/plate-editor/editor/plugins/toc-base-kit.tsx +5 -0
  111. package/src/internal/plate-editor/editor/plugins/toc-kit.tsx +14 -0
  112. package/src/internal/plate-editor/editor/plugins/toggle-base-kit.tsx +5 -0
  113. package/src/internal/plate-editor/editor/plugins/toggle-kit.tsx +9 -0
  114. package/src/internal/plate-editor/editor/transforms.ts +165 -0
  115. package/src/internal/plate-editor/editor/use-chat.ts +152 -0
  116. package/src/internal/plate-editor/hooks/index.ts +3 -0
  117. package/src/internal/plate-editor/hooks/use-copy-to-clipboard.ts +31 -0
  118. package/src/internal/plate-editor/hooks/use-is-touch-device.ts +26 -0
  119. package/src/internal/plate-editor/hooks/use-lock-scroll.ts +21 -0
  120. package/src/internal/plate-editor/hooks/use-media-query.ts +44 -0
  121. package/src/internal/plate-editor/hooks/use-mounted.ts +18 -0
  122. package/src/internal/plate-editor/hooks/use-on-click-outside.ts +114 -0
  123. package/src/internal/plate-editor/hooks/use-upload-file.ts +81 -0
  124. package/src/internal/plate-editor/i18n/context.tsx +58 -0
  125. package/src/internal/plate-editor/i18n/index.ts +3 -0
  126. package/src/internal/plate-editor/i18n/locales/de.json +57 -0
  127. package/src/internal/plate-editor/i18n/locales/el.json +57 -0
  128. package/src/internal/plate-editor/i18n/locales/en.json +57 -0
  129. package/src/internal/plate-editor/i18n/locales/es.json +57 -0
  130. package/src/internal/plate-editor/i18n/locales/fr.json +57 -0
  131. package/src/internal/plate-editor/i18n/locales/it.json +57 -0
  132. package/src/internal/plate-editor/i18n/locales/pt.json +57 -0
  133. package/src/internal/plate-editor/i18n/locales/sl.json +57 -0
  134. package/src/internal/plate-editor/i18n/locales/tr.json +57 -0
  135. package/src/internal/plate-editor/i18n/types.ts +59 -0
  136. package/src/internal/plate-editor/i18n/use-translation.ts +22 -0
  137. package/src/internal/plate-editor/index.ts +39 -0
  138. package/src/internal/plate-editor/lib/ai-output-converter.ts +153 -0
  139. package/src/internal/plate-editor/lib/download-file.ts +17 -0
  140. package/src/internal/plate-editor/plate-ui/ai-chat-editor.tsx +26 -0
  141. package/src/internal/plate-editor/plate-ui/ai-menu.tsx +828 -0
  142. package/src/internal/plate-editor/plate-ui/ai-node.tsx +41 -0
  143. package/src/internal/plate-editor/plate-ui/ai-toolbar-button.tsx +27 -0
  144. package/src/internal/plate-editor/plate-ui/alert-dialog.tsx +147 -0
  145. package/src/internal/plate-editor/plate-ui/align-toolbar-button.tsx +90 -0
  146. package/src/internal/plate-editor/plate-ui/avatar.tsx +3 -0
  147. package/src/internal/plate-editor/plate-ui/block-context-menu.tsx +106 -0
  148. package/src/internal/plate-editor/plate-ui/block-discussion.tsx +364 -0
  149. package/src/internal/plate-editor/plate-ui/block-draggable.tsx +556 -0
  150. package/src/internal/plate-editor/plate-ui/block-list-static.tsx +78 -0
  151. package/src/internal/plate-editor/plate-ui/block-list.tsx +85 -0
  152. package/src/internal/plate-editor/plate-ui/block-menu.tsx +557 -0
  153. package/src/internal/plate-editor/plate-ui/block-selection.tsx +47 -0
  154. package/src/internal/plate-editor/plate-ui/block-suggestion.tsx +469 -0
  155. package/src/internal/plate-editor/plate-ui/blockquote-node-static.tsx +10 -0
  156. package/src/internal/plate-editor/plate-ui/blockquote-node.tsx +11 -0
  157. package/src/internal/plate-editor/plate-ui/button.tsx +190 -0
  158. package/src/internal/plate-editor/plate-ui/calendar.tsx +3 -0
  159. package/src/internal/plate-editor/plate-ui/callout-node-static.tsx +76 -0
  160. package/src/internal/plate-editor/plate-ui/callout-node.tsx +54 -0
  161. package/src/internal/plate-editor/plate-ui/caption.tsx +48 -0
  162. package/src/internal/plate-editor/plate-ui/checkbox.tsx +3 -0
  163. package/src/internal/plate-editor/plate-ui/code-block-node-static.tsx +172 -0
  164. package/src/internal/plate-editor/plate-ui/code-block-node.tsx +228 -0
  165. package/src/internal/plate-editor/plate-ui/code-node-static.tsx +11 -0
  166. package/src/internal/plate-editor/plate-ui/code-node.tsx +12 -0
  167. package/src/internal/plate-editor/plate-ui/column-node-static.tsx +65 -0
  168. package/src/internal/plate-editor/plate-ui/column-node.tsx +24 -0
  169. package/src/internal/plate-editor/plate-ui/command.tsx +204 -0
  170. package/src/internal/plate-editor/plate-ui/comment-node-static.tsx +12 -0
  171. package/src/internal/plate-editor/plate-ui/comment-node.tsx +45 -0
  172. package/src/internal/plate-editor/plate-ui/comment-toolbar-button.tsx +24 -0
  173. package/src/internal/plate-editor/plate-ui/comment.tsx +619 -0
  174. package/src/internal/plate-editor/plate-ui/cursor-overlay.tsx +85 -0
  175. package/src/internal/plate-editor/plate-ui/date-node-static.tsx +43 -0
  176. package/src/internal/plate-editor/plate-ui/date-node.tsx +56 -0
  177. package/src/internal/plate-editor/plate-ui/dialog.tsx +426 -0
  178. package/src/internal/plate-editor/plate-ui/dropdown-menu.tsx +266 -0
  179. package/src/internal/plate-editor/plate-ui/editor-static.tsx +40 -0
  180. package/src/internal/plate-editor/plate-ui/editor.tsx +148 -0
  181. package/src/internal/plate-editor/plate-ui/emoji-node.tsx +48 -0
  182. package/src/internal/plate-editor/plate-ui/emoji-toolbar-button.tsx +626 -0
  183. package/src/internal/plate-editor/plate-ui/equation-node-static.tsx +155 -0
  184. package/src/internal/plate-editor/plate-ui/equation-node.tsx +226 -0
  185. package/src/internal/plate-editor/plate-ui/equation-toolbar-button.tsx +26 -0
  186. package/src/internal/plate-editor/plate-ui/export-toolbar-button.tsx +208 -0
  187. package/src/internal/plate-editor/plate-ui/fixed-toolbar-buttons.tsx +157 -0
  188. package/src/internal/plate-editor/plate-ui/fixed-toolbar.tsx +27 -0
  189. package/src/internal/plate-editor/plate-ui/floating-discussion.tsx +1129 -0
  190. package/src/internal/plate-editor/plate-ui/floating-toolbar-buttons.tsx +129 -0
  191. package/src/internal/plate-editor/plate-ui/floating-toolbar.tsx +99 -0
  192. package/src/internal/plate-editor/plate-ui/font-color-toolbar-button.tsx +211 -0
  193. package/src/internal/plate-editor/plate-ui/font-size-toolbar-button.tsx +154 -0
  194. package/src/internal/plate-editor/plate-ui/ghost-text.tsx +20 -0
  195. package/src/internal/plate-editor/plate-ui/heading-node-static.tsx +52 -0
  196. package/src/internal/plate-editor/plate-ui/heading-node.tsx +56 -0
  197. package/src/internal/plate-editor/plate-ui/highlight-node-static.tsx +9 -0
  198. package/src/internal/plate-editor/plate-ui/highlight-node.tsx +11 -0
  199. package/src/internal/plate-editor/plate-ui/history-toolbar-button.tsx +52 -0
  200. package/src/internal/plate-editor/plate-ui/hover-card.tsx +7 -0
  201. package/src/internal/plate-editor/plate-ui/hr-node-static.tsx +18 -0
  202. package/src/internal/plate-editor/plate-ui/hr-node.tsx +28 -0
  203. package/src/internal/plate-editor/plate-ui/import-toolbar-button.tsx +124 -0
  204. package/src/internal/plate-editor/plate-ui/indent-toolbar-button.tsx +34 -0
  205. package/src/internal/plate-editor/plate-ui/inline-combobox.tsx +409 -0
  206. package/src/internal/plate-editor/plate-ui/input.tsx +39 -0
  207. package/src/internal/plate-editor/plate-ui/insert-toolbar-button.tsx +260 -0
  208. package/src/internal/plate-editor/plate-ui/label.tsx +1 -0
  209. package/src/internal/plate-editor/plate-ui/line-height-toolbar-button.tsx +71 -0
  210. package/src/internal/plate-editor/plate-ui/link-node-static.tsx +15 -0
  211. package/src/internal/plate-editor/plate-ui/link-node.tsx +33 -0
  212. package/src/internal/plate-editor/plate-ui/link-toolbar-button.tsx +30 -0
  213. package/src/internal/plate-editor/plate-ui/link-toolbar.tsx +149 -0
  214. package/src/internal/plate-editor/plate-ui/list-toolbar-button.tsx +179 -0
  215. package/src/internal/plate-editor/plate-ui/mark-toolbar-button.tsx +36 -0
  216. package/src/internal/plate-editor/plate-ui/media-audio-node-static.tsx +21 -0
  217. package/src/internal/plate-editor/plate-ui/media-audio-node.tsx +32 -0
  218. package/src/internal/plate-editor/plate-ui/media-embed-node.tsx +103 -0
  219. package/src/internal/plate-editor/plate-ui/media-file-node-static.tsx +30 -0
  220. package/src/internal/plate-editor/plate-ui/media-file-node.tsx +52 -0
  221. package/src/internal/plate-editor/plate-ui/media-image-node-static.tsx +37 -0
  222. package/src/internal/plate-editor/plate-ui/media-image-node.tsx +183 -0
  223. package/src/internal/plate-editor/plate-ui/media-placeholder-node.tsx +441 -0
  224. package/src/internal/plate-editor/plate-ui/media-preview-dialog.tsx +127 -0
  225. package/src/internal/plate-editor/plate-ui/media-toolbar-button.tsx +229 -0
  226. package/src/internal/plate-editor/plate-ui/media-toolbar.tsx +216 -0
  227. package/src/internal/plate-editor/plate-ui/media-upload-toast.tsx +73 -0
  228. package/src/internal/plate-editor/plate-ui/media-video-node-static.tsx +35 -0
  229. package/src/internal/plate-editor/plate-ui/media-video-node.tsx +119 -0
  230. package/src/internal/plate-editor/plate-ui/mention-node-static.tsx +46 -0
  231. package/src/internal/plate-editor/plate-ui/mention-node.tsx +79 -0
  232. package/src/internal/plate-editor/plate-ui/menu.tsx +532 -0
  233. package/src/internal/plate-editor/plate-ui/mode-toolbar-button.tsx +126 -0
  234. package/src/internal/plate-editor/plate-ui/more-toolbar-button.tsx +34 -0
  235. package/src/internal/plate-editor/plate-ui/paragraph-node-static.tsx +15 -0
  236. package/src/internal/plate-editor/plate-ui/paragraph-node.tsx +16 -0
  237. package/src/internal/plate-editor/plate-ui/popover.tsx +77 -0
  238. package/src/internal/plate-editor/plate-ui/progress.tsx +1 -0
  239. package/src/internal/plate-editor/plate-ui/remote-cursor-overlay.tsx +81 -0
  240. package/src/internal/plate-editor/plate-ui/resize-handle.tsx +88 -0
  241. package/src/internal/plate-editor/plate-ui/separator.tsx +43 -0
  242. package/src/internal/plate-editor/plate-ui/slash-node.tsx +435 -0
  243. package/src/internal/plate-editor/plate-ui/spinner.tsx +1 -0
  244. package/src/internal/plate-editor/plate-ui/suggestion-node-static.tsx +35 -0
  245. package/src/internal/plate-editor/plate-ui/suggestion-node.tsx +168 -0
  246. package/src/internal/plate-editor/plate-ui/suggestion-toolbar-button.tsx +24 -0
  247. package/src/internal/plate-editor/plate-ui/table-node-static.tsx +85 -0
  248. package/src/internal/plate-editor/plate-ui/table-node.tsx +285 -0
  249. package/src/internal/plate-editor/plate-ui/table-toolbar-button.tsx +254 -0
  250. package/src/internal/plate-editor/plate-ui/tabs.tsx +3 -0
  251. package/src/internal/plate-editor/plate-ui/textarea.tsx +58 -0
  252. package/src/internal/plate-editor/plate-ui/toc-node-static.tsx +142 -0
  253. package/src/internal/plate-editor/plate-ui/toc-node.tsx +57 -0
  254. package/src/internal/plate-editor/plate-ui/toc-sidebar.tsx +50 -0
  255. package/src/internal/plate-editor/plate-ui/toggle-node-static.tsx +18 -0
  256. package/src/internal/plate-editor/plate-ui/toggle-node.tsx +33 -0
  257. package/src/internal/plate-editor/plate-ui/toggle-toolbar-button.tsx +26 -0
  258. package/src/internal/plate-editor/plate-ui/toggle.tsx +3 -0
  259. package/src/internal/plate-editor/plate-ui/toolbar.tsx +380 -0
  260. package/src/internal/plate-editor/plate-ui/tooltip.tsx +149 -0
  261. package/src/internal/plate-editor/plate-ui/turn-into-toolbar-button.tsx +177 -0
  262. package/src/internal/plate-editor/types/index.ts +22 -0
  263. package/src/internal/plate-editor/vite.ts +284 -0
  264. package/src/internal/sheets/components/univer-sheets.tsx +1104 -0
  265. package/src/internal/sheets/i18n/context.tsx +183 -0
  266. package/src/internal/sheets/i18n/index.ts +19 -0
  267. package/src/internal/sheets/i18n/locales/de.json +21 -0
  268. package/src/internal/sheets/i18n/locales/el.json +21 -0
  269. package/src/internal/sheets/i18n/locales/en.json +21 -0
  270. package/src/internal/sheets/i18n/locales/es.json +21 -0
  271. package/src/internal/sheets/i18n/locales/fr.json +21 -0
  272. package/src/internal/sheets/i18n/locales/it.json +21 -0
  273. package/src/internal/sheets/i18n/locales/pt.json +21 -0
  274. package/src/internal/sheets/i18n/locales/sl.json +21 -0
  275. package/src/internal/sheets/i18n/locales/tr.json +21 -0
  276. package/src/internal/sheets/i18n/types.ts +23 -0
  277. package/src/internal/sheets/i18n/use-translation.ts +17 -0
  278. package/src/internal/sheets/index.ts +14 -0
  279. package/src/internal/sheets/types/css.d.ts +11 -0
  280. package/src/internal/sheets/types/index.ts +260 -0
  281. package/src/internal/sheets/xlsx.ts +1169 -0
  282. package/src/lib/api-client.ts +77 -0
  283. package/src/lib/assistant-api-actions.ts +549 -0
  284. package/src/lib/assistant-config.tsx +71 -0
  285. package/src/lib/class-utils.ts +40 -0
  286. package/src/lib/index.ts +7 -0
  287. package/src/lib/message-utils.ts +131 -0
  288. package/src/tools/tools-schema.json +512 -0
  289. package/src/types/index.ts +235 -0
  290. package/src/views/assistant-view.tsx +1137 -0
  291. package/src/views/canvas-app.tsx +839 -0
  292. package/src/views/canvas-code.tsx +93 -0
  293. package/src/views/canvas-deep-research.tsx +44 -0
  294. package/src/views/canvas-image.tsx +25 -0
  295. package/src/views/canvas-record-view.tsx +285 -0
  296. package/src/views/canvas-spreadsheet.tsx +125 -0
  297. package/src/views/canvas-text.tsx +52 -0
  298. package/src/views/canvas.tsx +274 -0
  299. package/src/views/chat-panel.tsx +149 -0
  300. package/src/views/index.ts +20 -0
  301. package/src/views/memories-panel.tsx +365 -0
  302. package/src/views/message-list.tsx +370 -0
  303. package/src/views/project-detail.tsx +257 -0
  304. package/src/views/projects-panel.tsx +131 -0
  305. package/src/views/sessions-list.tsx +98 -0
  306. package/src/views/sidebar-content.tsx +256 -0
  307. package/src/views/work-detail.tsx +98 -0
  308. package/src/vite.ts +284 -0
@@ -0,0 +1,370 @@
1
+ 'use client';
2
+
3
+ import {
4
+ memo, useCallback, useMemo, useState
5
+ } from 'react';
6
+
7
+ import {
8
+ AIConversationContent as ChatContainerContent,
9
+ AIConversation as ChatContainerRoot,
10
+ AIConversationScrollButton as ChatContainerScrollAnchor,
11
+ Message,
12
+ AIMessageAvatar as MessageAvatar,
13
+ MessageAction,
14
+ MessageActions,
15
+ MessageContent,
16
+ MessageResponse,
17
+ Tool,
18
+ ToolContent,
19
+ ToolHeader,
20
+ ToolInput,
21
+ ToolOutput
22
+ } from '@docyrus/ui-pro-shared/ai';
23
+ import {
24
+ Reasoning,
25
+ ReasoningContent,
26
+ ReasoningTrigger
27
+ } from '@docyrus/ui-pro-shared/ai-elements/reasoning';
28
+ import { Spinner } from '@docyrus/ui-pro-shared/components/spinner';
29
+ import { cn } from '@docyrus/ui-pro-shared/lib/utils';
30
+ import { Check, Copy } from 'lucide-react';
31
+
32
+ import { useAssistantTranslation } from '../i18n';
33
+ import { type ToolActionEvent } from '../types';
34
+
35
+ import { AssistantAnimations } from '../components/assistant-animations';
36
+ import { GenerativeUITool } from '../components/generative-tool';
37
+ import {
38
+ GenerativeUIObject,
39
+ GENERATIVE_UI_PART_TYPES
40
+ } from '../components/generative-ui-object';
41
+ import { type CanvasViewOptions } from './chat-panel';
42
+
43
+ interface MessageListProps {
44
+ messages: any[];
45
+ isLoading: boolean;
46
+ logo?: string;
47
+ userPhoto?: string;
48
+ userDisplayName?: string;
49
+ description?: string;
50
+ title?: string;
51
+ welcomeMessage?: string;
52
+ isLoadingAgent?: boolean;
53
+ className?: string;
54
+ agents?: any[];
55
+ onToolAction?: (event: ToolActionEvent) => void;
56
+ openCanvasView?: (options: CanvasViewOptions) => void;
57
+ onForwardToAgent?: (options: { agentId: string; prompt?: string }) => void;
58
+ onUseWorkResult?: (data: {
59
+ workId?: string;
60
+ workVersionId?: string;
61
+ workType?: string;
62
+ workDataSourceId?: string;
63
+ data?: any;
64
+ state?: string;
65
+ }) => void;
66
+ }
67
+
68
+ const isToolPart = (part: any) => part.type?.startsWith('tool-') || part.type === 'dynamic-tool';
69
+
70
+ // Kept outside to avoid recreation on every render
71
+ const DISPLAY_ONLY_TOOLS = new Set([
72
+ 'generateChart',
73
+ 'showAdvancedDataTable',
74
+ 'showCreateRecordForm',
75
+ 'showUpdateRecordForm',
76
+ 'showRecordDetailsForm',
77
+ 'previewMermaidDiagram',
78
+ 'generateImage',
79
+ 'saveTextWork',
80
+ 'showWorkCanvas',
81
+ 'searchWeb',
82
+ 'web_search',
83
+ 'google_search',
84
+ 'browser_search',
85
+ 'str_replace_based_edit_tool',
86
+ 'extractFromWeb',
87
+ 'deepResearch',
88
+ 'runSpreadsheetCommand',
89
+ 'forwardToAgentById',
90
+ 'showPeopleCards',
91
+ 'showImage',
92
+ 'searchDocuments',
93
+ 'createNewWorkVersion',
94
+ 'showGeneratedContentOptions',
95
+ 'createAgentTask'
96
+ ]);
97
+
98
+ const INTERACTIVE_GENERATIVE_TOOLS = new Set(['requestApproval', 'previewCode', 'requestUserInput']);
99
+
100
+ function CopyButton({ text }: { text: string }) {
101
+ const { t } = useAssistantTranslation();
102
+ const [copied, setCopied] = useState(false);
103
+
104
+ const handleCopy = useCallback(() => {
105
+ navigator.clipboard.writeText(text);
106
+ setCopied(true);
107
+ setTimeout(() => setCopied(false), 2000);
108
+ }, [text]);
109
+
110
+ return (
111
+ <MessageAction
112
+ tooltip={copied ? t('common.copied') : t('common.copy')}
113
+ onClick={handleCopy}
114
+ className="h-7 w-7 text-muted-foreground hover:text-foreground">
115
+ {copied ? <Check className="w-3.5 h-3.5" /> : <Copy className="w-3.5 h-3.5" />}
116
+ </MessageAction>
117
+ );
118
+ }
119
+
120
+ interface MessageItemProps {
121
+ message: any;
122
+ isStreaming: boolean;
123
+ logo?: string;
124
+ userPhoto?: string;
125
+ userDisplayName?: string;
126
+ agents?: any[];
127
+ onToolAction?: (event: ToolActionEvent) => void;
128
+ openCanvasView?: (options: CanvasViewOptions) => void;
129
+ onForwardToAgent?: (options: { agentId: string; prompt?: string }) => void;
130
+ onUseWorkResult?: MessageListProps['onUseWorkResult'];
131
+ }
132
+
133
+ const MessageItem = memo(({
134
+ message,
135
+ isStreaming,
136
+ logo,
137
+ userPhoto,
138
+ userDisplayName = 'User',
139
+ agents = [],
140
+ onToolAction,
141
+ openCanvasView,
142
+ onForwardToAgent,
143
+ onUseWorkResult
144
+ }: MessageItemProps) => {
145
+ const isAssistantMessage = message.role === 'assistant';
146
+
147
+ const textContent = useMemo(() => {
148
+ return (message.parts || [])
149
+ .filter((p: any) => p.type === 'text')
150
+ .map((p: any) => p.text || '')
151
+ .join('\n')
152
+ .trim();
153
+ }, [message.parts]);
154
+
155
+ const renderToolPart = (part: any, messageId: string, idx: number) => {
156
+ const toolName
157
+ = part.type === 'dynamic-tool' ? part.toolName : part.type?.startsWith('tool-') ? part.type.replace(/^tool-/, '') : part.toolName || 'Unknown Tool';
158
+
159
+ const isSubagentTool = toolName.startsWith('call') && toolName.endsWith('Agent');
160
+ const isGenerativeTool
161
+ = DISPLAY_ONLY_TOOLS.has(toolName)
162
+ || (INTERACTIVE_GENERATIVE_TOOLS.has(toolName) && !!onToolAction)
163
+ || (isSubagentTool && (part.state === 'input-available' || part.state === 'input-streaming' || part.state === 'output-available'));
164
+
165
+ if (isGenerativeTool) {
166
+ return (
167
+ <GenerativeUITool
168
+ key={`${messageId}-gentool-${idx}`}
169
+ part={{
170
+ state: part.state || 'input-available',
171
+ input: part.args || part.input,
172
+ output: part.output,
173
+ errorText: part.errorText,
174
+ toolCallId: part.toolCallId || `${messageId}-${idx}`
175
+ }}
176
+ toolName={toolName}
177
+ onToolAction={onToolAction ?? (() => {})}
178
+ openCanvasView={openCanvasView}
179
+ onForwardToAgent={onForwardToAgent} />
180
+ );
181
+ }
182
+
183
+ const args = typeof part.args === 'string' ? JSON.parse(part.args) : part.args || {};
184
+ const output = part.output && typeof part.output === 'object' ? part.output : null;
185
+
186
+ return (
187
+ <Tool key={`${messageId}-tool-${idx}`} defaultOpen={false} className="my-2">
188
+ <ToolHeader
189
+ type={part.type === 'dynamic-tool' ? 'dynamic-tool' : (part.type || `tool-${toolName}`)}
190
+ state={part.state || 'output-available'}
191
+ title={output?.text || toolName}
192
+ iconName={output?.icon}
193
+ toolName={part.type === 'dynamic-tool' ? toolName : undefined} />
194
+ <ToolContent>
195
+ {Object.keys(args).length > 0 && <ToolInput input={args} />}
196
+ <ToolOutput output={part.output || null} errorText={part.errorText} />
197
+ </ToolContent>
198
+ </Tool>
199
+ );
200
+ };
201
+
202
+ const renderMessageContent = () => {
203
+ const parts = message.parts || [];
204
+ const hasParts = Array.isArray(parts) && parts.length > 0;
205
+
206
+ if (!hasParts) return message.content || '';
207
+
208
+ const hasStepStart = parts.some((p: any) => p.type === 'step-start');
209
+ const hasTextContent = parts.some((p: any) => p.type === 'text' && p.text?.trim());
210
+ const hasToolContent = parts.some((p: any) => isToolPart(p));
211
+ const isThinking = isStreaming && hasStepStart && !hasTextContent && !hasToolContent;
212
+
213
+ if (isThinking) {
214
+ return (
215
+ <Reasoning key={`${message.id}-thinking`} isStreaming defaultOpen className="mb-0 mt-3.5">
216
+ <ReasoningTrigger />
217
+ </Reasoning>
218
+ );
219
+ }
220
+
221
+ return parts.map((part: any, idx: number) => {
222
+ if (part.type === 'step-start') return null;
223
+
224
+ if (part.type === 'reasoning') {
225
+ const reasoningText = part.reasoning || part.text || '';
226
+
227
+ if (!reasoningText) return null;
228
+
229
+ return (
230
+ <Reasoning key={`${message.id}-reasoning-${idx}`} isStreaming={isStreaming} defaultOpen>
231
+ <ReasoningTrigger />
232
+ <ReasoningContent>{reasoningText}</ReasoningContent>
233
+ </Reasoning>
234
+ );
235
+ }
236
+
237
+ if (part.type === 'text') {
238
+ const content = part.text || part.content || '';
239
+
240
+ if (!content) return null;
241
+
242
+ return <MessageResponse key={`${message.id}-txt-${idx}`} mode={isStreaming ? 'streaming' : 'static'}>{content}</MessageResponse>;
243
+ }
244
+
245
+ if (isToolPart(part)) return renderToolPart(part, message.id, idx);
246
+
247
+ if (GENERATIVE_UI_PART_TYPES.has(part.type)) {
248
+ return (
249
+ <GenerativeUIObject
250
+ key={`${message.id}-genui-${idx}`}
251
+ part={part}
252
+ agents={agents}
253
+ isStreaming={isStreaming}
254
+ openCanvasView={openCanvasView as any}
255
+ onUseWorkResult={onUseWorkResult} />
256
+ );
257
+ }
258
+
259
+ return null;
260
+ });
261
+ };
262
+
263
+ return (
264
+ <Message key={message.id} from={message.role}>
265
+ <div className={cn(
266
+ 'flex items-start gap-3',
267
+ message.role === 'user' && 'flex-row-reverse'
268
+ )}>
269
+ {isStreaming && isAssistantMessage ? (
270
+ <AssistantAnimations animationType="working" className="w-12 h-12 shrink-0" />
271
+ ) : (
272
+ <MessageAvatar
273
+ src={message.role === 'user' ? (userPhoto || '') : (logo || '')}
274
+ name={message.role === 'user' ? userDisplayName : 'Assistant'}
275
+ isStreaming={isStreaming}
276
+ className="w-12 h-12" />
277
+ )}
278
+ <div className="flex flex-col min-w-0 max-w-full">
279
+ <MessageContent className="group-[.is-user]:p-2 group-[.is-user]:mt-0.5">
280
+ {renderMessageContent()}
281
+ </MessageContent>
282
+ {isAssistantMessage && !isStreaming && textContent && (
283
+ <MessageActions className="mt-1 opacity-0 group-hover:opacity-100 transition-opacity">
284
+ <CopyButton text={textContent} />
285
+ </MessageActions>
286
+ )}
287
+ </div>
288
+ </div>
289
+ </Message>
290
+ );
291
+ });
292
+
293
+ export const MessageList = memo(({
294
+ messages,
295
+ isLoading,
296
+ logo,
297
+ userPhoto,
298
+ userDisplayName = 'User',
299
+ description,
300
+ title,
301
+ welcomeMessage,
302
+ isLoadingAgent = false,
303
+ className,
304
+ agents = [],
305
+ onToolAction,
306
+ openCanvasView,
307
+ onForwardToAgent,
308
+ onUseWorkResult
309
+ }: MessageListProps) => {
310
+ const lastMsgIdx = messages.length - 1;
311
+
312
+ return (
313
+ <ChatContainerRoot className={cn('flex-1', className)}>
314
+ <ChatContainerContent className="p-4 h-full">
315
+ {messages.length === 0 ? (
316
+ <div className="h-full flex items-center justify-center">
317
+ {isLoadingAgent ? (
318
+ <div className="p-2 bg-muted rounded-md">
319
+ <Spinner className="size-10 text-muted-foreground" />
320
+ </div>
321
+ ) : (
322
+ <div className="flex flex-col items-center justify-center gap-3 text-center px-4">
323
+ <AssistantAnimations animationType="opening" className="w-32 h-32" />
324
+ {title && <p className="font-semibold text-base text-lg">{title}</p>}
325
+ <div className="max-w-sm text-md text-muted-foreground">
326
+ {welcomeMessage ? <MessageResponse>{welcomeMessage}</MessageResponse> : <p>{description || 'Your AI-powered assistant for all your document needs.'}</p>}
327
+ </div>
328
+ </div>
329
+ )}
330
+ </div>
331
+ ) : (
332
+ <div className="space-y-6">
333
+ {messages.map((message: any, msgIdx: number) => {
334
+ const isLastMessage = msgIdx === lastMsgIdx;
335
+ const isStreaming = isLoading && isLastMessage && message.role === 'assistant';
336
+
337
+ return (
338
+ <MessageItem
339
+ key={message.id}
340
+ message={message}
341
+ isStreaming={isStreaming}
342
+ logo={logo}
343
+ userPhoto={userPhoto}
344
+ userDisplayName={userDisplayName}
345
+ agents={agents}
346
+ onToolAction={onToolAction}
347
+ openCanvasView={openCanvasView}
348
+ onForwardToAgent={onForwardToAgent}
349
+ onUseWorkResult={onUseWorkResult} />
350
+ );
351
+ })}
352
+ {isLoading && messages.length > 0 && messages[lastMsgIdx]?.role !== 'assistant' && (
353
+ <Message from="assistant">
354
+ <div className="flex items-center gap-3">
355
+ <AssistantAnimations animationType="thinking" className="w-12 h-12 shrink-0" />
356
+ <MessageContent>
357
+ <Reasoning isStreaming defaultOpen className="mb-0">
358
+ <ReasoningTrigger />
359
+ </Reasoning>
360
+ </MessageContent>
361
+ </div>
362
+ </Message>
363
+ )}
364
+ </div>
365
+ )}
366
+ <ChatContainerScrollAnchor />
367
+ </ChatContainerContent>
368
+ </ChatContainerRoot>
369
+ );
370
+ });
@@ -0,0 +1,257 @@
1
+ import {
2
+ useState, type ChangeEvent, type FC, type FormEvent
3
+ } from 'react';
4
+
5
+ import { Button } from '@docyrus/ui-pro-shared/components/button';
6
+ import {
7
+ DropdownMenu,
8
+ DropdownMenuContent,
9
+ DropdownMenuItem,
10
+ DropdownMenuTrigger
11
+ } from '@docyrus/ui-pro-shared/components/dropdown-menu';
12
+ import {
13
+ Tabs, TabsContent, TabsList, TabsTrigger
14
+ } from '@docyrus/ui-pro-shared/components/tabs';
15
+ import {
16
+ ArrowLeft, Edit, MoreHorizontal, Trash
17
+ } from 'lucide-react';
18
+
19
+ import { AIInputArea } from '../components/input-area';
20
+ import { useAssistantTranslation } from '../i18n';
21
+ import {
22
+ type AssistantSession, type Project, type SpeechRecognitionInstance, type Work
23
+ } from '../types';
24
+
25
+ interface AssistantProjectDetailViewProps {
26
+ project: Project;
27
+ projectThreads: Record<string, AssistantSession[]>;
28
+ projectWorks: Record<string, Work[]>;
29
+ onBack: () => void;
30
+ onEditInstructions: (instructions: string) => void;
31
+ onProjectMessage: (e?: FormEvent) => void;
32
+ onThreadClick: (thread: AssistantSession) => void;
33
+ onEditSession: (thread: AssistantSession) => void;
34
+ onDeleteSession: (thread: AssistantSession) => void;
35
+ input: string;
36
+ onChange: (e: ChangeEvent<HTMLTextAreaElement>) => void;
37
+ isLoading: boolean;
38
+ supportFiles?: boolean;
39
+ supportWebSearch?: boolean;
40
+ supportDocumentSearch?: boolean;
41
+ supportDeepResearch?: boolean;
42
+ supportThinking?: boolean;
43
+ supportWorkCanvas?: boolean;
44
+ supportMultiModels?: boolean;
45
+ deploymentId?: string;
46
+ enableMicrophone?: boolean;
47
+ enableVoice?: boolean;
48
+ isRecording: boolean;
49
+ recognition: SpeechRecognitionInstance | null;
50
+ onMicrophoneClick: () => void;
51
+ }
52
+
53
+ export const AssistantProjectDetailView: FC<AssistantProjectDetailViewProps> = ({
54
+ project,
55
+ projectThreads,
56
+ projectWorks,
57
+ onBack,
58
+ onProjectMessage,
59
+ onThreadClick,
60
+ onEditSession,
61
+ onDeleteSession,
62
+ input,
63
+ onChange,
64
+ isLoading,
65
+ supportFiles,
66
+ supportWebSearch,
67
+ supportDocumentSearch,
68
+ supportDeepResearch,
69
+ supportThinking,
70
+ supportWorkCanvas,
71
+ supportMultiModels,
72
+ deploymentId,
73
+ enableMicrophone,
74
+ enableVoice,
75
+ isRecording,
76
+ recognition,
77
+ onMicrophoneClick
78
+ }) => {
79
+ const { t } = useAssistantTranslation();
80
+ const [activeTab, setActiveTab] = useState('sessions');
81
+
82
+ return (
83
+ <div className="flex-1 flex flex-col px-6 mt-2 overflow-y-auto">
84
+ {/* Header with Back Button */}
85
+ <div className="flex items-center gap-2 mb-2">
86
+ <Button
87
+ variant="ghost"
88
+ size="icon"
89
+ onClick={onBack}
90
+ className="text-muted-foreground cursor-pointer hover:text-foreground">
91
+ <ArrowLeft className="w-5 h-5" />
92
+ </Button>
93
+ <div className="text-sm text-muted-foreground">{t('labels.all_projects')}</div>
94
+ </div>
95
+
96
+ <div className="ps-2 mb-4">
97
+ <h1 className="text-2xl">{project.name}</h1>
98
+ <p className="text-sm text-muted-foreground">{project.description}</p>
99
+ </div>
100
+
101
+ {/* Project Chat - Full Width */}
102
+ <div className="mt-2 mb-20">
103
+ <AIInputArea
104
+ className="h-10"
105
+ onSubmit={onProjectMessage}
106
+ value={input}
107
+ onChange={onChange}
108
+ placeholder={t('placeholders.ask_about_project')}
109
+ isLoading={isLoading}
110
+ supportFiles={supportFiles}
111
+ supportWebSearch={supportWebSearch}
112
+ supportDocumentSearch={supportDocumentSearch}
113
+ supportDeepResearch={supportDeepResearch}
114
+ supportThinking={supportThinking}
115
+ supportWorkCanvas={supportWorkCanvas}
116
+ supportMultiModels={supportMultiModels}
117
+ deploymentId={deploymentId}
118
+ footerText={t('descriptions.footer_project')}
119
+ enableMicrophone={enableMicrophone}
120
+ enableVoice={enableVoice}
121
+ isRecording={isRecording}
122
+ recognition={recognition}
123
+ onMicrophoneClick={onMicrophoneClick}
124
+ showToolbar={true} />
125
+ </div>
126
+
127
+ {/* Tabs for Sessions, Works and Documents */}
128
+ <div className="mt-4">
129
+ <Tabs value={activeTab} onValueChange={setActiveTab} className="w-full">
130
+ <TabsList className="grid w-full grid-cols-3">
131
+ <TabsTrigger value="sessions">{t('tabs.sessions')}</TabsTrigger>
132
+ <TabsTrigger value="works">{t('tabs.works')}</TabsTrigger>
133
+ <TabsTrigger value="documents">{t('tabs.documents')}</TabsTrigger>
134
+ </TabsList>
135
+
136
+ <TabsContent value="sessions" className="mt-4">
137
+ {projectThreads[project.id] && projectThreads[project.id].length > 0 ? (
138
+ <>
139
+ <div className="flex justify-end items-center mb-3">
140
+ <span className="text-xs text-muted-foreground">
141
+ {projectThreads[project.id].length} {t('labels.threads')}
142
+ </span>
143
+ </div>
144
+ <div className="space-y-2 rounded-lg max-h-84 overflow-y-auto">
145
+ {projectThreads[project.id].map(thread => (
146
+ <div
147
+ key={thread.id}
148
+ className="group flex items-center gap-3 p-3 rounded-lg hover:bg-muted/50 transition-colors border border-border">
149
+ <div
150
+ onClick={() => onThreadClick(thread)}
151
+ className="flex items-center gap-3 flex-1 cursor-pointer">
152
+ <div className="w-2 h-2 rounded-full bg-muted-foreground/40 group-hover:bg-primary/60 transition-colors flex-shrink-0" />
153
+ <div className="flex-1 min-w-0">
154
+ <p className="text-sm font-medium text-foreground group-hover:text-primary transition-colors truncate">
155
+ {thread.title || t('common.untitled')}
156
+ </p>
157
+ <p className="text-xs text-muted-foreground">
158
+ {thread.updatedAt.toLocaleDateString()} at {thread.updatedAt.toLocaleTimeString()}
159
+ </p>
160
+ </div>
161
+ </div>
162
+ <DropdownMenu>
163
+ <DropdownMenuTrigger asChild>
164
+ <Button
165
+ variant="ghost"
166
+ size="icon"
167
+ className="h-6 w-6 text-muted-foreground hover:text-foreground opacity-0 group-hover:opacity-100 transition-opacity"
168
+ onClick={e => e.stopPropagation()}>
169
+ <MoreHorizontal className="w-4 h-4" />
170
+ </Button>
171
+ </DropdownMenuTrigger>
172
+ <DropdownMenuContent align="end">
173
+ <DropdownMenuItem
174
+ className="cursor-pointer"
175
+ onClick={(e) => {
176
+ e.stopPropagation();
177
+ onEditSession(thread);
178
+ }}>
179
+ <Edit className="w-4 h-4 mr-2" />
180
+ {t('common.rename')}
181
+ </DropdownMenuItem>
182
+ <DropdownMenuItem
183
+ onClick={(e) => {
184
+ e.stopPropagation();
185
+ onDeleteSession(thread);
186
+ }}
187
+ className="text-destructive focus:text-destructive cursor-pointer">
188
+ <Trash className="w-4 h-4 mr-2" />
189
+ {t('common.delete')}
190
+ </DropdownMenuItem>
191
+ </DropdownMenuContent>
192
+ </DropdownMenu>
193
+ </div>
194
+ ))}
195
+ </div>
196
+ </>
197
+ ) : (
198
+ <div className="text-center py-8">
199
+ <p className="text-sm text-muted-foreground">{t('messages.no_threads_yet')}</p>
200
+ <p className="text-xs text-muted-foreground mt-1">
201
+ {t('messages.start_conversation')}
202
+ </p>
203
+ </div>
204
+ )}
205
+ </TabsContent>
206
+
207
+ <TabsContent value="works" className="mt-4">
208
+ {projectWorks[project.id] && projectWorks[project.id].length > 0 ? (
209
+ <>
210
+ <div className="flex justify-end items-center mb-3">
211
+ <span className="text-xs text-muted-foreground">{projectWorks[project.id].length} {t('labels.works')}</span>
212
+ </div>
213
+ <div className="space-y-2 rounded-lg max-h-84 overflow-y-auto">
214
+ {projectWorks[project.id].map(work => (
215
+ <div
216
+ key={work.id}
217
+ className="group flex flex-col gap-2 p-3 rounded-lg hover:bg-muted/50 transition-colors border border-border cursor-pointer">
218
+ <div className="flex items-start justify-between">
219
+ <div className="flex-1">
220
+ <h4 className="text-sm font-medium">{work.title}</h4>
221
+ {work.description && (
222
+ <p className="text-xs text-muted-foreground mt-1">{work.description}</p>
223
+ )}
224
+ </div>
225
+ {work.image_url && (
226
+ <img
227
+ src={work.image_url}
228
+ alt={work.title}
229
+ className="w-12 h-12 rounded object-cover ml-2" />
230
+ )}
231
+ </div>
232
+ <div className="flex items-center justify-between text-xs text-muted-foreground">
233
+ <span>{work.type || t('labels.document')}</span>
234
+ <span>{work.created_on ? new Date(work.created_on).toLocaleDateString() : ''}</span>
235
+ </div>
236
+ </div>
237
+ ))}
238
+ </div>
239
+ </>
240
+ ) : (
241
+ <div className="text-center py-8">
242
+ <p className="text-sm text-muted-foreground">{t('messages.no_works_yet')}</p>
243
+ <p className="text-xs text-muted-foreground mt-1">{t('messages.create_works_to_track')}</p>
244
+ </div>
245
+ )}
246
+ </TabsContent>
247
+
248
+ <TabsContent value="documents" className="mt-4">
249
+ <div className="text-center py-8">
250
+ <p className="text-sm text-muted-foreground">{t('messages.no_documents_yet')}</p>
251
+ </div>
252
+ </TabsContent>
253
+ </Tabs>
254
+ </div>
255
+ </div>
256
+ );
257
+ };