@swiss-ai-hub/web 0.290.11

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 (313) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +479 -0
  3. package/app.config.ts +1 -0
  4. package/app.vue +52 -0
  5. package/assets/css/main.css +4 -0
  6. package/assets/images/logo.png +0 -0
  7. package/components/Agent/Avatar.vue +40 -0
  8. package/components/Agent/Card.vue +139 -0
  9. package/components/Agent/Configuration.vue +20 -0
  10. package/components/Agent/CreateModal.vue +287 -0
  11. package/components/Agent/EmptyCard.vue +35 -0
  12. package/components/Agent/List.vue +85 -0
  13. package/components/Agent/TemplateCard.vue +58 -0
  14. package/components/AppLoader.vue +55 -0
  15. package/components/Chat/Message.vue +90 -0
  16. package/components/Chat/SourceNodes.vue +120 -0
  17. package/components/Chat/Thread.vue +134 -0
  18. package/components/Costs/Table.vue +56 -0
  19. package/components/Dashboard/Component/BarChart.vue +46 -0
  20. package/components/Dashboard/Component/LineChart.vue +138 -0
  21. package/components/Dashboard/Component/Number.vue +31 -0
  22. package/components/Dashboard/Grid.vue +214 -0
  23. package/components/Dashboard/Item.vue +75 -0
  24. package/components/Dashboard/Trend.vue +34 -0
  25. package/components/Display/List/DisplayList.vue +93 -0
  26. package/components/Evaluation/Dataset/Card.vue +70 -0
  27. package/components/Evaluation/Dataset/Create.vue +81 -0
  28. package/components/Evaluation/Dataset/Edit.vue +132 -0
  29. package/components/Event/Display/AddMemoryToChatHistoryEvent.vue +60 -0
  30. package/components/Event/Display/AgentInTheLoopRequestEvent.vue +56 -0
  31. package/components/Event/Display/AgentInTheLoopResponseEvent.vue +17 -0
  32. package/components/Event/Display/Base.vue +125 -0
  33. package/components/Event/Display/BaseRetrieveMemoryEvent.vue +101 -0
  34. package/components/Event/Display/BaseStoreMemoryEvent.vue +182 -0
  35. package/components/Event/Display/ChunkEvent.vue +40 -0
  36. package/components/Event/Display/EmbeddingEvent.vue +25 -0
  37. package/components/Event/Display/ExceptionEvent.vue +21 -0
  38. package/components/Event/Display/GuardAcceptEvent.vue +25 -0
  39. package/components/Event/Display/GuardEvent.vue +17 -0
  40. package/components/Event/Display/GuardRejectionEvent.vue +25 -0
  41. package/components/Event/Display/HumanInTheLoopRequestEvent.vue +53 -0
  42. package/components/Event/Display/HumanInTheLoopResponseEvent.vue +40 -0
  43. package/components/Event/Display/LLMCostEvent.vue +25 -0
  44. package/components/Event/Display/LLMEvent.vue +92 -0
  45. package/components/Event/Display/LimitChatHistoryEvent.vue +60 -0
  46. package/components/Event/Display/RAGFailureStopEvent.vue +28 -0
  47. package/components/Event/Display/RAGStartEvent.vue +77 -0
  48. package/components/Event/Display/RAGSuccessStopEvent.vue +16 -0
  49. package/components/Event/Display/RawDataContent.vue +69 -0
  50. package/components/Event/Display/RerankerEvent.vue +39 -0
  51. package/components/Event/Display/RetrieverEvent.vue +22 -0
  52. package/components/Event/Display/RouterEvent.vue +54 -0
  53. package/components/Event/Display/StandaloneQuestionCondenserEvent.vue +38 -0
  54. package/components/Event/Display/StopEvent.vue +16 -0
  55. package/components/Event/Display/ThoughtEvent.vue +20 -0
  56. package/components/Event/Display/ToolEvent.vue +38 -0
  57. package/components/Event/Display/UnknownEvent.vue +17 -0
  58. package/components/Event/Display/UserMessageEvent.vue +35 -0
  59. package/components/Event/List/EventList.vue +249 -0
  60. package/components/Event/Statistics.vue +49 -0
  61. package/components/Event/Timeseries.vue +224 -0
  62. package/components/FormKit/AgentSelector.vue +307 -0
  63. package/components/FormKit/ChipsInput.vue +62 -0
  64. package/components/FormKit/DynamicConfiguration.vue +155 -0
  65. package/components/FormKit/IconSelector.vue +72 -0
  66. package/components/FormKit/KnowledgeDatabaseSelector.vue +92 -0
  67. package/components/FormKit/LocaleInput.vue +150 -0
  68. package/components/FormKit/ModelSelect.vue +110 -0
  69. package/components/FormKit/Repeater.vue +93 -0
  70. package/components/FormKit/VectorStoreInput.vue +247 -0
  71. package/components/Knowledge/Document/List.vue +140 -0
  72. package/components/Knowledge/Document/Overview.vue +28 -0
  73. package/components/Knowledge/Document/UploadModal.vue +298 -0
  74. package/components/Knowledge/Document/WithNodes.vue +105 -0
  75. package/components/Knowledge/Namespace/Card.vue +108 -0
  76. package/components/Knowledge/Namespace/CreateModal.vue +203 -0
  77. package/components/Knowledge/Namespace/EditModal.vue +134 -0
  78. package/components/Knowledge/Namespace/EmptyCard.vue +35 -0
  79. package/components/Knowledge/Node/Content.vue +71 -0
  80. package/components/Markdown/Renderer.vue +87 -0
  81. package/components/Memory/DetailPage.vue +48 -0
  82. package/components/Memory/Edit.vue +241 -0
  83. package/components/Memory/Graph.vue +318 -0
  84. package/components/Memory/List.vue +155 -0
  85. package/components/Memory/MemoryManagementPage.vue +178 -0
  86. package/components/Memory/OpenWebUIContent.vue +96 -0
  87. package/components/Memory/PageLayout.vue +72 -0
  88. package/components/Models/ModelDetailsPanel.vue +250 -0
  89. package/components/Models/NamespaceCard.vue +79 -0
  90. package/components/Navigation/Left.vue +85 -0
  91. package/components/Navigation/Top.vue +31 -0
  92. package/components/Notification/Item.vue +88 -0
  93. package/components/Notification/NotificationsOverlay.vue +164 -0
  94. package/components/Process/Card.vue +119 -0
  95. package/components/Process/Configuration.vue +20 -0
  96. package/components/Process/CreateModal.vue +276 -0
  97. package/components/Process/EmptyCard.vue +35 -0
  98. package/components/Process/Form.vue +153 -0
  99. package/components/Process/Starts.vue +44 -0
  100. package/components/Process/Walkthrough/List.vue +162 -0
  101. package/components/Role/AccessRulesEditor.vue +132 -0
  102. package/components/Role/Card.vue +68 -0
  103. package/components/Role/Create.vue +55 -0
  104. package/components/Role/Edit.vue +82 -0
  105. package/components/Role/UsageLimitsEditor.vue +225 -0
  106. package/components/Service/Selection.vue +148 -0
  107. package/components/Structural/Column.vue +74 -0
  108. package/components/Structural/Screen.vue +10 -0
  109. package/components/Structural/Substructure.vue +5 -0
  110. package/components/Tenant/Switcher.vue +102 -0
  111. package/components/Thread/Details.vue +135 -0
  112. package/components/Thread/Hierarchy.vue +136 -0
  113. package/components/Thread/Info.vue +41 -0
  114. package/components/Thread/List.vue +136 -0
  115. package/components/User/Bar.vue +74 -0
  116. package/components/User/List.vue +86 -0
  117. package/components/User/RoleChips.vue +83 -0
  118. package/components/User/Settings.vue +79 -0
  119. package/components/Workflow/Modal.vue +39 -0
  120. package/components/Workflow/NodeCard.vue +41 -0
  121. package/components/Workflow/StartNode.vue +24 -0
  122. package/components/Workflow/StepNode.vue +27 -0
  123. package/components/Workflow/StopNode.vue +24 -0
  124. package/components/Workflow/Visualization.vue +265 -0
  125. package/components/mdc/MarkdownFigure.vue +9 -0
  126. package/components/mdc/MarkdownTable.vue +9 -0
  127. package/components/mdc/ResolveImageComponent.vue +58 -0
  128. package/composables/agent/useAgentClass.ts +27 -0
  129. package/composables/agent/useAgentClassInstances.ts +27 -0
  130. package/composables/agent/useAgentClasses.ts +27 -0
  131. package/composables/agent/useAgentIconFromThread.ts +8 -0
  132. package/composables/agent/useAgentInstance.ts +28 -0
  133. package/composables/agent/useAgentInstanceThreads.ts +76 -0
  134. package/composables/agent/useAgentInstances.ts +25 -0
  135. package/composables/agent/useAgentNavigation.ts +35 -0
  136. package/composables/agent/useCreateAgentInstance.ts +33 -0
  137. package/composables/agent/useDeleteAgentInstance.ts +31 -0
  138. package/composables/agent/useUpdateAgentInstance.ts +40 -0
  139. package/composables/auth/useAuth.ts +54 -0
  140. package/composables/auth/useAuthProviders.ts +14 -0
  141. package/composables/chat/useChatCompletions.ts +30 -0
  142. package/composables/dashboard/useAgentNameFromDashboardWidget.ts +27 -0
  143. package/composables/dashboard/useDashboardComponent.ts +27 -0
  144. package/composables/dashboard/useSaveDashboard.ts +21 -0
  145. package/composables/document/useCreateNamespace.ts +26 -0
  146. package/composables/document/useDatabases.ts +23 -0
  147. package/composables/document/useDocument.ts +29 -0
  148. package/composables/document/useDocumentUrl.ts +20 -0
  149. package/composables/document/useDocuments.ts +107 -0
  150. package/composables/document/useNodes.ts +29 -0
  151. package/composables/document/useSummaryNodes.ts +32 -0
  152. package/composables/document/useUpdateNamespace.ts +22 -0
  153. package/composables/evaluation/useCreateDataset.ts +19 -0
  154. package/composables/evaluation/useDataset.ts +26 -0
  155. package/composables/evaluation/useDatasets.ts +25 -0
  156. package/composables/evaluation/useUpdateDataset.ts +23 -0
  157. package/composables/event/useBasicEventStatistics.ts +83 -0
  158. package/composables/event/useEventColor.ts +25 -0
  159. package/composables/event/useEventComponent.ts +87 -0
  160. package/composables/event/useEventTimeseries.ts +39 -0
  161. package/composables/event/useEventTimeseriesStats.ts +26 -0
  162. package/composables/file/useFileUpload.ts +91 -0
  163. package/composables/file/useSupportedFileTypes.ts +22 -0
  164. package/composables/form/useCreateInstanceForm.ts +251 -0
  165. package/composables/form/useFormKitTransform.ts +753 -0
  166. package/composables/memory/useMemoryCRUD.ts +88 -0
  167. package/composables/memory/useMemoryFactory.ts +319 -0
  168. package/composables/memory/useMemorySearchFilter.ts +74 -0
  169. package/composables/models/useModelsList.ts +24 -0
  170. package/composables/models/useSingleModel.ts +30 -0
  171. package/composables/notification/useNotificationPoller.ts +58 -0
  172. package/composables/notification/useNotifications.ts +57 -0
  173. package/composables/notification/useUpdateMultipleNotifications.ts +17 -0
  174. package/composables/notification/useUpdateNotification.ts +17 -0
  175. package/composables/process/useCreateProcessInstance.ts +32 -0
  176. package/composables/process/useDeleteProcessInstance.ts +31 -0
  177. package/composables/process/useProcessClasses.ts +27 -0
  178. package/composables/process/useProcessInstance.ts +28 -0
  179. package/composables/process/useProcessInstances.ts +27 -0
  180. package/composables/process/useProcessWalkthroughs.ts +73 -0
  181. package/composables/process/useSendProcessStartForm.ts +43 -0
  182. package/composables/process/useUpdateProcessInstance.ts +40 -0
  183. package/composables/role/useCreateRole.ts +19 -0
  184. package/composables/role/useDeleteRole.ts +21 -0
  185. package/composables/role/useRole.ts +30 -0
  186. package/composables/role/useRoles.ts +25 -0
  187. package/composables/role/useUpdateRole.ts +22 -0
  188. package/composables/suite/useApps.ts +31 -0
  189. package/composables/suite/useSuite.ts +26 -0
  190. package/composables/tenant/useActiveTenant.ts +27 -0
  191. package/composables/tenant/useSysadminNavigation.ts +19 -0
  192. package/composables/tenant/useTenant.ts +38 -0
  193. package/composables/tenant/useTenantMemberships.ts +15 -0
  194. package/composables/tenant/useTenantPath.ts +20 -0
  195. package/composables/tenant/useTenantPolling.ts +30 -0
  196. package/composables/tenant/useTenantReady.ts +12 -0
  197. package/composables/theme/useDarkMode.ts +5 -0
  198. package/composables/thread/useThread.ts +27 -0
  199. package/composables/thread/useThreadEvents.ts +91 -0
  200. package/composables/thread/useThreadUtils.ts +49 -0
  201. package/composables/thread/useThreads.ts +64 -0
  202. package/composables/thread/useThreadsInfinite.ts +56 -0
  203. package/composables/translation/useTranslate.ts +20 -0
  204. package/composables/useRouteReady.ts +21 -0
  205. package/composables/useTimeAgo.ts +40 -0
  206. package/composables/user/useAssignRoleToUser.ts +22 -0
  207. package/composables/user/useMyUser.ts +25 -0
  208. package/composables/user/useRevokeRoleFromUser.ts +21 -0
  209. package/composables/user/useUser.ts +30 -0
  210. package/composables/user/useUsers.ts +63 -0
  211. package/composables/utils/useJsonTree.ts +138 -0
  212. package/formkit.config.ts +44 -0
  213. package/i18n/locales/de.yaml +815 -0
  214. package/i18n/locales/en.yaml +804 -0
  215. package/i18n/locales/fr.yaml +812 -0
  216. package/i18n/locales/it.yaml +808 -0
  217. package/layouts/anonymous.vue +8 -0
  218. package/layouts/default.vue +116 -0
  219. package/middleware/auth.global.ts +62 -0
  220. package/nuxt.config.ts +145 -0
  221. package/package.json +114 -0
  222. package/pages/[tenant]/index.vue +31 -0
  223. package/pages/[tenant]/notifications/index.vue +235 -0
  224. package/pages/[tenant]/service/agents/[agent_class]-[agent_id]/chat.vue +67 -0
  225. package/pages/[tenant]/service/agents/[agent_class]-[agent_id]/configuration.vue +122 -0
  226. package/pages/[tenant]/service/agents/[agent_class]-[agent_id]/memories/[memory_id].vue +3 -0
  227. package/pages/[tenant]/service/agents/[agent_class]-[agent_id]/memories.vue +20 -0
  228. package/pages/[tenant]/service/agents/[agent_class]-[agent_id]/overview.vue +72 -0
  229. package/pages/[tenant]/service/agents/[agent_class]-[agent_id]/threads.vue +52 -0
  230. package/pages/[tenant]/service/agents/[agent_class]-[agent_id]/workflow.vue +19 -0
  231. package/pages/[tenant]/service/agents/[agent_class]-[agent_id].vue +63 -0
  232. package/pages/[tenant]/service/agents/templates.vue +102 -0
  233. package/pages/[tenant]/service/agents.vue +185 -0
  234. package/pages/[tenant]/service/datasets/[dataset_id].vue +81 -0
  235. package/pages/[tenant]/service/datasets.vue +53 -0
  236. package/pages/[tenant]/service/health/index.vue +3 -0
  237. package/pages/[tenant]/service/knowledge/[db]/[namespace]/[document_id]/nodes.vue +20 -0
  238. package/pages/[tenant]/service/knowledge/[db]/[namespace]/[document_id]/overview.vue +40 -0
  239. package/pages/[tenant]/service/knowledge/[db]/[namespace]/[document_id]/summary.vue +88 -0
  240. package/pages/[tenant]/service/knowledge/[db]/[namespace]/[document_id].vue +48 -0
  241. package/pages/[tenant]/service/knowledge/[db]/[namespace].vue +144 -0
  242. package/pages/[tenant]/service/knowledge.vue +126 -0
  243. package/pages/[tenant]/service/models/[model_name].vue +84 -0
  244. package/pages/[tenant]/service/models.vue +61 -0
  245. package/pages/[tenant]/service/my-account.vue +117 -0
  246. package/pages/[tenant]/service/openai/[thread_id]/[display_id]/memories.vue +66 -0
  247. package/pages/[tenant]/service/openai/[thread_id]/[display_id]/sources.vue +100 -0
  248. package/pages/[tenant]/service/openai/[thread_id]/[display_id]/tracing.vue +49 -0
  249. package/pages/[tenant]/service/openai.vue +101 -0
  250. package/pages/[tenant]/service/organization-memories/graph.vue +97 -0
  251. package/pages/[tenant]/service/organization-memories/list/[memory_id].vue +3 -0
  252. package/pages/[tenant]/service/organization-memories/list.vue +150 -0
  253. package/pages/[tenant]/service/organization-memories.vue +3 -0
  254. package/pages/[tenant]/service/processes/[process_class]-[process_id]/[process_walkthrough_id].vue +7 -0
  255. package/pages/[tenant]/service/processes/[process_class]-[process_id]/configuration.vue +106 -0
  256. package/pages/[tenant]/service/processes/[process_class]-[process_id]/overview.vue +67 -0
  257. package/pages/[tenant]/service/processes/[process_class]-[process_id]/start.vue +26 -0
  258. package/pages/[tenant]/service/processes/[process_class]-[process_id]/walkthroughs/[process_walkthrough_id]/overview.vue +14 -0
  259. package/pages/[tenant]/service/processes/[process_class]-[process_id]/walkthroughs.vue +54 -0
  260. package/pages/[tenant]/service/processes/[process_class]-[process_id].vue +60 -0
  261. package/pages/[tenant]/service/processes.vue +129 -0
  262. package/pages/[tenant]/service/roles/[role_id].vue +54 -0
  263. package/pages/[tenant]/service/roles.vue +84 -0
  264. package/pages/[tenant]/service/threads/[thread_id]/chat.vue +51 -0
  265. package/pages/[tenant]/service/threads/[thread_id]/display/[display_id].vue +21 -0
  266. package/pages/[tenant]/service/threads/[thread_id]/display.vue +29 -0
  267. package/pages/[tenant]/service/threads/[thread_id]/hierarchy.vue +14 -0
  268. package/pages/[tenant]/service/threads/[thread_id]/memories/[memory_id].vue +3 -0
  269. package/pages/[tenant]/service/threads/[thread_id]/memories.vue +19 -0
  270. package/pages/[tenant]/service/threads/[thread_id]/overview.vue +100 -0
  271. package/pages/[tenant]/service/threads/[thread_id].vue +54 -0
  272. package/pages/[tenant]/service/threads.vue +52 -0
  273. package/pages/[tenant]/service/user-memories/graph.vue +97 -0
  274. package/pages/[tenant]/service/user-memories/list/[memory_id].vue +3 -0
  275. package/pages/[tenant]/service/user-memories/list.vue +150 -0
  276. package/pages/[tenant]/service/user-memories.vue +3 -0
  277. package/pages/[tenant]/service/users/[user_id].vue +117 -0
  278. package/pages/[tenant]/service/users.vue +88 -0
  279. package/pages/auth/callback.vue +52 -0
  280. package/pages/auth/login.vue +80 -0
  281. package/pages/auth/renew.vue +24 -0
  282. package/pages/index.vue +59 -0
  283. package/pages/select-tenant.vue +76 -0
  284. package/plugins/0.runtime-config.client.ts +55 -0
  285. package/plugins/apexcharts.client.ts +5 -0
  286. package/plugins/api-client.client.ts +38 -0
  287. package/plugins/dark-mode.client.ts +12 -0
  288. package/plugins/keycloak-client.ts +41 -0
  289. package/plugins/oidc-client.ts +78 -0
  290. package/sdk/client/client/client.gen.ts +237 -0
  291. package/sdk/client/client/index.ts +24 -0
  292. package/sdk/client/client/types.gen.ts +213 -0
  293. package/sdk/client/client/utils.gen.ts +407 -0
  294. package/sdk/client/client.gen.ts +25 -0
  295. package/sdk/client/core/auth.gen.ts +42 -0
  296. package/sdk/client/core/bodySerializer.gen.ts +96 -0
  297. package/sdk/client/core/params.gen.ts +181 -0
  298. package/sdk/client/core/pathSerializer.gen.ts +180 -0
  299. package/sdk/client/core/queryKeySerializer.gen.ts +136 -0
  300. package/sdk/client/core/serverSentEvents.gen.ts +265 -0
  301. package/sdk/client/core/types.gen.ts +118 -0
  302. package/sdk/client/core/utils.gen.ts +143 -0
  303. package/sdk/client/index.ts +1013 -0
  304. package/sdk/client/schemas.gen.ts +35395 -0
  305. package/sdk/client/sdk.gen.ts +3438 -0
  306. package/sdk/client/transformers.gen.ts +143 -0
  307. package/sdk/client/types.gen.ts +27567 -0
  308. package/tailwind.config.mjs +27 -0
  309. package/themes/aihub-theme.ts +125 -0
  310. package/types/DashboardWidget.ts +13 -0
  311. package/types/EventChartInput.ts +7 -0
  312. package/types/NavItem.ts +6 -0
  313. package/types/TimeseriesInput.ts +7 -0
