windmill-components 1.555.1 → 1.558.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. package/package/components/AIAgentLogViewer.svelte.d.ts +3 -3
  2. package/package/components/AIProviderPicker.svelte.d.ts +3 -3
  3. package/package/components/ArgInput.svelte +2 -0
  4. package/package/components/DBManager.svelte.d.ts +3 -3
  5. package/package/components/DBManagerDrawer.svelte.d.ts +3 -3
  6. package/package/components/DBSchemaExplorer.svelte.d.ts +3 -3
  7. package/package/components/DBTable.svelte.d.ts +3 -3
  8. package/package/components/DBTableEditor.svelte +9 -12
  9. package/package/components/DBTableEditor.svelte.d.ts +3 -3
  10. package/package/components/DateTimeInput.svelte +19 -13
  11. package/package/components/DateTimeInput.svelte.d.ts +5 -0
  12. package/package/components/DucklakePicker.svelte +32 -0
  13. package/package/components/DucklakePicker.svelte.d.ts +13 -0
  14. package/package/components/Editor.svelte +1 -1
  15. package/package/components/EditorBar.svelte +14 -1
  16. package/package/components/FakeMonacoPlaceHolder.svelte +1 -1
  17. package/package/components/FlowGraphViewerStep.svelte +1 -1
  18. package/package/components/FlowPreviewContent.svelte +1 -1
  19. package/package/components/HighlightCode.svelte +21 -10
  20. package/package/components/HighlightCode.svelte.d.ts +12 -22
  21. package/package/components/InputTransformForm.svelte +9 -41
  22. package/package/components/InstanceSetting.svelte +1 -6
  23. package/package/components/ResourceEditor.svelte +1 -1
  24. package/package/components/ResourcePicker.svelte +0 -5
  25. package/package/components/apps/components/display/dbtable/AppDbExplorer.svelte +50 -34
  26. package/package/components/apps/components/display/dbtable/DbExplorerCount.svelte +7 -5
  27. package/package/components/apps/components/display/dbtable/DbExplorerCount.svelte.d.ts +2 -2
  28. package/package/components/apps/components/display/dbtable/DeleteRow.svelte +2 -2
  29. package/package/components/apps/components/display/dbtable/DeleteRow.svelte.d.ts +3 -2
  30. package/package/components/apps/components/display/dbtable/InsertRow.svelte +13 -7
  31. package/package/components/apps/components/display/dbtable/InsertRowRunnable.svelte +6 -3
  32. package/package/components/apps/components/display/dbtable/InsertRowRunnable.svelte.d.ts +2 -1
  33. package/package/components/apps/components/display/dbtable/UpdateCell.svelte +2 -2
  34. package/package/components/apps/components/display/dbtable/UpdateCell.svelte.d.ts +3 -2
  35. package/package/components/apps/components/display/dbtable/queries/count.d.ts +2 -1
  36. package/package/components/apps/components/display/dbtable/queries/count.js +28 -18
  37. package/package/components/apps/components/display/dbtable/queries/createTable.d.ts +1 -1
  38. package/package/components/apps/components/display/dbtable/queries/createTable.js +1 -1
  39. package/package/components/apps/components/display/dbtable/queries/delete.d.ts +2 -1
  40. package/package/components/apps/components/display/dbtable/queries/delete.js +19 -10
  41. package/package/components/apps/components/display/dbtable/queries/insert.d.ts +2 -1
  42. package/package/components/apps/components/display/dbtable/queries/insert.js +16 -10
  43. package/package/components/apps/components/display/dbtable/queries/select.d.ts +2 -1
  44. package/package/components/apps/components/display/dbtable/queries/select.js +20 -16
  45. package/package/components/apps/components/display/dbtable/queries/update.d.ts +2 -1
  46. package/package/components/apps/components/display/dbtable/queries/update.js +19 -10
  47. package/package/components/apps/components/display/dbtable/utils.d.ts +1 -1
  48. package/package/components/apps/components/display/dbtable/utils.js +12 -3
  49. package/package/components/apps/components/display/table/AppAggridExplorerTable.svelte +9 -1
  50. package/package/components/apps/components/display/table/AppAggridExplorerTable.svelte.d.ts +1 -0
  51. package/package/components/apps/components/display/table/AppAggridInfiniteTable.svelte +2 -1
  52. package/package/components/apps/components/display/table/AppAggridInfiniteTable.svelte.d.ts +1 -0
  53. package/package/components/apps/components/display/table/AppAggridInfiniteTableEe.svelte +2 -1
  54. package/package/components/apps/components/display/table/AppAggridInfiniteTableEe.svelte.d.ts +1 -0
  55. package/package/components/apps/components/display/table/AppAggridTable.svelte +9 -1
  56. package/package/components/apps/components/display/table/AppAggridTable.svelte.d.ts +1 -0
  57. package/package/components/apps/components/display/table/AppAggridTableEe.svelte +2 -1
  58. package/package/components/apps/components/display/table/AppAggridTableEe.svelte.d.ts +1 -0
  59. package/package/components/apps/components/helpers/RunnableComponent.svelte +3 -1
  60. package/package/components/apps/components/inputs/AppDateInput.svelte +1 -0
  61. package/package/components/apps/editor/AppEditor.svelte +6 -1
  62. package/package/components/apps/editor/AppEditorHeader.svelte +12 -8
  63. package/package/components/apps/editor/AppJobsDrawer.svelte +5 -5
  64. package/package/components/apps/editor/component/ComponentInner.svelte +4 -0
  65. package/package/components/apps/editor/component/components.d.ts +16 -0
  66. package/package/components/apps/editor/component/components.js +17 -1
  67. package/package/components/apps/editor/settingsPanel/AGChartRichEditor.svelte.d.ts +3 -3
  68. package/package/components/apps/editor/settingsPanel/CSSMigrationModal.svelte.d.ts +3 -3
  69. package/package/components/apps/editor/settingsPanel/ChartJSRichEditor.svelte.d.ts +3 -3
  70. package/package/components/apps/editor/settingsPanel/ComponentInputTypeEditor.svelte +23 -23
  71. package/package/components/apps/editor/settingsPanel/EventHandlers.svelte +7 -2
  72. package/package/components/apps/editor/settingsPanel/InputsSpecEditor.svelte +1 -0
  73. package/package/components/apps/editor/settingsPanel/InputsSpecsEditor.svelte +2 -1
  74. package/package/components/apps/editor/settingsPanel/inputEditor/DBTableSelect.svelte.d.ts +3 -3
  75. package/package/components/apps/editor/settingsPanel/inputEditor/StaticInputEditor.svelte +10 -0
  76. package/package/components/apps/inputType.d.ts +2 -2
  77. package/package/components/auditLogs/AuditLogsFilters.svelte.d.ts +1 -1
  78. package/package/components/common/button/ConnectionButton.svelte +12 -14
  79. package/package/components/common/button/ConnectionButton.svelte.d.ts +5 -18
  80. package/package/components/copilot/AIFormAssistant.svelte.d.ts +3 -3
  81. package/package/components/copilot/AIFormSettings.svelte.d.ts +3 -3
  82. package/package/components/copilot/FlowInlineScriptAIButton.svelte.d.ts +3 -3
  83. package/package/components/copilot/StepInputsGen.svelte +1 -1
  84. package/package/components/copilot/TestAIKey.svelte.d.ts +3 -3
  85. package/package/components/copilot/chat/AIChat.svelte.d.ts +3 -3
  86. package/package/components/copilot/chat/AIChatDisplay.svelte.d.ts +3 -3
  87. package/package/components/copilot/chat/AIChatInlineWidget.svelte.d.ts +3 -3
  88. package/package/components/copilot/chat/AIChatInput.svelte.d.ts +3 -3
  89. package/package/components/copilot/chat/AIChatMessage.svelte.d.ts +3 -3
  90. package/package/components/copilot/chat/ContextElementBadge.svelte +2 -2
  91. package/package/components/copilot/chat/flow/AIChangesWarningModal.svelte.d.ts +3 -3
  92. package/package/components/copilot/chat/flow/FlowAIButton.svelte.d.ts +3 -3
  93. package/package/components/copilot/chat/flow/FlowAIChat.svelte +4 -1
  94. package/package/components/copilot/chat/flow/FlowAIChat.svelte.d.ts +3 -3
  95. package/package/components/copilot/chat/script/CodeDisplay.svelte +30 -9
  96. package/package/components/copilot/chat/script/core.d.ts +2 -1
  97. package/package/components/copilot/chat/script/core.js +6 -1
  98. package/package/components/details/DetailPageLayout.svelte +11 -3
  99. package/package/components/details/DetailPageLayout.svelte.d.ts +1 -0
  100. package/package/components/flows/content/DynamicInputHelpBox.svelte +4 -4
  101. package/package/components/flows/content/FlowInput.svelte +1 -1
  102. package/package/components/flows/content/FlowInputsQuick.svelte +1 -1
  103. package/package/components/flows/content/FlowLoop.svelte +143 -10
  104. package/package/components/flows/conversations/FlowChatInterface.svelte +110 -0
  105. package/package/components/flows/{FlowChatInterface.svelte.d.ts → conversations/FlowChatInterface.svelte.d.ts} +1 -1
  106. package/package/components/flows/conversations/FlowChatManager.svelte.d.ts +52 -0
  107. package/package/components/flows/conversations/FlowChatManager.svelte.js +422 -0
  108. package/package/components/flows/conversations/FlowChatMessage.svelte +68 -0
  109. package/package/components/flows/{FlowChatMessage.svelte.d.ts → conversations/FlowChatMessage.svelte.d.ts} +2 -4
  110. package/package/components/flows/{FlowConversationsSidebar.svelte → conversations/FlowConversationsSidebar.svelte} +6 -6
  111. package/package/components/flows/flowInfers.js +1 -1
  112. package/package/components/flows/scheduleUtils.js +2 -1
  113. package/package/components/graph/renderers/nodes/AIToolNode.svelte.d.ts +3 -3
  114. package/package/components/graph/renderers/nodes/NewAIToolNode.svelte.d.ts +3 -3
  115. package/package/components/icons/CACertificate.svelte.d.ts +3 -3
  116. package/package/components/icons/MSSqlServerIcon.svelte.d.ts +3 -3
  117. package/package/components/icons/MSTeamsIcon.svelte.d.ts +3 -3
  118. package/package/components/icons/OracleDBIcon.svelte.d.ts +3 -3
  119. package/package/components/icons/PHPIcon.svelte.d.ts +3 -3
  120. package/package/components/icons/QRCodeIcon.svelte.d.ts +3 -3
  121. package/package/components/instanceSettings.js +11 -2
  122. package/package/components/runs/JobsLoader.svelte +3 -3
  123. package/package/components/runs/RunRow.svelte +1 -1
  124. package/package/components/schema/SchemaFormDND.svelte.d.ts +3 -3
  125. package/package/components/settings/AIUserSettings.svelte.d.ts +3 -3
  126. package/package/components/sidebar/SidebarContent.svelte +2 -2
  127. package/package/components/text_input/TextInput.svelte.d.ts +1 -1
  128. package/package/components/triggers/http/OpenAPISpecGenerator.svelte.d.ts +3 -3
  129. package/package/components/triggers/schedules/ScheduleEditorInner.svelte +42 -1
  130. package/package/components/vscode.js +16 -12
  131. package/package/components/wizards/ChartJSWizard.svelte.d.ts +3 -3
  132. package/package/components/wizards/DBExplorerWizard.svelte.d.ts +3 -3
  133. package/package/components/wizards/LoggedWizardResult.svelte +95 -0
  134. package/package/components/wizards/LoggedWizardResult.svelte.d.ts +17 -0
  135. package/package/components/workspaceSettings/AISettings.svelte.d.ts +3 -3
  136. package/package/components/workspaceSettings/DucklakeSettings.svelte +223 -89
  137. package/package/gen/core/OpenAPI.js +1 -1
  138. package/package/gen/schemas.gen.d.ts +73 -5
  139. package/package/gen/schemas.gen.js +73 -5
  140. package/package/gen/services.gen.d.ts +8 -8
  141. package/package/gen/services.gen.js +14 -12
  142. package/package/gen/types.gen.d.ts +69 -18
  143. package/package/svelte5Utils.svelte.d.ts +1 -0
  144. package/package/svelte5Utils.svelte.js +6 -0
  145. package/package/utils.js +2 -5
  146. package/package.json +11 -13
  147. package/package/components/flows/FlowChatInterface.svelte +0 -404
  148. package/package/components/flows/FlowChatMessage.svelte +0 -41
  149. package/package/components/meltComponents/Menubar.svelte.d.ts +0 -503
  150. /package/package/components/flows/{FlowConversationsSidebar.svelte.d.ts → conversations/FlowConversationsSidebar.svelte.d.ts} +0 -0
