windmill-components 1.511.0 → 1.522.0

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 (236) hide show
  1. package/package/components/AppConnectInner.svelte.d.ts +1 -1
  2. package/package/components/ArgInput.svelte +56 -18
  3. package/package/components/ArgInput.svelte.d.ts +2 -10
  4. package/package/components/AssignableTagsInner.svelte +5 -0
  5. package/package/components/AuthSettings.svelte +4 -2
  6. package/package/components/AuthSettings.svelte.d.ts +1 -0
  7. package/package/components/DBManagerDrawer.svelte +154 -151
  8. package/package/components/DBManagerDrawer.svelte.d.ts +2 -2
  9. package/package/components/DBTable.svelte +3 -3
  10. package/package/components/DBTable.svelte.d.ts +1 -0
  11. package/package/components/DBTableEditor.svelte +7 -7
  12. package/package/components/DBTableEditor.svelte.d.ts +1 -1
  13. package/package/components/DeployWorkspace.svelte +1 -1
  14. package/package/components/DisplayResult.svelte +34 -8
  15. package/package/components/DisplayResult.svelte.d.ts +4 -1
  16. package/package/components/DynSelect.svelte +58 -34
  17. package/package/components/DynSelect.svelte.d.ts +3 -11
  18. package/package/components/EditableSchemaForm.svelte +126 -6
  19. package/package/components/EditableSchemaForm.svelte.d.ts +5 -1
  20. package/package/components/Editor.svelte +1 -1
  21. package/package/components/EditorBar.svelte +82 -4
  22. package/package/components/ErrorOrRecoveryHandler.svelte +76 -8
  23. package/package/components/ErrorOrRecoveryHandler.svelte.d.ts +2 -1
  24. package/package/components/ExploreAssetButton.svelte +14 -4
  25. package/package/components/ExploreAssetButton.svelte.d.ts +1 -0
  26. package/package/components/FlowJobResult.svelte +3 -3
  27. package/package/components/FlowJobResult.svelte.d.ts +1 -0
  28. package/package/components/FlowPreviewContent.svelte +9 -0
  29. package/package/components/FlowPreviewContent.svelte.d.ts +3 -0
  30. package/package/components/FlowPreviewResult.svelte +4 -1
  31. package/package/components/FlowPreviewResult.svelte.d.ts +1 -0
  32. package/package/components/FlowStatusViewer.svelte +2 -1
  33. package/package/components/FlowStatusViewer.svelte.d.ts +3 -0
  34. package/package/components/FlowStatusViewerInner.svelte +23 -3
  35. package/package/components/FlowStatusViewerInner.svelte.d.ts +10 -1
  36. package/package/components/FolderEditor.svelte +1 -1
  37. package/package/components/GitDiffPreview.svelte +14 -18
  38. package/package/components/GitDiffPreview.svelte.d.ts +2 -8
  39. package/package/components/GitHubAppIntegration.svelte +3 -1
  40. package/package/components/IdEditorInput.svelte +25 -22
  41. package/package/components/IdEditorInput.svelte.d.ts +11 -23
  42. package/package/components/InstanceSetting.svelte +7 -2
  43. package/package/components/InstanceSettings.svelte +1 -0
  44. package/package/components/JobLoader.svelte +48 -5
  45. package/package/components/JobLoader.svelte.d.ts +7 -2
  46. package/package/components/Login.svelte +8 -2
  47. package/package/components/MemoryFootprintViewer.svelte +1 -1
  48. package/package/components/ModulePreviewResultViewer.svelte +2 -2
  49. package/package/components/MoveDrawer.svelte.d.ts +2 -2
  50. package/package/components/NextcloudSetting.svelte +84 -0
  51. package/package/components/NextcloudSetting.svelte.d.ts +7 -0
  52. package/package/components/ObjectResourceInput.svelte +3 -2
  53. package/package/components/ObjectResourceInput.svelte.d.ts +1 -0
  54. package/package/components/ParqetCsvTableRenderer.svelte +1 -1
  55. package/package/components/ResourceEditor.svelte +1 -1
  56. package/package/components/ResourcePicker.svelte +8 -1
  57. package/package/components/ResourcePicker.svelte.d.ts +1 -0
  58. package/package/components/ResultStreamDisplay.svelte +5 -0
  59. package/package/components/ResultStreamDisplay.svelte.d.ts +5 -0
  60. package/package/components/RunForm.svelte +9 -1
  61. package/package/components/SchemaForm.svelte +2 -2
  62. package/package/components/SchemaForm.svelte.d.ts +2 -10
  63. package/package/components/ScriptBuilder.svelte +13 -8
  64. package/package/components/ScriptBuilder.svelte.d.ts +1 -1
  65. package/package/components/ScriptEditor.svelte.d.ts +1 -1
  66. package/package/components/ScriptWrapper.svelte +1 -1
  67. package/package/components/ShareModal.svelte.d.ts +1 -1
  68. package/package/components/SimpleAgTable.svelte +2 -0
  69. package/package/components/SimpleAgTable.svelte.d.ts +2 -0
  70. package/package/components/SqlRepl.svelte +21 -7
  71. package/package/components/SqlRepl.svelte.d.ts +2 -2
  72. package/package/components/StringTypeNarrowing.svelte.d.ts +1 -1
  73. package/package/components/WorkerTagSelect.svelte +70 -1
  74. package/package/components/apps/components/display/AppDisplayComponent.svelte +13 -1
  75. package/package/components/apps/components/display/AppText.svelte +2 -2
  76. package/package/components/apps/components/display/dbtable/AppDbExplorer.svelte +8 -1
  77. package/package/components/apps/components/display/dbtable/InsertRow.svelte +5 -4
  78. package/package/components/apps/components/display/dbtable/queries/count.js +11 -1
  79. package/package/components/apps/components/display/dbtable/queries/createTable.d.ts +1 -1
  80. package/package/components/apps/components/display/dbtable/queries/createTable.js +3 -3
  81. package/package/components/apps/components/display/dbtable/queries/delete.js +7 -0
  82. package/package/components/apps/components/display/dbtable/queries/insert.js +2 -0
  83. package/package/components/apps/components/display/dbtable/queries/select.js +14 -0
  84. package/package/components/apps/components/display/dbtable/queries/update.js +7 -0
  85. package/package/components/apps/components/display/dbtable/utils.d.ts +6 -5
  86. package/package/components/apps/components/display/dbtable/utils.js +52 -28
  87. package/package/components/apps/components/display/table/AppAggridExplorerTable.svelte +1 -1
  88. package/package/components/apps/components/display/table/AppAggridInfiniteTable.svelte +1 -0
  89. package/package/components/apps/components/display/table/AppAggridInfiniteTable.svelte.d.ts +1 -0
  90. package/package/components/apps/components/display/table/AppAggridTable.svelte +5 -4
  91. package/package/components/apps/components/display/table/AppAggridTable.svelte.d.ts +1 -0
  92. package/package/components/apps/components/display/table/utils.js +7 -4
  93. package/package/components/apps/components/helpers/HiddenComponent.svelte +2 -2
  94. package/package/components/apps/components/helpers/RunnableComponent.svelte +4 -1
  95. package/package/components/apps/components/helpers/RunnableComponent.svelte.d.ts +2 -1
  96. package/package/components/apps/components/inputs/AppS3FileInput.svelte +2 -2
  97. package/package/components/apps/components/layout/AppDecisionTree.svelte +1 -1
  98. package/package/components/apps/components/layout/AppStepper.svelte +1 -1
  99. package/package/components/apps/components/layout/AppTabs.svelte +1 -1
  100. package/package/components/apps/editor/AppEditorHeader.svelte +13 -2
  101. package/package/components/apps/editor/GridViewer.svelte +1 -0
  102. package/package/components/apps/editor/RunnableJobPanelInner.svelte +2 -1
  103. package/package/components/apps/editor/contextPanel/components/IdEditor.svelte +7 -7
  104. package/package/components/apps/editor/contextPanel/components/IdEditor.svelte.d.ts +7 -19
  105. package/package/components/apps/editor/contextPanel/components/OutputHeader.svelte +8 -12
  106. package/package/components/apps/editor/inlineScriptsPanel/InlineScriptEditor.svelte.d.ts +1 -1
  107. package/package/components/apps/editor/inlineScriptsPanel/InlineScriptEditorDrawer.svelte.d.ts +1 -1
  108. package/package/components/apps/editor/inlineScriptsPanel/InlineScriptRunnableByPath.svelte.d.ts +1 -1
  109. package/package/components/apps/editor/settingsPanel/DecisionTreeGraphEditor.svelte +3 -3
  110. package/package/components/apps/editor/settingsPanel/decisionTree/DecisionTreePreview.svelte +1 -3
  111. package/package/components/assets/AssetsDropdownButton.svelte +1 -1
  112. package/package/components/assets/JobAssetsViewer.svelte +2 -2
  113. package/package/components/assets/lib.js +4 -0
  114. package/package/components/auditLogs/AuditLogsFilters.svelte +7 -9
  115. package/package/components/common/button/Button.svelte +4 -3
  116. package/package/components/common/button/Button.svelte.d.ts +1 -0
  117. package/package/components/common/confirmationModal/ConfirmationModal.svelte +6 -5
  118. package/package/components/common/confirmationModal/ConfirmationModal.svelte.d.ts +6 -11
  119. package/package/components/common/confirmationModal/asyncConfirmationModal.svelte.d.ts +26 -0
  120. package/package/components/common/confirmationModal/asyncConfirmationModal.svelte.js +50 -0
  121. package/package/components/common/modal/Modal.svelte +2 -5
  122. package/package/components/common/tabs/TabsV2.svelte +2 -1
  123. package/package/components/common/tabs/TabsV2.svelte.d.ts +1 -0
  124. package/package/components/copilot/chat/AIChatManager.svelte.js +61 -7
  125. package/package/components/copilot/chat/ContextTextarea.svelte +1 -1
  126. package/package/components/copilot/chat/script/core.js +28 -29
  127. package/package/components/copilot/chat/shared.d.ts +1 -1
  128. package/package/components/copilot/chat/shared.js +8 -2
  129. package/package/components/custom_ui.d.ts +3 -0
  130. package/package/components/dbOps.d.ts +20 -8
  131. package/package/components/dbOps.js +85 -40
  132. package/package/components/details/DetailPageHeader.svelte +0 -2
  133. package/package/components/flows/content/FlowInput.svelte +5 -0
  134. package/package/components/flows/content/FlowModuleComponent.svelte +1 -0
  135. package/package/components/flows/content/FlowModuleScript.svelte +0 -1
  136. package/package/components/flows/idUtils.js +2 -1
  137. package/package/components/flows/map/FlowModuleSchemaItem.svelte +3 -3
  138. package/package/components/flows/map/FlowModuleSchemaMap.svelte +5 -0
  139. package/package/components/flows/map/InsertModuleButton.svelte +4 -1
  140. package/package/components/flows/propPicker/OutputBadge.svelte +5 -1
  141. package/package/components/flows/propPicker/OutputPickerInner.svelte +9 -5
  142. package/package/components/flows/propPicker/OutputPickerInner.svelte.d.ts +6 -2
  143. package/package/components/flows/propPicker/StepHistory.svelte +4 -1
  144. package/package/components/git_sync/DetectionFlow.svelte +202 -0
  145. package/package/components/git_sync/DetectionFlow.svelte.d.ts +6 -0
  146. package/package/components/git_sync/GitSyncContext.svelte.d.ts +82 -0
  147. package/package/components/git_sync/GitSyncContext.svelte.js +461 -0
  148. package/package/components/git_sync/GitSyncModalManager.svelte +99 -0
  149. package/package/components/git_sync/GitSyncModalManager.svelte.d.ts +18 -0
  150. package/package/components/git_sync/GitSyncRepositoryCard.svelte +339 -0
  151. package/package/components/git_sync/GitSyncRepositoryCard.svelte.d.ts +6 -0
  152. package/package/components/git_sync/GitSyncRepositoryList.svelte +17 -0
  153. package/package/components/git_sync/GitSyncRepositoryList.svelte.d.ts +18 -0
  154. package/package/components/git_sync/GitSyncSection.svelte +89 -0
  155. package/package/components/git_sync/GitSyncSection.svelte.d.ts +3 -0
  156. package/package/components/git_sync/GitSyncSuccessModal.svelte +58 -0
  157. package/package/components/git_sync/GitSyncSuccessModal.svelte.d.ts +7 -0
  158. package/package/components/git_sync/PullWorkspaceModal.svelte +575 -0
  159. package/package/components/git_sync/PullWorkspaceModal.svelte.d.ts +15 -0
  160. package/package/components/git_sync/PushWorkspaceModal.svelte +320 -0
  161. package/package/components/git_sync/PushWorkspaceModal.svelte.d.ts +12 -0
  162. package/package/components/graph/FlowGraphV2.svelte +5 -1
  163. package/package/components/graph/graphBuilder.svelte.js +1 -1
  164. package/package/components/graph/renderers/nodes/AssetNode.svelte +4 -4
  165. package/package/components/icons/AssetDucklakeIcon.svelte +28 -0
  166. package/package/components/icons/AssetDucklakeIcon.svelte.d.ts +9 -0
  167. package/package/components/icons/AssetGenericIcon.svelte +3 -0
  168. package/package/components/icons/DucklakeIcon.svelte +18 -0
  169. package/package/components/icons/DucklakeIcon.svelte.d.ts +6 -0
  170. package/package/components/instanceSettings.js +11 -3
  171. package/package/components/runs/JobPreview.svelte +2 -2
  172. package/package/components/runs/NoWorkerWithTagWarning.svelte +3 -3
  173. package/package/components/runs/RunsFilter.svelte.d.ts +1 -1
  174. package/package/components/schema/FlowPropertyEditor.svelte +3 -2
  175. package/package/components/schema/FlowPropertyEditor.svelte.d.ts +1 -1
  176. package/package/components/schema/PropertyEditor.svelte +0 -2
  177. package/package/components/schema/PropertyEditor.svelte.d.ts +1 -1
  178. package/package/components/schema/SchemaFormDND.svelte +2 -1
  179. package/package/components/schema/SchemaFormDND.svelte.d.ts +2 -0
  180. package/package/components/scriptEditor/LogPanel.svelte +5 -3
  181. package/package/components/scriptEditor/LogPanel.svelte.d.ts +5 -1
  182. package/package/components/select/Select.svelte +7 -4
  183. package/package/components/select/Select.svelte.d.ts +5 -0
  184. package/package/components/select/SelectDropdown.svelte +2 -1
  185. package/package/components/select/SelectDropdown.svelte.d.ts +3 -0
  186. package/package/components/sidebar/changelogs.js +5 -0
  187. package/package/components/table/AutoDataTable.svelte +6 -4
  188. package/package/components/table/AutoDataTable.svelte.d.ts +1 -0
  189. package/package/components/table/DataTable.svelte +12 -10
  190. package/package/components/table/DataTable.svelte.d.ts +1 -0
  191. package/package/components/triggers/TriggerRetriesAndErrorHandler.svelte.d.ts +2 -2
  192. package/package/components/triggers/gcp/GcpTriggerEditorConfigSection.svelte +1 -1
  193. package/package/components/triggers/gcp/GcpTriggerEditorConfigSection.svelte.d.ts +2 -1
  194. package/package/components/triggers/gcp/GcpTriggerEditorInner.svelte +50 -11
  195. package/package/components/triggers/gcp/utils.js +1 -0
  196. package/package/components/triggers/http/utils.js +1 -1
  197. package/package/components/triggers/kafka/utils.js +1 -1
  198. package/package/components/triggers/mqtt/utils.js +1 -1
  199. package/package/components/triggers/nats/utils.js +1 -1
  200. package/package/components/triggers/postgres/utils.js +1 -1
  201. package/package/components/triggers/sqs/utils.js +1 -1
  202. package/package/components/triggers/utils.js +2 -1
  203. package/package/components/triggers/webhook/WebhooksConfigSection.svelte +24 -26
  204. package/package/components/triggers/webhook/WebhooksPanel.svelte +1 -15
  205. package/package/components/triggers/websocket/utils.js +1 -1
  206. package/package/components/workspaceSettings/AISettings.svelte +52 -36
  207. package/package/components/workspaceSettings/DucklakeSettings.svelte +321 -0
  208. package/package/components/workspaceSettings/DucklakeSettings.svelte.d.ts +23 -0
  209. package/package/components/workspaceSettings/GitSyncFilterSettings.svelte +122 -499
  210. package/package/components/workspaceSettings/GitSyncFilterSettings.svelte.d.ts +8 -10
  211. package/package/consts.js +2 -1
  212. package/package/gen/core/OpenAPI.js +1 -1
  213. package/package/gen/schemas.gen.d.ts +33 -24
  214. package/package/gen/schemas.gen.js +36 -27
  215. package/package/gen/services.gen.d.ts +19 -1
  216. package/package/gen/services.gen.js +38 -0
  217. package/package/gen/types.gen.d.ts +103 -9
  218. package/package/git-sync.d.ts +36 -0
  219. package/package/git-sync.js +1 -0
  220. package/package/hub.d.ts +1 -0
  221. package/package/hubPaths.json +5 -2
  222. package/package/infer.js +3 -2
  223. package/package/script_helpers.d.ts +2 -2
  224. package/package/script_helpers.js +29 -11
  225. package/package/services/JobManager.d.ts +28 -0
  226. package/package/services/JobManager.js +114 -0
  227. package/package/stores.d.ts +1 -1
  228. package/package/utils.d.ts +18 -1
  229. package/package/utils.js +55 -2
  230. package/package.json +13 -12
  231. package/package/components/InitGitRepoPopover.svelte +0 -410
  232. package/package/components/InitGitRepoPopover.svelte.d.ts +0 -13
  233. package/package/components/PullGitRepoPopover.svelte +0 -355
  234. package/package/components/PullGitRepoPopover.svelte.d.ts +0 -18
  235. package/package/inferArgSig.d.ts +0 -35
  236. package/package/inferArgSig.js +0 -191