@@ -0,0 +1,140 @@
1
+ <template>
2
+ <DataTable
3
+ :value="documents"
4
+ table-style="min-width: 50rem"
5
+ selection-mode="single"
6
+ :selection="selectedDocument"
7
+ :row-class="getRowClass"
8
+ :sort-field="sortField ?? undefined"
9
+ :sort-order="sortOrder"
10
+ removable-sort
11
+ size="small"
12
+ @update:selection="handleSelection"
13
+ @sort="handleSort"
14
+ >
15
+ <Column
16
+ field="document_title"
17
+ :header="t('document.list.title')"
18
+ sortable
19
+ >
20
+ <template #body="{ data }">
21
+ <div class="flex items-center gap-2">
22
+ <p
23
+ class="font-bold"
24
+ >
25
+ {{ data.document_title }}
26
+ </p>
27
+ <div
28
+ v-if="!data.is_ingested"
29
+ class="flex items-center gap-2"
30
+ >
31
+ <Tag
32
+ :value="t('document.list.is_processing')"
33
+ size="small"
34
+ icon="pi pi-clock"
35
+ severity="info"
36
+ />
37
+ </div>
38
+ </div>
39
+ </template>
40
+ </Column>
41
+ <Column
42
+ field="created_at"
43
+ :header="t('document.list.created')"
44
+ sortable
45
+ >
46
+ <template #body="{ data }">
47
+ <p>{{ formatted(data.created_at) }}</p>
48
+ </template>
49
+ </Column>
50
+ <Column
51
+ field="updated_at"
52
+ :header="t('document.list.updated_at')"
53
+ sortable
54
+ >
55
+ <template #body="{ data }">
56
+ <p>{{ formatted(data.updated_at) }}</p>
57
+ </template>
58
+ </Column>
59
+ <Column
60
+ field="number_of_pages"
61
+ :header="t('document.list.number_of_pages')"
62
+ >
63
+ <template #body="{ data }">
64
+ <Badge
65
+ :value="data.number_of_pages ?? '-'"
66
+ />
67
+ </template>
68
+ </Column>
69
+ <Column
70
+ field="source"
71
+ :header="t('document.list.download')"
72
+ >
73
+ <template #body="{ data }">
74
+ <Button
75
+ v-if="data.source"
76
+ rounded
77
+ size="small"
78
+ variant="outlined"
79
+ icon="pi pi-download"
80
+ @click="() => downloadFile(data.id)"
81
+ />
82
+ <span
83
+ v-else
84
+ class="text-sm text-surface-400"
85
+ >-</span>
86
+ </template>
87
+ </Column>
88
+ </DataTable>
89
+ </template>
90
+
91
+ <script setup lang="ts">
92
+ import type { DocumentDto } from '@core/sdk/client'
93
+ import type { DataTableSortEvent } from 'primevue/datatable'
94
+
95
+ const route = useRoute()
96
+ const { t } = useI18n()
97
+ const { tenantId } = useTenant()
98
+ const { getDocumentSourceUrl } = useDocumentUrl()
99
+
100
+ const props = defineProps<{
101
+ documents: DocumentDto[]
102
+ sortField: string | null
103
+ sortOrder: 1 | -1
104
+ }>()
105
+
106
+ const emit = defineEmits<{
107
+ selected: [document: DocumentDto]
108
+ sort: [field: string | null, order: 1 | -1]
109
+ }>()
110
+
111
+ const formatted = (datestr: string) => useDateFormat(new Date(datestr), 'DD.MM.YYYY')
112
+ const selectedDocument = computed(() => {
113
+ return props.documents.filter((document: DocumentDto) => {
114
+ return document.id === route.params.document_id
115
+ })
116
+ })
117
+
118
+ const handleSelection = (document: DocumentDto) => {
119
+ if (document.is_ingested) {
120
+ emit('selected', document)
121
+ }
122
+ }
123
+
124
+ const getRowClass = (data: DocumentDto) => {
125
+ return data.is_ingested ? '' : 'opacity-50 cursor-not-allowed pointer-events-none'
126
+ }
127
+
128
+ const handleSort = (event: DataTableSortEvent) => {
129
+ const field = event.sortField as string | null
130
+ const order = (event.sortOrder ?? 1) as 1 | -1
131
+ emit('sort', field, order)
132
+ }
133
+
134
+ const downloadFile = async (documentId: string) => {
135
+ const database = route.params.db as string
136
+ const namespace = route.params.namespace as string
137
+ const url = await getDocumentSourceUrl(tenantId.value!, database, namespace, documentId)
138
+ window.open(url, '_blank')
139
+ }
140
+ </script>
@@ -0,0 +1,28 @@
1
+ <template>
2
+ <div>
3
+ <div class="flex justify-between text-xs opacity-60">
4
+ <div>{{ document.document_title }}</div>
5
+ <div>{{ createdAt }}</div>
6
+ </div>
7
+ <Divider />
8
+ <slot />
9
+ <Divider />
10
+ <div class="flex justify-between text-xs opacity-60">
11
+ <div>{{ t('namespace') }}: {{ document.namespace }}</div>
12
+ <div>{{ t('document.list.number_of_pages') }}: {{ document.number_of_pages }}</div>
13
+ </div>
14
+ </div>
15
+ </template>
16
+
17
+ <script setup lang="ts">
18
+ import type { DocumentDto } from '@core/sdk/client'
19
+
20
+ const props = defineProps<{
21
+ document: DocumentDto
22
+ }>()
23
+
24
+ const { t } = useI18n()
25
+ const createdAt = computed(() => {
26
+ return useDateFormat(new Date(props.document.created_at), 'DD.MM.YYYY HH:mm:ss')
27
+ })
28
+ </script>
@@ -0,0 +1,298 @@
1
+ <template>
2
+ <Dialog
3
+ v-model:visible="isVisible"
4
+ modal
5
+ :header="t('knowledge.documents.upload.title')"
6
+ :style="{ width: '30rem' }"
7
+ :breakpoints="{ '1199px': '75vw', '575px': '90vw' }"
8
+ >
9
+ <div class="flex flex-col gap-6">
10
+ <div
11
+ ref="dropZone"
12
+ class="flex flex-col items-center justify-center rounded-lg border-2 border-dashed border-surface-300 p-8 transition-colors hover:border-primary-500 hover:bg-surface-50 dark:border-surface-600 dark:hover:bg-surface-800"
13
+ :class="{
14
+ 'border-primary-500 bg-surface-50 dark:bg-surface-800': isDragOver,
15
+ 'border-red-500 bg-red-50 dark:bg-red-900/20': hasError,
16
+ }"
17
+ @dragover.prevent="handleDragOver"
18
+ @dragleave.prevent="handleDragLeave"
19
+ @drop.prevent="handleDrop"
20
+ @click="() => fileInput?.click()"
21
+ >
22
+ <i
23
+ class="pi pi-cloud-upload mb-4 text-surface-400"
24
+ style="font-size: 3rem"
25
+ />
26
+ <p class="mb-2 text-sm text-surface-600 dark:text-surface-400">
27
+ <span class="font-semibold">{{ t('knowledge.documents.upload.drag_and_drop') }}</span>
28
+ </p>
29
+ <div
30
+ v-if="selectedFiles.length > 0"
31
+ class="mt-4 w-full"
32
+ >
33
+ <div
34
+ v-for="(file, index) in selectedFiles"
35
+ :key="index"
36
+ class="flex items-center justify-between rounded bg-surface-100 p-2 dark:bg-surface-700"
37
+ >
38
+ <div class="flex items-center gap-2">
39
+ <i class="pi pi-file text-surface-400" />
40
+ <span class="text-sm">{{ file.name }}</span>
41
+ </div>
42
+ <Button
43
+ icon="pi pi-times"
44
+ text
45
+ rounded
46
+ size="small"
47
+ severity="secondary"
48
+ @click="removeFile(index)"
49
+ />
50
+ </div>
51
+ </div>
52
+ </div>
53
+
54
+ <div
55
+ v-if="props.namespace && props.database"
56
+ class="flex flex-col gap-2"
57
+ >
58
+ <p class="text-sm font-medium">
59
+ {{ t('knowledge.documents.upload.target_location.label') }}
60
+ </p>
61
+ <div class="flex items-center gap-2 rounded-lg border border-surface-200 bg-surface-50 p-3 dark:border-surface-700 dark:bg-surface-800">
62
+ <i
63
+ class="pi pi-database text-surface-400"
64
+ style="font-size: 1rem"
65
+ />
66
+ <span class="text-sm text-surface-600 dark:text-surface-300">{{ databaseDisplayName }}</span>
67
+ <i
68
+ class="pi pi-angle-right text-surface-400"
69
+ style="font-size: 0.8rem"
70
+ />
71
+ <i
72
+ class="pi pi-folder text-primary-500"
73
+ style="font-size: 1rem"
74
+ />
75
+ <span class="text-sm font-medium text-surface-800 dark:text-surface-100">{{ namespaceDisplayName }}</span>
76
+ </div>
77
+ <small class="text-surface-500 dark:text-surface-400">
78
+ {{ t('knowledge.documents.upload.target_location.help') }}
79
+ </small>
80
+ </div>
81
+
82
+ <Message
83
+ v-if="errorMessage"
84
+ severity="error"
85
+ :closable="false"
86
+ >
87
+ {{ errorMessage }}
88
+ </Message>
89
+
90
+ <div
91
+ v-if="isUploading"
92
+ class="flex flex-col gap-2"
93
+ >
94
+ <div class="flex justify-between text-sm">
95
+ <span>{{ currentUploadFile }}</span>
96
+ <span>{{ uploadProgress }}%</span>
97
+ </div>
98
+ <ProgressBar :value="uploadProgress" />
99
+ </div>
100
+ </div>
101
+
102
+ <template #footer>
103
+ <div class="flex justify-end gap-2">
104
+ <Button
105
+ :label="t('knowledge.documents.upload.actions.cancel')"
106
+ severity="secondary"
107
+ outlined
108
+ :disabled="isUploading"
109
+ @click="closeModal"
110
+ />
111
+ <Button
112
+ :label="t('knowledge.documents.upload.actions.upload')"
113
+ :disabled="!canUpload"
114
+ :loading="isUploading"
115
+ @click="handleUpload"
116
+ />
117
+ </div>
118
+ </template>
119
+
120
+ <input
121
+ ref="fileInput"
122
+ type="file"
123
+ multiple
124
+ :accept="acceptedFileTypesString"
125
+ class="hidden"
126
+ @change="handleFileSelect"
127
+ >
128
+ </Dialog>
129
+ </template>
130
+
131
+ <script setup lang="ts">
132
+ import { useChangeCase } from '@vueuse/integrations/useChangeCase'
133
+
134
+ interface Props {
135
+ visible: boolean
136
+ database: string
137
+ namespace: string
138
+ databaseDisplayName?: string
139
+ namespaceDisplayName?: string
140
+ title?: string
141
+ }
142
+
143
+ const props = withDefaults(defineProps<Props>(), {
144
+ })
145
+
146
+ const { t } = useI18n()
147
+
148
+ const databaseDisplayName = computed(() => {
149
+ return props.databaseDisplayName || useChangeCase(props.database, 'capitalCase').value
150
+ })
151
+
152
+ const namespaceDisplayName = computed(() => {
153
+ return props.namespaceDisplayName || useChangeCase(props.namespace, 'capitalCase').value
154
+ })
155
+
156
+ const emit = defineEmits<{
157
+ 'update:visible': [value: boolean]
158
+ 'success': [data: { files: File[], namespace: string, database: string }]
159
+ }>()
160
+
161
+ const { uploadFile } = useFileUpload()
162
+ const { supportedFileTypes } = useSupportedFileTypes()
163
+ const { tenantId } = useTenant()
164
+
165
+ const acceptedFileTypesString = computed(() => {
166
+ return (supportedFileTypes.value ?? []).join(', ')
167
+ })
168
+ const selectedFiles = ref<File[]>([])
169
+ const isDragOver = ref(false)
170
+ const isUploading = ref(false)
171
+ const errorMessage = ref('')
172
+ const hasError = ref(false)
173
+ const uploadProgress = ref(0)
174
+ const currentUploadFile = ref('')
175
+
176
+ const fileInput = ref<HTMLInputElement>()
177
+
178
+ const isVisible = computed({
179
+ get: () => props.visible,
180
+ set: value => emit('update:visible', value),
181
+ })
182
+
183
+ const canUpload = computed(() => {
184
+ return selectedFiles.value.length > 0 && !isUploading.value
185
+ })
186
+
187
+ const addFiles = (files: FileList | File[]) => {
188
+ errorMessage.value = ''
189
+ hasError.value = false
190
+
191
+ const validFiles: File[] = []
192
+ const invalidFiles: File[] = []
193
+ const supportedTypes: string[] = supportedFileTypes.value ?? []
194
+
195
+ for (const file of Array.from(files)) {
196
+ const fileExtension = `.${file.name.split('.').pop()?.toLowerCase()}`
197
+
198
+ const isDuplicate = selectedFiles.value.some(existing => existing.name === file.name && existing.size === file.size)
199
+ const isSupported = supportedTypes.includes(fileExtension)
200
+
201
+ if (!isDuplicate && isSupported) {
202
+ validFiles.push(file)
203
+ }
204
+ else if (!isSupported) {
205
+ invalidFiles.push(file)
206
+ }
207
+ }
208
+
209
+ if (validFiles.length > 0) {
210
+ selectedFiles.value.push(...validFiles)
211
+ }
212
+
213
+ if (invalidFiles.length > 0) {
214
+ hasError.value = true
215
+ errorMessage.value = t('knowledge.documents.upload.errors.unsupported_file_type', {
216
+ count: invalidFiles.length,
217
+ supportedTypes: acceptedFileTypesString.value,
218
+ })
219
+ }
220
+ }
221
+
222
+ const removeFile = (index: number) => {
223
+ selectedFiles.value.splice(index, 1)
224
+ errorMessage.value = ''
225
+ hasError.value = false
226
+ }
227
+
228
+ const handleFileSelect = (event: Event) => {
229
+ const target = event.target as HTMLInputElement
230
+ if (target.files) {
231
+ addFiles(target.files)
232
+ }
233
+ }
234
+
235
+ const handleDragOver = (event: DragEvent) => {
236
+ event.preventDefault()
237
+ isDragOver.value = true
238
+ }
239
+
240
+ const handleDragLeave = (event: DragEvent) => {
241
+ event.preventDefault()
242
+ isDragOver.value = false
243
+ }
244
+
245
+ const handleDrop = (event: DragEvent) => {
246
+ event.preventDefault()
247
+ isDragOver.value = false
248
+
249
+ if (event.dataTransfer?.files) {
250
+ addFiles(event.dataTransfer.files)
251
+ }
252
+ }
253
+
254
+ const handleUpload = async () => {
255
+ if (!canUpload.value) return
256
+
257
+ const namespace = props.namespace
258
+ const database = props.database
259
+
260
+ isUploading.value = true
261
+ errorMessage.value = ''
262
+
263
+ for (const file of selectedFiles.value) {
264
+ currentUploadFile.value = file.name
265
+
266
+ await uploadFile({
267
+ filename: file.name,
268
+ file,
269
+ namespace,
270
+ database,
271
+ tenantId: tenantId.value!,
272
+ })
273
+ }
274
+
275
+ emit('success', { files: selectedFiles.value, namespace, database })
276
+ closeModal()
277
+ }
278
+
279
+ const resetState = () => {
280
+ selectedFiles.value = []
281
+ errorMessage.value = ''
282
+ hasError.value = false
283
+ isUploading.value = false
284
+ uploadProgress.value = 0
285
+ currentUploadFile.value = ''
286
+ }
287
+
288
+ const closeModal = () => {
289
+ resetState()
290
+ emit('update:visible', false)
291
+ }
292
+
293
+ watch(() => props.visible, (newVal) => {
294
+ if (newVal) {
295
+ resetState()
296
+ }
297
+ })
298
+ </script>
@@ -0,0 +1,105 @@
1
+ <template>
2
+ <div
3
+ v-if="!(documentNodesAreLoading || documentIsLoading)"
4
+ class="relative rounded-3xl border border-surface-100 bg-white p-9 dark:border-surface-600 dark:bg-surface-800"
5
+ >
6
+ <KnowledgeDocumentOverview :document="document">
7
+ <div class="mb-4 flex justify-end">
8
+ <Button
9
+ v-if="document?.source"
10
+ icon="pi pi-external-link"
11
+ :label="t('knowledge.original.view_button')"
12
+ size="small"
13
+ variant="outlined"
14
+ @click="openOriginalDocument"
15
+ />
16
+ </div>
17
+ <KnowledgeNodeContent
18
+ v-for="node in combinedNodes"
19
+ :key="node.node.id"
20
+ always-show-score
21
+ :node="node.node"
22
+ :active="node.isActive"
23
+ />
24
+ </KnowledgeDocumentOverview>
25
+ </div>
26
+ </template>
27
+
28
+ <script setup lang="ts">
29
+ import { type IngestedDocument, getDocumentById, getNodesForDocument, type IngestedNode } from '@core/sdk/client'
30
+ import { minutesToMilliseconds } from 'date-fns'
31
+
32
+ const props = defineProps<{
33
+ db: string
34
+ namespace: string
35
+ documentId: string
36
+ inputNodes: IngestedNode[]
37
+ showInactive: boolean
38
+ }>()
39
+
40
+ const { t } = useI18n()
41
+ const { tenantId } = useTenant()
42
+ const { getDocumentSourceUrl } = useDocumentUrl()
43
+
44
+ const isTenantReady = useTenantReady()
45
+
46
+ const { data: document, isPending: documentIsLoading } = useQuery<IngestedDocument>({
47
+ key: () => ['knowledge', 'db', props.db, 'namespace', props.namespace, 'document', props.documentId as string],
48
+ staleTime: minutesToMilliseconds(5),
49
+ enabled: isTenantReady,
50
+ query: async () => {
51
+ return await getDocumentById({
52
+ composable: '$fetch',
53
+ path: {
54
+ tenant_id: tenantId.value!,
55
+ database: props.db,
56
+ namespace: props.namespace,
57
+ document_id: props.documentId as string,
58
+ },
59
+ })
60
+ },
61
+ })
62
+
63
+ const { data: documentNodes, isPending: documentNodesAreLoading } = useQuery<Node[]>({
64
+ key: () => ['knowledge', 'db', props.db, 'namespace', props.namespace, 'document', props.documentId, 'nodes'],
65
+ staleTime: minutesToMilliseconds(5),
66
+ enabled: isTenantReady,
67
+ query: async () => {
68
+ return await getNodesForDocument({
69
+ composable: '$fetch',
70
+ path: {
71
+ tenant_id: tenantId.value!,
72
+ database: props.db,
73
+ namespace: props.namespace,
74
+ document_id: props.documentId as string,
75
+ },
76
+ })
77
+ },
78
+ })
79
+
80
+ const openOriginalDocument = async () => {
81
+ if (!document.value?.source) return
82
+
83
+ try {
84
+ const url = await getDocumentSourceUrl(tenantId.value!, props.db, props.namespace, props.documentId)
85
+ window.open(url, '_blank')
86
+ }
87
+ catch (e) {
88
+ console.error('Error opening document:', e)
89
+ }
90
+ }
91
+
92
+ const combinedNodes = computed<{ node: IngestedNode, isActive: boolean }[]>(() => {
93
+ const combNodes: { node: IngestedNode, isActive: boolean }[] = [];
94
+ (documentNodes.value ?? []).forEach((node: IngestedNode) => {
95
+ const activeNode = props.inputNodes.find((n: IngestedNode) => n.id === node.id)
96
+ if (activeNode) {
97
+ combNodes.push({ node: activeNode, isActive: true })
98
+ }
99
+ else if (props.showInactive) {
100
+ combNodes.push({ node, isActive: false })
101
+ }
102
+ })
103
+ return combNodes
104
+ })
105
+ </script>
@@ -0,0 +1,108 @@
1
+ <template>
2
+ <div
3
+ class="flex cursor-pointer flex-col gap-3 rounded-xl border border-surface-200 p-4 hover:bg-surface-100 dark:border-surface-800 hover:dark:bg-surface-800"
4
+ :class="{ 'bg-surface-100 dark:bg-surface-800': isActive }"
5
+ >
6
+ <div class="flex items-center justify-between gap-4">
7
+ <div class="flex items-center justify-start gap-2">
8
+ <div
9
+ class="flex items-center justify-center rounded-full bg-white p-3 dark:bg-surface-900"
10
+ >
11
+ <Icon
12
+ name="mage:book"
13
+ size="1.5em"
14
+ />
15
+ </div>
16
+ <div>
17
+ <h3 class="font-semibold opacity-80">
18
+ {{ displayName }}
19
+ </h3>
20
+ <p
21
+ v-if="namespace.description"
22
+ class="text-sm text-surface-500 dark:text-surface-400"
23
+ >
24
+ {{ namespace.description }}
25
+ </p>
26
+ </div>
27
+ </div>
28
+ <div class="flex items-center gap-2">
29
+ <Button
30
+ v-tooltip.top="t('knowledge.edit_namespace')"
31
+ icon="pi pi-pencil"
32
+ rounded
33
+ text
34
+ size="small"
35
+ severity="secondary"
36
+ @click.stop="handleEditClick"
37
+ />
38
+ <Button
39
+ v-if="!autoSync"
40
+ v-tooltip.top="t('knowledge.upload_documents')"
41
+ icon="pi pi-upload"
42
+ rounded
43
+ text
44
+ size="small"
45
+ severity="secondary"
46
+ @click.stop="handleUploadClick"
47
+ />
48
+ <Badge
49
+ :value="namespace.number_of_documents"
50
+ size="large"
51
+ />
52
+ </div>
53
+ </div>
54
+ <div>
55
+ <div class="text-sm">
56
+ {{ t('knowledge.created_at') }} <span class="font-light">{{ createdAt }}</span>
57
+ </div>
58
+ <div class="text-sm">
59
+ {{ t('knowledge.updated_at') }} <span class="font-light">{{ updatedAt }}</span>
60
+ </div>
61
+ </div>
62
+ </div>
63
+ </template>
64
+
65
+ <script setup lang="ts">
66
+ import { useChangeCase } from '@vueuse/integrations/useChangeCase'
67
+
68
+ import type { NamespaceDto } from '@core/sdk/client'
69
+
70
+ const props = defineProps<{
71
+ namespace: NamespaceDto
72
+ autoSync?: boolean
73
+ }>()
74
+
75
+ const emit = defineEmits<{
76
+ upload: [namespace: NamespaceDto]
77
+ edit: [namespace: NamespaceDto]
78
+ }>()
79
+
80
+ const route = useRoute()
81
+ const { t } = useI18n()
82
+
83
+ const displayName = computed(() => {
84
+ // Use display_name if available, otherwise fall back to formatted technical name
85
+ return props.namespace.display_name || useChangeCase(props.namespace.name, 'capitalCase')
86
+ })
87
+
88
+ const createdAt = computed(() => {
89
+ return useDateFormat(props.namespace.created_at * 1000, 'DD.MM.YYYY')
90
+ })
91
+ const updatedAt = computed(() => {
92
+ return useDateFormat(props.namespace.updated_at * 1000, 'DD.MM.YYYY HH:mm')
93
+ })
94
+
95
+ const isActive = computed(() => {
96
+ return route.params.namespace === props.namespace.name
97
+ })
98
+
99
+ const handleUploadClick = (event: Event) => {
100
+ event.stopPropagation()
101
+ emit('upload', props.namespace)
102
+ }
103
+
104
+ const handleEditClick = (event: Event) => {
105
+ event.stopPropagation()
106
+ emit('edit', props.namespace)
107
+ }
108
+ </script>