Skip to content

Commit eaf57ea

Browse files
feat(core): autocomplete subflow() namespace and id arguments (#16882)
1 parent 20fc773 commit eaf57ea

2 files changed

Lines changed: 33 additions & 0 deletions

File tree

ui/src/override/services/flowAutoCompletionProvider.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,30 @@ export class FlowAutoCompletion extends YamlAutoCompletion {
344344
case "tasksWithState": {
345345
return State.arrayAllStates().map(({name}) => QUOTE + name + QUOTE)
346346
}
347+
case "subflow": {
348+
// subflow(namespace='...', id='...'): the arg under the cursor is the last one parsed
349+
const argNames = Object.keys(args)
350+
const currentArg = argNames[argNames.length - 1]
351+
if (currentArg === "namespace") {
352+
const availableNamespaces = this.namespacesStore.autocomplete
353+
?? await this.namespacesStore.loadAutocomplete()
354+
return availableNamespaces.map((namespace: string) => QUOTE + namespace + QUOTE)
355+
}
356+
if (currentArg === "id") {
357+
const namespace = this.extractArgValue(namespaceArg)
358+
if (namespace === undefined) {
359+
return Promise.resolve([])
360+
}
361+
let flowIds: string[] = (await this.flowStore.flowsByNamespace(namespace))
362+
.map((flow: {id: string}) => flow.id)
363+
// avoid suggesting the flow itself: subflow() on its own id recurses (depth-capped)
364+
if (parsed?.id !== undefined && parsed?.namespace === namespace) {
365+
flowIds = flowIds.filter(flowId => flowId !== parsed?.id)
366+
}
367+
return flowIds.map(flowId => QUOTE + flowId + QUOTE)
368+
}
369+
break
370+
}
347371
}
348372
return Promise.resolve([])
349373
}

ui/tests/unit/services/flowAutoCompletionProvider.spec.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,4 +272,13 @@ tasks:
272272
expect(await provider.functionAutoCompletion(parsed, "kv", {})).toEqual(["'myFirstKv'", "'mySecondKv'"])
273273
expect(await provider.functionAutoCompletion(parsed, "kv", {namespace: "'another.namespace'"})).toEqual(["'anotherNsFirstKv'", "'anotherNsSecondKv'"])
274274
})
275+
276+
it("subflow function autocompletions suggest namespaces and flow ids", async () => {
277+
// editing the `namespace` arg → all namespaces, quoted (Monaco does the prefix filtering)
278+
expect(await provider.functionAutoCompletion(parsed, "subflow", {namespace: "'m"})).toEqual(["'my.namespace'", "'another.namespace'"])
279+
// editing the `id` arg → flow ids of the chosen namespace, quoted
280+
expect(await provider.functionAutoCompletion(parsed, "subflow", {namespace: "'another.namespace'", id: "'fl"})).toEqual(["'flow-other-namespace'", "'another-flow-other-namespace'"])
281+
// editing the `id` arg in the flow's own namespace excludes the flow itself (avoids self-recursion)
282+
expect(await provider.functionAutoCompletion(parsed, "subflow", {namespace: "'my.namespace'", id: "'m"})).toEqual([])
283+
})
275284
})

0 commit comments

Comments
 (0)