mirror of
https://github.com/n8n-io/n8n.git
synced 2026-06-01 01:07:04 +02:00
Add experimental store change
This commit is contained in:
parent
fcf559b93d
commit
bbc216ba49
|
|
@ -4,29 +4,54 @@ import { N8nText, N8nInput } from '@n8n/design-system';
|
|||
import { computed } from 'vue';
|
||||
import { useI18n } from '@n8n/i18n';
|
||||
import { isValueExpression } from '@/utils/nodeTypesUtils';
|
||||
import { useNodeSettingsParameters } from '@/composables/useNodeSettingsParameters';
|
||||
import { useWorkflowsStore } from '@/stores/workflows.store';
|
||||
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
|
||||
|
||||
defineOptions({ name: 'FocusPanel' });
|
||||
|
||||
const locale = useI18n();
|
||||
|
||||
const focusPanelStore = useFocusPanelStore();
|
||||
const nodeTypesStore = useNodeTypesStore();
|
||||
const nodeSettingsParameters = useNodeSettingsParameters();
|
||||
|
||||
const focusedNodeParameter = computed(() => focusPanelStore.focusedNodeParameters[0]);
|
||||
const resolvedParameter = computed(() =>
|
||||
focusPanelStore.isRichParameter(focusedNodeParameter.value)
|
||||
? focusedNodeParameter.value
|
||||
: undefined,
|
||||
);
|
||||
|
||||
const focusPanelActive = computed(() => focusPanelStore.focusPanelActive);
|
||||
|
||||
const isCodeBlock = computed(() => resolvedParameter.value?.parameterPath === 'parameters.jsCode');
|
||||
|
||||
const expressionModeEnabled = computed(
|
||||
() =>
|
||||
focusedNodeParameter.value &&
|
||||
isValueExpression(focusedNodeParameter.value.parameter, focusedNodeParameter.value.value),
|
||||
resolvedParameter.value &&
|
||||
isValueExpression(resolvedParameter.value.parameter, resolvedParameter.value.value),
|
||||
);
|
||||
|
||||
const isToolNode = computed(() =>
|
||||
resolvedParameter.value ? nodeTypesStore.isToolNode(resolvedParameter.value?.node.type) : false,
|
||||
);
|
||||
|
||||
function optionSelected() {
|
||||
// TODO: Handle the option selected (command: string) from the dropdown
|
||||
}
|
||||
|
||||
function valueChanged() {
|
||||
// TODO: Update parameter value
|
||||
function valueChanged(value: string) {
|
||||
if (resolvedParameter.value === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
nodeSettingsParameters.updateNodeParameter(
|
||||
{ value, name: `parameters.${focusedNodeParameter.value.parameter.name}` },
|
||||
value,
|
||||
resolvedParameter.value.node,
|
||||
isToolNode.value,
|
||||
);
|
||||
}
|
||||
|
||||
function executeFocusedNode() {
|
||||
|
|
@ -44,13 +69,13 @@ function executeFocusedNode() {
|
|||
<n8n-icon icon="arrow-right" color="text-base" />
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="focusedNodeParameter" :class="$style.content">
|
||||
<div v-if="resolvedParameter" :class="$style.content">
|
||||
<div :class="$style.tabHeader">
|
||||
<div :class="$style.tabHeaderText">
|
||||
<N8nText color="text-dark" size="small">{{
|
||||
focusedNodeParameter.parameter.displayName
|
||||
resolvedParameter.parameter.displayName
|
||||
}}</N8nText>
|
||||
<N8nText color="text-base" size="xsmall">{{ focusedNodeParameter.nodeName }}</N8nText>
|
||||
<N8nText color="text-base" size="xsmall">{{ resolvedParameter.node.name }}</N8nText>
|
||||
</div>
|
||||
<N8nTooltip>
|
||||
<n8n-button
|
||||
|
|
@ -71,31 +96,32 @@ function executeFocusedNode() {
|
|||
<div></div>
|
||||
<ParameterOptions
|
||||
:parameter="focusedNodeParameter.parameter"
|
||||
:value="focusedNodeParameter.value"
|
||||
:value="resolvedParameter.value"
|
||||
:is-read-only="false"
|
||||
@update:model-value="optionSelected"
|
||||
/>
|
||||
</div>
|
||||
<div :class="$style.editorContainer">
|
||||
<div v-if="typeof resolvedParameter.value === 'string'" :class="$style.editorContainer">
|
||||
<ExpressionEditorModalInput
|
||||
v-if="expressionModeEnabled"
|
||||
:model-value="focusedNodeParameter.value"
|
||||
:model-value="resolvedParameter.value"
|
||||
:class="$style.editor"
|
||||
:is-read-only="false"
|
||||
:path="focusedNodeParameter.parameterPath"
|
||||
:path="resolvedParameter.parameterPath"
|
||||
data-test-id="expression-modal-input"
|
||||
:target-node-parameter-context="{
|
||||
nodeName: focusedNodeParameter.nodeName,
|
||||
nodeName: resolvedParameter.node.name,
|
||||
parameterPath: focusedNodeParameter.parameterPath,
|
||||
}"
|
||||
@change="valueChanged"
|
||||
@change="valueChanged($event.value)"
|
||||
/>
|
||||
<N8nInput
|
||||
v-else
|
||||
v-model="focusedNodeParameter.value"
|
||||
v-model="resolvedParameter.value"
|
||||
:class="$style.editor"
|
||||
type="textarea"
|
||||
resize="none"
|
||||
@change="valueChanged"
|
||||
></N8nInput>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -121,6 +121,7 @@ export function searchNodes(searchFilter: string, items: INodeCreateElement[]) {
|
|||
}
|
||||
|
||||
const trimmedFilter = removeTrailingTrigger(searchFilter).toLowerCase();
|
||||
debugger;
|
||||
|
||||
// We have a snapshot of this call in sublimeSearch.test.ts to assert practical order for some cases
|
||||
// Please update the snapshots per the README next to the the snapshots if you modify items significantly.
|
||||
|
|
|
|||
|
|
@ -1048,10 +1048,9 @@ async function optionSelected(command: string) {
|
|||
|
||||
if (node.value && command === 'focus') {
|
||||
focusPanelStore.setFocusedNodeParameter({
|
||||
nodeName: node.value.name,
|
||||
nodeId: node.value.id,
|
||||
parameterPath: props.path,
|
||||
parameter: props.parameter,
|
||||
value: modelValueString.value,
|
||||
});
|
||||
|
||||
if (ndvStore.activeNode) {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import type {
|
|||
NodeParameterValue,
|
||||
NodeParameterValueType,
|
||||
} from 'n8n-workflow';
|
||||
import { ADD_FORM_NOTICE, deepCopy, NodeHelpers } from 'n8n-workflow';
|
||||
import { ADD_FORM_NOTICE, deepCopy, getParameterValueByPath, NodeHelpers } from 'n8n-workflow';
|
||||
import { computed, defineAsyncComponent, onErrorCaptured, ref, watch, type WatchSource } from 'vue';
|
||||
|
||||
import type { IUpdateInformation } from '@/Interface';
|
||||
|
|
@ -538,7 +538,7 @@ function getDependentParametersValues(parameter: INodeProperties): string | null
|
|||
function getParameterValue<T extends NodeParameterValueType = NodeParameterValueType>(
|
||||
name: string,
|
||||
): T {
|
||||
return nodeHelpers.getParameterValue(props.nodeValues, name, props.path) as T;
|
||||
return getParameterValueByPath(props.nodeValues, name, props.path) as T;
|
||||
}
|
||||
|
||||
function isRagStarterCallout(parameter: INodeProperties): boolean {
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ const shouldShowOptions = computed(() => {
|
|||
}
|
||||
|
||||
if (['codeNodeEditor', 'sqlEditor'].includes(props.parameter.typeOptions?.editor ?? '')) {
|
||||
return false;
|
||||
// return false;
|
||||
}
|
||||
|
||||
if (props.showOptions) {
|
||||
|
|
|
|||
|
|
@ -41,7 +41,6 @@ import { isObject } from '@/utils/objectUtils';
|
|||
import { useWorkflowsStore } from '@/stores/workflows.store';
|
||||
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
|
||||
import { useCredentialsStore } from '@/stores/credentials.store';
|
||||
import get from 'lodash/get';
|
||||
import { useI18n } from '@n8n/i18n';
|
||||
import { EnableNodeToggleCommand } from '@/models/history';
|
||||
import { useTelemetry } from './useTelemetry';
|
||||
|
|
@ -92,10 +91,6 @@ export function useNodeHelpers() {
|
|||
return false;
|
||||
}
|
||||
|
||||
function getParameterValue(nodeValues: INodeParameters, parameterName: string, path: string) {
|
||||
return get(nodeValues, path ? path + '.' + parameterName : parameterName);
|
||||
}
|
||||
|
||||
// Returns if the given parameter should be displayed or not
|
||||
function displayParameter(
|
||||
nodeValues: INodeParameters,
|
||||
|
|
@ -1005,7 +1000,6 @@ export function useNodeHelpers() {
|
|||
return {
|
||||
hasProxyAuth,
|
||||
isCustomApiCallSelected,
|
||||
getParameterValue,
|
||||
displayParameter,
|
||||
getNodeIssues,
|
||||
updateNodesInputIssues,
|
||||
|
|
|
|||
|
|
@ -1,22 +1,48 @@
|
|||
import { STORES } from '@n8n/stores';
|
||||
import { defineStore } from 'pinia';
|
||||
import { ref } from 'vue';
|
||||
import { computed, ref } from 'vue';
|
||||
|
||||
import type { INodeProperties } from 'n8n-workflow';
|
||||
import {
|
||||
getParameterValueByPath,
|
||||
type NodeParameterValueType,
|
||||
type INode,
|
||||
type INodeProperties,
|
||||
} from 'n8n-workflow';
|
||||
import { useWorkflowsStore } from './workflows.store';
|
||||
|
||||
type FocusedNodeParameter = {
|
||||
nodeName: string;
|
||||
nodeId: string;
|
||||
parameter: INodeProperties;
|
||||
parameterPath: string;
|
||||
value: string;
|
||||
};
|
||||
|
||||
export type RichFocusedNodeParameter = FocusedNodeParameter & {
|
||||
node: INode;
|
||||
value: NodeParameterValueType;
|
||||
};
|
||||
|
||||
export const useFocusPanelStore = defineStore(STORES.FOCUS_PANEL, () => {
|
||||
const workflowsStore = useWorkflowsStore();
|
||||
|
||||
const focusPanelActive = ref(false);
|
||||
const focusedNodeParameters = ref<FocusedNodeParameter[]>([]);
|
||||
const _focusedNodeParameters = ref<FocusedNodeParameter[]>([]);
|
||||
|
||||
// An unenriched parameter indicates a missing nodeId
|
||||
const focusedNodeParameters = computed<Array<RichFocusedNodeParameter | FocusedNodeParameter>>(
|
||||
() =>
|
||||
_focusedNodeParameters.value.map((x) => {
|
||||
const node = workflowsStore.getNodeById(x.nodeId);
|
||||
if (!node) return x;
|
||||
return {
|
||||
...x,
|
||||
node,
|
||||
value: getParameterValueByPath(node?.parameters ?? {}, x.parameter.name, x.parameterPath),
|
||||
} satisfies RichFocusedNodeParameter;
|
||||
}),
|
||||
);
|
||||
|
||||
const setFocusedNodeParameter = (nodeParameter: FocusedNodeParameter) => {
|
||||
focusedNodeParameters.value = [
|
||||
_focusedNodeParameters.value = [
|
||||
nodeParameter,
|
||||
// Uncomment when tabs are implemented
|
||||
// ...focusedNodeParameters.value.filter((p) => p.parameterPath !== nodeParameter.parameterPath),
|
||||
|
|
@ -31,10 +57,17 @@ export const useFocusPanelStore = defineStore(STORES.FOCUS_PANEL, () => {
|
|||
focusPanelActive.value = !focusPanelActive.value;
|
||||
};
|
||||
|
||||
function isRichParameter(
|
||||
p: RichFocusedNodeParameter | FocusedNodeParameter,
|
||||
): p is RichFocusedNodeParameter {
|
||||
return 'value' in p && 'node' in p;
|
||||
}
|
||||
|
||||
return {
|
||||
focusPanelActive,
|
||||
focusedNodeParameters,
|
||||
setFocusedNodeParameter,
|
||||
isRichParameter,
|
||||
closeFocusPanel,
|
||||
toggleFocusPanel,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1758,3 +1758,11 @@ export function getSubworkflowId(node: INode): string | undefined {
|
|||
}
|
||||
return;
|
||||
}
|
||||
|
||||
export function getParameterValue(
|
||||
nodeValues: INodeParameters,
|
||||
parameterName: string,
|
||||
path: string,
|
||||
) {
|
||||
return get(nodeValues, path ? path + '.' + parameterName : parameterName);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user