windmill-components 1.695.1 → 1.699.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/dist/sharedUtils/assets/tokens/colorTokensConfig.d.ts +2 -0
- package/dist/sharedUtils/base.d.ts +1 -0
- package/dist/sharedUtils/cloud.d.ts +1 -0
- package/dist/sharedUtils/common.d.ts +111 -0
- package/dist/sharedUtils/components/apps/components/display/dbtable/queries/count.d.ts +5 -0
- package/dist/sharedUtils/components/apps/components/display/dbtable/queries/delete.d.ts +5 -0
- package/dist/sharedUtils/components/apps/components/display/dbtable/queries/insert.d.ts +5 -0
- package/dist/sharedUtils/components/apps/components/display/dbtable/queries/select.d.ts +13 -0
- package/dist/sharedUtils/components/apps/components/display/dbtable/queries/update.d.ts +11 -0
- package/dist/sharedUtils/components/apps/components/display/dbtable/utils.d.ts +95 -0
- package/dist/sharedUtils/components/apps/editor/appPolicy.d.ts +6 -0
- package/dist/sharedUtils/components/apps/editor/appUtilsCore.d.ts +7 -0
- package/dist/sharedUtils/components/apps/editor/appUtilsS3.d.ts +33 -0
- package/dist/sharedUtils/components/apps/editor/commonAppUtils.d.ts +10 -0
- package/dist/sharedUtils/components/apps/editor/component/components.d.ts +5371 -0
- package/dist/sharedUtils/components/apps/editor/component/default-codes.d.ts +3 -0
- package/dist/sharedUtils/components/apps/editor/component/index.d.ts +3 -0
- package/dist/sharedUtils/components/apps/editor/component/sets.d.ts +7 -0
- package/dist/sharedUtils/components/apps/editor/componentsPanel/componentDefaultProps.d.ts +3 -0
- package/dist/sharedUtils/components/apps/gridUtils.d.ts +14 -0
- package/dist/sharedUtils/components/apps/inputType.d.ts +178 -0
- package/dist/sharedUtils/components/apps/rx.d.ts +29 -0
- package/dist/sharedUtils/components/apps/sharedTypes.d.ts +21 -0
- package/dist/sharedUtils/components/apps/types.d.ts +274 -0
- package/dist/sharedUtils/components/assets/lib.d.ts +25 -0
- package/dist/sharedUtils/components/common/alert/model.d.ts +2 -0
- package/dist/sharedUtils/components/common/badge/model.d.ts +8 -0
- package/dist/sharedUtils/components/common/button/model.d.ts +45 -0
- package/dist/sharedUtils/components/common/fileInput/model.d.ts +1 -0
- package/dist/sharedUtils/components/common/index.d.ts +24 -0
- package/dist/sharedUtils/components/common/skeleton/model.d.ts +21 -0
- package/dist/sharedUtils/components/dbTypes.d.ts +14 -0
- package/dist/sharedUtils/components/diff_drawer.d.ts +26 -0
- package/dist/sharedUtils/components/ducklake.d.ts +1 -0
- package/dist/sharedUtils/components/flows/scheduleUtils.d.ts +7 -0
- package/dist/sharedUtils/components/icons/index.d.ts +101 -0
- package/dist/sharedUtils/components/random_positive_adjetive.d.ts +1 -0
- package/dist/sharedUtils/components/raw_apps/rawAppPolicy.d.ts +10 -0
- package/dist/sharedUtils/components/raw_apps/utils.d.ts +15 -0
- package/dist/sharedUtils/components/triggers/email/utils.d.ts +4 -0
- package/dist/sharedUtils/components/triggers/gcp/utils.d.ts +2 -0
- package/dist/sharedUtils/components/triggers/http/utils.d.ts +11 -0
- package/dist/sharedUtils/components/triggers/kafka/utils.d.ts +2 -0
- package/dist/sharedUtils/components/triggers/mqtt/utils.d.ts +2 -0
- package/dist/sharedUtils/components/triggers/nats/utils.d.ts +2 -0
- package/dist/sharedUtils/components/triggers/postgres/utils.d.ts +8 -0
- package/dist/sharedUtils/components/triggers/sqs/utils.d.ts +2 -0
- package/dist/sharedUtils/components/triggers/triggers.svelte.d.ts +32 -0
- package/dist/sharedUtils/components/triggers/utils.d.ts +80 -0
- package/dist/sharedUtils/components/triggers/websocket/utils.d.ts +2 -0
- package/dist/sharedUtils/components/triggers.d.ts +20 -0
- package/dist/sharedUtils/gen/core/ApiError.d.ts +10 -0
- package/dist/sharedUtils/gen/core/ApiRequestOptions.d.ts +13 -0
- package/dist/sharedUtils/gen/core/ApiResult.d.ts +7 -0
- package/dist/sharedUtils/gen/core/CancelablePromise.d.ts +26 -0
- package/dist/sharedUtils/gen/core/OpenAPI.d.ts +27 -0
- package/dist/sharedUtils/gen/core/request.d.ts +29 -0
- package/dist/sharedUtils/gen/index.d.ts +6 -0
- package/dist/sharedUtils/gen/schemas.gen.d.ts +7036 -0
- package/dist/sharedUtils/gen/services.gen.d.ts +6047 -0
- package/dist/sharedUtils/gen/types.gen.d.ts +21881 -0
- package/dist/sharedUtils/history.svelte.d.ts +9 -0
- package/dist/sharedUtils/hub.d.ts +49 -0
- package/dist/sharedUtils/jsr.json +6 -0
- package/dist/sharedUtils/lib.d.ts +5 -0
- package/dist/sharedUtils/lib.es.js +1588 -0
- package/dist/sharedUtils/package.json +12 -0
- package/dist/sharedUtils/schema.d.ts +3 -0
- package/dist/sharedUtils/stores.d.ts +97 -0
- package/dist/sharedUtils/svelte5Utils.svelte.d.ts +80 -0
- package/dist/sharedUtils/toast.d.ts +8 -0
- package/dist/sharedUtils/utils.d.ts +265 -0
- package/package/components/AppConnectInner.svelte +38 -5
- package/package/components/CompareWorkspaces.svelte +142 -486
- package/package/components/DisplayResult.svelte +39 -19
- package/package/components/Editor.svelte +5 -4
- package/package/components/Editor.svelte.d.ts +1 -0
- package/package/components/FilterSearchbar.svelte +3 -1
- package/package/components/FilterSearchbar.svelte.d.ts +1 -0
- package/package/components/FlowStatusViewerInner.svelte +23 -9
- package/package/components/ForkWorkspaceBanner.svelte +16 -0
- package/package/components/HistoricInputs.svelte +2 -1
- package/package/components/InstanceSetting.svelte +47 -5
- package/package/components/LogViewer.svelte +101 -71
- package/package/components/OnBehalfOfSelector.svelte +10 -7
- package/package/components/ParqetCsvTableRenderer.svelte +9 -4
- package/package/components/Path.svelte +10 -0
- package/package/components/ResourceEditor.svelte +198 -311
- package/package/components/ResourceEditor.svelte.d.ts +3 -3
- package/package/components/ResourceEditorDrawer.svelte +17 -6
- package/package/components/ResourceForm.svelte +235 -0
- package/package/components/ResourceForm.svelte.d.ts +25 -0
- package/package/components/RunsPage.svelte +1 -0
- package/package/components/S3FilePickerInner.svelte +22 -8
- package/package/components/ScriptBuilder.svelte +1 -0
- package/package/components/ScriptEditor.svelte +44 -7
- package/package/components/ScriptEditor.svelte.d.ts +1 -0
- package/package/components/ShareModal.svelte.d.ts +1 -1
- package/package/components/TaggedTextInput.svelte +4 -1
- package/package/components/TaggedTextInput.svelte.d.ts +2 -0
- package/package/components/VariableEditor.svelte +177 -199
- package/package/components/VariableEditor.svelte.d.ts +1 -2
- package/package/components/VariableForm.svelte +133 -0
- package/package/components/VariableForm.svelte.d.ts +22 -0
- package/package/components/WsSpecificVersions.svelte +39 -0
- package/package/components/WsSpecificVersions.svelte.d.ts +9 -0
- package/package/components/apps/editor/AppEditorHeaderDeploy.svelte.d.ts +1 -1
- package/package/components/common/fileDownload/FileDownload.svelte +16 -6
- package/package/components/common/table/AppRow.svelte +2 -1
- package/package/components/common/table/AppRow.svelte.d.ts +1 -0
- package/package/components/common/table/FlowRow.svelte +2 -1
- package/package/components/common/table/FlowRow.svelte.d.ts +1 -0
- package/package/components/common/table/RawAppRow.svelte +2 -1
- package/package/components/common/table/RawAppRow.svelte.d.ts +1 -0
- package/package/components/common/table/Row.svelte +11 -3
- package/package/components/common/table/Row.svelte.d.ts +2 -1
- package/package/components/common/table/RowIcon.svelte +18 -2
- package/package/components/common/table/RowIcon.svelte.d.ts +1 -1
- package/package/components/common/table/ScriptRow.svelte +2 -1
- package/package/components/common/table/ScriptRow.svelte.d.ts +1 -0
- package/package/components/copilot/autocomplete/Autocompletor.d.ts +3 -1
- package/package/components/copilot/autocomplete/Autocompletor.js +5 -2
- package/package/components/copilot/autocomplete/request.d.ts +1 -0
- package/package/components/copilot/autocomplete/request.js +1 -1
- package/package/components/copilot/chat/AIChatManager.svelte.js +14 -4
- package/package/components/copilot/chat/AiChatLayout.svelte +2 -0
- package/package/components/copilot/chat/ContextManager.svelte.d.ts +1 -0
- package/package/components/copilot/chat/CreatedResourceActionDrawers.svelte +129 -0
- package/package/components/copilot/chat/CreatedResourceActionDrawers.svelte.d.ts +4 -0
- package/package/components/copilot/chat/ToolExecutionDisplay.svelte +14 -6
- package/package/components/copilot/chat/ToolMessageActions.svelte +73 -0
- package/package/components/copilot/chat/ToolMessageActions.svelte.d.ts +7 -0
- package/package/components/copilot/chat/createdResourceActions.svelte.d.ts +6 -0
- package/package/components/copilot/chat/createdResourceActions.svelte.js +29 -0
- package/package/components/copilot/chat/script/core.d.ts +6 -2
- package/package/components/copilot/chat/script/core.js +13 -7
- package/package/components/copilot/chat/script/wacPrompt.test.d.ts +1 -0
- package/package/components/copilot/chat/script/wacPrompt.test.js +25 -0
- package/package/components/copilot/chat/shared.d.ts +12 -0
- package/package/components/copilot/chat/shared.test.js +23 -2
- package/package/components/copilot/chat/workspaceTools.js +34 -4
- package/package/components/flows/content/ScriptEditorDrawer.svelte +1 -0
- package/package/components/flows/idUtils.js +4 -1
- package/package/components/flows/stepsInputArgs.svelte.js +6 -1
- package/package/components/graph/wacToFlow.js +1 -1
- package/package/components/graph/wacToFlow.test.d.ts +1 -0
- package/package/components/graph/wacToFlow.test.js +17 -0
- package/package/components/home/Item.svelte +5 -1
- package/package/components/home/Item.svelte.d.ts +1 -0
- package/package/components/home/ItemsList.svelte +260 -3
- package/package/components/instanceSettings/SecretBackendConfig.svelte +492 -98
- package/package/components/propertyPicker/ObjectViewer.svelte +10 -4
- package/package/components/runs/runsFilter.d.ts +1 -1
- package/package/components/runs/useJobsLoader.svelte.d.ts +1 -0
- package/package/components/runs/useJobsLoader.svelte.js +8 -12
- package/package/components/scriptEditor/LogPanel.svelte +4 -1
- package/package/components/scriptEditor/LogPanel.svelte.d.ts +1 -0
- package/package/components/settings/WorkspaceOperatorSettings.svelte +1 -1
- package/package/components/sidebar/SidebarContent.svelte +40 -2
- package/package/components/sidebar/WorkspaceMenu.svelte +19 -5
- package/package/externalDomain.d.ts +2 -0
- package/package/externalDomain.js +16 -0
- package/package/gen/core/OpenAPI.js +1 -1
- package/package/gen/schemas.gen.d.ts +33 -4
- package/package/gen/schemas.gen.js +33 -4
- package/package/gen/services.gen.d.ts +20 -1
- package/package/gen/services.gen.js +40 -0
- package/package/gen/types.gen.d.ts +70 -3
- package/package/hubPaths.json +2 -2
- package/package/system_prompts/index.d.ts +1 -1
- package/package/system_prompts/index.js +22 -3
- package/package/system_prompts/prompts.d.ts +2 -2
- package/package/system_prompts/prompts.js +7 -4
- package/package/utils/downloadFile.d.ts +11 -0
- package/package/utils/downloadFile.js +48 -0
- package/package/utils_deployable.d.ts +162 -638
- package/package/utils_deployable.js +75 -143
- package/package/utils_workspace_deploy.d.ts +10 -4
- package/package/utils_workspace_deploy.js +167 -42
- package/package.json +7 -3
|
@@ -3,6 +3,7 @@ import { Highlight } from 'svelte-highlight';
|
|
|
3
3
|
import { json } from 'svelte-highlight/languages';
|
|
4
4
|
import { copyToClipboard, parseS3Object, roughSizeOfObject } from '../utils';
|
|
5
5
|
import { base } from '../base';
|
|
6
|
+
import { downloadViaClient, shouldDownloadViaClient } from '../utils/downloadFile';
|
|
6
7
|
import { Button, Drawer, DrawerContent } from './common';
|
|
7
8
|
import { ClipboardCopy, Download, PanelRightOpen, Table2, Braces, Highlighter, ArrowDownFromLine, Loader2 } from 'lucide-svelte';
|
|
8
9
|
import Portal from './Portal.svelte';
|
|
@@ -72,6 +73,21 @@ function isTableRowObjectInner(json, hasHeaders) {
|
|
|
72
73
|
}));
|
|
73
74
|
}
|
|
74
75
|
let largeObject = $state(undefined);
|
|
76
|
+
let resultApiPath = $derived(workspaceId && jobId
|
|
77
|
+
? nodeId
|
|
78
|
+
? `/w/${workspaceId}/jobs/result_by_id/${jobId}/${nodeId}`
|
|
79
|
+
: `/w/${workspaceId}/jobs_u/completed/get_result/${jobId}`
|
|
80
|
+
: undefined);
|
|
81
|
+
let resultDownloadHref = $derived(resultApiPath
|
|
82
|
+
? `${base}/api${resultApiPath}`
|
|
83
|
+
: `data:text/json;charset=utf-8,${encodeURIComponent(toJsonStr(result))}`);
|
|
84
|
+
let resultDownloadName = $derived(`${filename ?? 'result'}.json`);
|
|
85
|
+
async function onResultDownload(e) {
|
|
86
|
+
if (!resultApiPath || !shouldDownloadViaClient())
|
|
87
|
+
return;
|
|
88
|
+
e.preventDefault();
|
|
89
|
+
await downloadViaClient(resultApiPath, resultDownloadName);
|
|
90
|
+
}
|
|
75
91
|
function checkIfS3(result, keys) {
|
|
76
92
|
return keys.includes('s3') && typeof result.s3 === 'string';
|
|
77
93
|
}
|
|
@@ -860,12 +876,9 @@ $effect(() => {
|
|
|
860
876
|
{#if largeObject}
|
|
861
877
|
<div class="text-xs text-emphasis"
|
|
862
878
|
><a
|
|
863
|
-
download=
|
|
864
|
-
href={
|
|
865
|
-
|
|
866
|
-
? `${base}/api/w/${workspaceId}/jobs/result_by_id/${jobId}/${nodeId}`
|
|
867
|
-
: `${base}/api/w/${workspaceId}/jobs_u/completed/get_result/${jobId}`
|
|
868
|
-
: `data:text/json;charset=utf-8,${encodeURIComponent(toJsonStr(result))}`}
|
|
879
|
+
download={resultDownloadName}
|
|
880
|
+
href={resultDownloadHref}
|
|
881
|
+
onclick={onResultDownload}
|
|
869
882
|
>
|
|
870
883
|
Download {filename ? '' : 'as JSON'}
|
|
871
884
|
</a>
|
|
@@ -933,19 +946,26 @@ $effect(() => {
|
|
|
933
946
|
<DrawerContent title="Expanded Result" on:close={jsonViewer.closeDrawer}>
|
|
934
947
|
{#snippet actions()}
|
|
935
948
|
{#if customUi?.disableDownload !== true}
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
+
{#if resultApiPath && shouldDownloadViaClient()}
|
|
950
|
+
<Button
|
|
951
|
+
on:click={() => downloadViaClient(resultApiPath!, resultDownloadName)}
|
|
952
|
+
startIcon={{ icon: Download }}
|
|
953
|
+
variant="subtle"
|
|
954
|
+
unifiedSize="md"
|
|
955
|
+
>
|
|
956
|
+
Download
|
|
957
|
+
</Button>
|
|
958
|
+
{:else}
|
|
959
|
+
<Button
|
|
960
|
+
download={resultDownloadName}
|
|
961
|
+
href={resultDownloadHref}
|
|
962
|
+
startIcon={{ icon: Download }}
|
|
963
|
+
variant="subtle"
|
|
964
|
+
unifiedSize="md"
|
|
965
|
+
>
|
|
966
|
+
Download
|
|
967
|
+
</Button>
|
|
968
|
+
{/if}
|
|
949
969
|
{/if}
|
|
950
970
|
<Button
|
|
951
971
|
on:click={() => copyToClipboard(toJsonStr(result))}
|
|
@@ -58,7 +58,7 @@ import { resource, useDebounce, watch } from 'runed';
|
|
|
58
58
|
// import EditorTheme from './EditorTheme.svelte'
|
|
59
59
|
let divEl = $state(null);
|
|
60
60
|
let editor = $state(null);
|
|
61
|
-
let { code = $bindable(), cmdEnterAction = undefined, formatAction = undefined, automaticLayout = true, websocketAlive = $bindable(), shouldBindKey = true, fixedOverflowWidgets = true, path = undefined, yContent = undefined, awareness = undefined, folding = false, args = undefined, useWebsockets = true, small = false, scriptLang, disabled = false, lineNumbersMinChars = 3, files = {}, extraLib = undefined, changeTimeout = 500, loadAsync = false, key = undefined, class: clazz = undefined, moduleId = undefined, enablePreprocessorSnippet = false, rawAppRunnableKey = undefined, preparedAssetsSqlQueries, customTag } = $props();
|
|
61
|
+
let { code = $bindable(), cmdEnterAction = undefined, formatAction = undefined, automaticLayout = true, websocketAlive = $bindable(), shouldBindKey = true, fixedOverflowWidgets = true, path = undefined, yContent = undefined, awareness = undefined, folding = false, args = undefined, useWebsockets = true, small = false, scriptLang, workflowAsCode = false, disabled = false, lineNumbersMinChars = 3, files = {}, extraLib = undefined, changeTimeout = 500, loadAsync = false, key = undefined, class: clazz = undefined, moduleId = undefined, enablePreprocessorSnippet = false, rawAppRunnableKey = undefined, preparedAssetsSqlQueries, customTag } = $props();
|
|
62
62
|
$effect.pre(() => {
|
|
63
63
|
if (websocketAlive == undefined) {
|
|
64
64
|
websocketAlive = {
|
|
@@ -627,11 +627,11 @@ function addChatHandler(editor) {
|
|
|
627
627
|
}
|
|
628
628
|
}
|
|
629
629
|
let autocompletor = $state(undefined);
|
|
630
|
-
function addAutoCompletor(editor, scriptLang) {
|
|
630
|
+
function addAutoCompletor(editor, scriptLang, workflowAsCode) {
|
|
631
631
|
if (autocompletor) {
|
|
632
632
|
autocompletor.dispose();
|
|
633
633
|
}
|
|
634
|
-
autocompletor = new Autocompletor(editor, scriptLang);
|
|
634
|
+
autocompletor = new Autocompletor(editor, scriptLang, { workflowAsCode });
|
|
635
635
|
}
|
|
636
636
|
const outputChannel = {
|
|
637
637
|
name: 'Language Server Client',
|
|
@@ -1543,13 +1543,14 @@ $effect(() => {
|
|
|
1543
1543
|
(!dbSchema || lang !== 'graphql') && untrack(() => disposeGaphqlService());
|
|
1544
1544
|
});
|
|
1545
1545
|
$effect(() => {
|
|
1546
|
+
const currentWorkflowAsCode = workflowAsCode;
|
|
1546
1547
|
$copilotInfo.enabled &&
|
|
1547
1548
|
$codeCompletionSessionEnabled &&
|
|
1548
1549
|
Autocompletor.isProviderModelSupported($copilotInfo.codeCompletionModel) &&
|
|
1549
1550
|
initialized &&
|
|
1550
1551
|
editor &&
|
|
1551
1552
|
scriptLang &&
|
|
1552
|
-
untrack(() => editor && addAutoCompletor(editor, scriptLang));
|
|
1553
|
+
untrack(() => editor && addAutoCompletor(editor, scriptLang, currentWorkflowAsCode));
|
|
1553
1554
|
});
|
|
1554
1555
|
$effect(() => {
|
|
1555
1556
|
$copilotInfo.enabled && initialized && editor && untrack(() => editor && addChatHandler(editor));
|
|
@@ -23,6 +23,7 @@ interface Props {
|
|
|
23
23
|
useWebsockets?: boolean;
|
|
24
24
|
small?: boolean;
|
|
25
25
|
scriptLang: Preview['language'] | 'bunnative' | 'tsx' | 'jsx' | 'json' | undefined;
|
|
26
|
+
workflowAsCode?: boolean;
|
|
26
27
|
disabled?: boolean;
|
|
27
28
|
lineNumbersMinChars?: number;
|
|
28
29
|
files?: Record<string, {
|
|
@@ -185,7 +185,7 @@ import Button from './common/button/Button.svelte';
|
|
|
185
185
|
import Badge from './common/badge/Badge.svelte';
|
|
186
186
|
import InlineCalendarInput, { fromCalendarDate, toCalendarDate } from './common/InlineCalendarInput.svelte';
|
|
187
187
|
import { ButtonType } from './common';
|
|
188
|
-
let { schema, value: valueInput = $bindable(), presets: _presets = [], class: className, placeholder = 'Filter...' } = $props();
|
|
188
|
+
let { schema, value: valueInput = $bindable(), presets: _presets = [], class: className, placeholder = 'Filter...', autofocus } = $props();
|
|
189
189
|
let _value = new DebouncedTempValue(() => clone(valueInput), (v) => !errors.length && (valueInput = clone(v)), (t) => Object.entries(t));
|
|
190
190
|
let value = $derived(_value.current);
|
|
191
191
|
let errors = $derived(validateFilterInstance(schema, value));
|
|
@@ -493,6 +493,8 @@ function appendFilterAsText(presetValue) {
|
|
|
493
493
|
inputSizeClasses.md
|
|
494
494
|
)}
|
|
495
495
|
{placeholder}
|
|
496
|
+
onKeyDown={() => (open = true)}
|
|
497
|
+
{autofocus}
|
|
496
498
|
/>
|
|
497
499
|
{#if asText.val}
|
|
498
500
|
<CloseButton small class="mr-1.5" onClick={() => (_value.current = {})} />
|
|
@@ -81,6 +81,7 @@ type Props<SchemaT extends FilterSchemaRec> = {
|
|
|
81
81
|
}[];
|
|
82
82
|
class?: string;
|
|
83
83
|
placeholder?: string;
|
|
84
|
+
autofocus?: boolean;
|
|
84
85
|
};
|
|
85
86
|
declare const FilterSearchbar: import("svelte").Component<Props<FilterSchemaRec>, {}, "value">;
|
|
86
87
|
type FilterSearchbar = ReturnType<typeof FilterSearchbar>;
|
|
@@ -12,6 +12,7 @@ import Tabs from './common/tabs/Tabs.svelte';
|
|
|
12
12
|
import {} from './graph';
|
|
13
13
|
import ModuleStatus from './ModuleStatus.svelte';
|
|
14
14
|
import { clone, isScriptPreview, msToSec, readFieldsRecursively, truncateRev } from '../utils';
|
|
15
|
+
import { downloadViaClient, shouldDownloadViaClient } from '../utils/downloadFile';
|
|
15
16
|
import JobArgs from './JobArgs.svelte';
|
|
16
17
|
import { ChevronDown, Download, ExternalLink, Hourglass } from 'lucide-svelte';
|
|
17
18
|
import { deepEqual } from 'fast-equals';
|
|
@@ -1481,16 +1482,29 @@ let totalEventsWaiting = $derived(Object.values(suspendStatus?.val ?? {}).reduce
|
|
|
1481
1482
|
style="min-height: {minTabHeight}px"
|
|
1482
1483
|
>
|
|
1483
1484
|
{#if !hideDownloadLogs && !isReplay && job?.id}
|
|
1485
|
+
{@const logsApiPath = `/w/${workspace}/jobs_u/get_flow_all_logs/${job.id}`}
|
|
1486
|
+
{@const logsName = `windmill_flow_logs_${job.id}.txt`}
|
|
1484
1487
|
<div class="flex justify-end p-1">
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1488
|
+
{#if shouldDownloadViaClient()}
|
|
1489
|
+
<Button
|
|
1490
|
+
on:click={() => downloadViaClient(logsApiPath, logsName)}
|
|
1491
|
+
color="light"
|
|
1492
|
+
size="xs"
|
|
1493
|
+
startIcon={{ icon: Download }}
|
|
1494
|
+
>
|
|
1495
|
+
Download all logs
|
|
1496
|
+
</Button>
|
|
1497
|
+
{:else}
|
|
1498
|
+
<Button
|
|
1499
|
+
href="{base}/api{logsApiPath}"
|
|
1500
|
+
download={logsName}
|
|
1501
|
+
color="light"
|
|
1502
|
+
size="xs"
|
|
1503
|
+
startIcon={{ icon: Download }}
|
|
1504
|
+
>
|
|
1505
|
+
Download all logs
|
|
1506
|
+
</Button>
|
|
1507
|
+
{/if}
|
|
1494
1508
|
</div>
|
|
1495
1509
|
{/if}
|
|
1496
1510
|
<FlowLogViewerWrapper
|
|
@@ -213,6 +213,22 @@ function forkAheadBehindMessage(changesAhead, changesBehind) {
|
|
|
213
213
|
: ''}
|
|
214
214
|
</span>
|
|
215
215
|
{/if}
|
|
216
|
+
{#if comparison.summary.schedules_changed > 0}
|
|
217
|
+
<span class="text-blue-700 dark:text-blue-100">
|
|
218
|
+
{comparison.summary.schedules_changed} schedule{comparison.summary
|
|
219
|
+
.schedules_changed !== 1
|
|
220
|
+
? 's'
|
|
221
|
+
: ''}
|
|
222
|
+
</span>
|
|
223
|
+
{/if}
|
|
224
|
+
{#if comparison.summary.triggers_changed > 0}
|
|
225
|
+
<span class="text-blue-700 dark:text-blue-100">
|
|
226
|
+
{comparison.summary.triggers_changed} trigger{comparison.summary
|
|
227
|
+
.triggers_changed !== 1
|
|
228
|
+
? 's'
|
|
229
|
+
: ''}
|
|
230
|
+
</span>
|
|
231
|
+
{/if}
|
|
216
232
|
</div>
|
|
217
233
|
|
|
218
234
|
{#if ciTestTotal > 0}
|
|
@@ -81,7 +81,8 @@ let jobsLoader = useJobsLoader(() => ({
|
|
|
81
81
|
syncQueuedRunsCount: false,
|
|
82
82
|
refreshRate: 10000,
|
|
83
83
|
currentWorkspace: $workspaceStore ?? '',
|
|
84
|
-
skip: !runnableId
|
|
84
|
+
skip: !runnableId,
|
|
85
|
+
excludesEntrypointOverride: true
|
|
85
86
|
}));
|
|
86
87
|
let jobs = $derived(jobsLoader?.jobs ?? []);
|
|
87
88
|
</script>
|
|
@@ -29,6 +29,7 @@ import SettingCard from './instanceSettings/SettingCard.svelte';
|
|
|
29
29
|
let { setting, version, values, loading = true, openSmtpSettings, oauths, warning } = $props();
|
|
30
30
|
const dispatch = createEventDispatcher();
|
|
31
31
|
let latestKeyRenewalAttempt = $state(null);
|
|
32
|
+
let offlineCapStatus = $state(null);
|
|
32
33
|
function showSetting(setting, values) {
|
|
33
34
|
if (setting == 'dev_instance') {
|
|
34
35
|
if (values['license_key'] == undefined) {
|
|
@@ -42,6 +43,14 @@ let opening = $state(false);
|
|
|
42
43
|
async function reloadKeyrenewalAttemptInfo() {
|
|
43
44
|
latestKeyRenewalAttempt = await SettingService.getLatestKeyRenewalAttempt();
|
|
44
45
|
}
|
|
46
|
+
async function reloadLicenseStatus() {
|
|
47
|
+
try {
|
|
48
|
+
offlineCapStatus = (await SettingService.getOfflineLicenseStatus());
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
offlineCapStatus = null;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
45
54
|
async function reloadLicenseKey() {
|
|
46
55
|
$values['license_key'] = await SettingService.getGlobal({
|
|
47
56
|
key: 'license_key'
|
|
@@ -49,7 +58,10 @@ async function reloadLicenseKey() {
|
|
|
49
58
|
}
|
|
50
59
|
$effect(() => {
|
|
51
60
|
if (setting.key == 'license_key') {
|
|
52
|
-
untrack(() =>
|
|
61
|
+
untrack(() => {
|
|
62
|
+
reloadKeyrenewalAttemptInfo();
|
|
63
|
+
reloadLicenseStatus();
|
|
64
|
+
});
|
|
53
65
|
}
|
|
54
66
|
});
|
|
55
67
|
export async function renewLicenseKey() {
|
|
@@ -393,7 +405,7 @@ $effect(() => {
|
|
|
393
405
|
</div>
|
|
394
406
|
{/if}
|
|
395
407
|
{/if}
|
|
396
|
-
{#if latestKeyRenewalAttempt}
|
|
408
|
+
{#if latestKeyRenewalAttempt && !offlineCapStatus}
|
|
397
409
|
{@const attemptedAt = new Date(latestKeyRenewalAttempt.attempted_at).toLocaleString()}
|
|
398
410
|
{@const isTrial = latestKeyRenewalAttempt.result.startsWith('error: trial:')}
|
|
399
411
|
<div class="relative">
|
|
@@ -463,11 +475,41 @@ $effect(() => {
|
|
|
463
475
|
</div>
|
|
464
476
|
{/if}
|
|
465
477
|
|
|
478
|
+
{#if offlineCapStatus}
|
|
479
|
+
{@const cap = offlineCapStatus}
|
|
480
|
+
{@const seatsOver = cap.seats_used > cap.seats_cap}
|
|
481
|
+
{@const cuOver = cap.cu_over_cap}
|
|
482
|
+
<div class="mt-1 flex flex-row items-center gap-2 text-xs">
|
|
483
|
+
<div class="flex flex-row items-center gap-1">
|
|
484
|
+
{#if seatsOver}
|
|
485
|
+
<BadgeX class="text-red-600" size={12} />
|
|
486
|
+
{:else}
|
|
487
|
+
<BadgeCheck class="text-green-600" size={12} />
|
|
488
|
+
{/if}
|
|
489
|
+
<span class={seatsOver ? 'text-red-600' : 'text-green-600'}>
|
|
490
|
+
Seats: {cap.seats_used.toFixed(1)} / {cap.seats_cap}
|
|
491
|
+
</span>
|
|
492
|
+
</div>
|
|
493
|
+
<div class="flex flex-row items-center gap-1">
|
|
494
|
+
{#if cuOver}
|
|
495
|
+
<BadgeX class="text-red-600" size={12} />
|
|
496
|
+
{:else}
|
|
497
|
+
<BadgeCheck class="text-green-600" size={12} />
|
|
498
|
+
{/if}
|
|
499
|
+
<span class={cuOver ? 'text-red-600' : 'text-green-600'}>
|
|
500
|
+
CUs: {cap.current_cu.toFixed(2)} / {cap.cu_cap.toFixed(2)}
|
|
501
|
+
</span>
|
|
502
|
+
</div>
|
|
503
|
+
</div>
|
|
504
|
+
{/if}
|
|
505
|
+
|
|
466
506
|
{#if valid || expiration}
|
|
467
507
|
<div class="flex flex-row gap-2 mt-1">
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
508
|
+
{#if !offlineCapStatus}
|
|
509
|
+
<Button on:click={renewLicenseKey} loading={renewing} size="xs" variant="accent"
|
|
510
|
+
>Renew key
|
|
511
|
+
</Button>
|
|
512
|
+
{/if}
|
|
471
513
|
<Button variant="accent" size="xs" loading={opening} on:click={openCustomerPortal}>
|
|
472
514
|
Open customer portal
|
|
473
515
|
</Button>
|
|
@@ -8,10 +8,12 @@ const s3LogPrefixes = [
|
|
|
8
8
|
const S3_LOG_SEARCH_LIMIT = 2000;
|
|
9
9
|
</script>
|
|
10
10
|
|
|
11
|
-
<script lang="ts">import { ClipboardCopy, Download, Expand, Loader2 } from 'lucide-svelte';
|
|
11
|
+
<script lang="ts">import { ClipboardCopy, Download, Expand, Loader2, Timer, Cpu } from 'lucide-svelte';
|
|
12
12
|
import { Button, Drawer, DrawerContent } from './common';
|
|
13
13
|
import { copyToClipboard } from '../utils';
|
|
14
14
|
import { base } from '../base';
|
|
15
|
+
import { withExternalDomain } from '../externalDomain';
|
|
16
|
+
import { downloadViaClient, shouldDownloadViaClient } from '../utils/downloadFile';
|
|
15
17
|
import { workspaceStore } from '../stores';
|
|
16
18
|
import { AnsiUp } from 'ansi_up';
|
|
17
19
|
import NoWorkerWithTagWarning from './runs/NoWorkerWithTagWarning.svelte';
|
|
@@ -24,7 +26,7 @@ let { content, isLoading, duration = undefined, mem = undefined, wrapperClass =
|
|
|
24
26
|
const ansi_up = $state(new AnsiUp());
|
|
25
27
|
ansi_up.use_classes = true;
|
|
26
28
|
let scroll = $state(true);
|
|
27
|
-
let
|
|
29
|
+
let preEl = $state(null);
|
|
28
30
|
// let downloadStartUrl: string | undefined = undefined
|
|
29
31
|
let LOG_INC = 10000;
|
|
30
32
|
let LOG_LIMIT = $state(LOG_INC);
|
|
@@ -95,8 +97,7 @@ function truncateContent(jobContent, loadedFromObjectStore, limit) {
|
|
|
95
97
|
return content;
|
|
96
98
|
}
|
|
97
99
|
export function scrollToBottom() {
|
|
98
|
-
|
|
99
|
-
scroll && setTimeout(() => div?.scroll({ top: div?.scrollHeight, behavior: 'smooth' }), 100);
|
|
100
|
+
scroll && setTimeout(() => preEl?.scroll({ top: preEl?.scrollHeight, behavior: 'smooth' }), 100);
|
|
100
101
|
}
|
|
101
102
|
let logViewer = $state();
|
|
102
103
|
async function getStoreLogs() {
|
|
@@ -132,6 +133,15 @@ $effect.pre(() => {
|
|
|
132
133
|
scroll = true;
|
|
133
134
|
}
|
|
134
135
|
});
|
|
136
|
+
let logsApiPath = $derived(`/w/${$workspaceStore}/jobs_u/get_logs/${jobId}`);
|
|
137
|
+
let downloadHref = $derived(withExternalDomain(`${base}/api${logsApiPath}`));
|
|
138
|
+
let downloadName = $derived(`windmill_logs_${jobId}.txt`);
|
|
139
|
+
async function onDownloadClick(e) {
|
|
140
|
+
if (!shouldDownloadViaClient())
|
|
141
|
+
return;
|
|
142
|
+
e.preventDefault();
|
|
143
|
+
await downloadViaClient(logsApiPath, downloadName);
|
|
144
|
+
}
|
|
135
145
|
let truncatedContent = $derived(truncateContent(content, loadedFromObjectStore, LOG_LIMIT));
|
|
136
146
|
let prefixInfo = $derived(findPrefixInfo(truncatedContent));
|
|
137
147
|
let downloadStartUrl = $derived(findStartUrl(truncatedContent, prefixInfo));
|
|
@@ -169,17 +179,30 @@ let html = $derived.by(() => {
|
|
|
169
179
|
<DrawerContent title="Expanded Logs" on:close={logViewer.closeDrawer}>
|
|
170
180
|
{#snippet actions()}
|
|
171
181
|
{#if jobId && download}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
182
|
+
{#if shouldDownloadViaClient()}
|
|
183
|
+
<Button
|
|
184
|
+
on:click={() => downloadViaClient(logsApiPath, downloadName)}
|
|
185
|
+
color="light"
|
|
186
|
+
size="xs"
|
|
187
|
+
startIcon={{
|
|
188
|
+
icon: Download
|
|
189
|
+
}}
|
|
190
|
+
>
|
|
191
|
+
Download
|
|
192
|
+
</Button>
|
|
193
|
+
{:else}
|
|
194
|
+
<Button
|
|
195
|
+
href={downloadHref}
|
|
196
|
+
download={downloadName}
|
|
197
|
+
color="light"
|
|
198
|
+
size="xs"
|
|
199
|
+
startIcon={{
|
|
200
|
+
icon: Download
|
|
201
|
+
}}
|
|
202
|
+
>
|
|
203
|
+
Download
|
|
204
|
+
</Button>
|
|
205
|
+
{/if}
|
|
183
206
|
{/if}
|
|
184
207
|
|
|
185
208
|
<Button
|
|
@@ -199,12 +222,12 @@ let html = $derived.by(() => {
|
|
|
199
222
|
>{#if content}{@const len =
|
|
200
223
|
(content?.length ?? 0) +
|
|
201
224
|
(loadedFromObjectStore?.length ?? 0)}{#if splitHtml}{@html splitHtml.before}<button
|
|
202
|
-
onclick={getStoreLogs}
|
|
203
|
-
>Show more... <Tooltip>{tooltipText(prefixInfo)}</Tooltip></button
|
|
204
|
-
>{@html splitHtml.after}{:else if downloadStartUrl}<button
|
|
205
225
|
onclick={getStoreLogs}
|
|
206
226
|
>Show more... <Tooltip>{tooltipText(prefixInfo)}</Tooltip></button
|
|
207
|
-
|
|
227
|
+
>{@html splitHtml.after}{:else if downloadStartUrl}<button onclick={getStoreLogs}
|
|
228
|
+
>Show more... <Tooltip>{tooltipText(prefixInfo)}</Tooltip></button
|
|
229
|
+
><br
|
|
230
|
+
/>{@html html}{:else if len > LOG_LIMIT}(truncated to the last {LOG_LIMIT} characters)...<br
|
|
208
231
|
/><button onclick={() => showMoreTruncate(len)}>Show more..</button><br
|
|
209
232
|
/>{@html html}{:else}{@html html}{/if}{:else if isLoading}Waiting for job to start...{:else}No logs are available yet{/if}</pre
|
|
210
233
|
>
|
|
@@ -215,19 +238,58 @@ let html = $derived.by(() => {
|
|
|
215
238
|
<div class="w-full h-full {wrapperClass}">
|
|
216
239
|
<div class="w-full h-full relative">
|
|
217
240
|
<div
|
|
218
|
-
|
|
219
|
-
class="w-full h-full overflow-auto bg-surface-secondary pt-4 {noMaxH ? '' : 'max-h-screen'}"
|
|
241
|
+
class="w-full h-full bg-surface-secondary flex flex-col {noMaxH ? '' : 'max-h-screen'}"
|
|
220
242
|
data-nav-id={navigationId}
|
|
221
243
|
>
|
|
222
|
-
<div
|
|
223
|
-
|
|
244
|
+
<div
|
|
245
|
+
class="flex gap-2 ml-2 {small ? 'py-1' : 'py-2'} border-b overflow-x-auto overflow-y-hidden"
|
|
246
|
+
>
|
|
247
|
+
{#if isLoading}
|
|
248
|
+
<div class="flex gap-2 items-center">
|
|
249
|
+
<Loader2 class="animate-spin" />
|
|
250
|
+
{#if tag}
|
|
251
|
+
<div class="flex flex-row items-center gap-1">
|
|
252
|
+
<div class="text-secondary text-2xs">{tagLabel ?? 'tag'}: {tag}</div>
|
|
253
|
+
<NoWorkerWithTagWarning {tagLabel} {tag} />
|
|
254
|
+
</div>
|
|
255
|
+
{/if}
|
|
256
|
+
{#if jobId}
|
|
257
|
+
<QueuePosition {jobId} />
|
|
258
|
+
{/if}
|
|
259
|
+
</div>
|
|
260
|
+
{:else if duration}
|
|
261
|
+
<span
|
|
262
|
+
class={twMerge(
|
|
263
|
+
'flex items-center gap-1 text-secondary dark:text-gray-400',
|
|
264
|
+
small ? '!text-2xs' : '!text-xs'
|
|
265
|
+
)}
|
|
266
|
+
title="Duration"
|
|
267
|
+
>
|
|
268
|
+
<Timer size={small ? 10 : 12} />
|
|
269
|
+
{duration}ms
|
|
270
|
+
</span>
|
|
271
|
+
{/if}
|
|
272
|
+
{#if mem}
|
|
273
|
+
<span
|
|
274
|
+
class={twMerge(
|
|
275
|
+
'flex items-center gap-1 text-secondary dark:text-gray-400',
|
|
276
|
+
small ? '!text-2xs' : '!text-xs'
|
|
277
|
+
)}
|
|
278
|
+
title="Memory peak"
|
|
279
|
+
>
|
|
280
|
+
<Cpu size={small ? 10 : 12} />
|
|
281
|
+
{(mem / 1024).toPrecision(4)}MB
|
|
282
|
+
</span>
|
|
283
|
+
{/if}
|
|
284
|
+
<div class="flex gap-2 justify-end flex-1">
|
|
224
285
|
{#if jobId && download}
|
|
225
286
|
<div class="flex items-center">
|
|
226
287
|
<a
|
|
227
288
|
class="text-primary pb-0.5"
|
|
228
289
|
target="_blank"
|
|
229
|
-
href=
|
|
230
|
-
download=
|
|
290
|
+
href={downloadHref}
|
|
291
|
+
download={downloadName}
|
|
292
|
+
onclick={onDownloadClick}
|
|
231
293
|
><Download size="14" />
|
|
232
294
|
</a>
|
|
233
295
|
</div>
|
|
@@ -235,66 +297,34 @@ let html = $derived.by(() => {
|
|
|
235
297
|
<button onclick={logViewer.openDrawer}><Expand size="12" /></button>
|
|
236
298
|
{#if !noAutoScroll}
|
|
237
299
|
<label
|
|
238
|
-
class="
|
|
239
|
-
? ''
|
|
240
|
-
: 'py-2'} pr-2 text-2xs flex gap-2 font-normal text-primary items-center"
|
|
300
|
+
class="pr-2 text-2xs flex gap-2 font-normal text-primary items-center whitespace-nowrap"
|
|
241
301
|
>
|
|
242
|
-
|
|
302
|
+
auto-scroll
|
|
243
303
|
<input class="windmillapp" type="checkbox" bind:checked={scroll} />
|
|
244
304
|
</label>
|
|
245
305
|
{/if}
|
|
246
306
|
</div>
|
|
247
307
|
</div>
|
|
248
|
-
{#if isLoading}
|
|
249
|
-
<div class="flex gap-2 absolute top-2 left-2 items-center z-10">
|
|
250
|
-
<Loader2 class="animate-spin" />
|
|
251
|
-
{#if tag}
|
|
252
|
-
<div class="flex flex-row items-center gap-1">
|
|
253
|
-
<div class="text-primary text-2xs">{tagLabel ?? 'tag'}: {tag}</div>
|
|
254
|
-
<NoWorkerWithTagWarning {tagLabel} {tag} />
|
|
255
|
-
</div>
|
|
256
|
-
{/if}
|
|
257
|
-
{#if jobId}
|
|
258
|
-
<QueuePosition {jobId} />
|
|
259
|
-
{/if}
|
|
260
|
-
</div>
|
|
261
|
-
{:else if duration}
|
|
262
|
-
<span
|
|
263
|
-
class={twMerge(
|
|
264
|
-
'absolute text-primary dark:text-gray-400',
|
|
265
|
-
small ? '!text-2xs' : '!text-xs',
|
|
266
|
-
small ? 'top-0' : 'top-2',
|
|
267
|
-
noPadding ? '' : 'left-2'
|
|
268
|
-
)}>took {duration}ms</span
|
|
269
|
-
>
|
|
270
|
-
{/if}
|
|
271
|
-
{#if mem}
|
|
272
|
-
<span
|
|
273
|
-
class="absolute {small ? '!text-2xs' : '!text-xs'} text-primary dark:text-gray-400 {small
|
|
274
|
-
? 'top-0'
|
|
275
|
-
: 'top-2'} left-36">mem peak: {(mem / 1024).toPrecision(4)}MB</span
|
|
276
|
-
>
|
|
277
|
-
{/if}
|
|
278
308
|
<pre
|
|
309
|
+
bind:this={preEl}
|
|
279
310
|
class={twMerge(
|
|
280
|
-
'whitespace-pre break-words w-full ',
|
|
311
|
+
'whitespace-pre break-words w-full flex-1 overflow-auto',
|
|
281
312
|
small ? '!text-2xs' : '!text-xs',
|
|
282
313
|
noPadding ? '' : 'p-2'
|
|
283
314
|
)}
|
|
284
315
|
>{#if content}{@const len =
|
|
285
|
-
(content?.length ?? 0) +
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
>{:else if downloadStartUrl}<button
|
|
316
|
+
(content?.length ?? 0) + (loadedFromObjectStore?.length ?? 0)}{#if splitHtml}<span
|
|
317
|
+
>{@html splitHtml.before}</span
|
|
318
|
+
><button onclick={getStoreLogs}
|
|
319
|
+
>Show more... <Tooltip>{tooltipText(prefixInfo)}</Tooltip></button
|
|
320
|
+
><span>{@html splitHtml.after}</span>{:else if downloadStartUrl}<button
|
|
291
321
|
onclick={getStoreLogs}
|
|
292
322
|
>Show more... <Tooltip>{tooltipText(prefixInfo)}</Tooltip></button
|
|
293
|
-
><br /><span>{@html html}</span
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
>{
|
|
323
|
+
><br /><span>{@html html}</span>{:else if len > LOG_LIMIT}<button
|
|
324
|
+
onclick={() => showMoreTruncate(len)}>Show more..</button
|
|
325
|
+
> ({LOG_LIMIT}/{len} chars)<br /><span>{@html html}</span>{:else}<span
|
|
326
|
+
>{@html html}</span
|
|
327
|
+
>{/if}{:else if !isLoading}<span>{customEmptyMessage}</span>{/if}</pre
|
|
298
328
|
>
|
|
299
329
|
</div>
|
|
300
330
|
</div>
|
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
<script lang="ts" module
|
|
1
|
+
<script lang="ts" module>import { isTriggerOrScheduleKind } from 'windmill-utils-internal';
|
|
2
|
+
/**
|
|
2
3
|
* Check if an item needs on_behalf_of selection.
|
|
3
4
|
* Shows the selector when the source item has an on_behalf_of value set.
|
|
4
5
|
*/
|
|
5
6
|
export function needsOnBehalfOfSelection(kind, sourceValue) {
|
|
6
|
-
|
|
7
|
-
kind
|
|
8
|
-
kind
|
|
9
|
-
kind
|
|
10
|
-
kind
|
|
7
|
+
const supported = kind === 'flow' ||
|
|
8
|
+
kind === 'script' ||
|
|
9
|
+
kind === 'app' ||
|
|
10
|
+
kind === 'raw_app' ||
|
|
11
|
+
kind === 'trigger' ||
|
|
12
|
+
isTriggerOrScheduleKind(kind);
|
|
13
|
+
if (!supported)
|
|
11
14
|
return false;
|
|
12
15
|
return !!sourceValue;
|
|
13
16
|
}
|
|
@@ -20,7 +23,7 @@ import { userStore } from '../stores';
|
|
|
20
23
|
import { UserService } from '../gen';
|
|
21
24
|
import TextInput from './text_input/TextInput.svelte';
|
|
22
25
|
let { targetWorkspace, targetValue, selected, onSelect, kind, canPreserve, customValue, isDeployment = true, folderDefault = undefined } = $props();
|
|
23
|
-
const isTrigger = $derived(kind === 'trigger');
|
|
26
|
+
const isTrigger = $derived(kind === 'trigger' || isTriggerOrScheduleKind(kind));
|
|
24
27
|
let label = $derived(isTrigger
|
|
25
28
|
? 'Set the user this will be permissioned as:'
|
|
26
29
|
: 'Set the user this will be run on behalf of:');
|
|
@@ -6,6 +6,7 @@ import { twMerge } from 'tailwind-merge';
|
|
|
6
6
|
import DarkModeObserver from './DarkModeObserver.svelte';
|
|
7
7
|
import { HelpersService } from '../gen';
|
|
8
8
|
import { base } from '../base';
|
|
9
|
+
import { downloadViaClient, shouldDownloadViaClient } from '../utils/downloadFile';
|
|
9
10
|
import { enterpriseLicense, workspaceStore } from '../stores';
|
|
10
11
|
import { Download } from 'lucide-svelte';
|
|
11
12
|
import { Loader2 } from 'lucide-svelte';
|
|
@@ -171,13 +172,17 @@ run(() => {
|
|
|
171
172
|
</div>
|
|
172
173
|
{/if}
|
|
173
174
|
{#if !disable_download && !s3resource.endsWith('.csv')}
|
|
175
|
+
{@const csvApiPath = `/w/${workspaceId}/job_helpers/download_s3_parquet_file_as_csv?file_key=${encodeURIComponent(s3resource)}${storage ? `&storage=${storage}` : ''}`}
|
|
176
|
+
{@const csvName = (s3resource.split('/').pop() ?? 'download') + '.csv'}
|
|
174
177
|
<a
|
|
175
178
|
target="_blank"
|
|
176
|
-
href="{base}/api
|
|
177
|
-
s3resource
|
|
178
|
-
)}{storage ? `&storage=${storage}` : ''}"
|
|
179
|
+
href="{base}/api{csvApiPath}"
|
|
179
180
|
class="text-secondary w-full text-right underline text-2xs whitespace-nowrap"
|
|
180
|
-
|
|
181
|
+
onclick={async (e) => {
|
|
182
|
+
if (!shouldDownloadViaClient()) return
|
|
183
|
+
e.preventDefault()
|
|
184
|
+
await downloadViaClient(csvApiPath, csvName)
|
|
185
|
+
}}><div class="flex flex-row-reverse gap-2 items-center"><Download size={12} /> CSV</div></a
|
|
181
186
|
>
|
|
182
187
|
{/if}
|
|
183
188
|
|