@datalayer/core 1.1.59 → 1.1.66

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 (366) hide show
  1. package/README.md +2 -2
  2. package/lib/api/DatalayerApi.d.ts +42 -1
  3. package/lib/api/DatalayerApi.js +90 -3
  4. package/lib/api/constants.d.ts +18 -0
  5. package/lib/api/constants.js +18 -0
  6. package/lib/api/contents/attachments.d.ts +9 -0
  7. package/lib/api/contents/attachments.js +43 -0
  8. package/lib/api/contents/bridges.d.ts +22 -0
  9. package/lib/api/contents/bridges.js +79 -0
  10. package/lib/api/contents/capabilities.d.ts +11 -0
  11. package/lib/api/contents/capabilities.js +21 -0
  12. package/lib/api/contents/cloudStorage.d.ts +31 -0
  13. package/lib/api/contents/cloudStorage.js +89 -0
  14. package/lib/api/contents/dataservers.d.ts +37 -0
  15. package/lib/api/contents/dataservers.js +121 -0
  16. package/lib/api/contents/datasets.d.ts +15 -0
  17. package/lib/api/contents/datasets.js +45 -0
  18. package/lib/api/contents/datasources.d.ts +70 -0
  19. package/lib/api/contents/datasources.js +149 -0
  20. package/lib/api/contents/generated.d.ts +1070 -0
  21. package/lib/api/contents/index.d.ts +16 -0
  22. package/lib/api/contents/index.js +20 -0
  23. package/lib/api/contents/mcp.d.ts +46 -0
  24. package/lib/api/contents/mcp.js +157 -0
  25. package/lib/api/contents/objects.d.ts +31 -0
  26. package/lib/api/contents/objects.js +88 -0
  27. package/lib/api/contents/operations.d.ts +3 -0
  28. package/lib/api/contents/operations.js +19 -0
  29. package/lib/api/contents/runtimeMounts.d.ts +40 -0
  30. package/lib/api/contents/runtimeMounts.js +59 -0
  31. package/lib/api/contents/sandboxUid.d.ts +53 -0
  32. package/lib/api/contents/sandboxUid.js +78 -0
  33. package/lib/api/contents/sources.d.ts +19 -0
  34. package/lib/api/contents/sources.js +119 -0
  35. package/lib/api/contents/sync.d.ts +18 -0
  36. package/lib/api/contents/sync.js +69 -0
  37. package/lib/api/contents/transfers.d.ts +38 -0
  38. package/lib/api/contents/transfers.js +123 -0
  39. package/lib/api/iam/connectedAgents.d.ts +39 -0
  40. package/lib/api/iam/connectedAgents.js +52 -0
  41. package/lib/api/iam/index.d.ts +2 -1
  42. package/lib/api/iam/index.js +2 -1
  43. package/lib/api/iam/mcpAlertRules.d.ts +51 -0
  44. package/lib/api/iam/mcpAlertRules.js +198 -0
  45. package/lib/api/iam/mcpAuditSettings.d.ts +46 -0
  46. package/lib/api/iam/mcpAuditSettings.js +120 -0
  47. package/lib/api/iam/mcpPolicy.d.ts +80 -0
  48. package/lib/api/iam/mcpPolicy.js +132 -0
  49. package/lib/api/iam/organizationTeams.d.ts +13 -0
  50. package/lib/api/iam/organizationTeams.js +43 -0
  51. package/lib/api/iam/serviceAgents.d.ts +68 -0
  52. package/lib/api/iam/serviceAgents.js +119 -0
  53. package/lib/api/index.d.ts +4 -1
  54. package/lib/api/index.js +3 -1
  55. package/lib/api/mcp/activity.d.ts +37 -0
  56. package/lib/api/mcp/activity.js +26 -0
  57. package/lib/api/mcp/alerts.d.ts +25 -0
  58. package/lib/api/mcp/alerts.js +51 -0
  59. package/lib/api/mcp/audit.d.ts +29 -0
  60. package/lib/api/mcp/audit.js +55 -0
  61. package/lib/api/mcp/bindings.d.ts +18 -0
  62. package/lib/api/mcp/bindings.js +42 -0
  63. package/lib/api/mcp/forwarding.d.ts +25 -0
  64. package/lib/api/mcp/forwarding.js +46 -0
  65. package/lib/api/mcp/gateway.d.ts +16 -0
  66. package/lib/api/mcp/gateway.js +70 -0
  67. package/lib/api/mcp/generated.d.ts +22 -0
  68. package/lib/api/mcp/generated.js +213 -0
  69. package/lib/api/mcp/index.d.ts +17 -0
  70. package/lib/api/mcp/index.js +25 -0
  71. package/lib/api/mcp/observability.d.ts +125 -0
  72. package/lib/api/mcp/observability.js +254 -0
  73. package/lib/api/mcp/operations.d.ts +83 -0
  74. package/lib/api/mcp/operations.js +50 -0
  75. package/lib/api/mcp/organizations.d.ts +102 -0
  76. package/lib/api/mcp/organizations.js +46 -0
  77. package/lib/api/mcp/policy.d.ts +9 -0
  78. package/lib/api/mcp/policy.js +23 -0
  79. package/lib/api/mcp/tasks.d.ts +49 -0
  80. package/lib/api/mcp/tasks.js +147 -0
  81. package/lib/api/utils/validation.d.ts +1 -1
  82. package/lib/api/utils/validation.js +1 -1
  83. package/lib/client/auth/index.js +0 -5
  84. package/lib/client/auth/storage.js +0 -5
  85. package/lib/client/auth/strategies.js +0 -5
  86. package/lib/client/base.d.ts +6 -0
  87. package/lib/client/base.js +8 -0
  88. package/lib/client/index.d.ts +0 -10
  89. package/lib/client/index.js +2 -2
  90. package/lib/client/mixins/ContentsMixin.d.ts +71 -0
  91. package/lib/client/mixins/ContentsMixin.js +157 -0
  92. package/lib/client/mixins/IAMMixin.d.ts +0 -31
  93. package/lib/client/mixins/IAMMixin.js +0 -58
  94. package/lib/components/animation/AnimatedText.d.ts +1 -0
  95. package/lib/components/animation/AnimatedText.js +0 -4
  96. package/lib/components/auth/SigInAPIKey.d.ts +1 -0
  97. package/lib/components/auth/SigInAPIKey.js +0 -6
  98. package/lib/components/auth/SignIn.d.ts +1 -0
  99. package/lib/components/auth/SignIn.js +0 -4
  100. package/lib/components/auth/SignIn.stories.d.ts +2 -2
  101. package/lib/components/avatars/BoringAvatar.d.ts +1 -1
  102. package/lib/components/avatars/BoringAvatar.stories.d.ts +1 -1
  103. package/lib/components/avatars/DLAvatar.d.ts +1 -1
  104. package/lib/components/avatars/DLAvatar.js +0 -4
  105. package/lib/components/avatars/UserAvatar.d.ts +18 -1
  106. package/lib/components/avatars/UserAvatar.js +14 -14
  107. package/lib/components/avatars/UserProfileAvatar.d.ts +1 -1
  108. package/lib/components/banners/NoAutomationBanner.d.ts +1 -1
  109. package/lib/components/billing/BillingEntitySelect.d.ts +10 -0
  110. package/lib/components/billing/BillingEntitySelect.js +0 -17
  111. package/lib/components/billing/index.js +0 -4
  112. package/lib/components/buttons/DownloadCSVButton.d.ts +1 -1
  113. package/lib/components/buttons/DownloadJsonButton.d.ts +1 -1
  114. package/lib/components/buttons/LongActionButton.d.ts +1 -0
  115. package/lib/components/buttons/LongActionButton.js +0 -4
  116. package/lib/components/buttons/UploadButton.d.ts +1 -0
  117. package/lib/components/buttons/UploadButton.js +0 -4
  118. package/lib/components/checkout/StripeCheckout.d.ts +1 -1
  119. package/lib/components/collaboration/LiveEditorCollaborators.d.ts +31 -0
  120. package/lib/components/collaboration/LiveEditorCollaborators.js +98 -53
  121. package/lib/components/collaboration/index.js +0 -4
  122. package/lib/components/confetti/ConfettiSuccess.d.ts +1 -1
  123. package/lib/components/contents/ContentSourceCard.d.ts +8 -0
  124. package/lib/components/contents/ContentSourceCard.js +23 -0
  125. package/lib/components/contents/HomeFolderObjectsBrowser.d.ts +10 -0
  126. package/lib/components/contents/HomeFolderObjectsBrowser.js +148 -0
  127. package/lib/components/contents/index.d.ts +2 -0
  128. package/lib/components/contents/index.js +6 -0
  129. package/lib/components/context/OrganizationSelect.d.ts +1 -1
  130. package/lib/components/display/AvatarSkeleton.d.ts +1 -1
  131. package/lib/components/display/BusyDots.d.ts +1 -1
  132. package/lib/components/display/CenteredSpinner.d.ts +1 -1
  133. package/lib/components/display/CodePreview.d.ts +1 -1
  134. package/lib/components/display/DatalayerBox.d.ts +7 -2
  135. package/lib/components/display/DatalayerBox.js +6 -6
  136. package/lib/components/display/HorizontalCenter.d.ts +1 -1
  137. package/lib/components/display/JupyterDialog.d.ts +1 -0
  138. package/lib/components/display/JupyterDialog.js +1 -7
  139. package/lib/components/display/Markdown.d.ts +1 -0
  140. package/lib/components/display/NotebookSkeleton.d.ts +1 -1
  141. package/lib/components/display/Placeholder.d.ts +1 -1
  142. package/lib/components/display/ToTopBranded.d.ts +1 -1
  143. package/lib/components/echarts/EChartsReact.d.ts +1 -1
  144. package/lib/components/flashes/FlashClosable.d.ts +1 -0
  145. package/lib/components/flashes/FlashClosable.js +0 -4
  146. package/lib/components/flashes/FlashGuest.d.ts +1 -1
  147. package/lib/components/flashes/FlashSurveys.d.ts +1 -1
  148. package/lib/components/flashes/FlashUnauthorized.d.ts +1 -0
  149. package/lib/components/flashes/FlashUnauthorized.js +0 -6
  150. package/lib/components/flashes/surveys/Survey2025_1.d.ts +1 -1
  151. package/lib/components/iam/ExternalTokenSilentLogin.d.ts +1 -1
  152. package/lib/components/index.d.ts +2 -0
  153. package/lib/components/index.js +2 -0
  154. package/lib/components/labels/StatusLabels.d.ts +10 -0
  155. package/lib/components/labels/StatusLabels.js +30 -1
  156. package/lib/components/labels/VisibilityLabel.d.ts +1 -1
  157. package/lib/components/landings/StepBlock.d.ts +1 -1
  158. package/lib/components/mcp/ClientBadge.d.ts +41 -0
  159. package/lib/components/mcp/ClientBadge.js +33 -0
  160. package/lib/components/mcp/McpErrorBlankslate.d.ts +21 -0
  161. package/lib/components/mcp/McpErrorBlankslate.js +17 -0
  162. package/lib/components/mcp/ScopeList.d.ts +28 -0
  163. package/lib/components/mcp/ScopeList.js +14 -0
  164. package/lib/components/mcp/index.d.ts +10 -0
  165. package/lib/components/mcp/index.js +18 -0
  166. package/lib/components/navbar/NavigationVisbilityObserver.d.ts +2 -1
  167. package/lib/components/navbar/SubdomainNavBar.d.ts +10 -5
  168. package/lib/components/navbar/SubdomainNavBar.js +2 -1
  169. package/lib/components/notebooks/JupyterNotebook.d.ts +1 -1
  170. package/lib/components/notebooks/JupyterNotebookToolbar.d.ts +1 -1
  171. package/lib/components/principal/PrincipalAppearance.d.ts +1 -0
  172. package/lib/components/principal/PrincipalAppearance.js +0 -8
  173. package/lib/components/principal/PrincipalAvatar.d.ts +9 -1
  174. package/lib/components/principal/PrincipalAvatar.js +25 -10
  175. package/lib/components/principal/PrincipalBadge.d.ts +1 -1
  176. package/lib/components/principal/PrincipalBanner.d.ts +1 -1
  177. package/lib/components/principal/PrincipalDetailsOverlay.d.ts +31 -1
  178. package/lib/components/principal/PrincipalDetailsOverlay.js +64 -33
  179. package/lib/components/principal/PrincipalHoverCard.d.ts +31 -0
  180. package/lib/components/principal/PrincipalHoverCard.js +52 -0
  181. package/lib/components/principal/PrincipalSwitcherMenu.d.ts +1 -0
  182. package/lib/components/principal/PrincipalSwitcherMenu.js +7 -15
  183. package/lib/components/principal/index.d.ts +2 -1
  184. package/lib/components/principal/index.js +2 -1
  185. package/lib/components/progress/ConsumptionBar.d.ts +1 -0
  186. package/lib/components/progress/ConsumptionBar.js +0 -4
  187. package/lib/components/progress/ProgressRing.d.ts +1 -0
  188. package/lib/components/progress/SpinnerBar.d.ts +1 -1
  189. package/lib/components/progress/Timer.d.ts +1 -0
  190. package/lib/components/progress/Timer.js +0 -4
  191. package/lib/components/screencapture/ScreencaptureButton.d.ts +1 -1
  192. package/lib/components/sharing/ShareAccessComponent.d.ts +15 -1
  193. package/lib/components/sharing/ShareAccessComponent.js +36 -23
  194. package/lib/components/sharing/SharingEditor.d.ts +17 -0
  195. package/lib/components/sharing/SharingEditor.js +0 -24
  196. package/lib/components/sparklines/Sparklines.js +3 -4
  197. package/lib/components/sparklines/index.js +0 -4
  198. package/lib/components/storage/ContentsBrowser.d.ts +25 -1
  199. package/lib/components/storage/ContentsBrowser.js +145 -52
  200. package/lib/components/storage/ContentsBrowserMock.d.ts +3 -0
  201. package/lib/components/storage/ContentsBrowserMock.js +75 -0
  202. package/lib/components/storage/ContentsItems.d.ts +2 -1
  203. package/lib/components/storage/ContentsItems.js +0 -4
  204. package/lib/components/storage/ContentsTable.d.ts +50 -0
  205. package/lib/components/storage/ContentsTable.js +134 -0
  206. package/lib/components/storage/HomeFolderDrive.d.ts +71 -0
  207. package/lib/components/storage/HomeFolderDrive.js +248 -0
  208. package/lib/components/storage/index.d.ts +2 -0
  209. package/lib/components/storage/index.js +2 -0
  210. package/lib/components/students/StudentItemStatus.d.ts +1 -1
  211. package/lib/components/students/StudentResultCircle.d.ts +1 -1
  212. package/lib/components/subnav/SubNav.d.ts +5 -5
  213. package/lib/components/subnav/SubNav.js +11 -9
  214. package/lib/components/tables/DataTable.d.ts +1 -1
  215. package/lib/components/text-reveal/TextRevealAnimation.d.ts +2 -2
  216. package/lib/components/text-reveal/useTextRevealAnimationLines.d.ts +1 -1
  217. package/lib/components/time/LiveRelativeTime.d.ts +1 -0
  218. package/lib/components/time/LiveRelativeTime.js +0 -8
  219. package/lib/components/time/index.js +0 -4
  220. package/lib/components/timeline/Timeline.d.ts +1 -1
  221. package/lib/components/timeline/index.js +0 -4
  222. package/lib/components/users/PeerIndicator.d.ts +1 -0
  223. package/lib/components/users/PeerIndicator.js +0 -4
  224. package/lib/config/Configuration.d.ts +15 -17
  225. package/lib/config/Configuration.js +7 -0
  226. package/lib/hooks/index.d.ts +2 -0
  227. package/lib/hooks/index.js +2 -0
  228. package/lib/hooks/layouts/LayoutBackdrop.d.ts +1 -1
  229. package/lib/hooks/layouts/LayoutScreencapture.d.ts +1 -1
  230. package/lib/hooks/useBackdrop.d.ts +1 -1
  231. package/lib/hooks/useBackdropJupyterLab.d.ts +3 -2
  232. package/lib/hooks/useBackdropJupyterLab.js +0 -4
  233. package/lib/hooks/useCache.d.ts +310 -105
  234. package/lib/hooks/useCache.js +142 -355
  235. package/lib/hooks/useContainsFocus.d.ts +1 -1
  236. package/lib/hooks/useContents.d.ts +313 -0
  237. package/lib/hooks/useContents.js +964 -0
  238. package/lib/hooks/useFocusTrap.d.ts +4 -4
  239. package/lib/hooks/useFocusTrap.js +1 -1
  240. package/lib/hooks/useMcp.d.ts +229 -0
  241. package/lib/hooks/useMcp.js +656 -0
  242. package/lib/hooks/useMobile.js +0 -5
  243. package/lib/hooks/useProjectStore.d.ts +3 -3
  244. package/lib/hooks/useProjectStore.js +4 -4
  245. package/lib/hooks/useRef.d.ts +1 -1
  246. package/lib/hooks/useRef.js +3 -0
  247. package/lib/hooks/useScreencapture.d.ts +2 -1
  248. package/lib/hooks/useScreencapture.js +0 -4
  249. package/lib/hooks/useToast.js +0 -4
  250. package/lib/hooks/useUser.js +42 -0
  251. package/lib/hooks/useVisibilityObserver.d.ts +1 -1
  252. package/lib/index.d.ts +4 -1
  253. package/lib/index.js +3 -1
  254. package/lib/mocks/components/FlashMock.d.ts +1 -1
  255. package/lib/mocks/views/ActionMenuMock.d.ts +1 -1
  256. package/lib/mocks/views/ChartMock.d.ts +1 -1
  257. package/lib/mocks/views/DashboardMock.d.ts +1 -1
  258. package/lib/mocks/views/FormMock.d.ts +1 -1
  259. package/lib/mocks/views/TableMock.d.ts +1 -1
  260. package/lib/mocks/views/WipMock.d.ts +1 -1
  261. package/lib/models/Credits.d.ts +16 -0
  262. package/lib/models/Credits.js +22 -0
  263. package/lib/models/McpAuditEvent.d.ts +52 -0
  264. package/lib/models/McpAuditEvent.js +5 -0
  265. package/lib/models/McpBinding.d.ts +51 -0
  266. package/lib/models/McpBinding.js +5 -0
  267. package/lib/models/McpPolicy.d.ts +77 -0
  268. package/lib/models/McpPolicy.js +5 -0
  269. package/lib/models/McpTask.d.ts +94 -0
  270. package/lib/models/McpTask.js +7 -0
  271. package/lib/models/StartedBy.d.ts +57 -0
  272. package/lib/models/StartedBy.js +81 -0
  273. package/lib/models/UserDTO.js +4 -2
  274. package/lib/models/contents/__fixtures__/solr-codec.json +57 -0
  275. package/lib/models/contents/__fixtures__/v1-contracts.json +66 -0
  276. package/lib/models/contents/fieldCase.d.ts +8 -0
  277. package/lib/models/contents/fieldCase.js +37 -0
  278. package/lib/models/contents/index.d.ts +2 -0
  279. package/lib/models/contents/index.js +6 -0
  280. package/lib/models/contents/permissions.d.ts +16 -0
  281. package/lib/models/contents/permissions.js +34 -0
  282. package/lib/models/index.d.ts +5 -1
  283. package/lib/models/index.js +5 -1
  284. package/lib/state/substates/CoreState.d.ts +15 -7
  285. package/lib/state/substates/CoreState.js +18 -14
  286. package/lib/state/substates/IAMState.d.ts +1 -1
  287. package/lib/state/substates/IAMState.js +5 -5
  288. package/lib/state/substates/ProfileState.js +0 -4
  289. package/lib/state/substates/index.d.ts +0 -1
  290. package/lib/state/substates/index.js +0 -1
  291. package/lib/utils/Jwt.d.ts +26 -0
  292. package/lib/utils/Jwt.js +37 -0
  293. package/lib/utils/WithSuspense.d.ts +1 -1
  294. package/lib/views/api-keys/APIKeyEdit.d.ts +1 -1
  295. package/lib/views/api-keys/APIKeyNew.d.ts +1 -1
  296. package/lib/views/api-keys/APIKeys.d.ts +1 -1
  297. package/lib/views/api-keys/APIKeys.js +30 -4
  298. package/lib/views/api-keys/APIKeysStandalone.d.ts +5 -1
  299. package/lib/views/api-keys/APIKeysStandalone.js +2 -2
  300. package/lib/views/datasources/DatasourceDetail.d.ts +12 -5
  301. package/lib/views/datasources/DatasourceDetail.js +80 -110
  302. package/lib/views/datasources/DatasourceNew.d.ts +14 -8
  303. package/lib/views/datasources/DatasourceNew.js +129 -118
  304. package/lib/views/datasources/Datasources.d.ts +39 -7
  305. package/lib/views/datasources/Datasources.js +95 -40
  306. package/lib/views/datasources/DatasourcesMock.d.ts +3 -0
  307. package/lib/views/datasources/DatasourcesMock.js +57 -0
  308. package/lib/views/iam/SignInSimple.d.ts +12 -0
  309. package/lib/views/iam/SignInSimple.js +4 -4
  310. package/lib/views/index.d.ts +1 -0
  311. package/lib/views/index.js +1 -0
  312. package/lib/views/mcp/AlertDestinations.d.ts +34 -0
  313. package/lib/views/mcp/AlertDestinations.js +75 -0
  314. package/lib/views/mcp/AlertRules.d.ts +32 -0
  315. package/lib/views/mcp/AlertRules.js +245 -0
  316. package/lib/views/mcp/AuditLog.d.ts +42 -0
  317. package/lib/views/mcp/AuditLog.js +144 -0
  318. package/lib/views/mcp/ConnectedAgents.d.ts +34 -0
  319. package/lib/views/mcp/ConnectedAgents.js +100 -0
  320. package/lib/views/mcp/EnterpriseConsole.d.ts +74 -0
  321. package/lib/views/mcp/EnterpriseConsole.js +173 -0
  322. package/lib/views/mcp/McpDashboard.d.ts +50 -0
  323. package/lib/views/mcp/McpDashboard.js +347 -0
  324. package/lib/views/mcp/McpHome.d.ts +92 -0
  325. package/lib/views/mcp/McpHome.js +153 -0
  326. package/lib/views/mcp/McpObservability.d.ts +50 -0
  327. package/lib/views/mcp/McpObservability.js +150 -0
  328. package/lib/views/mcp/OrganizationPolicy.d.ts +45 -0
  329. package/lib/views/mcp/OrganizationPolicy.js +107 -0
  330. package/lib/views/mcp/OrganizationUsage.d.ts +69 -0
  331. package/lib/views/mcp/OrganizationUsage.js +113 -0
  332. package/lib/views/mcp/PersonalPolicy.d.ts +54 -0
  333. package/lib/views/mcp/PersonalPolicy.js +125 -0
  334. package/lib/views/mcp/Policies.d.ts +53 -0
  335. package/lib/views/mcp/Policies.js +210 -0
  336. package/lib/views/mcp/PolicyForm.d.ts +67 -0
  337. package/lib/views/mcp/PolicyForm.js +91 -0
  338. package/lib/views/mcp/PolicyHistory.d.ts +45 -0
  339. package/lib/views/mcp/PolicyHistory.js +62 -0
  340. package/lib/views/mcp/ServiceAgents.d.ts +46 -0
  341. package/lib/views/mcp/ServiceAgents.js +194 -0
  342. package/lib/views/mcp/TeamPolicies.d.ts +33 -0
  343. package/lib/views/mcp/TeamPolicies.js +98 -0
  344. package/lib/views/mcp/format.d.ts +25 -0
  345. package/lib/views/mcp/format.js +77 -0
  346. package/lib/views/mcp/index.d.ts +29 -0
  347. package/lib/views/mcp/index.js +37 -0
  348. package/lib/views/mcp/types.d.ts +66 -0
  349. package/lib/views/mcp/types.js +5 -0
  350. package/lib/views/secrets/SecretEdit.d.ts +5 -1
  351. package/lib/views/secrets/SecretEdit.js +2 -2
  352. package/lib/views/secrets/SecretNew.d.ts +11 -1
  353. package/lib/views/secrets/SecretNew.js +2 -2
  354. package/lib/views/secrets/Secrets.d.ts +12 -1
  355. package/lib/views/secrets/Secrets.js +2 -2
  356. package/package.json +28 -24
  357. package/scripts/generate-contents-types.py +169 -0
  358. package/scripts/generate-mcp-types.py +233 -0
  359. package/lib/api/iam/datasources.d.ts +0 -86
  360. package/lib/api/iam/datasources.js +0 -185
  361. package/lib/components/toolbars/index.d.ts +0 -1
  362. package/lib/models/Datasource.d.ts +0 -181
  363. package/lib/models/Datasource.js +0 -154
  364. package/lib/state/substates/DatasourceState.d.ts +0 -11
  365. package/lib/state/substates/DatasourceState.js +0 -16
  366. /package/lib/{components/toolbars/index.js → api/contents/generated.js} +0 -0
