fix(editor): Use selected input item for autocomplete (#10019)

This commit is contained in:
Elias Meire 2024-07-12 10:11:59 +02:00 committed by GitHub
parent 56dd491bca
commit 1d2b403644
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 42 additions and 34 deletions

View file

@ -88,7 +88,7 @@ const hint = computed(() => {
undefined, undefined,
ndvStore.isInputParentOfActiveNode ndvStore.isInputParentOfActiveNode
? { ? {
targetItem: ndvStore.hoveringItem ?? undefined, targetItem: ndvStore.expressionTargetItem ?? undefined,
inputNodeName: ndvStore.ndvInputNodeName, inputNodeName: ndvStore.ndvInputNodeName,
inputRunIndex: ndvStore.ndvInputRunIndex, inputRunIndex: ndvStore.ndvInputRunIndex,
inputBranchIndex: ndvStore.ndvInputBranchIndex, inputBranchIndex: ndvStore.ndvInputBranchIndex,
@ -104,9 +104,7 @@ const hint = computed(() => {
return stringifyExpressionResult(result); return stringifyExpressionResult(result);
}); });
const highlightHint = computed(() => const highlightHint = computed(() => Boolean(hint.value && ndvStore.getHoveringItem));
Boolean(hint.value && ndvStore.hoveringItem && ndvStore.isInputParentOfActiveNode),
);
const valueIsExpression = computed(() => { const valueIsExpression = computed(() => {
const { value } = assignment.value; const { value } = assignment.value;

View file

@ -7,7 +7,6 @@ describe('InlineExpressionEditorOutput.vue', () => {
const { getByTestId } = renderComponent(InlineExpressionEditorOutput, { const { getByTestId } = renderComponent(InlineExpressionEditorOutput, {
pinia: createTestingPinia(), pinia: createTestingPinia(),
props: { props: {
hoveringItemNumber: 0,
visible: true, visible: true,
segments: [ segments: [
{ {
@ -56,7 +55,6 @@ describe('InlineExpressionEditorOutput.vue', () => {
const { getByTestId } = renderComponent(InlineExpressionEditorOutput, { const { getByTestId } = renderComponent(InlineExpressionEditorOutput, {
pinia: createTestingPinia(), pinia: createTestingPinia(),
props: { props: {
hoveringItemNumber: 0,
visible: true, visible: true,
segments: [ segments: [
{ {

View file

@ -149,7 +149,7 @@ const parameterHint = computed(() => {
return props.hint; return props.hint;
}); });
const targetItem = computed(() => ndvStore.hoveringItem); const targetItem = computed(() => ndvStore.expressionTargetItem);
const isInputParentOfActiveNode = computed(() => ndvStore.isInputParentOfActiveNode); const isInputParentOfActiveNode = computed(() => ndvStore.isInputParentOfActiveNode);

View file

@ -330,22 +330,7 @@ export const useExpressionEditor = ({
return result; return result;
} }
const targetItem = computed<TargetItem | null>(() => { const targetItem = computed<TargetItem | null>(() => ndvStore.expressionTargetItem);
if (ndvStore.hoveringItem) {
return ndvStore.hoveringItem;
}
if (ndvStore.expressionOutputItemIndex && ndvStore.ndvInputNodeName) {
return {
nodeName: ndvStore.ndvInputNodeName,
runIndex: ndvStore.ndvInputRunIndex ?? 0,
outputIndex: ndvStore.ndvInputBranchIndex ?? 0,
itemIndex: ndvStore.expressionOutputItemIndex,
};
}
return null;
});
const resolvableSegments = computed<Resolvable[]>(() => { const resolvableSegments = computed<Resolvable[]>(() => {
return segments.value.filter((s): s is Resolvable => s.kind === 'resolvable'); return segments.value.filter((s): s is Resolvable => s.kind === 'resolvable');

View file

@ -1,5 +1,4 @@
import { resolveParameter } from '@/composables/useWorkflowHelpers'; import { prefixMatch, longestCommonPrefix, resolveAutocompleteExpression } from './utils';
import { prefixMatch, longestCommonPrefix } from './utils';
import type { Completion, CompletionContext, CompletionResult } from '@codemirror/autocomplete'; import type { Completion, CompletionContext, CompletionResult } from '@codemirror/autocomplete';
import type { Resolved } from './types'; import type { Resolved } from './types';
import { escapeMappingString } from '@/utils/mappingUtils'; import { escapeMappingString } from '@/utils/mappingUtils';
@ -31,7 +30,7 @@ export function bracketAccessCompletions(context: CompletionContext): Completion
let resolved: Resolved; let resolved: Resolved;
try { try {
resolved = resolveParameter(`={{ ${base} }}`); resolved = resolveAutocompleteExpression(`={{ ${base} }}`);
} catch { } catch {
return null; return null;
} }

View file

@ -1,4 +1,3 @@
import { resolveParameter } from '@/composables/useWorkflowHelpers';
import { VALID_EMAIL_REGEX } from '@/constants'; import { VALID_EMAIL_REGEX } from '@/constants';
import { i18n } from '@/plugins/i18n'; import { i18n } from '@/plugins/i18n';
import { useEnvironmentsStore } from '@/stores/environments.ee.store'; import { useEnvironmentsStore } from '@/stores/environments.ee.store';
@ -48,6 +47,7 @@ import {
isSplitInBatchesAbsent, isSplitInBatchesAbsent,
longestCommonPrefix, longestCommonPrefix,
prefixMatch, prefixMatch,
resolveAutocompleteExpression,
sortCompletionsAlpha, sortCompletionsAlpha,
splitBaseTail, splitBaseTail,
stripExcessParens, stripExcessParens,
@ -83,7 +83,7 @@ export function datatypeCompletions(context: CompletionContext): CompletionResul
let resolved: Resolved; let resolved: Resolved;
try { try {
resolved = resolveParameter(`={{ ${base} }}`); resolved = resolveAutocompleteExpression(`={{ ${base} }}`);
} catch (error) { } catch (error) {
return null; return null;
} }
@ -126,7 +126,7 @@ export function datatypeCompletions(context: CompletionContext): CompletionResul
function explicitDataTypeOptions(expression: string): Completion[] { function explicitDataTypeOptions(expression: string): Completion[] {
try { try {
const resolved = resolveParameter(`={{ ${expression} }}`); const resolved = resolveAutocompleteExpression(`={{ ${expression} }}`);
return datatypeOptions({ return datatypeOptions({
resolved, resolved,
base: expression, base: expression,

View file

@ -82,7 +82,7 @@ export const isAllowedInDotNotation = (str: string) => {
export function receivesNoBinaryData() { export function receivesNoBinaryData() {
try { try {
return resolveParameter('={{ $binary }}')?.data === undefined; return resolveAutocompleteExpression('={{ $binary }}')?.data === undefined;
} catch { } catch {
return true; return true;
} }
@ -92,7 +92,7 @@ export function hasNoParams(toResolve: string) {
let params; let params;
try { try {
params = resolveParameter(`={{ ${toResolve}.params }}`); params = resolveAutocompleteExpression(`={{ ${toResolve}.params }}`);
} catch { } catch {
return true; return true;
} }
@ -104,6 +104,21 @@ export function hasNoParams(toResolve: string) {
return paramKeys.length === 1 && isPseudoParam(paramKeys[0]); return paramKeys.length === 1 && isPseudoParam(paramKeys[0]);
} }
export function resolveAutocompleteExpression(expression: string) {
const ndvStore = useNDVStore();
return resolveParameter(
expression,
ndvStore.isInputParentOfActiveNode
? {
targetItem: ndvStore.expressionTargetItem ?? undefined,
inputNodeName: ndvStore.ndvInputNodeName,
inputRunIndex: ndvStore.ndvInputRunIndex,
inputBranchIndex: ndvStore.ndvInputBranchIndex,
}
: {},
);
}
// ---------------------------------- // ----------------------------------
// state-based utils // state-based utils
// ---------------------------------- // ----------------------------------

View file

@ -151,9 +151,6 @@ export const useNDVStore = defineStore(STORES.NDV, {
const parentNodes = workflow.getParentNodes(this.activeNode.name, NodeConnectionType.Main, 1); const parentNodes = workflow.getParentNodes(this.activeNode.name, NodeConnectionType.Main, 1);
return parentNodes.includes(inputNodeName); return parentNodes.includes(inputNodeName);
}, },
hoveringItemNumber(): number {
return (this.hoveringItem?.itemIndex ?? 0) + 1;
},
getHoveringItem(): TargetItem | null { getHoveringItem(): TargetItem | null {
if (this.isInputParentOfActiveNode) { if (this.isInputParentOfActiveNode) {
return this.hoveringItem; return this.hoveringItem;
@ -161,6 +158,22 @@ export const useNDVStore = defineStore(STORES.NDV, {
return null; return null;
}, },
expressionTargetItem(): TargetItem | null {
if (this.getHoveringItem) {
return this.getHoveringItem;
}
if (this.expressionOutputItemIndex && this.ndvInputNodeName) {
return {
nodeName: this.ndvInputNodeName,
runIndex: this.ndvInputRunIndex ?? 0,
outputIndex: this.ndvInputBranchIndex ?? 0,
itemIndex: this.expressionOutputItemIndex,
};
}
return null;
},
isNDVOpen(): boolean { isNDVOpen(): boolean {
return this.activeNodeName !== null; return this.activeNodeName !== null;
}, },