n8n/packages/editor-ui/src/stores/ndv.store.ts
Mutasem Aldmour 151e60f829
fix(editor): Fix local storage flags defaulting to undefined string (#7603)
useStorage takes the default value `undefined` and sets it in local
storage.. also returns "undefined" as string which breaks onboarding
flows

Github issue / Community forum post (link here to close automatically):
2023-11-07 10:06:08 +01:00

253 lines
6.8 KiB
TypeScript

import { useStorage } from '@/composables/useStorage';
import { LOCAL_STORAGE_MAPPING_IS_ONBOARDED, STORES } from '@/constants';
import type {
INodeUi,
IRunDataDisplayMode,
NDVState,
NodePanelType,
TargetItem,
XYPosition,
} from '@/Interface';
import type { INodeIssues, IRunData } from 'n8n-workflow';
import { NodeConnectionType } from 'n8n-workflow';
import { defineStore } from 'pinia';
import { v4 as uuid } from 'uuid';
import { useWorkflowsStore } from './workflows.store';
export const useNDVStore = defineStore(STORES.NDV, {
state: (): NDVState => ({
activeNodeName: null,
mainPanelDimensions: {},
sessionId: '',
input: {
displayMode: 'schema',
nodeName: undefined,
run: undefined,
branch: undefined,
data: {
isEmpty: true,
},
},
output: {
displayMode: 'table',
branch: undefined,
data: {
isEmpty: true,
},
editMode: {
enabled: false,
value: '',
},
},
focusedMappableInput: '',
mappingTelemetry: {},
hoveringItem: null,
draggable: {
isDragging: false,
type: '',
data: '',
canDrop: false,
stickyPosition: null,
},
isMappingOnboarded: useStorage(LOCAL_STORAGE_MAPPING_IS_ONBOARDED).value === 'true',
}),
getters: {
activeNode(): INodeUi | null {
const workflowsStore = useWorkflowsStore();
return workflowsStore.getNodeByName(this.activeNodeName || '');
},
ndvInputData(): IRunData[] {
const workflowsStore = useWorkflowsStore();
const executionData = workflowsStore.getWorkflowExecution;
const inputNodeName: string | undefined = this.input.nodeName;
const inputRunIndex: number = this.input.run ?? 0;
const inputBranchIndex: number = this.input.branch ?? 0;
if (
!executionData ||
!inputNodeName ||
inputRunIndex === undefined ||
inputBranchIndex === undefined
) {
return [];
}
return executionData.data?.resultData?.runData?.[inputNodeName]?.[inputRunIndex]?.data
?.main?.[inputBranchIndex];
},
getPanelDisplayMode() {
return (panel: NodePanelType) => this[panel].displayMode;
},
inputPanelDisplayMode(): IRunDataDisplayMode {
return this.input.displayMode;
},
outputPanelDisplayMode(): IRunDataDisplayMode {
return this.output.displayMode;
},
isDraggableDragging(): boolean {
return this.draggable.isDragging;
},
draggableType(): string {
return this.draggable.type;
},
draggableData(): string {
return this.draggable.data;
},
canDraggableDrop(): boolean {
return this.draggable.canDrop;
},
outputPanelEditMode(): NDVState['output']['editMode'] {
return this.output.editMode;
},
getMainPanelDimensions() {
return (panelType: string) => {
const defaults = { relativeRight: 1, relativeLeft: 1, relativeWidth: 1 };
return { ...defaults, ...this.mainPanelDimensions[panelType] };
};
},
draggableStickyPos(): XYPosition | null {
return this.draggable.stickyPosition;
},
ndvInputNodeName(): string | undefined {
return this.input.nodeName;
},
ndvInputRunIndex(): number | undefined {
return this.input.run;
},
ndvInputBranchIndex(): number | undefined {
return this.input.branch;
},
isDNVDataEmpty() {
return (panel: 'input' | 'output'): boolean => this[panel].data.isEmpty;
},
isInputParentOfActiveNode(): boolean {
const inputNodeName = this.ndvInputNodeName;
if (!this.activeNode || !inputNodeName) {
return false;
}
const workflow = useWorkflowsStore().getCurrentWorkflow();
const parentNodes = workflow.getParentNodes(this.activeNode.name, NodeConnectionType.Main, 1);
return parentNodes.includes(inputNodeName);
},
hoveringItemNumber(): number {
return (this.hoveringItem?.itemIndex ?? 0) + 1;
},
getHoveringItem(): TargetItem | null {
if (this.isInputParentOfActiveNode) {
return this.hoveringItem;
}
return null;
},
},
actions: {
setActiveNodeName(nodeName: string | null): void {
this.activeNodeName = nodeName;
},
setInputNodeName(nodeName: string | undefined): void {
this.input = {
...this.input,
nodeName,
};
},
setInputRunIndex(run?: number): void {
this.input = {
...this.input,
run,
};
},
setMainPanelDimensions(params: {
panelType: string;
dimensions: { relativeLeft?: number; relativeRight?: number; relativeWidth?: number };
}): void {
this.mainPanelDimensions = {
...this.mainPanelDimensions,
[params.panelType]: {
...this.mainPanelDimensions[params.panelType],
...params.dimensions,
},
};
},
setNDVSessionId(): void {
this.sessionId = `ndv-${uuid()}`;
},
resetNDVSessionId(): void {
this.sessionId = '';
},
setPanelDisplayMode(params: { pane: NodePanelType; mode: IRunDataDisplayMode }): void {
this[params.pane].displayMode = params.mode;
},
setOutputPanelEditModeEnabled(isEnabled: boolean): void {
this.output.editMode.enabled = isEnabled;
},
setOutputPanelEditModeValue(payload: string): void {
this.output.editMode.value = payload;
},
setMappableNDVInputFocus(paramName: string): void {
this.focusedMappableInput = paramName;
},
draggableStartDragging({ type, data }: { type: string; data: string }): void {
this.draggable = {
isDragging: true,
type,
data,
canDrop: false,
stickyPosition: null,
};
},
draggableStopDragging(): void {
this.draggable = {
isDragging: false,
type: '',
data: '',
canDrop: false,
stickyPosition: null,
};
},
setDraggableStickyPos(position: XYPosition | null): void {
this.draggable.stickyPosition = position;
},
setDraggableCanDrop(canDrop: boolean): void {
this.draggable.canDrop = canDrop;
},
setMappingTelemetry(telemetry: { [key: string]: string | number | boolean }): void {
this.mappingTelemetry = { ...this.mappingTelemetry, ...telemetry };
},
resetMappingTelemetry(): void {
this.mappingTelemetry = {};
},
setHoveringItem(item: null | NDVState['hoveringItem']): void {
this.hoveringItem = item;
},
setNDVBranchIndex(e: { pane: 'input' | 'output'; branchIndex: number }): void {
this[e.pane].branch = e.branchIndex;
},
setNDVPanelDataIsEmpty(payload: { panel: 'input' | 'output'; isEmpty: boolean }): void {
this[payload.panel].data.isEmpty = payload.isEmpty;
},
disableMappingHint(store = true) {
this.isMappingOnboarded = true;
if (store) {
useStorage(LOCAL_STORAGE_MAPPING_IS_ONBOARDED).value = 'true';
}
},
updateNodeParameterIssues(issues: INodeIssues): void {
const workflowsStore = useWorkflowsStore();
const activeNode = workflowsStore.getNodeByName(this.activeNodeName || '');
if (activeNode) {
const nodeIndex = workflowsStore.workflow.nodes.findIndex((node) => {
return node.name === activeNode.name;
});
workflowsStore.updateNodeAtIndex(nodeIndex, {
issues: {
...activeNode.issues,
...issues,
},
});
}
},
},
});