CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-n8n-editor-ui

Workflow Editor UI for n8n - a comprehensive Vue.js-based visual workflow editor with drag-and-drop functionality.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

composables.mddocs/

Composables

Vue 3 composables providing reusable functionality for canvas operations, workflow helpers, UI interactions, and common utilities.

Capabilities

Canvas Composables

Composables for canvas and node operations.

/**
 * Access canvas node data within node components
 */
function useCanvasNode(): UseCanvasNodeReturn;

interface UseCanvasNodeReturn {
  node: InjectedCanvasNode;
  id: ComputedRef<string>;
  name: ComputedRef<string>;
  label: ComputedRef<string>;
  subtitle: ComputedRef<string>;
  inputs: ComputedRef<CanvasConnectionPort[]>;
  outputs: ComputedRef<CanvasConnectionPort[]>;
  connections: ComputedRef<INodeConnections>;
  isDisabled: ComputedRef<boolean>;
  isReadOnly: ComputedRef<boolean>;
  isSelected: ComputedRef<boolean>;
  pinnedDataCount: ComputedRef<number>;
  hasPinnedData: ComputedRef<boolean>;
  runDataIterations: ComputedRef<number>;
  runDataOutputMap: ComputedRef<Record<string, any>>;
  hasRunData: ComputedRef<boolean>;
  issues: ComputedRef<string[]>;
  hasIssues: ComputedRef<boolean>;
  executionStatus: ComputedRef<ExecutionStatus | undefined>;
  executionWaiting: ComputedRef<string | undefined>;
  executionWaitingForNext: ComputedRef<boolean>;
  executionRunning: ComputedRef<boolean>;
  render: ComputedRef<CanvasNodeRender>;
  eventBus: ComputedRef<EventBus | undefined>;
}

/**
 * Canvas operations for node manipulation
 */
function useCanvasOperations(): CanvasOperationsReturn;

interface CanvasOperationsReturn {
  addNodes(nodes: AddedNode[], connections?: AddedNodeConnection[]): void;
  deleteNode(id: string): void;
  copyNodes(ids: string[]): void;
  pasteNodes(position?: XYPosition): void;
  createConnection(source: CanvasConnectionPort, target: CanvasConnectionPort): void;
  updateNodePosition(id: string, position: XYPosition): void;
}

/**
 * Canvas layout and arrangement
 */
function useCanvasLayout(): CanvasLayoutReturn;

interface CanvasLayoutReturn {
  layout(target: 'all' | 'selection'): void;
  arrangeNodes(nodes: INodeUi[], direction?: 'horizontal' | 'vertical'): INodeUi[];
}

Workflow Composables

Composables for workflow operations and management.

/**
 * Workflow helper functions
 */
function useWorkflowHelpers(): WorkflowHelpersReturn;

interface WorkflowHelpersReturn {
  getWorkflowDataToSave(): IWorkflowDataUpdate;
  saveCurrentWorkflow(options?: { tags?: string[] }): Promise<void>;
  getCurrentWorkflow(copyData?: boolean): Workflow;
  initializeWorkflow(): void;
  resolveRequiredParameters(node: INodeUi, nodeType: INodeTypeDescription): INodeParameters;
}

/**
 * Workflow execution helpers
 */
function useRunWorkflow(): RunWorkflowReturn;

interface RunWorkflowReturn {
  runWorkflowData: Ref<IStartRunData | null>;
  isExecutionPreview: Ref<boolean>;
  runWorkflow(data: IStartRunData): Promise<IExecutionPushResponse>;
  stopCurrentExecution(): Promise<void>;
  stopExecution(executionId: string): Promise<void>;
}

/**
 * Workflow saving functionality
 */
function useWorkflowSaving(): WorkflowSavingReturn;

interface WorkflowSavingReturn {
  isSaving: Ref<boolean>;
  hasUnsavedChanges: Ref<boolean>;
  saveWorkflow(options?: { tags?: string[]; redirect?: boolean }): Promise<void>;
  saveAsNewWorkflow(name: string): Promise<void>;
}

Node Composables

Node-specific helper composables.

/**
 * Node helper functions
 */
function useNodeHelpers(): NodeHelpersReturn;

