From 7bb68a5d73e469d54f03bb1c12dced060668b95c Mon Sep 17 00:00:00 2001 From: Ruben Fiszel Date: Mon, 24 Nov 2025 09:37:55 +0100 Subject: [PATCH] fix: listScripts include description with opt-out query arg (#7210) * description jobs * all --- backend/windmill-api/openapi.yaml | 63 ++++++++++------ backend/windmill-api/src/flows.rs | 6 +- backend/windmill-api/src/scripts.rs | 5 ++ backend/windmill-common/src/flows.rs | 4 +- backend/windmill-common/src/scripts.rs | 3 + .../src/lib/components/ScriptPicker.svelte | 10 ++- .../mainInput/WorkspaceFlowList.svelte | 3 +- .../mainInput/WorkspaceScriptList.svelte | 3 +- .../lib/components/copilot/chat/flow/core.ts | 2 +- .../flows/content/FlowInputsFlow.svelte | 38 ++++++---- .../flows/content/FlowInputsFlowQuick.svelte | 73 ------------------- .../pickers/WorkspaceScriptPicker.svelte | 61 ++++++++++------ .../pickers/WorkspaceScriptPickerQuick.svelte | 9 ++- .../src/lib/components/home/ItemsList.svelte | 6 +- .../search/GlobalSearchModal.svelte | 6 +- .../components/settings/CreateToken.svelte | 6 +- .../src/routes/(root)/(logged)/+layout.svelte | 6 +- 17 files changed, 153 insertions(+), 151 deletions(-) delete mode 100644 frontend/src/lib/components/flows/content/FlowInputsFlowQuick.svelte diff --git a/backend/windmill-api/openapi.yaml b/backend/windmill-api/openapi.yaml index ea74c163e0..b1e67ad122 100644 --- a/backend/windmill-api/openapi.yaml +++ b/backend/windmill-api/openapi.yaml @@ -5180,6 +5180,14 @@ paths: Accepts multiple values as a comma-separated list. schema: type: string + - name: without_description + in: query + description: | + (default false) + If true, the description field will be omitted from the response. + schema: + type: boolean + responses: "200": description: All scripts @@ -6463,6 +6471,13 @@ paths: in: query schema: type: boolean + - name: without_description + in: query + description: | + (default false) + If true, the description field will be omitted from the response. + schema: + type: boolean responses: "200": description: All flow @@ -11999,32 +12014,32 @@ paths: schema: type: boolean /w/{workspace}/email_triggers/setenabled/{path}: - post: - summary: enable/disable email trigger - operationId: setEmailTriggerEnabled - tags: - - email_trigger - parameters: - - $ref: "#/components/parameters/WorkspaceId" - - $ref: "#/components/parameters/Path" - requestBody: - required: true + post: + summary: enable/disable email trigger + operationId: setEmailTriggerEnabled + tags: + - email_trigger + parameters: + - $ref: "#/components/parameters/WorkspaceId" + - $ref: "#/components/parameters/Path" + requestBody: + required: true + content: + application/json: + schema: + type: object + properties: + enabled: + type: boolean + required: + - enabled + responses: + "200": + description: email trigger enable/disable content: - application/json: + text/plain: schema: - type: object - properties: - enabled: - type: boolean - required: - - enabled - responses: - "200": - description: email trigger enable/disable - content: - text/plain: - schema: - type: string + type: string /groups/list: get: diff --git a/backend/windmill-api/src/flows.rs b/backend/windmill-api/src/flows.rs index a2e8e307e6..2a75045f9f 100644 --- a/backend/windmill-api/src/flows.rs +++ b/backend/windmill-api/src/flows.rs @@ -133,7 +133,11 @@ async fn list_flows( "o.workspace_id", "o.path", "summary", - "description", + if !lq.without_description.unwrap_or(false) { + "description" + } else { + "NULL as description" + }, "fv.created_by as edited_by", "fv.created_at as edited_at", "archived", diff --git a/backend/windmill-api/src/scripts.rs b/backend/windmill-api/src/scripts.rs index 82c8864fe3..a772100a50 100644 --- a/backend/windmill-api/src/scripts.rs +++ b/backend/windmill-api/src/scripts.rs @@ -228,6 +228,11 @@ async fn list_scripts( "COALESCE(draft.created_at, o.created_at) as created_at", "archived", "extra_perms", + if !lq.without_description.unwrap_or(false) { + "description" + } else { + "NULL as description" + }, "CASE WHEN lock_error_logs IS NOT NULL THEN true ELSE false END as has_deploy_errors", "language", "favorite.path IS NOT NULL as starred", diff --git a/backend/windmill-common/src/flows.rs b/backend/windmill-common/src/flows.rs index 27044c1dd3..41e02b7ee8 100644 --- a/backend/windmill-common/src/flows.rs +++ b/backend/windmill-common/src/flows.rs @@ -78,7 +78,8 @@ pub struct ListableFlow { pub workspace_id: String, pub path: String, pub summary: String, - pub description: String, + #[serde(skip_serializing_if = "Option::is_none")] + pub description: Option, pub edited_by: Option, pub edited_at: Option>, pub archived: bool, @@ -1122,6 +1123,7 @@ where #[derive(Deserialize)] pub struct ListFlowQuery { + pub without_description: Option, pub path_start: Option, pub path_exact: Option, pub edited_by: Option, diff --git a/backend/windmill-common/src/scripts.rs b/backend/windmill-common/src/scripts.rs index 11d6758caa..a5ba95f93b 100644 --- a/backend/windmill-common/src/scripts.rs +++ b/backend/windmill-common/src/scripts.rs @@ -353,6 +353,8 @@ pub struct ListableScript { pub starred: bool, pub tag: Option, #[serde(skip_serializing_if = "Option::is_none")] + pub description: Option, + #[serde(skip_serializing_if = "Option::is_none")] pub has_draft: Option, #[serde(skip_serializing_if = "Option::is_none")] pub draft_only: Option, @@ -492,6 +494,7 @@ where #[derive(Debug, Deserialize)] pub struct ListScriptQuery { + pub without_description: Option, pub path_start: Option, pub path_exact: Option, pub created_by: Option, diff --git a/frontend/src/lib/components/ScriptPicker.svelte b/frontend/src/lib/components/ScriptPicker.svelte index a10f1c30fe..5fa0618edd 100644 --- a/frontend/src/lib/components/ScriptPicker.svelte +++ b/frontend/src/lib/components/ScriptPicker.svelte @@ -57,15 +57,19 @@ async function loadItems(): Promise { if (itemKind == 'flow') { - items = (await FlowService.listFlows({ workspace: $workspaceStore! })).map((flow) => ({ + items = ( + await FlowService.listFlows({ workspace: $workspaceStore!, withoutDescription: true }) + ).map((flow) => ({ value: flow.path, - label: `${flow.path}${flow.summary ? ` | ${truncate(flow.summary, 20)}` : ''}` + label: `${flow.path}${flow.summary ? ` | ${truncate(flow.summary, 20)}` : ''}`, + withoutDescription: true })) } else if (itemKind == 'script') { items = ( await ScriptService.listScripts({ workspace: $workspaceStore!, - kinds: kinds.join(',') + kinds: kinds.join(','), + withoutDescription: true }) ).map((script) => ({ value: script.path, diff --git a/frontend/src/lib/components/apps/editor/settingsPanel/mainInput/WorkspaceFlowList.svelte b/frontend/src/lib/components/apps/editor/settingsPanel/mainInput/WorkspaceFlowList.svelte index 1f6fdcf8b0..b2cc91fc01 100644 --- a/frontend/src/lib/components/apps/editor/settingsPanel/mainInput/WorkspaceFlowList.svelte +++ b/frontend/src/lib/components/apps/editor/settingsPanel/mainInput/WorkspaceFlowList.svelte @@ -27,7 +27,8 @@ async function loadFlow(): Promise { const loadedFlows = await FlowService.listFlows({ workspace: $workspaceStore!, - perPage: 300 + perPage: 300, + withoutDescription: true }) flows = loadedFlows diff --git a/frontend/src/lib/components/apps/editor/settingsPanel/mainInput/WorkspaceScriptList.svelte b/frontend/src/lib/components/apps/editor/settingsPanel/mainInput/WorkspaceScriptList.svelte index c477c7ef1f..be261ca5e8 100644 --- a/frontend/src/lib/components/apps/editor/settingsPanel/mainInput/WorkspaceScriptList.svelte +++ b/frontend/src/lib/components/apps/editor/settingsPanel/mainInput/WorkspaceScriptList.svelte @@ -27,7 +27,8 @@ async function loadScripts(): Promise { const loadedScripts = await ScriptService.listScripts({ workspace: $workspaceStore!, - perPage: 300 + perPage: 300, + withoutDescription: true }) scripts = loadedScripts diff --git a/frontend/src/lib/components/copilot/chat/flow/core.ts b/frontend/src/lib/components/copilot/chat/flow/core.ts index d9879f8399..8fd4233570 100644 --- a/frontend/src/lib/components/copilot/chat/flow/core.ts +++ b/frontend/src/lib/components/copilot/chat/flow/core.ts @@ -374,7 +374,7 @@ class WorkspaceScriptsSearch { private async init(workspace: string) { this.scripts = await ScriptService.listScripts({ - workspace + workspace, }) this.workspace = workspace } diff --git a/frontend/src/lib/components/flows/content/FlowInputsFlow.svelte b/frontend/src/lib/components/flows/content/FlowInputsFlow.svelte index faee8fb3d9..9f16d95bab 100644 --- a/frontend/src/lib/components/flows/content/FlowInputsFlow.svelte +++ b/frontend/src/lib/components/flows/content/FlowInputsFlow.svelte @@ -6,28 +6,38 @@ import { workspaceStore } from '$lib/stores' import { emptyString } from '$lib/utils' - import { createEventDispatcher } from 'svelte' + import { createEventDispatcher, untrack } from 'svelte' import { flip } from 'svelte/animate' import { fade } from 'svelte/transition' + interface Props { + children?: import('svelte').Snippet + } + + let { children }: Props = $props() // export let failureModule: boolean const dispatch = createEventDispatcher() - let items: Flow[] | undefined = undefined - let filteredItems: (Flow & { marked?: string })[] | undefined = undefined - let filter = '' - $: $workspaceStore && loadFlows() + let items = $state(undefined) as Flow[] | undefined + let filteredItems = $state(undefined) as (Flow & { marked?: string })[] | undefined + let filter = $state('') - let ownerFilter: string | undefined = undefined - $: prefilteredItems = ownerFilter ? items?.filter((x) => x.path.startsWith(ownerFilter!)) : items - - $: owners = Array.from( - new Set(filteredItems?.map((x) => x.path.split('/').slice(0, 2).join('/')) ?? []) - ).sort() + let ownerFilter: string | undefined = $state(undefined) async function loadFlows() { - items = await FlowService.listFlows({ workspace: $workspaceStore! }) + items = await FlowService.listFlows({ workspace: $workspaceStore!, withoutDescription: true }) } + $effect(() => { + $workspaceStore && untrack(() => loadFlows()) + }) + let prefilteredItems = $derived( + ownerFilter ? items?.filter((x) => x.path.startsWith(ownerFilter!)) : items + ) + let owners = $derived( + Array.from( + new Set(filteredItems?.map((x) => x.path.split('/').slice(0, 2).join('/')) ?? []) + ).sort() + )

Pick a Workspace Flow

- + {@render children?.()} - - {/each} - - {:else} - {#each Array(10).fill(0) as _} - - {/each} - {/if} -
diff --git a/frontend/src/lib/components/flows/pickers/WorkspaceScriptPicker.svelte b/frontend/src/lib/components/flows/pickers/WorkspaceScriptPicker.svelte index def0c1e58e..ce1a7e63e0 100644 --- a/frontend/src/lib/components/flows/pickers/WorkspaceScriptPicker.svelte +++ b/frontend/src/lib/components/flows/pickers/WorkspaceScriptPicker.svelte @@ -1,6 +1,6 @@
- + {@render children?.()}