@@ -1,131 +1,142 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  /*
3
3
  * Copyright (c) 2023-2025 Datalayer, Inc.
4
4
  * Distributed under the terms of the Modified BSD License.
5
5
  */
6
- import { useEffect, useState } from 'react';
7
- import { PageLayout, FormControl, Button, TextInput, Text, Heading, Textarea, Select, Flash, Link, } from '@primer/react';
6
+ /*
7
+ * Copyright (c) 2023-2026 Datalayer, Inc.
8
+ * Distributed under the terms of the Modified BSD License.
9
+ */
10
+ import { useMemo, useRef, useState, } from 'react';
11
+ import { PageLayout, FormControl, Button, Checkbox, CheckboxGroup, TextInput, Text, Heading, Textarea, Select, Flash, Link, } from '@primer/react';
8
12
  import { Box } from '@datalayer/primer-addons';
9
- import { useCache, useNavigate, useToast } from '../../hooks/index.js';
10
- import { useRunStore } from '../../state/index.js';
11
- export const DatasourceNew = ({ datasourcesListRoute = '/settings/integrations/datasources', secretsRoute = '/settings/iam/secrets', principalUid, principalKind, accountPrincipal, } = {}) => {
12
- const runStore = useRunStore();
13
- const { useCreateDatasource } = useCache();
14
- const createDatasourceMutation = useCreateDatasource({
15
- principalUid,
16
- principalKind,
17
- });
13
+ import { DATASOURCE_CONNECTOR_LABELS, DATASOURCE_OPERATIONS, } from '../../api/contents/index.js';
14
+ import { useCache, useContentSources, useCreateContentSource, useNavigate, useToast, } from '../../hooks/index.js';
15
+ const CONNECTORS = [
16
+ 'athena',
17
+ 'bigquery',
18
+ 'sql',
19
+ ];
20
+ /** What the connector needs to be told, and what the field is called. */
21
+ const TARGET_LABELS = {
22
+ athena: {
23
+ endpoint: 'Region or workgroup endpoint',
24
+ target: 'Database',
25
+ hint: 'The Glue database queries run in. The Secret holds the AWS key pair and the output bucket.',
26
+ },
27
+ bigquery: {
28
+ endpoint: 'Endpoint',
29
+ target: 'Project',
30
+ hint: 'The Google Cloud project billed for the queries. The Secret holds the service account.',
31
+ },
32
+ sql: {
33
+ endpoint: 'Endpoint',
34
+ target: 'Database',
35
+ hint: 'host:port of the server and the database to open. The Secret holds the user and password.',
36
+ },
37
+ };
38
+ /**
39
+ * Connect a Datasource: a `kind=datasource` content source.
40
+ *
41
+ * Everything but the credential lives in Contents. The credential is a
42
+ * Secret reference — IAM is consulted here only to list the Secrets to pick
43
+ * from — and a source routed through a Dataserver needs none, because the
44
+ * gateway holds the credential in the network the database lives in.
45
+ */
46
+ export const DatasourceNew = ({ datasourcesListRoute = '/datasources', secretsRoute = '/secrets', spaceUid, accountPrincipal, } = {}) => {
18
47
  const navigate = useNavigate();
19
48
  const { enqueueToast } = useToast();
20
- const [formValues, setFormValues] = useState({
21
- variant: 'athena',
22
- database: undefined,
23
- outputBucket: undefined,
24
- name: undefined,
25
- description: undefined,
26
- });
27
- const [validationResult, setValidationResult] = useState({
28
- variant: undefined,
29
- database: undefined,
30
- outputBucket: undefined,
31
- name: undefined,
32
- description: undefined,
33
- });
34
- const valueVariantChange = (event) => {
35
- setFormValues(prevFormValues => ({
36
- ...prevFormValues,
37
- variant: event.target.value,
38
- }));
39
- };
40
- const valueDatabaseChange = (event) => {
41
- setFormValues(prevFormValues => ({
42
- ...prevFormValues,
43
- database: event.target.value,
44
- }));
49
+ const createSource = useCreateContentSource();
50
+ const { useSecrets } = useCache();
51
+ const secrets = useSecrets();
52
+ const dataservers = useContentSources({ kind: 'data-server' });
53
+ const idempotencyKey = useRef(`contents-datasource-${crypto.randomUUID()}`);
54
+ const [name, setName] = useState('');
55
+ const [description, setDescription] = useState('');
56
+ const [connectorType, setConnectorType] = useState('bigquery');
57
+ const [endpoint, setEndpoint] = useState('');
58
+ const [target, setTarget] = useState('');
59
+ const [route, setRoute] = useState('direct');
60
+ const [credentialUid, setCredentialUid] = useState('');
61
+ const [dataServerUid, setDataServerUid] = useState('');
62
+ const [operations, setOperations] = useState([
63
+ 'select',
64
+ 'describe',
65
+ 'list',
66
+ ]);
67
+ const [rowLimit, setRowLimit] = useState('10000');
68
+ const [maxBytes, setMaxBytes] = useState('');
69
+ const [maxSeconds, setMaxSeconds] = useState('60');
70
+ const labels = TARGET_LABELS[connectorType];
71
+ const dataserverOptions = useMemo(() => (dataservers.data?.items ?? []).map(item => {
72
+ const configuration = item.source
73
+ .configuration;
74
+ return {
75
+ uid: item.source.uid,
76
+ name: item.source.name,
77
+ state: configuration.state ??
78
+ (configuration.lastHeartbeatAt ? 'ready' : 'registering'),
79
+ };
80
+ }), [dataservers.data]);
81
+ const numberOrUndefined = (value) => {
82
+ const parsed = Number.parseInt(value, 10);
83
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : undefined;
45
84
  };
46
- const valueOutputBucketChange = (event) => {
47
- setFormValues(prevFormValues => ({
48
- ...prevFormValues,
49
- outputBucket: event.target.value,
50
- }));
51
- };
52
- const valueNameChange = (event) => {
53
- setFormValues(prevFormValues => ({
54
- ...prevFormValues,
55
- name: event.target.value,
56
- }));
57
- };
58
- const valueDescriptionChange = (event) => {
59
- setFormValues(prevFormValues => ({
60
- ...prevFormValues,
61
- description: event.target.value,
62
- }));
63
- };
64
- useEffect(() => {
65
- setValidationResult(prev => ({
66
- ...prev,
67
- name: formValues.name === undefined
68
- ? undefined
69
- : formValues.name.length > 2
70
- ? true
71
- : false,
72
- description: formValues.description === undefined
73
- ? undefined
74
- : formValues.description.length > 2
75
- ? true
76
- : false,
77
- database: formValues.variant !== 'athena'
78
- ? true
79
- : formValues.database === undefined
80
- ? undefined
81
- : formValues.database.length > 0
82
- ? true
83
- : false,
84
- outputBucket: formValues.variant !== 'athena'
85
- ? true
86
- : formValues.outputBucket === undefined
87
- ? undefined
88
- : formValues.outputBucket.length > 0
89
- ? true
90
- : false,
91
- }));
92
- }, [formValues]);
93
- const submitCreate = () => {
94
- if (!formValues.name || !formValues.description) {
85
+ const nameValid = name.trim().length > 2;
86
+ const credentialValid = route === 'dataserver' ? Boolean(dataServerUid) : Boolean(credentialUid);
87
+ const canSubmit = nameValid &&
88
+ credentialValid &&
89
+ operations.length > 0 &&
90
+ !createSource.isPending;
91
+ const toggleOperation = (operation, checked) => setOperations(current => checked
92
+ ? DATASOURCE_OPERATIONS.filter(item => item === operation || current.includes(item))
93
+ : current.filter(item => item !== operation));
94
+ const submit = async (event) => {
95
+ event.preventDefault();
96
+ if (!canSubmit) {
95
97
  return;
96
98
  }
97
- runStore.layout().showBackdrop('Creating an datasource...');
98
- createDatasourceMutation.mutate({
99
- name: formValues.name,
100
- variant: formValues.variant,
101
- database: formValues.database ?? '',
102
- outputBucket: formValues.outputBucket ?? '',
103
- description: formValues.description,
104
- }, {
105
- onSuccess: (resp) => {
106
- if (typeof resp === 'object' &&
107
- resp !== null &&
108
- 'success' in resp &&
109
- resp.success) {
110
- const message = 'message' in resp &&
111
- typeof resp.message === 'string'
112
- ? resp.message
113
- : 'Datasource created.';
114
- enqueueToast(message, { variant: 'success' });
115
- navigate(datasourcesListRoute);
116
- }
117
- },
118
- onSettled: () => {
119
- runStore.layout().hideBackdrop();
120
- },
121
- });
99
+ try {
100
+ const created = await createSource.mutateAsync({
101
+ source: {
102
+ name: name.trim(),
103
+ description: description.trim() || null,
104
+ spaceUid,
105
+ kind: 'datasource',
106
+ capabilities: ['query'],
107
+ credentialUid: route === 'direct' ? credentialUid : null,
108
+ configuration: {
109
+ kind: 'datasource',
110
+ connectorType,
111
+ endpoint: endpoint.trim() || null,
112
+ databaseOrProject: target.trim() || null,
113
+ credentialUid: route === 'direct' ? credentialUid : null,
114
+ networkRoute: route,
115
+ dataServerUid: route === 'dataserver' ? dataServerUid : null,
116
+ allowedOperations: operations,
117
+ defaultRowLimit: numberOrUndefined(rowLimit),
118
+ maxBytes: numberOrUndefined(maxBytes),
119
+ maxSeconds: numberOrUndefined(maxSeconds),
120
+ },
121
+ },
122
+ idempotencyKey: idempotencyKey.current,
123
+ });
124
+ enqueueToast('Datasource connected.', { variant: 'success' });
125
+ navigate(`${datasourcesListRoute}/${created.value.source.uid}`);
126
+ }
127
+ catch {
128
+ // The error is shown under the form; the idempotency key makes a retry safe.
129
+ }
122
130
  };
123
- return (_jsx(PageLayout, { containerWidth: "full", padding: "normal", style: { overflow: 'visible', minHeight: 'calc(100vh - 45px)' }, children: _jsx(PageLayout.Content, { children: _jsxs(Box, { sx: { maxWidth: 960, mx: 'auto', width: '100%' }, children: [_jsxs(Box, { sx: { mb: 4 }, children: [_jsx(Heading, { as: "h2", sx: { fontSize: 3, mb: 1 }, children: "New Datasource" }), _jsx(Text, { sx: { color: 'fg.muted', fontSize: 1 }, children: "Create a datasource and configure required secrets for the selected provider." }), accountPrincipal && _jsx(Box, { sx: { mt: 2 }, children: accountPrincipal })] }), _jsxs(Flash, { variant: "warning", sx: { mb: 3 }, children: [formValues.variant === 'athena' && (_jsxs(Text, { children: ["For", ' ', _jsx(Link, { href: "https://aws.amazon.com/athena", children: "Amazon Athena" }), ",", ' ', "ensure the following", ' ', _jsx(Link, { href: "javascript: return false;", onClick: e => navigate(secretsRoute, e), children: "Secrets" }), ' ', "are available:", ' ', _jsx(Text, { as: "code", children: "AWS_SECRET_ACCESS_KEY" }), ' ', _jsx(Text, { as: "code", children: "AWS_ACCESS_KEY_ID" }), ' ', _jsx(Text, { as: "code", children: "AWS_DEFAULT_REGION" })] })), formValues.variant === 'bigquery' && (_jsxs(Text, { children: ["For", ' ', _jsx(Link, { href: "https://cloud.google.com/bigquery", children: "Google Big Query" }), ", ensure the following", ' ', _jsx(Link, { href: "javascript: return false;", onClick: e => navigate(secretsRoute, e), children: "Secret" }), ' ', "is available:", ' ', _jsx(Text, { as: "code", children: "GOOGLE_APPLICATION_CREDENTIALS" })] })), formValues.variant === 'mssentinel' && (_jsxs(Text, { children: ["For", ' ', _jsx(Link, { href: "https://learn.microsoft.com/en-us/azure/sentinel/overview?tabs=defender-portaly", children: "Microsoft Sentinel" }), ", ensure the following", ' ', _jsx(Link, { href: "javascript: return false;", onClick: e => navigate(secretsRoute, e), children: "Secret" }), ' ', "is available:", ' ', _jsx(Text, { as: "code", children: "AZURE_TENANT_ID" }), ` `, _jsx(Text, { as: "code", children: "AZURE_CLIENT_ID" }), ` `, _jsx(Text, { as: "code", children: "AZURE_CLIENT_SECRET" }), ` `, _jsx(Text, { as: "code", children: "AZURE_SUBSCRIPTION_ID" }), ` `, _jsx(Text, { as: "code", children: "AZURE_RESOURCE_GROUP" }), ` `, _jsx(Text, { as: "code", children: "MSSENTINEL_WORKSPACE_ID" }), ` `, _jsx(Text, { as: "code", children: "MSSENTINEL_WORKSPACE_NAME" })] })), formValues.variant === 'splunk' && (_jsxs(Text, { children: ["For ", _jsx(Link, { href: "https://www.splunk.com/", children: "Splunk" }), ", ensure the following", ' ', _jsx(Link, { href: "javascript: return false;", onClick: e => navigate(secretsRoute, e), children: "Secret" }), ' ', "is available:", ' ', _jsx(Text, { as: "code", children: "SPLUNK_HOST" }), ` `, _jsx(Text, { as: "code", children: "SPLUNK_PORT" }), ` `, _jsx(Text, { as: "code", children: "SPLUNK_USERNAME" }), ` `, _jsx(Text, { as: "code", children: "SPLUNK_PASSWORD" })] }))] }), _jsxs(Box, { sx: { label: { marginTop: 2 } }, children: [_jsxs(FormControl, { required: true, children: [_jsx(FormControl.Label, { children: "Datasource type" }), _jsxs(Select, { name: "type", value: formValues.variant, onChange: valueVariantChange, children: [_jsx(Select.Option, { value: "athena", children: "Amazon Athena" }), _jsx(Select.Option, { value: "bigquery", children: "Google BigQuery" }), _jsx(Select.Option, { value: "mssentinel", children: "Microsoft Sentinel" }), _jsx(Select.Option, { value: "splunk", children: "Splunk" })] }), _jsx(FormControl.Caption, { children: "Pick the most appropriate datasource type." })] }), _jsxs(FormControl, { required: true, children: [_jsx(FormControl.Label, { children: "Name" }), _jsx(TextInput, { block: true, value: formValues.name, onChange: valueNameChange, autoFocus: true }), _jsx(FormControl.Caption, { children: "Hint: The datasource name is a short name that identifies in a unique way your datasource." }), validationResult.name === false && (_jsx(FormControl.Validation, { variant: "error", children: "Name length must be between 2 and 32 characters." }))] }), formValues.variant === 'athena' && (_jsxs(_Fragment, { children: [_jsxs(FormControl, { required: true, children: [_jsx(FormControl.Label, { children: "Database" }), _jsx(TextInput, { block: true, value: formValues.database, onChange: valueDatabaseChange }), validationResult.database === false && (_jsx(FormControl.Validation, { variant: "error", children: "Database must have more than 1." }))] }), _jsxs(FormControl, { required: true, children: [_jsx(FormControl.Label, { children: "Output Bucket" }), _jsx(TextInput, { block: true, value: formValues.outputBucket, onChange: valueOutputBucketChange }), validationResult.database === false && (_jsx(FormControl.Validation, { variant: "error", children: "Output bucket must have more than 1." }))] })] })), _jsxs(FormControl, { required: true, children: [_jsx(FormControl.Label, { children: "Description" }), _jsx(Textarea, { block: true, value: formValues.description, onChange: valueDescriptionChange }), validationResult.description === false && (_jsx(FormControl.Validation, { variant: "error", children: "Description must have more than 2 characters." }))] }), _jsx(Button, { variant: "primary", disabled: !validationResult.database ||
124
- !validationResult.outputBucket ||
125
- !validationResult.name ||
126
- !validationResult.description, sx: { marginTop: 2 }, onClick: e => {
127
- e.preventDefault();
128
- submitCreate();
129
- }, children: "Create a datasource" })] })] }) }) }));
131
+ return (_jsx(PageLayout, { containerWidth: "full", padding: "normal", style: { overflow: 'visible', minHeight: 'calc(100vh - 45px)' }, children: _jsx(PageLayout.Content, { children: _jsxs(Box, { sx: { maxWidth: 960, mx: 'auto', width: '100%' }, children: [_jsxs(Box, { sx: { mb: 4 }, children: [_jsx(Heading, { as: "h2", sx: { fontSize: 3, mb: 1 }, children: "Connect a Datasource" }), _jsx(Text, { sx: { color: 'fg.muted', fontSize: 1 }, children: "A database, warehouse or query service your notebooks and agents query through Datalayer. The credential stays in Vault; a query receives a short-lived, scoped connection." }), accountPrincipal && _jsx(Box, { sx: { mt: 2 }, children: accountPrincipal })] }), _jsxs(Box, { as: "form", onSubmit: submit, sx: { display: 'grid', gap: 3 }, children: [_jsxs(FormControl, { required: true, children: [_jsx(FormControl.Label, { children: "Connector" }), _jsx(Select, { value: connectorType, onChange: event => setConnectorType(event.target.value), children: CONNECTORS.map(connector => (_jsx(Select.Option, { value: connector, children: DATASOURCE_CONNECTOR_LABELS[connector] }, connector))) }), _jsx(FormControl.Caption, { children: labels.hint })] }), _jsxs(FormControl, { required: true, children: [_jsx(FormControl.Label, { children: "Name" }), _jsx(TextInput, { block: true, value: name, onChange: event => setName(event.target.value), autoFocus: true }), name.length > 0 && !nameValid && (_jsx(FormControl.Validation, { variant: "error", children: "Name must have more than 2 characters." }))] }), _jsxs(FormControl, { children: [_jsx(FormControl.Label, { children: "Description" }), _jsx(Textarea, { block: true, value: description, onChange: event => setDescription(event.target.value) })] }), _jsxs(FormControl, { children: [_jsx(FormControl.Label, { children: labels.endpoint }), _jsx(TextInput, { block: true, monospace: true, value: endpoint, placeholder: connectorType === 'sql' ? 'warehouse.internal:5432' : '', onChange: event => setEndpoint(event.target.value) })] }), _jsxs(FormControl, { children: [_jsx(FormControl.Label, { children: labels.target }), _jsx(TextInput, { block: true, monospace: true, value: target, onChange: event => setTarget(event.target.value) })] }), _jsxs(FormControl, { required: true, children: [_jsx(FormControl.Label, { children: "Network route" }), _jsxs(Select, { value: route, onChange: event => setRoute(event.target.value), children: [_jsx(Select.Option, { value: "direct", children: "Direct \u2014 Datalayer reaches the endpoint" }), _jsx(Select.Option, { value: "dataserver", children: "Through a Dataserver in your network" })] }), _jsx(FormControl.Caption, { children: "A private endpoint is reached through a Dataserver, which holds the credential in the network the database lives in." })] }), route === 'direct' ? (_jsxs(FormControl, { required: true, children: [_jsx(FormControl.Label, { children: "Credential" }), _jsxs(Select, { value: credentialUid, onChange: event => setCredentialUid(event.target.value), children: [_jsx(Select.Option, { value: "", children: "Choose a Secret\u2026" }), (secrets.data ?? []).map(secret => (_jsx(Select.Option, { value: secret.id, children: secret.name }, secret.id)))] }), _jsxs(FormControl.Caption, { children: ["Held in Vault and resolved server-side for each query; never handed to notebook code. Add one under", ' ', _jsx(Link, { href: secretsRoute, onClick: event => {
132
+ event.preventDefault();
133
+ navigate(secretsRoute, event);
134
+ }, children: "Secrets" }), "."] })] })) : (_jsxs(FormControl, { required: true, children: [_jsx(FormControl.Label, { children: "Dataserver" }), _jsxs(Select, { value: dataServerUid, onChange: event => setDataServerUid(event.target.value), children: [_jsx(Select.Option, { value: "", children: "Choose a Dataserver\u2026" }), dataserverOptions.map(option => (_jsxs(Select.Option, { value: option.uid, children: [option.name, " (", option.state, ")"] }, option.uid)))] }), _jsx(FormControl.Caption, { children: dataserverOptions.length === 0
135
+ ? 'No Dataserver is registered yet; register one under Dataservers first.'
136
+ : 'The gateway that reaches the endpoint. Contents routes to it only while it is online.' })] })), _jsxs(CheckboxGroup, { children: [_jsx(CheckboxGroup.Label, { children: "Allowed operations" }), DATASOURCE_OPERATIONS.map(operation => (_jsxs(FormControl, { children: [_jsx(Checkbox, { value: operation, checked: operations.includes(operation), onChange: event => toggleOperation(operation, event.target.checked) }), _jsx(FormControl.Label, { sx: { textTransform: 'capitalize' }, children: operation })] }, operation))), _jsx(CheckboxGroup.Caption, { children: "The service refuses any statement outside this list before a query exists. Writes are never allowed through a Datasource." })] }), _jsxs(Box, { sx: {
137
+ display: 'grid',
138
+ gridTemplateColumns: ['1fr', 'repeat(3, minmax(0, 1fr))'],
139
+ gap: 3,
140
+ }, children: [_jsxs(FormControl, { children: [_jsx(FormControl.Label, { children: "Default row limit" }), _jsx(TextInput, { block: true, type: "number", min: 1, value: rowLimit, onChange: event => setRowLimit(event.target.value) })] }), _jsxs(FormControl, { children: [_jsx(FormControl.Label, { children: "Max bytes" }), _jsx(TextInput, { block: true, type: "number", min: 1, value: maxBytes, placeholder: "Unlimited", onChange: event => setMaxBytes(event.target.value) })] }), _jsxs(FormControl, { children: [_jsx(FormControl.Label, { children: "Max seconds" }), _jsx(TextInput, { block: true, type: "number", min: 1, value: maxSeconds, onChange: event => setMaxSeconds(event.target.value) })] })] }), createSource.isError && (_jsx(Flash, { variant: "danger", children: createSource.error.message })), _jsxs(Box, { sx: { display: 'flex', gap: 2 }, children: [_jsx(Button, { type: "button", onClick: event => navigate(datasourcesListRoute, event), children: "Cancel" }), _jsx(Button, { type: "submit", variant: "primary", disabled: !canSubmit, children: createSource.isPending ? 'Connecting…' : 'Connect Datasource' })] })] })] }) }) }));
130
141
  };
131
142
  export default DatasourceNew;
@@ -1,14 +1,46 @@
1
+ import type { CatalogSource } from '../../api/contents';
1
2
  export type DatasourcesProps = {
2
- /** Route to navigate when clicking "New datasource" button. Defaults to '/new/datasource'. */
3
+ /** Route to navigate when clicking "New datasource" button. Defaults to '/datasources/new'. */
3
4
  newDatasourceRoute?: string;
4
- /** Base route for the datasources list (used for edit navigation). Defaults to current relative path. */
5
+ /** Base route for the datasources list (used for detail navigation). Defaults to the relative uid. */
5
6
  datasourcesListRoute?: string;
6
- /** Optional principal uid used to scope datasource reads. */
7
- principalUid?: string;
8
- /** Optional principal kind used to scope datasource reads. */
9
- principalKind?: 'personal' | 'organization' | 'team';
7
+ /** Only the Datasources of one Space. */
8
+ spaceUid?: string;
10
9
  /** Show local inline spinner in empty state while loading. */
11
10
  showInlineLoadingIndicator?: boolean;
11
+ /** Render the real view with inert, invented data for documentation. */
12
+ mock?: boolean;
13
+ /**
14
+ * Drawn inside a page that already has a heading and an inset of its own.
15
+ *
16
+ * On its own route this is a page: a frame, a centred column, a full-height
17
+ * minimum and a title. Inside the Contents catalog all four fight the page
18
+ * around it — the inset doubles, the column narrows past its neighbours, the
19
+ * min-height leaves a gap under a short list, and the title names the
20
+ * section twice.
21
+ */
22
+ embedded?: boolean;
12
23
  };
13
- export declare const Datasources: ({ newDatasourceRoute, datasourcesListRoute, principalUid, principalKind, showInlineLoadingIndicator, }?: DatasourcesProps) => import("react/jsx-runtime").JSX.Element;
24
+ type DatasourceRow = {
25
+ id: string;
26
+ uid: string;
27
+ name: string;
28
+ description: string;
29
+ connector: string;
30
+ target: string;
31
+ route: 'direct' | 'dataserver';
32
+ operations: string;
33
+ status: string;
34
+ canExecute: boolean;
35
+ };
36
+ /** What a Datasource is, in the terms the table shows. */
37
+ export declare const toDatasourceRow: (item: CatalogSource) => DatasourceRow;
38
+ /**
39
+ * The Datasources of the Contents catalog.
40
+ *
41
+ * A Datasource is a `kind=datasource` content source: its connector, route,
42
+ * limits and allowed operations live in Contents. IAM is consulted only when
43
+ * one is created, to pick the Secret that holds its credential.
44
+ */
45
+ export declare const Datasources: ({ newDatasourceRoute, datasourcesListRoute, spaceUid, showInlineLoadingIndicator, mock, embedded, }?: DatasourcesProps) => import("react").JSX.Element;
14
46
  export default Datasources;
@@ -1,40 +1,45 @@
1
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  /*
3
3
  * Copyright (c) 2023-2025 Datalayer, Inc.
4
4
  * Distributed under the terms of the Modified BSD License.
5
5
  */
6
- import { useState, useEffect } from 'react';
6
+ /*
7
+ * Copyright (c) 2023-2026 Datalayer, Inc.
8
+ * Distributed under the terms of the Modified BSD License.
9
+ */
10
+ import { useMemo } from 'react';
7
11
  import { PageLayout, Button, IconButton, Spinner, Text, Label, Heading, } from '@primer/react';
8
12
  import { Blankslate, Table, DataTable } from '@primer/react/experimental';
9
13
  import { DatabaseIcon } from '@primer/octicons-react';
10
14
  import { Box } from '@datalayer/primer-addons';
11
15
  import { EditIcon } from '@datalayer/icons-react';
12
- import { useCache, useNavigate } from '../../hooks/index.js';
13
- const DatasourcesTable = ({ datasourcesListRoute, principalUid, principalKind, showInlineLoadingIndicator = true, }) => {
14
- const { useDatasources } = useCache();
15
- const datasourcesQuery = useDatasources({ principalUid, principalKind });
16
+ import { DATASOURCE_CONNECTOR_LABELS, } from '../../api/contents/index.js';
17
+ import { useContentSources, useNavigate } from '../../hooks/index.js';
18
+ import { DATASOURCES_MOCK } from './DatasourcesMock.js';
19
+ /** What a Datasource is, in the terms the table shows. */
20
+ export const toDatasourceRow = (item) => {
21
+ const configuration = item.source.configuration;
22
+ const connector = configuration.connectorType;
23
+ return {
24
+ id: item.source.uid,
25
+ uid: item.source.uid,
26
+ name: item.source.name,
27
+ description: item.source.description ?? '',
28
+ connector: DATASOURCE_CONNECTOR_LABELS[connector] ?? configuration.connectorType,
29
+ target: configuration.databaseOrProject ?? configuration.endpoint ?? '',
30
+ route: configuration.networkRoute === 'dataserver' ? 'dataserver' : 'direct',
31
+ operations: (configuration.allowedOperations ?? []).join(', '),
32
+ status: item.source.status,
33
+ canExecute: item.permissions.execute,
34
+ };
35
+ };
36
+ const DatasourcesTable = ({ datasources, datasourcesListRoute, mock = false, }) => {
16
37
  const navigate = useNavigate();
17
- const [datasources, setDatasources] = useState([]);
18
- const showInitialSpinner = datasources.length === 0 &&
19
- (datasourcesQuery.isLoading ||
20
- datasourcesQuery.isFetching ||
21
- !Array.isArray(datasourcesQuery.data));
22
- useEffect(() => {
23
- if (datasourcesQuery.data) {
24
- setDatasources(datasourcesQuery.data || []);
25
- }
26
- }, [datasourcesQuery.data]);
27
- return datasources.length === 0 ? (_jsx(Blankslate, { border: true, spacious: true, children: showInitialSpinner && showInlineLoadingIndicator ? (_jsx(Box, { sx: {
28
- display: 'flex',
29
- alignItems: 'center',
30
- justifyContent: 'center',
31
- minHeight: '40px',
32
- }, children: _jsx(Spinner, {}) })) : showInitialSpinner ? (_jsxs(_Fragment, { children: [_jsx(Blankslate.Heading, { children: "Datasources" }), _jsx(Blankslate.Description, { children: _jsx(Text, { sx: { textAlign: 'center' }, children: "Loading datasources..." }) })] })) : (_jsxs(_Fragment, { children: [_jsx(Blankslate.Heading, { children: "Datasources" }), _jsx(Blankslate.Description, { children: _jsx(Text, { sx: { textAlign: 'center' }, children: "No Datasources found." }) })] })) })) : (_jsx(Table.Container, { children: _jsx(DataTable, { "aria-labelledby": "teams", "aria-describedby": "teams-subtitle", data: datasources, columns: [
33
- // @ts-ignore
38
+ return datasources.length === 0 ? (_jsxs(Blankslate, { border: true, spacious: true, children: [_jsx(Blankslate.Visual, { children: _jsx(DatabaseIcon, { size: 24 }) }), _jsx(Blankslate.Heading, { children: "Datasources" }), _jsx(Blankslate.Description, { children: _jsx(Text, { sx: { textAlign: 'center' }, children: "No Datasource yet. Connect a database, warehouse or query service to run governed queries from notebooks and agents." }) })] })) : (_jsx(Table.Container, { children: _jsx(DataTable, { "aria-labelledby": "datasources", "aria-describedby": "datasources-subtitle", data: datasources, columns: [
34
39
  {
35
- header: 'Type',
36
- field: 'variant',
37
- renderCell: datasource => _jsx(Label, { children: datasource.variant }),
40
+ header: 'Connector',
41
+ field: 'connector',
42
+ renderCell: datasource => _jsx(Label, { children: datasource.connector }),
38
43
  },
39
44
  {
40
45
  header: 'Name',
@@ -42,27 +47,77 @@ const DatasourcesTable = ({ datasourcesListRoute, principalUid, principalKind, s
42
47
  rowHeader: true,
43
48
  },
44
49
  {
45
- header: 'Description',
46
- field: 'description',
50
+ header: 'Database or project',
51
+ field: 'target',
52
+ renderCell: datasource => datasource.target ? (_jsx(Text, { sx: { fontFamily: 'mono', fontSize: 0 }, children: datasource.target })) : (_jsx(Text, { sx: { color: 'fg.muted' }, children: "\u2014" })),
53
+ },
54
+ {
55
+ header: 'Route',
56
+ field: 'route',
57
+ renderCell: datasource => (_jsx(Label, { variant: datasource.route === 'dataserver' ? 'accent' : 'secondary', children: datasource.route === 'dataserver' ? 'Dataserver' : 'Direct' })),
58
+ },
59
+ {
60
+ header: 'Operations',
61
+ field: 'operations',
62
+ renderCell: datasource => datasource.operations ? (_jsx(Text, { sx: { fontSize: 0 }, children: datasource.operations })) : (_jsx(Text, { sx: { color: 'fg.muted' }, children: "\u2014" })),
63
+ },
64
+ {
65
+ header: 'Status',
66
+ field: 'status',
67
+ renderCell: datasource => (_jsx(Label, { variant: datasource.status === 'ready' ? 'success' : 'secondary', children: datasource.status })),
47
68
  },
48
69
  {
49
70
  header: '',
50
71
  field: 'id',
51
- renderCell: datasource => (_jsx(IconButton, { icon: EditIcon, "aria-label": "Edit", size: "small", variant: "invisible", onClick: e => navigate(datasourcesListRoute
52
- ? `${datasourcesListRoute}/${datasource.id}`
53
- : `${datasource.id}`, e) })),
72
+ renderCell: datasource => (_jsx(IconButton, { icon: EditIcon, "aria-label": `Open ${datasource.name}`, size: "small", variant: "invisible", disabled: mock, onClick: e => {
73
+ if (!mock) {
74
+ navigate(datasourcesListRoute
75
+ ? `${datasourcesListRoute}/${datasource.uid}`
76
+ : `${datasource.uid}`, e);
77
+ }
78
+ } })),
54
79
  },
55
80
  ] }) }));
56
81
  };
57
- export const Datasources = ({ newDatasourceRoute = '/new/datasource', datasourcesListRoute, principalUid, principalKind, showInlineLoadingIndicator = true, } = {}) => {
82
+ const LiveDatasourcesTable = ({ datasourcesListRoute, spaceUid, showInlineLoadingIndicator = true, }) => {
83
+ const datasourcesQuery = useContentSources({ kind: 'datasource', spaceUid });
84
+ const datasources = useMemo(() => (datasourcesQuery.data?.items ?? [])
85
+ .map(toDatasourceRow)
86
+ .sort((left, right) => left.name.localeCompare(right.name)), [datasourcesQuery.data]);
87
+ const showInitialSpinner = datasources.length === 0 && datasourcesQuery.isPending;
88
+ if (datasourcesQuery.isError && datasources.length === 0) {
89
+ return (_jsxs(Blankslate, { border: true, spacious: true, children: [_jsx(Blankslate.Visual, { children: _jsx(DatabaseIcon, { size: 24 }) }), _jsx(Blankslate.Heading, { children: "Datasources could not be listed" }), _jsx(Blankslate.Description, { children: _jsx(Text, { sx: { textAlign: 'center' }, children: datasourcesQuery.error.message }) }), _jsx(Blankslate.PrimaryAction, { onClick: () => datasourcesQuery.refetch(), children: "Try again" })] }));
90
+ }
91
+ return showInitialSpinner ? (_jsx(Blankslate, { border: true, spacious: true, children: showInlineLoadingIndicator ? (_jsx(Box, { sx: {
92
+ display: 'flex',
93
+ alignItems: 'center',
94
+ justifyContent: 'center',
95
+ minHeight: '40px',
96
+ }, children: _jsx(Spinner, {}) })) : (_jsxs(_Fragment, { children: [_jsx(Blankslate.Heading, { children: "Datasources" }), _jsx(Blankslate.Description, { children: _jsx(Text, { sx: { textAlign: 'center' }, children: "Loading datasources..." }) })] })) })) : (_jsx(DatasourcesTable, { datasources: datasources, datasourcesListRoute: datasourcesListRoute }));
97
+ };
98
+ /**
99
+ * The Datasources of the Contents catalog.
100
+ *
101
+ * A Datasource is a `kind=datasource` content source: its connector, route,
102
+ * limits and allowed operations live in Contents. IAM is consulted only when
103
+ * one is created, to pick the Secret that holds its credential.
104
+ */
105
+ export const Datasources = ({ newDatasourceRoute = '/datasources/new', datasourcesListRoute, spaceUid, showInlineLoadingIndicator = true, mock = false, embedded = false, } = {}) => {
58
106
  const navigate = useNavigate();
59
- return (_jsx(PageLayout, { containerWidth: "full", padding: "normal", style: { overflow: 'visible', minHeight: 'calc(100vh - 45px)' }, children: _jsx(PageLayout.Content, { children: _jsxs(Box, { sx: { maxWidth: 960, mx: 'auto', width: '100%' }, children: [_jsxs(Box, { sx: {
60
- display: 'flex',
61
- alignItems: 'flex-start',
62
- justifyContent: 'space-between',
63
- gap: 3,
64
- flexWrap: 'wrap',
65
- mb: 4,
66
- }, children: [_jsxs(Box, { children: [_jsx(Heading, { as: "h2", sx: { fontSize: 3, mb: 1 }, children: "Datasources" }), _jsx(Text, { sx: { color: 'fg.muted', fontSize: 1 }, children: "Configure external data providers available to your workspaces and agents." })] }), _jsx(Button, { size: "small", variant: "primary", leadingVisual: DatabaseIcon, onClick: e => navigate(newDatasourceRoute, e), children: "New datasource" })] }), _jsx(DatasourcesTable, { datasourcesListRoute: datasourcesListRoute, principalUid: principalUid, principalKind: principalKind, showInlineLoadingIndicator: showInlineLoadingIndicator })] }) }) }));
107
+ const body = (_jsxs(Box, { sx: { maxWidth: embedded ? undefined : 960, mx: 'auto', width: '100%' }, children: [_jsxs(Box, { sx: {
108
+ display: 'flex',
109
+ alignItems: 'flex-start',
110
+ justifyContent: 'space-between',
111
+ gap: 3,
112
+ flexWrap: 'wrap',
113
+ mb: embedded ? 2 : 4,
114
+ }, children: [_jsx(Box, { children: !embedded && (_jsxs(_Fragment, { children: [_jsx(Heading, { as: "h2", sx: { fontSize: 3, mb: 1 }, children: "Datasources" }), _jsx(Text, { sx: { color: 'fg.muted', fontSize: 1 }, children: "Databases, warehouses and query services your notebooks and agents query through Datalayer, without holding the credential." })] })) }), _jsx(Button, { size: "small", variant: "primary", leadingVisual: DatabaseIcon, disabled: mock, onClick: e => navigate(newDatasourceRoute, e), children: "Connect Datasource" })] }), mock ? (_jsx(DatasourcesTable, { datasources: DATASOURCES_MOCK.map(toDatasourceRow), mock: true })) : (_jsx(LiveDatasourcesTable, { datasourcesListRoute: datasourcesListRoute, spaceUid: spaceUid, showInlineLoadingIndicator: showInlineLoadingIndicator }))] }));
115
+ if (embedded) {
116
+ return body;
117
+ }
118
+ return (_jsx(PageLayout, { containerWidth: "full", padding: "normal", style: {
119
+ overflow: 'visible',
120
+ minHeight: mock ? undefined : 'calc(100vh - 45px)',
121
+ }, children: _jsx(PageLayout.Content, { children: body }) }));
67
122
  };
68
123
  export default Datasources;
@@ -0,0 +1,3 @@
1
+ import type { CatalogSource } from '../../api/contents';
2
+ /** Invented records used when the real Datasources view is embedded in docs. */
3
+ export declare const DATASOURCES_MOCK: CatalogSource[];
@@ -0,0 +1,57 @@
1
+ /*
2
+ * Copyright (c) 2023-2025 Datalayer, Inc.
3
+ * Distributed under the terms of the Modified BSD License.
4
+ */
5
+ const OWNER = '01HZZZZZZZZZZZZZZZZZZZZZZZ';
6
+ const catalog = (uid, name, description, configuration) => ({
7
+ source: {
8
+ contractVersion: 'v1',
9
+ uid,
10
+ kind: 'datasource',
11
+ name,
12
+ description,
13
+ principalUid: OWNER,
14
+ principalKind: 'user',
15
+ configuration: { kind: 'datasource', ...configuration },
16
+ capabilities: ['query'],
17
+ status: 'ready',
18
+ createdAt: '2026-08-24T12:00:00Z',
19
+ updatedAt: '2026-08-24T12:00:00Z',
20
+ },
21
+ permissions: {
22
+ view: true,
23
+ update: true,
24
+ execute: true,
25
+ effectiveAccessLevel: 'execute',
26
+ isOwner: true,
27
+ },
28
+ });
29
+ /** Invented records used when the real Datasources view is embedded in docs. */
30
+ export const DATASOURCES_MOCK = [
31
+ catalog('01DATASRC0EARTH00000000000', 'Earth Observation Analytics', 'Curated satellite observations for geospatial analysis.', {
32
+ connectorType: 'bigquery',
33
+ databaseOrProject: 'earth-observation',
34
+ networkRoute: 'direct',
35
+ credentialUid: '01CREDENT1AL00000000000000',
36
+ allowedOperations: ['select', 'describe', 'list'],
37
+ defaultRowLimit: 10000,
38
+ }),
39
+ catalog('01DATASRC0LAKEH0USE0000000', 'Research Lakehouse', 'Shared Parquet datasets queried through Amazon Athena.', {
40
+ connectorType: 'athena',
41
+ databaseOrProject: 'research',
42
+ networkRoute: 'direct',
43
+ credentialUid: '01CREDENT1AL00000000000001',
44
+ allowedOperations: ['select', 'describe'],
45
+ defaultRowLimit: 5000,
46
+ }),
47
+ catalog('01DATASRC0PR1VATE000000000', 'Private Warehouse', 'An on-premises PostgreSQL reached through the Frankfurt Dataserver.', {
48
+ connectorType: 'sql',
49
+ endpoint: 'warehouse.internal:5432',
50
+ databaseOrProject: 'analytics',
51
+ networkRoute: 'dataserver',
52
+ dataServerUid: '01DATASRV0FRANKFURT0000000',
53
+ allowedOperations: ['select'],
54
+ defaultRowLimit: 1000,
55
+ maxSeconds: 60,
56
+ }),
57
+ ];
@@ -78,6 +78,18 @@ export interface SignInSimpleProps {
78
78
  * Disable all interactive controls (useful when embedded in documentation).
79
79
  */
80
80
  asDoc?: boolean;
81
+ /**
82
+ * Whether the form centres itself in the viewport.
83
+ *
84
+ * True by default, which is right for a page that is nothing but this form.
85
+ * False for a host that has placed it — a column beside something else —
86
+ * where `min-height: 100vh` pushes it half a screen down from whatever it
87
+ * was meant to sit level with.
88
+ *
89
+ * Distinct from `hideHero`, which also top-aligns but takes the title, icon
90
+ * and description with it, and from `asDoc`, which disables the form.
91
+ */
92
+ fillHeight?: boolean;
81
93
  /**
82
94
  * Hide header title and description area.
83
95
  */