@@ -30,7 +30,7 @@ export function convertDucklakeSettingsToBackend(settings) {
30
30
  </script>
31
31
 
32
32
  <script>
33
- import { Plus } from 'lucide-svelte'
33
+ import { ArrowRight, TriangleAlert, Plus } from 'lucide-svelte'
34
34
 
35
35
  import Button from '../common/button/Button.svelte'
36
36
 
@@ -42,7 +42,7 @@ export function convertDucklakeSettingsToBackend(settings) {
42
42
  import Select from '../select/Select.svelte'
43
43
  import ResourcePicker from '../ResourcePicker.svelte'
44
44
  import { usePromise } from '../../svelte5Utils.svelte'
45
- import { SettingService, WorkspaceService } from '../../gen'
45
+ import { SettingService, WorkspaceService, type DucklakeInstanceCatalogDbStatus } from '../../gen'
46
46
  import { type GetSettingsResponse } from '../../gen'
47
47
 
48
48
  import { superadmin, workspaceStore } from '../../stores'
@@ -53,12 +53,14 @@ export function convertDucklakeSettingsToBackend(settings) {
53
53
  import { isCloudHosted } from '../../cloud'
54
54
  import ConfirmationModal from '../common/confirmationModal/ConfirmationModal.svelte'
55
55
  import { createAsyncConfirmationModal } from '../common/confirmationModal/asyncConfirmationModal.svelte'
56
- import { clone, pluralize } from '../../utils'
56
+ import { clone } from '../../utils'
57
57
  import Alert from '../common/alert/Alert.svelte'
58
58
  import { deepEqual } from 'fast-equals'
59
59
  import Popover from '../meltComponents/Popover.svelte'
60
60
  import TextInput from '../text_input/TextInput.svelte'
61
- import Section from '../Section.svelte'
61
+ import LoggedWizardResult, { firstEmptyStepIsError } from '../wizards/LoggedWizardResult.svelte'
62
+ import { safeSelectItems } from '../select/utils.svelte'
63
+ import { slide } from 'svelte/transition'
62
64
 
63
65
  const DEFAULT_DUCKLAKE_CATALOG_NAME = 'ducklake_catalog'
64
66
 
@@ -68,7 +70,7 @@ export function convertDucklakeSettingsToBackend(settings) {
68
70
  }
69
71
  let { ducklakeSettings = $bindable(), ducklakeSavedSettings = $bindable() }: Props = $props()
70
72
 
71
- let isWmDbEnabled = $derived($superadmin && !isCloudHosted())
73
+ let isInstanceCatalogEnabled = $derived($superadmin && !isCloudHosted())
72
74
 
73
75
  function onNewDucklake() {
74
76
  const name = ducklakeSettings.ducklakes.some((d) => d.name === 'main')
@@ -77,8 +79,8 @@ export function convertDucklakeSettingsToBackend(settings) {
77
79
  ducklakeSettings.ducklakes.push({
78
80
  name,
79
81
  catalog: {
80
- resource_type: isWmDbEnabled ? 'instance' : 'postgresql',
81
- resource_path: isWmDbEnabled ? DEFAULT_DUCKLAKE_CATALOG_NAME : undefined
82
+ resource_type: isInstanceCatalogEnabled ? 'instance' : 'postgresql',
83
+ resource_path: isInstanceCatalogEnabled ? DEFAULT_DUCKLAKE_CATALOG_NAME : undefined
82
84
  },
83
85
  storage: {
84
86
  storage: undefined,
@@ -91,12 +93,6 @@ export function convertDucklakeSettingsToBackend(settings) {
91
93
  ducklakeSettings.ducklakes.splice(index, 1)
92
94
  }
93
95
 
94
- const windmillDbNames = $derived(
95
- ducklakeSettings.ducklakes
96
- .filter((d) => d.catalog.resource_type === 'instance')
97
- .map((d) => d.catalog.resource_path ?? '')
98
- )
99
-
100
96
  const ducklakeIsDirty: Record<string, boolean> = $derived(
101
97
  Object.fromEntries(
102
98
  ducklakeSettings.ducklakes.map((d) => {
@@ -106,25 +102,27 @@ export function convertDucklakeSettingsToBackend(settings) {
106
102
  )
107
103
  )
108
104
 
105
+ let instanceCatalogSetupIsRunning = $state(false)
106
+ const instanceCatalogStatuses = usePromise(SettingService.getDucklakeInstanceCatalogDbStatus, {
107
+ clearValueOnRefresh: false
108
+ })
109
+
109
110
  async function onSave() {
110
111
  try {
111
- if (windmillDbNames.length) {
112
- // Ensure that all instance dbs exist
113
- const nonExistentDbs = await SettingService.databasesExist({ requestBody: windmillDbNames })
114
- if (nonExistentDbs.length) {
115
- let confirmed = await confirmationModal.ask({
116
- title: "The following databases do not exist in Windmill's Postgres instance",
117
- confirmationText: `Create ${pluralize(nonExistentDbs.length, 'database')}`,
118
- children: `<span>
119
- Confirm running the following in the instance's Postgres :<br />
120
- ${nonExistentDbs.map((db) => `<pre class='border mt-1 p-2 rounded-md'>CREATE DATABASE "${db}";</pre>`).join('\n')}
121
- </span>`
122
- })
123
- if (!confirmed) return
124
- await Promise.all(
125
- nonExistentDbs.map((name) => SettingService.createDucklakeDatabase({ name }))
126
- )
127
- }
112
+ if (
113
+ isInstanceCatalogEnabled &&
114
+ ducklakeSettings.ducklakes.some(
115
+ (d) =>
116
+ d.catalog.resource_type === 'instance' &&
117
+ !instanceCatalogStatuses.value?.[d.catalog.resource_path ?? '']?.success
118
+ )
119
+ ) {
120
+ let confirm = await confirmationModal.ask({
121
+ title: 'Some instance catalogs are not setup',
122
+ children: 'Are you sure you want to save without setting them up ?',
123
+ confirmationText: 'Save anyway'
124
+ })
125
+ if (!confirm) return
128
126
  }
129
127
  const settings = convertDucklakeSettingsToBackend(ducklakeSettings)
130
128
  await WorkspaceService.editDucklakeConfig({
@@ -158,6 +156,7 @@ export function convertDucklakeSettingsToBackend(settings) {
158
156
  }
159
157
 
160
158
  let dbManagerDrawer: DbManagerDrawer | undefined = $state()
159
+ let instanceCatalogPopover: Popover | undefined = $state()
161
160
  let confirmationModal = createAsyncConfirmationModal()
162
161
  </script>
163
162
 
@@ -172,56 +171,12 @@ export function convertDucklakeSettingsToBackend(settings) {
172
171
  </div>
173
172
 
174
173
  {#if ducklakeSettings.ducklakes.some((d) => d.catalog.resource_type === 'instance')}
175
- <Alert title="Instance catalogs use the Windmill database" class="mb-4" type="info">
176
- Using an instance catalog is the fastest way to get started with Ducklake. They are public to
177
- the instance and can be re-used in other workspaces' Ducklake settings.
178
- <div>
179
- <Section
180
- label="Manual setup instructions"
181
- collapsable
182
- headerClass="mt-6 border bg-surface px-3 py-1 rounded-md text-xs text-secondary"
183
- class="text-secondary"
184
- animate
185
- >
186
- This is what happens when you create a new Instance catalog with the name
187
- <code>ducklake_catalog</code>. This may be useful to debug issues in case the automatic
188
- setup fails in the middle, but in most cases Windmill will handle it for you.
189
- <br /><br />
190
-
191
- If the database <code>ducklake_catalog</code> already exists, Windmill assumes that the
192
- setup was successful and does not do anything. However, it is possible that it failed in the
193
- middle (in which case you should have seen an error pop up during setup). There is no
194
- rollback as the following operations do not work in a transaction.
195
- <br />
196
- This is what the setup does :
197
- <br /><br />
198
- Connect to the Windmill PostgreSQL as the default user (the one in your DATABASE_URL, usually
199
- 'postgres') and run :
200
- <br />
201
- <code class="block p-2 border rounded-md bg-surface mt-2">
202
- CREATE DATABASE <code>ducklake_catalog</code>;<br />
203
- GRANT CONNECT ON DATABASE <code>ducklake_catalog</code> TO ducklake_user;
204
- </code>
205
- <br />
206
- Then, connect to the <code>ducklake_catalog</code> database with the same user as above (NOT
207
- ducklake_user) and run :
208
- <code class="block p-2 border rounded-md bg-surface mt-2">
209
- GRANT USAGE ON SCHEMA public TO ducklake_user;<br />
210
- GRANT CREATE ON SCHEMA public TO ducklake_user;<br />
211
- ALTER DEFAULT PRIVILEGES IN SCHEMA public<br />
212
- &nbsp;&nbsp;GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO ducklake_user;
213
- </code>
214
- <br />
215
- After doing that, creating a new Ducklake with an Instance catalog named
216
- <code>ducklake_catalog</code> should not prompt you to run the automatic setup, and
217
- everything should work fine.
218
- <br /><br />
219
- Note : the ducklake_user is automatically created by Windmill in a migration. Its password is
220
- auto-generated and stored in the database table <code>global_settings</code> with the key
221
- <code>ducklake_user_pg_pwd</code>.
222
- </Section>
223
- </div>
224
- </Alert>
174
+ <div transition:slide={{ duration: 200 }} class="mb-4">
175
+ <Alert title="Instance catalogs use the Windmill database" type="info">
176
+ Using an instance catalog is the fastest way to get started with Ducklake. They are public to
177
+ the instance and can be re-used in other workspaces' Ducklake settings.
178
+ </Alert>
179
+ </div>
225
180
  {/if}
226
181
 
227
182
  <DataTable>
@@ -251,7 +206,7 @@ export function convertDucklakeSettingsToBackend(settings) {
251
206
  <Row>
252
207
  <Cell first class="w-48 relative">
253
208
  {#if ducklake.name === 'main'}
254
- <Tooltip wrapperClass="absolute mt-2.5 right-4" placement="bottom-start">
209
+ <Tooltip wrapperClass="absolute mt-3 right-4" placement="bottom-start">
255
210
  The <i>main</i> ducklake can be accessed with the
256
211
  <br />
257
212
  <code class="px-1 py-0.5 border rounded-md">ATTACH 'ducklake' AS dl;</code> shorthand
@@ -260,10 +215,10 @@ export function convertDucklakeSettingsToBackend(settings) {
260
215
  <TextInput bind:value={ducklake.name} inputProps={{ placeholder: 'Name' }} />
261
216
  </Cell>
262
217
  <Cell>
263
- <div class="flex gap-4">
218
+ <div class="flex gap-2">
264
219
  <div class="relative">
265
220
  {#if ducklake.catalog.resource_type === 'instance'}
266
- <Tooltip wrapperClass="absolute mt-2.5 right-2 z-20" placement="bottom-start">
221
+ <Tooltip wrapperClass="absolute mt-3 right-2 z-20" placement="bottom-start">
267
222
  Use Windmill's PostgreSQL instance as a catalog
268
223
  </Tooltip>
269
224
  {/if}
@@ -271,7 +226,11 @@ export function convertDucklakeSettingsToBackend(settings) {
271
226
  items={[
272
227
  { value: 'postgresql', label: 'PostgreSQL' },
273
228
  { value: 'mysql', label: 'MySQL' },
274
- ...(isWmDbEnabled ? [{ value: 'instance', label: 'Instance' }] : [])
229
+ {
230
+ value: 'instance',
231
+ label: 'Instance',
232
+ subtitle: isInstanceCatalogEnabled ? undefined : 'Superadmin only'
233
+ }
275
234
  ]}
276
235
  bind:value={
277
236
  () => ducklake.catalog.resource_type,
@@ -286,7 +245,7 @@ export function convertDucklakeSettingsToBackend(settings) {
286
245
  class="w-28"
287
246
  />
288
247
  </div>
289
- <div class="flex items-center gap-1 w-80">
248
+ <div class="flex items-center gap-1 w-80 relative">
290
249
  {#if ducklake.catalog.resource_type !== 'instance'}
291
250
  <ResourcePicker
292
251
  bind:value={ducklake.catalog.resource_path}
@@ -295,16 +254,51 @@ export function convertDucklakeSettingsToBackend(settings) {
295
254
  class="min-h-9"
296
255
  />
297
256
  {:else}
298
- <TextInput
257
+ {@const status =
258
+ instanceCatalogStatuses.value?.[ducklake.catalog.resource_path ?? '']}
259
+ <Select
260
+ class="flex-1"
261
+ inputClass="pr-20"
299
262
  bind:value={ducklake.catalog.resource_path}
300
- inputProps={{ placeholder: 'PostgreSQL database name' }}
263
+ onCreateItem={(i) => (ducklake.catalog.resource_path = i)}
264
+ placeholder="PostgreSQL database name"
265
+ items={safeSelectItems(Object.keys(instanceCatalogStatuses.value ?? {}))}
266
+ disabled={!isInstanceCatalogEnabled}
301
267
  />
268
+
269
+ <Popover
270
+ class="absolute right-1.5"
271
+ enableFlyTransition
272
+ contentClasses="py-5 px-6 w-[34rem] bg-surface-secondary -translate-y-2"
273
+ closeOnOtherPopoverOpen
274
+ closeOnOutsideClick
275
+ bind:this={instanceCatalogPopover}
276
+ >
277
+ <svelte:fragment slot="trigger">
278
+ <Button spacingSize="xs2" variant="border" color="light" btnClasses="h-6">
279
+ {#if !status}
280
+ <span class="text-yellow-600 dark:text-yellow-400">
281
+ Setup <ArrowRight class="inline" size={14} />
282
+ </span>
283
+ {:else if !status.success}
284
+ <span class="text-red-400 flex gap-1">
285
+ Error <TriangleAlert class="inline" size={16} />
286
+ </span>
287
+ {:else}
288
+ <div class="w-1.5 h-1.5 rounded-full bg-green-400"></div>
289
+ {/if}
290
+ </Button>
291
+ </svelte:fragment>
292
+ <svelte:fragment slot="content">
293
+ {@render instanceCatalogWizard(status, ducklake.catalog.resource_path ?? '')}
294
+ </svelte:fragment>
295
+ </Popover>
302
296
  {/if}
303
297
  </div>
304
298
  </div>
305
299
  </Cell>
306
300
  <Cell>
307
- <div class="flex gap-4">
301
+ <div class="flex gap-2">
308
302
  <Select
309
303
  placeholder="Default storage"
310
304
  items={[
@@ -346,6 +340,7 @@ export function convertDucklakeSettingsToBackend(settings) {
346
340
  </Popover>
347
341
  {:else}
348
342
  <ExploreAssetButton
343
+ class="h-9"
349
344
  asset={{ kind: 'ducklake', path: ducklake.name }}
350
345
  {dbManagerDrawer}
351
346
  />
@@ -368,7 +363,7 @@ export function convertDucklakeSettingsToBackend(settings) {
368
363
  </tbody>
369
364
  </DataTable>
370
365
  <Button
371
- wrapperClasses="mt-4 mb-44 max-w-fit"
366
+ wrapperClasses="mt-4 mb-16 max-w-fit"
372
367
  on:click={onSave}
373
368
  disabled={ducklakeSavedSettings.ducklakes.length === ducklakeSettings.ducklakes.length &&
374
369
  Object.values(ducklakeIsDirty).every((v) => v === false)}
@@ -378,3 +373,142 @@ export function convertDucklakeSettingsToBackend(settings) {
378
373
  <DbManagerDrawer bind:this={dbManagerDrawer} />
379
374
 
380
375
  <ConfirmationModal {...confirmationModal.props} />
376
+
377
+ {#snippet instanceCatalogWizard(
378
+ status: DucklakeInstanceCatalogDbStatus | undefined,
379
+ dbname: string
380
+ )}
381
+ {@const showManageCatalogButton =
382
+ status?.logs.created_database === 'OK' || status?.logs.created_database === 'SKIP'}
383
+ {#if !status}
384
+ <div class="mb-4 text-secondary text-sm">
385
+ {dbname} needs to be configured in the Windmill postgres instance
386
+ </div>
387
+ {/if}
388
+
389
+ {#if status?.error}
390
+ <div transition:slide={{ duration: 200 }} class="mb-4">
391
+ <Alert title="Error setting up ducklake instance catalog" type="error">
392
+ {status.error}
393
+ </Alert>
394
+ </div>
395
+ {/if}
396
+
397
+ <LoggedWizardResult
398
+ class="max-h-[24rem] overflow-y-auto"
399
+ steps={firstEmptyStepIsError(
400
+ [
401
+ {
402
+ title: 'Super admin required',
403
+ status: status?.logs.super_admin,
404
+ description:
405
+ 'You need to be a super admin to setup an instance catalog, as it requires creating a new database in the Windmill PostgreSQL instance'
406
+ },
407
+ {
408
+ title: 'Retrieve and parse database credentials',
409
+ status: status?.logs.database_credentials,
410
+ description:
411
+ 'Windmill uses the DATABASE_URL or DATABASE_URL_FILE environment variable to connect to the PostgreSQL instance. Make sure it is correctly set'
412
+ },
413
+ {
414
+ title: 'Catalog name is valid',
415
+ status: status?.logs.valid_dbname,
416
+ description:
417
+ 'The catalog name must be alphanumeric (underscores allowed) and cannot be named the same as the Windmill database (usually "windmill")'
418
+ },
419
+ {
420
+ title:
421
+ 'Create database' +
422
+ (status?.logs.created_database === 'SKIP' ? ' (already exists, skipped)' : ''),
423
+ status: status?.logs.created_database,
424
+ description: `In the Windmill PostgreSQL instance, run: CREATE DATABASE "${dbname}".`
425
+ },
426
+ {
427
+ title: `Connect to the ${dbname} database`,
428
+ status: status?.logs.db_connect,
429
+ description:
430
+ "Connect to the newly created database with the default admin user (the one in DATABASE_URL, usually 'postgres') to run the next commands"
431
+ },
432
+ {
433
+ title: 'Grant permissions to ducklake_user',
434
+ status: status?.logs.grant_permissions,
435
+ description:
436
+ 'Gives ducklake_user the required permissions to use the database as a Ducklake catalog. ducklake_user is already created during a migration and has an auto-generated password stored in global_settings.ducklake_settings.ducklake_user_pg_pwd. These are the commands : \n\n' +
437
+ `GRANT CONNECT ON DATABASE "${dbname}" TO ducklake_user;\n` +
438
+ 'GRANT USAGE ON SCHEMA public TO ducklake_user;\n' +
439
+ 'GRANT CREATE ON SCHEMA public TO ducklake_user;\n' +
440
+ 'ALTER DEFAULT PRIVILEGES IN SCHEMA public \n' +
441
+ ' GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES\n TO ducklake_user;'
442
+ }
443
+ ],
444
+ status?.error ?? undefined
445
+ )}
446
+ />
447
+ {#if showManageCatalogButton}
448
+ <div class="text-tertiary text-xs mt-6">
449
+ Note: the 'Manage catalog' button below is different from the Manage Ducklake button. This
450
+ will show you the content of the PostgreSQL database used as a catalog, while the other button
451
+ shows you the actual content of the ducklake (the parquet files).
452
+ </div>
453
+ {/if}
454
+ <div class="flex gap-2 mt-2">
455
+ <Button
456
+ wrapperClasses="flex-1"
457
+ size="sm"
458
+ disabled={!isInstanceCatalogEnabled}
459
+ onClick={async () => {
460
+ if (instanceCatalogSetupIsRunning) return
461
+
462
+ let wasAlreadySuccessful = status?.success ?? false
463
+ if (status?.logs.created_database != 'OK' && status?.logs.created_database != 'SKIP') {
464
+ instanceCatalogPopover?.close()
465
+ let confirm = await confirmationModal.ask({
466
+ title: 'Confirm setup',
467
+ children: `This will create a new database ${dbname} in the Windmill PostgreSQL instance`,
468
+ confirmationText: 'Setup catalog'
469
+ })
470
+ instanceCatalogPopover?.open()
471
+ if (!confirm) return
472
+ }
473
+
474
+ try {
475
+ instanceCatalogSetupIsRunning = true
476
+ let result = await SettingService.setupDucklakeCatalogDb({ name: dbname })
477
+ await instanceCatalogStatuses.refresh()
478
+ if (result.success) {
479
+ if (!wasAlreadySuccessful) sendUserToast('Setup successful')
480
+ else sendUserToast('Everything OK')
481
+ } else {
482
+ sendUserToast(result.error ?? 'An error occured', true)
483
+ }
484
+ } catch (e) {
485
+ sendUserToast('Unexpected error, check console for details', true)
486
+ console.error('Error setting up ducklake instance catalog', e)
487
+ } finally {
488
+ instanceCatalogSetupIsRunning = false
489
+ }
490
+ }}
491
+ loading={instanceCatalogSetupIsRunning}
492
+ >
493
+ {#if !isInstanceCatalogEnabled}
494
+ Only superadmins can setup instance catalogs
495
+ {:else if status?.success}
496
+ Check again
497
+ {:else if status?.error}
498
+ Try again
499
+ {:else}
500
+ Setup {dbname}
501
+ {/if}
502
+ </Button>
503
+ {#if showManageCatalogButton}
504
+ <ExploreAssetButton
505
+ class="flex-1"
506
+ asset={{ kind: 'resource', path: 'INSTANCE_DUCKLAKE_CATALOG/' + dbname }}
507
+ _resourceMetadata={{ resource_type: 'postgresql' }}
508
+ {dbManagerDrawer}
509
+ disabled={!isInstanceCatalogEnabled}
510
+ onClick={() => instanceCatalogPopover?.close()}
511
+ />
512
+ {/if}
513
+ </div>
514
+ {/snippet}
@@ -21,7 +21,7 @@ export const OpenAPI = {
21
21
  PASSWORD: undefined,
22
22
  TOKEN: undefined,
23
23
  USERNAME: undefined,
24
- VERSION: '1.554.1',
24
+ VERSION: '1.558.1',
25
25
  WITH_CREDENTIALS: false,
26
26
  interceptors: {
27
27
  request: new Interceptors(),
@@ -426,7 +426,7 @@ export declare const $ForloopFlow: {
426
426
  readonly type: "boolean";
427
427
  };
428
428
  readonly parallelism: {
429
- readonly type: "integer";
429
+ readonly $ref: "#/components/schemas/InputTransform";
430
430
  };
431
431
  };
432
432
  readonly required: readonly ["modules", "iterator", "skip_failures", "type"];
@@ -451,7 +451,7 @@ export declare const $WhileloopFlow: {
451
451
  readonly type: "boolean";
452
452
  };
453
453
  readonly parallelism: {
454
- readonly type: "integer";
454
+ readonly $ref: "#/components/schemas/InputTransform";
455
455
  };
456
456
  };
457
457
  readonly required: readonly ["modules", "skip_failures", "type"];
@@ -826,7 +826,7 @@ export declare const $FlowConversationMessage: {
826
826
  };
827
827
  readonly message_type: {
828
828
  readonly type: "string";
829
- readonly enum: readonly ["user", "assistant", "system"];
829
+ readonly enum: readonly ["user", "assistant", "system", "tool"];
830
830
  readonly description: "Type of the message";
831
831
  };
832
832
  readonly content: {
@@ -844,6 +844,14 @@ export declare const $FlowConversationMessage: {
844
844
  readonly format: "date-time";
845
845
  readonly description: "When the message was created";
846
846
  };
847
+ readonly step_name: {
848
+ readonly type: "string";
849
+ readonly description: "The step name that produced that message";
850
+ };
851
+ readonly success: {
852
+ readonly type: "boolean";
853
+ readonly description: "Whether the message is a success";
854
+ };
847
855
  };
848
856
  };
849
857
  export declare const $EndpointTool: {
@@ -1392,7 +1400,7 @@ export declare const $QueuedJob: {
1392
1400
  };
1393
1401
  readonly job_kind: {
1394
1402
  readonly type: "string";
1395
- readonly enum: readonly ["script", "preview", "dependencies", "flowdependencies", "appdependencies", "flow", "flowpreview", "script_hub", "identity", "deploymentcallback", "singlescriptflow", "flowscript", "flownode", "appscript", "aiagent"];
1403
+ readonly enum: readonly ["script", "preview", "dependencies", "flowdependencies", "appdependencies", "flow", "flowpreview", "script_hub", "identity", "deploymentcallback", "singlestepflow", "flowscript", "flownode", "appscript", "aiagent"];
1396
1404
  };
1397
1405
  readonly schedule_path: {
1398
1406
  readonly type: "string";
@@ -1510,7 +1518,7 @@ export declare const $CompletedJob: {
1510
1518
  };
1511
1519
  readonly job_kind: {
1512
1520
  readonly type: "string";
1513
- readonly enum: readonly ["script", "preview", "dependencies", "flow", "flowdependencies", "appdependencies", "flowpreview", "script_hub", "identity", "deploymentcallback", "singlescriptflow", "flowscript", "flownode", "appscript", "aiagent"];
1521
+ readonly enum: readonly ["script", "preview", "dependencies", "flow", "flowdependencies", "appdependencies", "flowpreview", "script_hub", "identity", "deploymentcallback", "singlestepflow", "flowscript", "flownode", "appscript", "aiagent"];
1514
1522
  };
1515
1523
  readonly schedule_path: {
1516
1524
  readonly type: "string";
@@ -2413,6 +2421,10 @@ export declare const $Schedule: {
2413
2421
  readonly cron_version: {
2414
2422
  readonly type: "string";
2415
2423
  };
2424
+ readonly dynamic_skip: {
2425
+ readonly type: "string";
2426
+ readonly description: "Path to a script that validates scheduled datetimes. Receives scheduled_for datetime and returns boolean.";
2427
+ };
2416
2428
  };
2417
2429
  readonly required: readonly ["path", "edited_by", "edited_at", "schedule", "script_path", "timezone", "extra_perms", "is_flow", "enabled", "email"];
2418
2430
  };
@@ -2547,6 +2559,10 @@ export declare const $NewSchedule: {
2547
2559
  readonly type: "string";
2548
2560
  readonly description: "The version of the cron schedule to use (last is v2)";
2549
2561
  };
2562
+ readonly dynamic_skip: {
2563
+ readonly type: "string";
2564
+ readonly description: "Path to a script that validates scheduled datetimes. Receives scheduled_for datetime and returns boolean.";
2565
+ };
2550
2566
  };
2551
2567
  readonly required: readonly ["path", "schedule", "timezone", "script_path", "is_flow", "args"];
2552
2568
  };
@@ -2634,6 +2650,10 @@ export declare const $EditSchedule: {
2634
2650
  readonly type: "string";
2635
2651
  readonly description: "The version of the cron schedule to use (last is v2)";
2636
2652
  };
2653
+ readonly dynamic_skip: {
2654
+ readonly type: "string";
2655
+ readonly description: "Path to a script that validates scheduled datetimes. Receives scheduled_for datetime and returns boolean.";
2656
+ };
2637
2657
  };
2638
2658
  readonly required: readonly ["schedule", "timezone", "args"];
2639
2659
  };
@@ -3645,6 +3665,54 @@ export declare const $SqsTrigger: {
3645
3665
  };
3646
3666
  readonly required: readonly ["queue_url", "aws_resource_path", "enabled", "aws_auth_resource_type"];
3647
3667
  };
3668
+ export declare const $LoggedWizardStatus: {
3669
+ readonly type: "string";
3670
+ readonly enum: readonly ["OK", "SKIP", "FAIL"];
3671
+ };
3672
+ export declare const $DucklakeInstanceCatalogDbStatusLogs: {
3673
+ readonly type: "object";
3674
+ readonly properties: {
3675
+ readonly super_admin: {
3676
+ readonly $ref: "#/components/schemas/LoggedWizardStatus";
3677
+ };
3678
+ readonly database_credentials: {
3679
+ readonly $ref: "#/components/schemas/LoggedWizardStatus";
3680
+ };
3681
+ readonly valid_dbname: {
3682
+ readonly $ref: "#/components/schemas/LoggedWizardStatus";
3683
+ };
3684
+ readonly created_database: {
3685
+ readonly $ref: "#/components/schemas/LoggedWizardStatus";
3686
+ readonly description: "Created database status log";
3687
+ };
3688
+ readonly db_connect: {
3689
+ readonly $ref: "#/components/schemas/LoggedWizardStatus";
3690
+ };
3691
+ readonly grant_permissions: {
3692
+ readonly $ref: "#/components/schemas/LoggedWizardStatus";
3693
+ };
3694
+ };
3695
+ };
3696
+ export declare const $DucklakeInstanceCatalogDbStatus: {
3697
+ readonly type: "object";
3698
+ readonly required: readonly ["logs", "success"];
3699
+ readonly properties: {
3700
+ readonly logs: {
3701
+ readonly $ref: "#/components/schemas/DucklakeInstanceCatalogDbStatusLogs";
3702
+ };
3703
+ readonly success: {
3704
+ readonly type: "boolean";
3705
+ readonly description: "Whether the operation completed successfully";
3706
+ readonly example: true;
3707
+ };
3708
+ readonly error: {
3709
+ readonly type: "string";
3710
+ readonly nullable: true;
3711
+ readonly description: "Error message if the operation failed";
3712
+ readonly example: "Connection timeout";
3713
+ };
3714
+ };
3715
+ };
3648
3716
  export declare const $NewSqsTrigger: {
3649
3717
  readonly type: "object";
3650
3718
  readonly properties: {