interface NodeHelpersReturn {
  getNodeSubtitle(node: INodeUi, nodeType?: INodeTypeDescription, workflow?: Workflow): string;
  hasNodeCredential(node: INodeUi, credentialType: string): boolean;
  assignNodeId(node: INodeUi): string;
  getNodeIssues(node: INodeUi, workflow: Workflow): INodeIssues | null;
  updateNodeParameterIssues(node: INodeUi, issues?: INodeIssues): void;
}

/**
 * Node type information
 */
function useNodeType(params: { node: Ref<INodeUi | null> }): NodeTypeReturn;

interface NodeTypeReturn {
  nodeType: ComputedRef<INodeTypeDescription | null>;
  isSubNode: ComputedRef<boolean>;
  isTriggerNode: ComputedRef<boolean>;
  isConfigNode: ComputedRef<boolean>;
  hasMultipleOutputs: ComputedRef<boolean>;
}

/**
 * Node connections management
 */
function useNodeConnections(): NodeConnectionsReturn;

interface NodeConnectionsReturn {
  getNodeConnections(nodeName: string): { input: IConnection[][]; output: IConnection[][] };
  getChildNodes(nodeName: string): string[];
  getParentNodes(nodeName: string): string[];
  hasInputConnections(nodeName: string): boolean;
  hasOutputConnections(nodeName: string): boolean;
}

UI Interaction Composables

Composables for user interface interactions.

/**
 * Keyboard shortcuts management
 */
function useKeybindings(
  keymap: MaybeRefOrGetter<KeyMap>, 
  options?: KeybindingOptions
): void;

interface KeyMap {
  [key: string]: (event: KeyboardEvent) => void | boolean;
}

interface KeybindingOptions {
  disabled?: MaybeRefOrGetter<boolean>;
  preventDefault?: boolean;
  stopPropagation?: boolean;
}

/**
 * Toast notifications
 */
function useToast(): ToastReturn;

interface ToastReturn {
  showMessage(config: NotificationOptions): void;
  showError(error: Error | string, title?: string): void;
  showSuccess(message: string, title?: string): void;
  showWarning(message: string, title?: string): void;
  showInfo(message: string, title?: string): void;
}

/**
 * Loading states management
 */
function useLoadingService(): LoadingServiceReturn;

interface LoadingServiceReturn {
  startLoading(text?: string): void;
  stopLoading(): void;
  setLoadingText(text: string): void;
}

/**
 * Clipboard operations
 */
function useClipboard(): ClipboardReturn;

interface ClipboardReturn {
  copy(text: string): Promise<void>;
  paste(): Promise<string>;
  isSupported: boolean;
}

Data Management Composables

Composables for data processing and management.

/**
 * Data schema inference and handling
 */
function useDataSchema(): DataSchemaReturn;

interface DataSchemaReturn {
  getSchemaForData(data: INodeExecutionData[]): Schema[];
  inferSchema(value: unknown, path?: string): Schema;
  validateDataAgainstSchema(data: unknown, schema: Schema[]): ValidationResult;
}

/**
 * Pinned data management
 */
function usePinnedData(node: Ref<INodeUi>): PinnedDataReturn;

interface PinnedDataReturn {
  pinnedData: ComputedRef<IDataObject[] | undefined>;
  hasPinnedData: ComputedRef<boolean>;
  setPinnedData(data: IDataObject[]): void;
  removePinnedData(): void;
  canPinData: ComputedRef<boolean>;
}

/**
 * Expression editor functionality
 */
function useExpressionEditor(): ExpressionEditorReturn;

interface ExpressionEditorReturn {
  segments: Ref<Segment[]>;
  selection: Ref<Range>;
  insertText(text: string): void;
  insertExpression(expression: string): void;
  getValue(): string;
  setValue(value: string): void;
}

Utility Composables

General utility composables for common functionality.

/**
 * Debounced reactive values
 */
function useDebounce<T>(value: Ref<T>, delay: number): {
  debouncedValue: Ref<T>;
  flush(): void;
  cancel(): void;
};

/**
 * Document title management
 */
function useDocumentTitle(): DocumentTitleReturn;

