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.
- package/package/components/AppConnectInner.svelte.d.ts +1 -1
- package/package/components/ArgInput.svelte +56 -18
- package/package/components/ArgInput.svelte.d.ts +2 -10
- package/package/components/AssignableTagsInner.svelte +5 -0
- package/package/components/AuthSettings.svelte +4 -2
- package/package/components/AuthSettings.svelte.d.ts +1 -0
- package/package/components/DBManagerDrawer.svelte +154 -151
- package/package/components/DBManagerDrawer.svelte.d.ts +2 -2
- package/package/components/DBTable.svelte +3 -3
- package/package/components/DBTable.svelte.d.ts +1 -0
- package/package/components/DBTableEditor.svelte +7 -7
- package/package/components/DBTableEditor.svelte.d.ts +1 -1
- package/package/components/DeployWorkspace.svelte +1 -1
- package/package/components/DisplayResult.svelte +34 -8
- package/package/components/DisplayResult.svelte.d.ts +4 -1
- package/package/components/DynSelect.svelte +58 -34
- package/package/components/DynSelect.svelte.d.ts +3 -11
- package/package/components/EditableSchemaForm.svelte +126 -6
- package/package/components/EditableSchemaForm.svelte.d.ts +5 -1
- package/package/components/Editor.svelte +1 -1
- package/package/components/EditorBar.svelte +82 -4
- package/package/components/ErrorOrRecoveryHandler.svelte +76 -8
- package/package/components/ErrorOrRecoveryHandler.svelte.d.ts +2 -1
- package/package/components/ExploreAssetButton.svelte +14 -4
- package/package/components/ExploreAssetButton.svelte.d.ts +1 -0
- package/package/components/FlowJobResult.svelte +3 -3
- package/package/components/FlowJobResult.svelte.d.ts +1 -0
- package/package/components/FlowPreviewContent.svelte +9 -0
- package/package/components/FlowPreviewContent.svelte.d.ts +3 -0
- package/package/components/FlowPreviewResult.svelte +4 -1
- package/package/components/FlowPreviewResult.svelte.d.ts +1 -0
- package/package/components/FlowStatusViewer.svelte +2 -1
- package/package/components/FlowStatusViewer.svelte.d.ts +3 -0
- package/package/components/FlowStatusViewerInner.svelte +23 -3
- package/package/components/FlowStatusViewerInner.svelte.d.ts +10 -1
- package/package/components/FolderEditor.svelte +1 -1
- package/package/components/GitDiffPreview.svelte +14 -18
- package/package/components/GitDiffPreview.svelte.d.ts +2 -8
- package/package/components/GitHubAppIntegration.svelte +3 -1
- package/package/components/IdEditorInput.svelte +25 -22
- package/package/components/IdEditorInput.svelte.d.ts +11 -23
- package/package/components/InstanceSetting.svelte +7 -2
- package/package/components/InstanceSettings.svelte +1 -0
- package/package/components/JobLoader.svelte +48 -5
- package/package/components/JobLoader.svelte.d.ts +7 -2
- package/package/components/Login.svelte +8 -2
- package/package/components/MemoryFootprintViewer.svelte +1 -1
- package/package/components/ModulePreviewResultViewer.svelte +2 -2
- package/package/components/MoveDrawer.svelte.d.ts +2 -2
- package/package/components/NextcloudSetting.svelte +84 -0
- package/package/components/NextcloudSetting.svelte.d.ts +7 -0
- package/package/components/ObjectResourceInput.svelte +3 -2
- package/package/components/ObjectResourceInput.svelte.d.ts +1 -0
- package/package/components/ParqetCsvTableRenderer.svelte +1 -1
- package/package/components/ResourceEditor.svelte +1 -1
- package/package/components/ResourcePicker.svelte +8 -1
- package/package/components/ResourcePicker.svelte.d.ts +1 -0
- package/package/components/ResultStreamDisplay.svelte +5 -0
- package/package/components/ResultStreamDisplay.svelte.d.ts +5 -0
- package/package/components/RunForm.svelte +9 -1
- package/package/components/SchemaForm.svelte +2 -2
- package/package/components/SchemaForm.svelte.d.ts +2 -10
- package/package/components/ScriptBuilder.svelte +13 -8
- package/package/components/ScriptBuilder.svelte.d.ts +1 -1
- package/package/components/ScriptEditor.svelte.d.ts +1 -1
- package/package/components/ScriptWrapper.svelte +1 -1
- package/package/components/ShareModal.svelte.d.ts +1 -1
- package/package/components/SimpleAgTable.svelte +2 -0
- package/package/components/SimpleAgTable.svelte.d.ts +2 -0
- package/package/components/SqlRepl.svelte +21 -7
- package/package/components/SqlRepl.svelte.d.ts +2 -2
- package/package/components/StringTypeNarrowing.svelte.d.ts +1 -1
- package/package/components/WorkerTagSelect.svelte +70 -1
- package/package/components/apps/components/display/AppDisplayComponent.svelte +13 -1
- package/package/components/apps/components/display/AppText.svelte +2 -2
- package/package/components/apps/components/display/dbtable/AppDbExplorer.svelte +8 -1
- package/package/components/apps/components/display/dbtable/InsertRow.svelte +5 -4
- package/package/components/apps/components/display/dbtable/queries/count.js +11 -1
- package/package/components/apps/components/display/dbtable/queries/createTable.d.ts +1 -1
- package/package/components/apps/components/display/dbtable/queries/createTable.js +3 -3
- package/package/components/apps/components/display/dbtable/queries/delete.js +7 -0
- package/package/components/apps/components/display/dbtable/queries/insert.js +2 -0
- package/package/components/apps/components/display/dbtable/queries/select.js +14 -0
- package/package/components/apps/components/display/dbtable/queries/update.js +7 -0
- package/package/components/apps/components/display/dbtable/utils.d.ts +6 -5
- package/package/components/apps/components/display/dbtable/utils.js +52 -28
- package/package/components/apps/components/display/table/AppAggridExplorerTable.svelte +1 -1
- package/package/components/apps/components/display/table/AppAggridInfiniteTable.svelte +1 -0
- package/package/components/apps/components/display/table/AppAggridInfiniteTable.svelte.d.ts +1 -0
- package/package/components/apps/components/display/table/AppAggridTable.svelte +5 -4
- package/package/components/apps/components/display/table/AppAggridTable.svelte.d.ts +1 -0
- package/package/components/apps/components/display/table/utils.js +7 -4
- package/package/components/apps/components/helpers/HiddenComponent.svelte +2 -2
- package/package/components/apps/components/helpers/RunnableComponent.svelte +4 -1
- package/package/components/apps/components/helpers/RunnableComponent.svelte.d.ts +2 -1
- package/package/components/apps/components/inputs/AppS3FileInput.svelte +2 -2
- package/package/components/apps/components/layout/AppDecisionTree.svelte +1 -1
- package/package/components/apps/components/layout/AppStepper.svelte +1 -1
- package/package/components/apps/components/layout/AppTabs.svelte +1 -1
- package/package/components/apps/editor/AppEditorHeader.svelte +13 -2
- package/package/components/apps/editor/GridViewer.svelte +1 -0
- package/package/components/apps/editor/RunnableJobPanelInner.svelte +2 -1
- package/package/components/apps/editor/contextPanel/components/IdEditor.svelte +7 -7
- package/package/components/apps/editor/contextPanel/components/IdEditor.svelte.d.ts +7 -19
- package/package/components/apps/editor/contextPanel/components/OutputHeader.svelte +8 -12
- package/package/components/apps/editor/inlineScriptsPanel/InlineScriptEditor.svelte.d.ts +1 -1
- package/package/components/apps/editor/inlineScriptsPanel/InlineScriptEditorDrawer.svelte.d.ts +1 -1
- package/package/components/apps/editor/inlineScriptsPanel/InlineScriptRunnableByPath.svelte.d.ts +1 -1
- package/package/components/apps/editor/settingsPanel/DecisionTreeGraphEditor.svelte +3 -3
- package/package/components/apps/editor/settingsPanel/decisionTree/DecisionTreePreview.svelte +1 -3
- package/package/components/assets/AssetsDropdownButton.svelte +1 -1
- package/package/components/assets/JobAssetsViewer.svelte +2 -2
- package/package/components/assets/lib.js +4 -0
- package/package/components/auditLogs/AuditLogsFilters.svelte +7 -9
- package/package/components/common/button/Button.svelte +4 -3
- package/package/components/common/button/Button.svelte.d.ts +1 -0
- package/package/components/common/confirmationModal/ConfirmationModal.svelte +6 -5
- package/package/components/common/confirmationModal/ConfirmationModal.svelte.d.ts +6 -11
- package/package/components/common/confirmationModal/asyncConfirmationModal.svelte.d.ts +26 -0
- package/package/components/common/confirmationModal/asyncConfirmationModal.svelte.js +50 -0
- package/package/components/common/modal/Modal.svelte +2 -5
- package/package/components/common/tabs/TabsV2.svelte +2 -1
- package/package/components/common/tabs/TabsV2.svelte.d.ts +1 -0
- package/package/components/copilot/chat/AIChatManager.svelte.js +61 -7
- package/package/components/copilot/chat/ContextTextarea.svelte +1 -1
- package/package/components/copilot/chat/script/core.js +28 -29
- package/package/components/copilot/chat/shared.d.ts +1 -1
- package/package/components/copilot/chat/shared.js +8 -2
- package/package/components/custom_ui.d.ts +3 -0
- package/package/components/dbOps.d.ts +20 -8
- package/package/components/dbOps.js +85 -40
- package/package/components/details/DetailPageHeader.svelte +0 -2
- package/package/components/flows/content/FlowInput.svelte +5 -0
- package/package/components/flows/content/FlowModuleComponent.svelte +1 -0
- package/package/components/flows/content/FlowModuleScript.svelte +0 -1
- package/package/components/flows/idUtils.js +2 -1
- package/package/components/flows/map/FlowModuleSchemaItem.svelte +3 -3
- package/package/components/flows/map/FlowModuleSchemaMap.svelte +5 -0
- package/package/components/flows/map/InsertModuleButton.svelte +4 -1
- package/package/components/flows/propPicker/OutputBadge.svelte +5 -1
- package/package/components/flows/propPicker/OutputPickerInner.svelte +9 -5
- package/package/components/flows/propPicker/OutputPickerInner.svelte.d.ts +6 -2
- package/package/components/flows/propPicker/StepHistory.svelte +4 -1
- package/package/components/git_sync/DetectionFlow.svelte +202 -0
- package/package/components/git_sync/DetectionFlow.svelte.d.ts +6 -0
- package/package/components/git_sync/GitSyncContext.svelte.d.ts +82 -0
- package/package/components/git_sync/GitSyncContext.svelte.js +461 -0
- package/package/components/git_sync/GitSyncModalManager.svelte +99 -0
- package/package/components/git_sync/GitSyncModalManager.svelte.d.ts +18 -0
- package/package/components/git_sync/GitSyncRepositoryCard.svelte +339 -0
- package/package/components/git_sync/GitSyncRepositoryCard.svelte.d.ts +6 -0
- package/package/components/git_sync/GitSyncRepositoryList.svelte +17 -0
- package/package/components/git_sync/GitSyncRepositoryList.svelte.d.ts +18 -0
- package/package/components/git_sync/GitSyncSection.svelte +89 -0
- package/package/components/git_sync/GitSyncSection.svelte.d.ts +3 -0
- package/package/components/git_sync/GitSyncSuccessModal.svelte +58 -0
- package/package/components/git_sync/GitSyncSuccessModal.svelte.d.ts +7 -0
- package/package/components/git_sync/PullWorkspaceModal.svelte +575 -0
- package/package/components/git_sync/PullWorkspaceModal.svelte.d.ts +15 -0
- package/package/components/git_sync/PushWorkspaceModal.svelte +320 -0
- package/package/components/git_sync/PushWorkspaceModal.svelte.d.ts +12 -0
- package/package/components/graph/FlowGraphV2.svelte +5 -1
- package/package/components/graph/graphBuilder.svelte.js +1 -1
- package/package/components/graph/renderers/nodes/AssetNode.svelte +4 -4
- package/package/components/icons/AssetDucklakeIcon.svelte +28 -0
- package/package/components/icons/AssetDucklakeIcon.svelte.d.ts +9 -0
- package/package/components/icons/AssetGenericIcon.svelte +3 -0
- package/package/components/icons/DucklakeIcon.svelte +18 -0
- package/package/components/icons/DucklakeIcon.svelte.d.ts +6 -0
- package/package/components/instanceSettings.js +11 -3
- package/package/components/runs/JobPreview.svelte +2 -2
- package/package/components/runs/NoWorkerWithTagWarning.svelte +3 -3
- package/package/components/runs/RunsFilter.svelte.d.ts +1 -1
- package/package/components/schema/FlowPropertyEditor.svelte +3 -2
- package/package/components/schema/FlowPropertyEditor.svelte.d.ts +1 -1
- package/package/components/schema/PropertyEditor.svelte +0 -2
- package/package/components/schema/PropertyEditor.svelte.d.ts +1 -1
- package/package/components/schema/SchemaFormDND.svelte +2 -1
- package/package/components/schema/SchemaFormDND.svelte.d.ts +2 -0
- package/package/components/scriptEditor/LogPanel.svelte +5 -3
- package/package/components/scriptEditor/LogPanel.svelte.d.ts +5 -1
- package/package/components/select/Select.svelte +7 -4
- package/package/components/select/Select.svelte.d.ts +5 -0
- package/package/components/select/SelectDropdown.svelte +2 -1
- package/package/components/select/SelectDropdown.svelte.d.ts +3 -0
- package/package/components/sidebar/changelogs.js +5 -0
- package/package/components/table/AutoDataTable.svelte +6 -4
- package/package/components/table/AutoDataTable.svelte.d.ts +1 -0
- package/package/components/table/DataTable.svelte +12 -10
- package/package/components/table/DataTable.svelte.d.ts +1 -0
- package/package/components/triggers/TriggerRetriesAndErrorHandler.svelte.d.ts +2 -2
- package/package/components/triggers/gcp/GcpTriggerEditorConfigSection.svelte +1 -1
- package/package/components/triggers/gcp/GcpTriggerEditorConfigSection.svelte.d.ts +2 -1
- package/package/components/triggers/gcp/GcpTriggerEditorInner.svelte +50 -11
- package/package/components/triggers/gcp/utils.js +1 -0
- package/package/components/triggers/http/utils.js +1 -1
- package/package/components/triggers/kafka/utils.js +1 -1
- package/package/components/triggers/mqtt/utils.js +1 -1
- package/package/components/triggers/nats/utils.js +1 -1
- package/package/components/triggers/postgres/utils.js +1 -1
- package/package/components/triggers/sqs/utils.js +1 -1
- package/package/components/triggers/utils.js +2 -1
- package/package/components/triggers/webhook/WebhooksConfigSection.svelte +24 -26
- package/package/components/triggers/webhook/WebhooksPanel.svelte +1 -15
- package/package/components/triggers/websocket/utils.js +1 -1
- package/package/components/workspaceSettings/AISettings.svelte +52 -36
- package/package/components/workspaceSettings/DucklakeSettings.svelte +321 -0
- package/package/components/workspaceSettings/DucklakeSettings.svelte.d.ts +23 -0
- package/package/components/workspaceSettings/GitSyncFilterSettings.svelte +122 -499
- package/package/components/workspaceSettings/GitSyncFilterSettings.svelte.d.ts +8 -10
- package/package/consts.js +2 -1
- package/package/gen/core/OpenAPI.js +1 -1
- package/package/gen/schemas.gen.d.ts +33 -24
- package/package/gen/schemas.gen.js +36 -27
- package/package/gen/services.gen.d.ts +19 -1
- package/package/gen/services.gen.js +38 -0
- package/package/gen/types.gen.d.ts +103 -9
- package/package/git-sync.d.ts +36 -0
- package/package/git-sync.js +1 -0
- package/package/hub.d.ts +1 -0
- package/package/hubPaths.json +5 -2
- package/package/infer.js +3 -2
- package/package/script_helpers.d.ts +2 -2
- package/package/script_helpers.js +29 -11
- package/package/services/JobManager.d.ts +28 -0
- package/package/services/JobManager.js +114 -0
- package/package/stores.d.ts +1 -1
- package/package/utils.d.ts +18 -1
- package/package/utils.js +55 -2
- package/package.json +13 -12
- package/package/components/InitGitRepoPopover.svelte +0 -410
- package/package/components/InitGitRepoPopover.svelte.d.ts +0 -13
- package/package/components/PullGitRepoPopover.svelte +0 -355
- package/package/components/PullGitRepoPopover.svelte.d.ts +0 -18
- package/package/inferArgSig.d.ts +0 -35
- 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
|
-
<
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
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
|
-
|
|
135
|
-
|
|
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
|
-
|
|
150
|
-
|
|
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 (
|
|
154
|
-
|
|
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;
|