@@ -11,6 +11,8 @@ import ArgEnum from '../ArgEnum.svelte';
11
11
  import Button from '../common/button/Button.svelte';
12
12
  import MultiSelect from '../select/MultiSelect.svelte';
13
13
  import { safeSelectItems } from '../select/utils.svelte';
14
+ import Badge from '../common/badge/Badge.svelte';
15
+ import Tooltip from '../Tooltip.svelte';
14
16
  const aiProviderLabels = [
15
17
  ['openai', 'OpenAI'],
16
18
  ['azure_openai', 'Azure OpenAI'],
@@ -115,48 +117,62 @@ async function onAiProviderChange(provider) {
115
117
  <div class="flex flex-col gap-4">
116
118
  {#each aiProviderLabels as [provider, label]}
117
119
  <div class="flex flex-col gap-2">
118
- <Toggle
119
- options={{
120
- right: label
121
- }}
122
- checked={!!aiProviders[provider]}
123
- on:change={(e) => {
124
- if (e.detail) {
125
- aiProviders = {
126
- ...aiProviders,
127
- [provider]: {
128
- resource_path: '',
129
- models:
130
- availableAiModels[provider].length > 0 ? [availableAiModels[provider][0]] : []
120
+ <div class="flex flex-row gap-2">
121
+ <Toggle
122
+ options={{
123
+ right: label
124
+ }}
125
+ checked={!!aiProviders[provider]}
126
+ on:change={(e) => {
127
+ if (e.detail) {
128
+ aiProviders = {
129
+ ...aiProviders,
130
+ [provider]: {
131
+ resource_path: '',
132
+ models:
133
+ availableAiModels[provider].length > 0
134
+ ? [availableAiModels[provider][0]]
135
+ : []
136
+ }
131
137
  }
132
- }
133
138
 
134
- if (availableAiModels[provider].length > 0 && !defaultModel) {
135
- defaultModel = availableAiModels[provider][0]
136
- }
137
- } else {
138
- aiProviders = Object.fromEntries(
139
- Object.entries(aiProviders).filter(([key]) => key !== provider)
140
- )
141
- if (defaultModel) {
142
- const currentDefaultModel = Object.values(aiProviders).find(
143
- (p) => defaultModel && p.models.includes(defaultModel)
144
- )
145
- if (!currentDefaultModel) {
146
- defaultModel = undefined
139
+ if (availableAiModels[provider].length > 0 && !defaultModel) {
140
+ defaultModel = availableAiModels[provider][0]
147
141
  }
148
- }
149
- if (codeCompletionModel) {
150
- const currentCodeCompletionModel = Object.values(aiProviders).find(
151
- (p) => codeCompletionModel && p.models.includes(codeCompletionModel)
142
+ } else {
143
+ aiProviders = Object.fromEntries(
144
+ Object.entries(aiProviders).filter(([key]) => key !== provider)
152
145
  )
153
- if (!currentCodeCompletionModel) {
154
- codeCompletionModel = undefined
146
+ if (defaultModel) {
147
+ const currentDefaultModel = Object.values(aiProviders).find(
148
+ (p) => defaultModel && p.models.includes(defaultModel)
149
+ )
150
+ if (!currentDefaultModel) {
151
+ defaultModel = undefined
152
+ }
153
+ }
154
+ if (codeCompletionModel) {
155
+ const currentCodeCompletionModel = Object.values(aiProviders).find(
156
+ (p) => codeCompletionModel && p.models.includes(codeCompletionModel)
157
+ )
158
+ if (!currentCodeCompletionModel) {
159
+ codeCompletionModel = undefined
160
+ }
155
161
  }
156
162
  }
157
- }
158
- }}
159
- />
163
+ }}
164
+ />
165
+ {#if provider === 'anthropic'}
166
+ <Badge color="blue">
167
+ Recommended
168
+ <Tooltip class="text-blue-800 dark:text-blue-800 mt-0.5">
169
+ Anthropic models handle tool calls better than other providers, which makes them a
170
+ better choice for AI chat.
171
+ </Tooltip>
172
+ </Badge>
173
+ {/if}
174
+ </div>
175
+
160
176
  {#if aiProviders[provider]}
161
177
  <div class="mb-4 flex flex-col gap-2">
162
178
  <div class="flex flex-row gap-1">
@@ -0,0 +1,321 @@
1
+ <script module lang="ts">import { _ } from 'ag-grid-community';
2
+ export function convertDucklakeSettingsFromBackend(settings) {
3
+ const s = { ducklakes: [] };
4
+ if (settings?.ducklakes) {
5
+ for (const [name, rest] of Object.entries(settings.ducklakes)) {
6
+ s.ducklakes.push({ name, ...rest });
7
+ }
8
+ }
9
+ return s;
10
+ }
11
+ export function convertDucklakeSettingsToBackend(settings) {
12
+ const s = { ducklakes: {} };
13
+ for (const ducklake of settings.ducklakes) {
14
+ const catalog = ducklake.catalog;
15
+ if (ducklake.name in s.ducklakes)
16
+ throw 'Settings contain duplicate ducklake name: ' + ducklake.name;
17
+ if (!catalog.resource_path)
18
+ throw 'No resource selected for ' + ducklake.name;
19
+ if (catalog.resource_type === 'instance' && catalog.resource_path === 'windmill')
20
+ throw ducklake.name + ' catalog cannot be called "windmill"';
21
+ if (ducklake.storage.path.startsWith('/'))
22
+ ducklake.storage.path = ducklake.storage.path.slice(1);
23
+ s.ducklakes[ducklake.name] = {
24
+ catalog: ducklake.catalog,
25
+ storage: ducklake.storage
26
+ };
27
+ }
28
+ return s;
29
+ }
30
+ </script>
31
+
32
+ <script>
33
+ import { Plus } from 'lucide-svelte'
34
+
35
+ import Button from '../common/button/Button.svelte'
36
+
37
+ import Description from '../Description.svelte'
38
+ import { random_adj } from '../random_positive_adjetive'
39
+ import { DataTable, Cell, Row } from '../table'
40
+ import Head from '../table/Head.svelte'
41
+ import CloseButton from '../common/CloseButton.svelte'
42
+ import Select from '../select/Select.svelte'
43
+ import ResourcePicker from '../ResourcePicker.svelte'
44
+ import { usePromise } from '../../svelte5Utils.svelte'
45
+ import { SettingService, WorkspaceService, type GetSettingsResponse } from '../../gen'
46
+ import { superadmin, workspaceStore } from '../../stores'
47
+ import { sendUserToast } from '../../toast'
48
+ import ExploreAssetButton from '../ExploreAssetButton.svelte'
49
+ import DbManagerDrawer from '../DBManagerDrawer.svelte'
50
+ import Tooltip from '../Tooltip.svelte'
51
+ import { isCloudHosted } from '../../cloud'
52
+ import ConfirmationModal from '../common/confirmationModal/ConfirmationModal.svelte'
53
+ import { createAsyncConfirmationModal } from '../common/confirmationModal/asyncConfirmationModal.svelte'
54
+ import { clone, pluralize } from '../../utils'
55
+ import Alert from '../common/alert/Alert.svelte'
56
+ import { deepEqual } from 'fast-equals'
57
+ import Popover from '../meltComponents/Popover.svelte'
58
+
59
+ const DEFAULT_DUCKLAKE_CATALOG_NAME = 'ducklake_catalog'
60
+
61
+ type Props = {
62
+ ducklakeSettings: DucklakeSettingsType
63
+ ducklakeSavedSettings: DucklakeSettingsType
64
+ }
65
+ let { ducklakeSettings = $bindable(), ducklakeSavedSettings = $bindable() }: Props = $props()
66
+
67
+ let isWmDbEnabled = $derived($superadmin && !isCloudHosted())
68
+
69
+ function onNewDucklake() {
70
+ const name = ducklakeSettings.ducklakes.some((d) => d.name === 'main')
71
+ ? `${random_adj()}_ducklake`
72
+ : 'main'
73
+ ducklakeSettings.ducklakes.push({
74
+ name,
75
+ catalog: {
76
+ resource_type: isWmDbEnabled ? 'instance' : 'postgresql',
77
+ resource_path: isWmDbEnabled ? DEFAULT_DUCKLAKE_CATALOG_NAME : undefined
78
+ },
79
+ storage: {
80
+ storage: undefined,
81
+ path: ''
82
+ }
83
+ })
84
+ }
85
+
86
+ function removeDucklake(index: number) {
87
+ ducklakeSettings.ducklakes.splice(index, 1)
88
+ }
89
+
90
+ const windmillDbNames = $derived(
91
+ ducklakeSettings.ducklakes
92
+ .filter((d) => d.catalog.resource_type === 'instance')
93
+ .map((d) => d.catalog.resource_path ?? '')
94
+ )
95
+
96
+ const ducklakeIsDirty: Record<string, boolean> = $derived(
97
+ Object.fromEntries(
98
+ ducklakeSettings.ducklakes.map((d) => {
99
+ const saved = ducklakeSavedSettings.ducklakes.find((saved) => saved.name === d.name)
100
+ return [d.name, !deepEqual(saved, d)] as const
101
+ })
102
+ )
103
+ )
104
+
105
+ async function onSave() {
106
+ try {
107
+ if (windmillDbNames.length) {
108
+ // Ensure that all instance dbs exist
109
+ const nonExistentDbs = await SettingService.databasesExist({ requestBody: windmillDbNames })
110
+ if (nonExistentDbs.length) {
111
+ let confirmed = await confirmationModal.ask({
112
+ title: "The following databases do not exist in Windmill's Postgres instance",
113
+ confirmationText: `Create ${pluralize(nonExistentDbs.length, 'database')}`,
114
+ children: `<span>
115
+ Confirm running the following in the instance's Postgres :<br />
116
+ ${nonExistentDbs.map((db) => `<pre class='border mt-1 p-2 rounded-md'>CREATE DATABASE "${db}";</pre>`).join('\n')}
117
+ </span>`
118
+ })
119
+ if (!confirmed) return
120
+ await Promise.all(
121
+ nonExistentDbs.map((name) => SettingService.createDucklakeDatabase({ name }))
122
+ )
123
+ }
124
+ }
125
+ const settings = convertDucklakeSettingsToBackend(ducklakeSettings)
126
+ await WorkspaceService.editDucklakeConfig({
127
+ workspace: $workspaceStore!,
128
+ requestBody: { settings }
129
+ })
130
+ ducklakeSavedSettings = clone(ducklakeSettings)
131
+ sendUserToast('Ducklake settings saved successfully')
132
+ } catch (e) {
133
+ sendUserToast(e, true)
134
+ console.error('Error saving ducklake settings', e)
135
+ }
136
+ }
137
+
138
+ let secondaryStorageNames = usePromise(
139
+ () => SettingService.getSecondaryStorageNames({ workspace: $workspaceStore! }),
140
+ { loadInit: false }
141
+ )
142
+ $effect(() => {
143
+ $workspaceStore
144
+ secondaryStorageNames.refresh()
145
+ })
146
+
147
+ let tableHeadNames = ['Name', 'Catalog', 'Workspace storage', '', ''] as const
148
+
149
+ let tableHeadTooltips: Partial<Record<(typeof tableHeadNames)[number], string | undefined>> = {
150
+ Name: "Ducklakes are referenced in DuckDB scripts with the <code class='px-1 py-0.5 border rounded-md'>ATTACH 'ducklake://name' AS dl;</code> syntax",
151
+ Catalog: 'Ducklake needs an SQL database to store metadata about the data',
152
+ 'Workspace storage':
153
+ 'Where the data is actually stored, in parquet format. You need to configure a workspace storage first'
154
+ }
155
+
156
+ let dbManagerDrawer: DbManagerDrawer | undefined = $state()
157
+ let confirmationModal = createAsyncConfirmationModal()
158
+ </script>
159
+
160
+ <div class="flex flex-col gap-4 mb-8 mt-20">
161
+ <div class="flex flex-col gap-1">
162
+ <div class="text-primary text-lg font-semibold">Ducklake</div>
163
+ <Description link="https://www.windmill.dev/docs/core_concepts/ducklake">
164
+ Windmill has first class support for Ducklake. You can use and explore ducklakes like a normal
165
+ SQL database, even through the data is actually stored in parquet files in S3 !
166
+ </Description>
167
+ </div>
168
+ </div>
169
+
170
+ {#if ducklakeSettings.ducklakes.some((d) => d.catalog.resource_type === 'instance')}
171
+ <Alert title="Instance catalogs use the Windmill database" class="mb-4" type="info">
172
+ Using an instance catalog is the fastest way to get started with Ducklake. They are public to
173
+ the instance and can be re-used in other workspaces' Ducklake settings.
174
+ </Alert>
175
+ {/if}
176
+
177
+ <DataTable>
178
+ <Head>
179
+ <tr>
180
+ {#each tableHeadNames as name, i}
181
+ <Cell head first={i == 0} last={i == tableHeadNames.length - 1}>
182
+ {name}
183
+ {#if tableHeadTooltips[name]}
184
+ <Tooltip>
185
+ {@html tableHeadTooltips[name]}
186
+ </Tooltip>
187
+ {/if}
188
+ </Cell>
189
+ {/each}
190
+ </tr>
191
+ </Head>
192
+ <tbody class="divide-y bg-surface">
193
+ {#if ducklakeSettings.ducklakes.length == 0}
194
+ <Row>
195
+ <Cell colspan={tableHeadNames.length} class="text-center">
196
+ No ducklake in this workspace yet
197
+ </Cell>
198
+ </Row>
199
+ {/if}
200
+ {#each ducklakeSettings.ducklakes as ducklake, ducklakeIndex}
201
+ <Row>
202
+ <Cell first class="w-48 relative">
203
+ {#if ducklake.name === 'main'}
204
+ <Tooltip wrapperClass="absolute mt-2.5 right-4" placement="bottom-start">
205
+ The <i>main</i> ducklake can be accessed with the
206
+ <br />
207
+ <code class="px-1 py-0.5 border rounded-md">ATTACH 'ducklake' AS dl;</code> shorthand
208
+ </Tooltip>
209
+ {/if}
210
+ <input bind:value={ducklake.name} placeholder="Name" />
211
+ </Cell>
212
+ <Cell>
213
+ <div class="flex gap-4">
214
+ <div class="relative">
215
+ {#if ducklake.catalog.resource_type === 'instance'}
216
+ <Tooltip wrapperClass="absolute mt-2.5 right-2 z-20" placement="bottom-start">
217
+ Use Windmill's PostgreSQL instance as a catalog
218
+ </Tooltip>
219
+ {/if}
220
+ <Select
221
+ items={[
222
+ { value: 'postgresql', label: 'PostgreSQL' },
223
+ { value: 'mysql', label: 'MySQL' },
224
+ ...(isWmDbEnabled ? [{ value: 'instance', label: 'Instance' }] : [])
225
+ ]}
226
+ bind:value={
227
+ () => ducklake.catalog.resource_type,
228
+ (resource_type) => {
229
+ ducklake.catalog = {
230
+ resource_type,
231
+ resource_path:
232
+ resource_type === 'instance' ? DEFAULT_DUCKLAKE_CATALOG_NAME : undefined
233
+ }
234
+ }
235
+ }
236
+ class="w-28"
237
+ />
238
+ </div>
239
+ <div class="flex items-center gap-1 w-80">
240
+ {#if ducklake.catalog.resource_type !== 'instance'}
241
+ <ResourcePicker
242
+ bind:value={ducklake.catalog.resource_path}
243
+ resourceType={ducklake.catalog.resource_type}
244
+ />
245
+ {:else}
246
+ <input
247
+ bind:value={ducklake.catalog.resource_path}
248
+ placeholder="PostgreSQL database name"
249
+ />
250
+ {/if}
251
+ </div>
252
+ </div>
253
+ </Cell>
254
+ <Cell>
255
+ <div class="flex gap-4">
256
+ <Select
257
+ placeholder="Default storage"
258
+ items={[
259
+ { value: undefined, label: 'Default storage' },
260
+ ...(secondaryStorageNames.value?.map((value) => ({ value })) ?? [])
261
+ ]}
262
+ bind:value={
263
+ () => ducklake.storage.storage,
264
+ (s) => {
265
+ if (s) ducklake.storage.storage = s
266
+ else delete ducklake.storage.storage
267
+ }
268
+ }
269
+ class="w-48"
270
+ inputClass="!placeholder-primary"
271
+ />
272
+ <input placeholder="Data path (defaults to /)" bind:value={ducklake.storage.path} />
273
+ </div>
274
+ </Cell>
275
+ <Cell class="w-12">
276
+ {#if ducklakeIsDirty[ducklake.name]}
277
+ <Popover
278
+ openOnHover
279
+ contentClasses="p-2 text-sm text-secondary italic"
280
+ class="cursor-not-allowed"
281
+ >
282
+ <svelte:fragment slot="trigger">
283
+ <ExploreAssetButton
284
+ asset={{ kind: 'ducklake', path: ducklake.name }}
285
+ {dbManagerDrawer}
286
+ disabled
287
+ />
288
+ </svelte:fragment>
289
+ <svelte:fragment slot="content">Please save settings first</svelte:fragment>
290
+ </Popover>
291
+ {:else}
292
+ <ExploreAssetButton
293
+ asset={{ kind: 'ducklake', path: ducklake.name }}
294
+ {dbManagerDrawer}
295
+ />
296
+ {/if}
297
+ </Cell>
298
+ <Cell class="w-12">
299
+ <CloseButton small on:close={() => removeDucklake(ducklakeIndex)} />
300
+ </Cell>
301
+ </Row>
302
+ {/each}
303
+ <Row class="!border-0">
304
+ <Cell colspan={tableHeadNames.length} class="pt-0 pb-2">
305
+ <div class="flex justify-center">
306
+ <Button size="sm" btnClasses="max-w-fit" variant="border" on:click={onNewDucklake}>
307
+ <Plus /> New ducklake
308
+ </Button>
309
+ </div>
310
+ </Cell>
311
+ </Row>
312
+ </tbody>
313
+ </DataTable>
314
+ <Button
315
+ wrapperClasses="mt-4 mb-44 max-w-fit"
316
+ on:click={onSave}
317
+ disabled={Object.values(ducklakeIsDirty).every((v) => v === false)}>Save ducklake settings</Button
318
+ >
319
+ <DbManagerDrawer bind:this={dbManagerDrawer} />
320
+
321
+ <ConfirmationModal {...confirmationModal.props} />
@@ -0,0 +1,23 @@
1
+ export type DucklakeSettingsType = {
2
+ ducklakes: {
3
+ name: string;
4
+ catalog: {
5
+ resource_type: 'postgresql' | 'mysql' | 'instance';
6
+ resource_path?: string;
7
+ };
8
+ storage: {
9
+ storage?: string;
10
+ path: string;
11
+ };
12
+ }[];
13
+ };
14
+ export declare function convertDucklakeSettingsFromBackend(settings: GetSettingsResponse['ducklake']): DucklakeSettingsType;
15
+ export declare function convertDucklakeSettingsToBackend(settings: DucklakeSettingsType): NonNullable<GetSettingsResponse['ducklake']>;
16
+ import { type GetSettingsResponse } from '../../gen';
17
+ type Props = {
18
+ ducklakeSettings: DucklakeSettingsType;
19
+ ducklakeSavedSettings: DucklakeSettingsType;
20
+ };
21
+ declare const DucklakeSettings: import("svelte").Component<Props, {}, "ducklakeSettings" | "ducklakeSavedSettings">;
22
+ type DucklakeSettings = ReturnType<typeof DucklakeSettings>;
23
+ export default DucklakeSettings;