interface DocumentTitleReturn {
  title: Ref<string>;
  setTitle(newTitle: string): void;
  resetTitle(): void;
}

/**
 * Local storage with reactivity
 */
function useN8nLocalStorage<T>(
  key: string, 
  defaultValue: T
): [Ref<T>, (value: T) => void];

/**
 * Message handling
 */
function useMessage(): MessageReturn;

interface MessageReturn {
  confirm(config: MessageBoxConfig): Promise<boolean>;
  alert(config: MessageBoxConfig): Promise<void>;
  prompt(config: MessageBoxConfig): Promise<string>;
}

/**
 * External hooks integration
 */
function useExternalHooks(): ExternalHooksReturn;

interface ExternalHooksReturn {
  run(hookName: string, ...args: any[]): Promise<void>;
  runWithReturn<T>(hookName: string, ...args: any[]): Promise<T>;
}

Usage Examples

Canvas Node Composable:

<script setup lang="ts">
import { useCanvasNode } from '@/composables/useCanvasNode';

// Access node data within canvas node component
const {
  node,
  name,
  label,
  inputs,
  outputs,
  isSelected,
  hasIssues,
  executionRunning
} = useCanvasNode();

// Reactive node properties
watchEffect(() => {
  if (hasIssues.value) {
    console.warn(`Node ${name.value} has issues`);
  }
});
</script>

Keyboard Bindings:

import { useKeybindings } from '@/composables/useKeybindings';

// Define keyboard shortcuts
const keyMap = {
  'ctrl+s': () => saveWorkflow(),
  'ctrl+z': () => undo(),
  'ctrl+y': () => redo(),
  'delete': () => deleteSelectedNodes(),
  'ctrl+c': () => copyNodes(),
  'ctrl+v': () => pasteNodes(),
  'escape': () => deselectAll()
};

// Apply keybindings with options
useKeybindings(keyMap, {
  disabled: computed(() => isModalOpen.value),
  preventDefault: true
});

Toast Notifications:

import { useToast } from '@/composables/useToast';

const toast = useToast();

// Show different types of notifications
const handleSuccess = () => {
  toast.showSuccess('Workflow saved successfully!');
};

const handleError = (error: Error) => {
  toast.showError(error, 'Failed to save workflow');
};

const handleCustomMessage = () => {
  toast.showMessage({
    message: 'Custom notification',
    type: 'info',
    duration: 5000,
    showClose: true
  });
};

Data Schema Usage:

import { useDataSchema } from '@/composables/useDataSchema';

const { getSchemaForData, inferSchema } = useDataSchema();

// Infer schema from execution data
const executionData = [
  { json: { id: 1, name: 'John', active: true } },
  { json: { id: 2, name: 'Jane', active: false } }
];

const schema = getSchemaForData(executionData);
console.log(schema); // Inferred schema structure

Types

interface Segment {
  kind: SegmentKind;
  content: string;
  from: number;
  to: number;
}

enum SegmentKind {
  Text = 'text',
  Expression = 'expression',
  Resolvable = 'resolvable'
}

interface Range {
  from: number;
  to: number;
}

interface Schema {
  type: SchemaType;
  key?: string;
  value: string | Schema[];
  path: string;
}

type SchemaType = 
  | 'string' 
  | 'number' 
  | 'boolean' 
  | 'array' 
  | 'object' 
  | 'null' 
  | 'undefined';

interface ValidationResult {
  isValid: boolean;
  errors: string[];
}

interface NotificationOptions {
  message: string;
  title?: string;
  type?: 'success' | 'warning' | 'info' | 'error';
  duration?: number;
  showClose?: boolean;
  offset?: number;
  onClose?: () => void;
}

interface MessageBoxConfig {
  title?: string;
  message: string;
  type?: 'success' | 'warning' | 'info' | 'error';
  confirmButtonText?: string;
  cancelButtonText?: string;
  showCancelButton?: boolean;
  dangerouslyUseHTMLString?: boolean;
}

type MaybeRefOrGetter<T> = T | Ref<T> | (() => T);

docs

api-client.md

canvas-operations.md

component-system.md

composables.md

index.md

state-management.md

workflow-management.md

tile.json