refactor(editor): Refactor VariableSelector and VariableSelectorItem to composition API (no-changelog) (#10030)

This commit is contained in:
oleg
2024-07-12 12:03:30 +02:00
committed by GitHub
parent e4e66ab7da
commit 3b2d76e358
2 changed files with 920 additions and 925 deletions

View File

@@ -1,32 +1,7 @@
<template>
<div class="variable-selector-wrapper" @keydown.stop>
<div class="input-wrapper">
<n8n-input
ref="inputField"
v-model="variableFilter"
:placeholder="$locale.baseText('variableSelector.variableFilter')"
size="small"
type="text"
></n8n-input>
</div>
<div class="result-wrapper">
<VariableSelectorItem
v-for="option in currentResults"
:key="option.key"
:item="option"
:extend-all="extendAll"
:redact-values="redactValues"
@item-selected="forwardItemSelected"
></VariableSelectorItem>
</div>
</div>
</template>
<script lang="ts">
/* eslint-disable prefer-spread */
import { defineComponent } from 'vue';
import { mapStores } from 'pinia';
<script setup lang="ts">
import { ref, computed } from 'vue';
import { useRouter } from 'vue-router';
import { storeToRefs } from 'pinia';
import { PLACEHOLDER_FILLED_AT_EXECUTION_TIME, STICKY_NODE_TYPE } from '@/constants';
import type {
@@ -43,66 +18,49 @@ import type {
import { NodeConnectionType, WorkflowDataProxy } from 'n8n-workflow';
import VariableSelectorItem from '@/components/VariableSelectorItem.vue';
import type { INodeUi, IVariableItemSelected, IVariableSelectorOption } from '@/Interface';
import type { IVariableItemSelected, IVariableSelectorOption } from '@/Interface';
import { useWorkflowsStore } from '@/stores/workflows.store';
import { useRootStore } from '@/stores/root.store';
import { useNDVStore } from '@/stores/ndv.store';
import { useRouter } from 'vue-router';
import { useWorkflowHelpers } from '@/composables/useWorkflowHelpers';
import { useI18n } from '@/composables/useI18n';
import { escapeMappingString } from '@/utils/mappingUtils';
// Node types that should not be displayed in variable selector
const SKIPPED_NODE_TYPES = [STICKY_NODE_TYPE];
export default defineComponent({
name: 'VariableSelector',
components: {
VariableSelectorItem,
},
props: ['path', 'redactValues'],
setup() {
const router = useRouter();
const workflowHelpers = useWorkflowHelpers({ router });
const props = defineProps<{
path: string;
redactValues: boolean;
}>();
return {
workflowHelpers,
};
},
data() {
return {
variableFilter: '',
selectorOpenInputIndex: null as number | null,
};
},
computed: {
...mapStores(useNDVStore, useRootStore, useWorkflowsStore),
activeNode(): INodeUi | null {
const activeNode = this.ndvStore.activeNode!;
if (!activeNode) {
return null;
}
return this.workflow.getParentMainInputNode(activeNode);
},
extendAll(): boolean {
if (this.variableFilter) {
return true;
}
const emit = defineEmits<{
itemSelected: [value: IVariableItemSelected];
}>();
return false;
},
currentResults(): IVariableSelectorOption[] {
return this.getFilterResults(this.variableFilter.toLowerCase(), 0);
},
workflow(): Workflow {
return this.workflowHelpers.getCurrentWorkflow();
},
},
methods: {
forwardItemSelected(eventData: IVariableItemSelected) {
this.$emit('itemSelected', eventData);
},
sortOptions(options: IVariableSelectorOption[] | null): IVariableSelectorOption[] | null {
const router = useRouter();
const i18n = useI18n();
const workflowHelpers = useWorkflowHelpers({ router });
const workflowsStore = useWorkflowsStore();
const ndvStore = useNDVStore();
const { activeNode } = storeToRefs(ndvStore);
const variableFilter = ref('');
const extendAll = computed(() => !!variableFilter.value);
const currentResults = computed(() => getFilterResults(variableFilter.value.toLowerCase(), 0));
const workflow = computed(() => workflowHelpers.getCurrentWorkflow());
// Helper functions
/**
* Sorts the options alphabetically. Categories get sorted before items.
*/
function sortOptions(options: IVariableSelectorOption[] | null): IVariableSelectorOption[] | null {
if (options === null) {
return null;
}
@@ -127,15 +85,19 @@ export default defineComponent({
}
return 0;
});
},
removeEmptyEntries(
}
/**
* Removes all empty entries from the list
*/
function removeEmptyEntries(
inputData: IVariableSelectorOption[] | IVariableSelectorOption | null,
): IVariableSelectorOption[] | IVariableSelectorOption | null {
): IVariableSelectorOption[] | IVariableSelectorOption | null {
if (Array.isArray(inputData)) {
const newItems: IVariableSelectorOption[] = [];
let tempItem: IVariableSelectorOption;
inputData.forEach((item) => {
tempItem = this.removeEmptyEntries(item) as IVariableSelectorOption;
tempItem = removeEmptyEntries(item) as IVariableSelectorOption;
if (tempItem !== null) {
newItems.push(tempItem);
}
@@ -144,7 +106,7 @@ export default defineComponent({
}
if (inputData?.options) {
const newOptions = this.removeEmptyEntries(inputData.options);
const newOptions = removeEmptyEntries(inputData.options);
if (Array.isArray(newOptions) && newOptions.length) {
// Has still options left so return
inputData.options = newOptions;
@@ -159,9 +121,12 @@ export default defineComponent({
// Is an item no category
return inputData;
}
},
// Normalizes the path so compare paths which have use dots or brakets
getPathNormalized(path: string | undefined): string {
}
/**
* Normalizes the path so compare paths which have use dots or brakets
*/
function getPathNormalized(path: string | undefined): string {
if (path === undefined) {
return '';
}
@@ -197,8 +162,9 @@ export default defineComponent({
}
return finalArray.join('|');
},
jsonDataToFilterOption(
}
function jsonDataToFilterOption(
inputData: IDataObject | GenericValue | IDataObject[] | GenericValue[] | null,
parentPath: string,
propertyName: string,
@@ -206,7 +172,7 @@ export default defineComponent({
propertyIndex?: number,
displayName?: string,
skipKey?: string,
): IVariableSelectorOption[] {
): IVariableSelectorOption[] {
let fullpath = `${parentPath}["${propertyName}"]`;
if (propertyIndex !== undefined) {
fullpath += `[${propertyIndex}]`;
@@ -231,9 +197,8 @@ export default defineComponent({
const arrayData: IVariableSelectorOption[] = [];
for (let i = 0; i < inputData.length; i++) {
arrayData.push.apply(
arrayData,
this.jsonDataToFilterOption(
arrayData.push(
...jsonDataToFilterOption(
inputData[i],
newParentPath,
newPropertyName,
@@ -256,9 +221,8 @@ export default defineComponent({
const tempValue: IVariableSelectorOption[] = [];
for (const key of Object.keys(inputData)) {
tempValue.push.apply(
tempValue,
this.jsonDataToFilterOption(
tempValue.push(
...jsonDataToFilterOption(
(inputData as IDataObject)[key],
fullpath,
key,
@@ -273,7 +237,7 @@ export default defineComponent({
if (tempValue.length) {
returnData.push({
name: displayName || propertyName,
options: this.sortOptions(tempValue),
options: sortOptions(tempValue),
key: fullpath,
allowParentSelect: true,
dataType: 'object',
@@ -281,11 +245,12 @@ export default defineComponent({
}
} else {
if (filterText !== undefined && propertyName.toLowerCase().indexOf(filterText) === -1) {
// If filter is set apply it
return returnData;
}
// Skip is currently only needed for leafs so only check here
if (this.getPathNormalized(skipKey) !== this.getPathNormalized(fullpath)) {
if (getPathNormalized(skipKey) !== getPathNormalized(fullpath)) {
returnData.push({
name: propertyName,
key: fullpath,
@@ -295,9 +260,9 @@ export default defineComponent({
}
return returnData;
},
}
/**
/**
* Get the node's output using runData
*
* @param {string} nodeName The name of the node to get the data of
@@ -309,7 +274,7 @@ export default defineComponent({
* @param {number} [outputIndex=0] The index of the output
* @param {boolean} [useShort=false] Use short notation $json vs. $('NodeName').json
*/
getNodeRunDataOutput(
function getNodeRunDataOutput(
nodeName: string,
runData: IRunData,
filterText: string,
@@ -318,7 +283,7 @@ export default defineComponent({
inputName = NodeConnectionType.Main,
outputIndex = 0,
useShort = false,
): IVariableSelectorOption[] | null {
): IVariableSelectorOption[] | null {
if (!runData.hasOwnProperty(nodeName)) {
// No data found for node
return null;
@@ -338,31 +303,31 @@ export default defineComponent({
return null;
}
if (!runData[nodeName][runIndex].data!.hasOwnProperty(inputName)) {
if (!runData[nodeName][runIndex].data.hasOwnProperty(inputName)) {
// No data found for inputName
return null;
}
if (runData[nodeName][runIndex].data![inputName].length <= outputIndex) {
if (runData[nodeName][runIndex].data[inputName].length <= outputIndex) {
// No data found for output Index
return null;
}
// The data should be identical no matter to which node it gets so always select the first one
if (
runData[nodeName][runIndex].data![inputName][outputIndex] === null ||
runData[nodeName][runIndex].data![inputName][outputIndex]!.length <= itemIndex
runData[nodeName][runIndex].data[inputName][outputIndex] === null ||
runData[nodeName][runIndex].data[inputName][outputIndex].length <= itemIndex
) {
// No data found for node connection found
return null;
}
const outputData = runData[nodeName][runIndex].data![inputName][outputIndex]![itemIndex];
const outputData = runData[nodeName][runIndex].data[inputName][outputIndex][itemIndex];
return this.getNodeOutput(nodeName, outputData, filterText, useShort);
},
return getNodeOutput(nodeName, outputData, filterText, useShort);
}
/**
/**
* Get the node's output using pinData
*
* @param {string} nodeName The name of the node to get the data of
@@ -370,18 +335,18 @@ export default defineComponent({
* @param {string} filterText Filter text for parameters
* @param {boolean} [useShort=false] Use short notation $json vs. $('NodeName').json
*/
getNodePinDataOutput(
function getNodePinDataOutput(
nodeName: string,
pinData: IPinData[string],
filterText: string,
useShort = false,
): IVariableSelectorOption[] | null {
): IVariableSelectorOption[] | null {
const outputData = pinData.map((data) => ({ json: data }) as INodeExecutionData)[0];
return this.getNodeOutput(nodeName, outputData, filterText, useShort);
},
return getNodeOutput(nodeName, outputData, filterText, useShort);
}
/**
/**
* Returns the node's output data
*
* @param {string} nodeName The name of the node to get the data of
@@ -389,12 +354,12 @@ export default defineComponent({
* @param {string} filterText Filter text for parameters
* @param {boolean} [useShort=false] Use short notation
*/
getNodeOutput(
function getNodeOutput(
nodeName: string,
outputData: INodeExecutionData,
filterText: string,
useShort = false,
): IVariableSelectorOption[] | null {
): IVariableSelectorOption[] | null {
const returnData: IVariableSelectorOption[] = [];
// Get json data
@@ -405,9 +370,8 @@ export default defineComponent({
const jsonDataOptions: IVariableSelectorOption[] = [];
for (const propertyName of Object.keys(outputData.json)) {
jsonDataOptions.push.apply(
jsonDataOptions,
this.jsonDataToFilterOption(
jsonDataOptions.push(
...jsonDataToFilterOption(
outputData.json[propertyName],
jsonPropertyPrefix,
propertyName,
@@ -419,7 +383,7 @@ export default defineComponent({
if (jsonDataOptions.length) {
returnData.push({
name: 'JSON',
options: this.sortOptions(jsonDataOptions),
options: sortOptions(jsonDataOptions),
});
}
}
@@ -456,7 +420,7 @@ export default defineComponent({
binaryData.push({
name: dataPropertyName,
key: `${binaryPropertyPrefix}.${dataPropertyName}`,
options: this.sortOptions(binaryPropertyData),
options: sortOptions(binaryPropertyData),
allowParentSelect: true,
});
}
@@ -465,36 +429,37 @@ export default defineComponent({
returnData.push({
name: 'Binary',
key: binaryPropertyPrefix,
options: this.sortOptions(binaryData),
options: sortOptions(binaryData),
allowParentSelect: true,
});
}
}
return returnData;
},
getNodeContext(
}
function getNodeContext(
workflow: Workflow,
runExecutionData: IRunExecutionData | null,
parentNode: string[],
nodeName: string,
filterText: string,
): IVariableSelectorOption[] | null {
): IVariableSelectorOption[] | null {
const itemIndex = 0;
const inputName = NodeConnectionType.Main;
const runIndex = 0;
const returnData: IVariableSelectorOption[] = [];
if (this.activeNode === null) {
if (activeNode.value === null) {
return returnData;
}
const nodeConnection = this.workflow.getNodeConnectionIndexes(
this.activeNode.name,
const nodeConnection = workflow.getNodeConnectionIndexes(
activeNode.value.name,
parentNode[0],
inputName,
);
const connectionInputData = this.workflowHelpers.connectionInputData(
const connectionInputData = workflowHelpers.connectionInputData(
parentNode,
nodeName,
inputName,
@@ -532,7 +497,6 @@ export default defineComponent({
);
const proxy = dataProxy.getDataProxy();
// @ts-ignore
const nodeContext = proxy.$node[nodeName].context as IContextObject;
for (const key of Object.keys(nodeContext)) {
if (filterText !== undefined && key.toLowerCase().indexOf(filterText) === -1) {
@@ -543,14 +507,14 @@ export default defineComponent({
returnData.push({
name: key,
key: `$('${escapeMappingString(nodeName)}').context['${escapeMappingString(key)}']`,
// @ts-ignore
value: nodeContext[key],
});
}
return returnData;
},
/**
}
/**
* Returns all the node parameters with values
*
* @param {string} nodeName The name of the node to return data of
@@ -558,13 +522,13 @@ export default defineComponent({
* @param {string} [skipParameter] Parameter to skip
* @param {string} [filterText] Filter text for parameters
*/
getNodeParameters(
function getNodeParameters(
nodeName: string,
path: string,
skipParameter?: string,
filterText?: string,
): IVariableSelectorOption[] | null {
const node = this.workflow.getNode(nodeName);
): IVariableSelectorOption[] | null {
const node = workflow.value.getNode(nodeName);
if (node === null) {
return null;
}
@@ -581,9 +545,8 @@ export default defineComponent({
continue;
}
returnParameters.push.apply(
returnParameters,
this.jsonDataToFilterOption(
returnParameters.push(
...jsonDataToFilterOption(
node.parameters[parameterName],
path,
parameterName,
@@ -596,17 +559,18 @@ export default defineComponent({
}
return returnParameters;
},
getFilterResults(filterText: string, itemIndex: number): IVariableSelectorOption[] {
}
function getFilterResults(filterText: string, itemIndex: number): IVariableSelectorOption[] {
const inputName = NodeConnectionType.Main;
if (this.activeNode === null) {
if (activeNode.value === null) {
return [];
}
const executionData = this.workflowsStore.getWorkflowExecution;
let parentNode = this.workflow.getParentNodes(this.activeNode.name, inputName, 1);
let runData = this.workflowsStore.getWorkflowRunData;
const executionData = workflowsStore.getWorkflowExecution;
let parentNode = workflow.value.getParentNodes(activeNode.value.name, inputName, 1);
let runData = workflowsStore.getWorkflowRunData;
if (runData === null) {
runData = {};
@@ -625,17 +589,17 @@ export default defineComponent({
if (executionData?.data !== undefined) {
const runExecutionData: IRunExecutionData = executionData.data;
tempOptions = this.getNodeContext(
this.workflow,
tempOptions = getNodeContext(
workflow.value,
runExecutionData,
parentNode,
this.activeNode.name,
activeNode.value.name,
filterText,
) as IVariableSelectorOption[];
if (tempOptions.length) {
currentNodeData.push({
name: 'Context',
options: this.sortOptions(tempOptions),
options: sortOptions(tempOptions),
} as IVariableSelectorOption);
}
}
@@ -645,27 +609,29 @@ export default defineComponent({
if (parentNode.length) {
// If the node has an input node add the input data
let ndvInputNodeName = this.ndvStore.ndvInputNodeName;
let ndvInputNodeName = ndvStore.ndvInputNodeName;
if (!ndvInputNodeName) {
// If no input node is set use the first parent one
// this is imporant for config-nodes which do not have
// this is important for config-nodes which do not have
// a main input
ndvInputNodeName = parentNode[0];
}
const activeInputParentNode = parentNode.find((node) => node === ndvInputNodeName)!;
const activeInputParentNode = parentNode.find((node) => node === ndvInputNodeName);
if (!activeInputParentNode) {
return [];
}
// Check from which output to read the data.
// Depends on how the nodes are connected.
// (example "IF" node. If node is connected to "true" or to "false" output)
const nodeConnection = this.workflow.getNodeConnectionIndexes(
this.activeNode.name,
const nodeConnection = workflow.value.getNodeConnectionIndexes(
activeNode.value.name,
activeInputParentNode,
inputName,
);
const outputIndex = nodeConnection === undefined ? 0 : nodeConnection.sourceIndex;
tempOutputData = this.getNodeRunDataOutput(
tempOutputData = getNodeRunDataOutput(
activeInputParentNode,
runData,
filterText,
@@ -683,18 +649,18 @@ export default defineComponent({
},
];
parentNode.forEach((parentNodeName) => {
const pinData = this.workflowsStore.pinDataByNodeName(parentNodeName);
const pinData = workflowsStore.pinDataByNodeName(parentNodeName);
if (pinData) {
const output = this.getNodePinDataOutput(parentNodeName, pinData, filterText, true);
const output = getNodePinDataOutput(parentNodeName, pinData, filterText, true);
pinDataOptions[0].options = pinDataOptions[0].options!.concat(
output?.[0]?.options ?? [],
);
if (pinDataOptions[0].options) {
pinDataOptions[0].options = pinDataOptions[0].options.concat(output?.[0]?.options ?? []);
}
}
});
if (pinDataOptions[0].options!.length > 0) {
if ((pinDataOptions[0]?.options ?? []).length > 0) {
if (tempOutputData) {
const jsonTempOutputData = tempOutputData.find((tempData) => tempData.name === 'JSON');
@@ -703,7 +669,7 @@ export default defineComponent({
jsonTempOutputData.options = [];
}
(pinDataOptions[0].options || []).forEach((pinDataOption) => {
(pinDataOptions[0].options ?? []).forEach((pinDataOption) => {
const existingOptionIndex = jsonTempOutputData.options!.findIndex(
(option) => option.name === pinDataOption.name,
);
@@ -726,7 +692,7 @@ export default defineComponent({
// Data is reasonable small (< 100kb) so add it
currentNodeData.push({
name: 'Input Data',
options: this.sortOptions(tempOutputData),
options: sortOptions(tempOutputData),
});
} else {
// Data is to large so do not add
@@ -743,16 +709,16 @@ export default defineComponent({
}
const initialPath = '$parameter';
let skipParameter = this.path;
let skipParameter = props.path;
if (skipParameter.startsWith('parameters.')) {
skipParameter = initialPath + skipParameter.substring(10);
}
currentNodeData.push({
name: this.$locale.baseText('variableSelector.parameters'),
options: this.sortOptions(
this.getNodeParameters(
this.activeNode.name,
name: i18n.baseText('variableSelector.parameters'),
options: sortOptions(
getNodeParameters(
activeNode.value.name,
initialPath,
skipParameter,
filterText,
@@ -761,8 +727,8 @@ export default defineComponent({
});
returnData.push({
name: this.$locale.baseText('variableSelector.currentNode'),
options: this.sortOptions(currentNodeData),
name: i18n.baseText('variableSelector.currentNode'),
options: sortOptions(currentNodeData),
});
// Add the input data
@@ -772,9 +738,9 @@ export default defineComponent({
// -----------------------------------------
const allNodesData: IVariableSelectorOption[] = [];
let nodeOptions: IVariableSelectorOption[];
const upstreamNodes = this.workflow.getParentNodes(this.activeNode.name, inputName);
const upstreamNodes = workflow.value.getParentNodes(activeNode.value.name, inputName);
const workflowNodes = Object.entries(this.workflow.nodes);
const workflowNodes = Object.entries(workflow.value.nodes);
// Sort the nodes according to their position relative to the current node
workflowNodes.sort((a, b) => {
@@ -785,7 +751,7 @@ export default defineComponent({
// Add the parameters of all nodes
// TODO: Later have to make sure that no parameters can be referenced which have expression which use input-data (for nodes which are not parent nodes)
if (nodeName === this.activeNode.name) {
if (nodeName === activeNode.value.name) {
// Skip the current node as this one get added separately
continue;
}
@@ -796,9 +762,9 @@ export default defineComponent({
nodeOptions = [
{
name: this.$locale.baseText('variableSelector.parameters'),
options: this.sortOptions(
this.getNodeParameters(
name: i18n.baseText('variableSelector.parameters'),
options: sortOptions(
getNodeParameters(
nodeName,
`$('${escapeMappingString(nodeName)}').params`,
undefined,
@@ -811,9 +777,9 @@ export default defineComponent({
if (executionData?.data !== undefined) {
const runExecutionData: IRunExecutionData = executionData.data;
parentNode = this.workflow.getParentNodes(nodeName, inputName, 1);
tempOptions = this.getNodeContext(
this.workflow,
parentNode = workflow.value.getParentNodes(nodeName, inputName, 1);
tempOptions = getNodeContext(
workflow.value,
runExecutionData,
parentNode,
nodeName,
@@ -822,8 +788,8 @@ export default defineComponent({
if (tempOptions.length) {
nodeOptions = [
{
name: this.$locale.baseText('variableSelector.context'),
options: this.sortOptions(tempOptions),
name: i18n.baseText('variableSelector.context'),
options: sortOptions(tempOptions),
} as IVariableSelectorOption,
];
}
@@ -831,48 +797,75 @@ export default defineComponent({
if (upstreamNodes.includes(nodeName)) {
// If the node is an upstream node add also the output data which can be referenced
const pinData = this.workflowsStore.pinDataByNodeName(nodeName);
const pinData = workflowsStore.pinDataByNodeName(nodeName);
tempOutputData = pinData
? this.getNodePinDataOutput(nodeName, pinData, filterText)
: this.getNodeRunDataOutput(nodeName, runData, filterText, itemIndex);
? getNodePinDataOutput(nodeName, pinData, filterText)
: getNodeRunDataOutput(nodeName, runData, filterText, itemIndex);
if (tempOutputData) {
nodeOptions.push({
name: this.$locale.baseText('variableSelector.outputData'),
options: this.sortOptions(tempOutputData),
name: i18n.baseText('variableSelector.outputData'),
options: sortOptions(tempOutputData),
} as IVariableSelectorOption);
}
}
const shortNodeType = this.$locale.shortNodeType(node.type);
const shortNodeType = i18n.shortNodeType(node.type);
allNodesData.push({
name: this.$locale.headerText({
name: i18n.headerText({
key: `headers.${shortNodeType}.displayName`,
fallback: nodeName,
}),
options: this.sortOptions(nodeOptions),
options: sortOptions(nodeOptions),
});
}
returnData.push({
name: this.$locale.baseText('variableSelector.nodes'),
name: i18n.baseText('variableSelector.nodes'),
options: allNodesData,
});
// Remove empty entries and return
returnData = this.removeEmptyEntries(returnData) as IVariableSelectorOption[] | null;
returnData = removeEmptyEntries(returnData) as IVariableSelectorOption[] | null;
if (returnData === null) {
return [];
}
return returnData;
},
},
});
}
function forwardItemSelected(eventData: IVariableItemSelected) {
emit('itemSelected', eventData);
}
</script>
<template>
<div class="variable-selector-wrapper" @keydown.stop>
<div class="input-wrapper">
<n8n-input
ref="inputField"
v-model="variableFilter"
:placeholder="i18n.baseText('variableSelector.variableFilter')"
size="small"
type="text"
></n8n-input>
</div>
<div class="result-wrapper">
<VariableSelectorItem
v-for="option in currentResults"
:key="option.key"
:item="option"
:extend-all="extendAll"
:redact-values="redactValues"
@item-selected="forwardItemSelected"
></VariableSelectorItem>
</div>
</div>
</template>
<style scoped lang="scss">
.variable-selector-wrapper {
border-radius: 0 0 4px 4px;

View File

@@ -59,68 +59,70 @@
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
<script setup lang="ts">
import { ref, computed, onMounted } from 'vue';
import type { IVariableSelectorOption, IVariableItemSelected } from '@/Interface';
export default defineComponent({
name: 'VariableSelectorItem',
props: ['allowParentSelect', 'extendAll', 'item', 'redactValues'],
data() {
return {
extended: false,
};
},
computed: {
itemAddOperations() {
const props = defineProps<{
allowParentSelect?: boolean;
extendAll?: boolean;
item: IVariableSelectorOption;
redactValues?: boolean;
}>();
const emit = defineEmits<{
itemSelected: [value: IVariableItemSelected];
}>();
const extended = ref(false);
const itemAddOperations = computed(() => {
const returnOptions = [
{
command: 'raw',
displayName: 'Raw value',
},
];
if (this.item.dataType === 'array') {
returnOptions.push({
if (props.item.dataType === 'array') {
returnOptions.push(
{
command: 'arrayLength',
displayName: 'Length',
});
returnOptions.push({
},
{
command: 'arrayValues',
displayName: 'Values',
});
} else if (this.item.dataType === 'object') {
returnOptions.push({
},
);
} else if (props.item.dataType === 'object') {
returnOptions.push(
{
command: 'objectKeys',
displayName: 'Keys',
});
returnOptions.push({
},
{
command: 'objectValues',
displayName: 'Values',
});
},
);
}
return returnOptions;
},
},
mounted() {
if (this.extended) return;
});
onMounted(() => {
if (extended.value) return;
const shouldAutoExtend =
[
this.$locale.baseText('variableSelectorItem.currentNode'),
this.$locale.baseText('variableSelectorItem.inputData'),
this.$locale.baseText('variableSelectorItem.binary'),
this.$locale.baseText('variableSelectorItem.json'),
].includes(this.item.name) && this.item.key === undefined;
['Current Node', 'Input Data', 'Binary', 'JSON'].includes(props.item.name) &&
props.item.key === undefined;
if (shouldAutoExtend) {
this.extended = true;
extended.value = true;
}
},
methods: {
optionSelected(command: string, item: IVariableSelectorOption) {
// By default it is raw
let variable = item.key;
});
const optionSelected = (command: string, item: IVariableSelectorOption) => {
let variable = item.key ?? '';
if (command === 'arrayValues') {
variable = `${item.key}.join(', ')`;
} else if (command === 'arrayLength') {
@@ -130,16 +132,16 @@ export default defineComponent({
} else if (command === 'objectValues') {
variable = `Object.values(${item.key}).join(', ')`;
}
this.$emit('itemSelected', { variable });
},
selectItem(item: IVariableSelectorOption) {
this.$emit('itemSelected', { variable: item.key });
},
forwardItemSelected(eventData: IVariableItemSelected) {
this.$emit('itemSelected', eventData);
},
},
});
emit('itemSelected', { variable });
};
const selectItem = (item: IVariableSelectorOption) => {
emit('itemSelected', { variable: item.key ?? '' });
};
const forwardItemSelected = (eventData: IVariableItemSelected) => {
emit('itemSelected', eventData);
};
</script>
<style scoped lang="scss">