mirror of
https://github.com/n8n-io/n8n.git
synced 2024-12-25 20:54:07 -08:00
fix(editor): Use selected input item for autocomplete (#10019)
This commit is contained in:
parent
56dd491bca
commit
1d2b403644
|
@ -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;
|
||||||
|
|
|
@ -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: [
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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');
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
// ----------------------------------
|
// ----------------------------------
|
||||||
|
|
|
@ -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;
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue