Skip to content

Commit

Permalink
feat: Add reusable frontend composables package (#13077)
Browse files Browse the repository at this point in the history
Co-authored-by: कारतोफ्फेलस्क्रिप्ट™ <[email protected]>
  • Loading branch information
alexgrozav and netroy authored Feb 6, 2025
1 parent df89c6f commit ef87da4
Show file tree
Hide file tree
Showing 49 changed files with 684 additions and 309 deletions.
1 change: 1 addition & 0 deletions codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ component_management:
- packages/@n8n/codemirror-lang/**
- packages/design-system/**
- packages/editor-ui/**
- packages/frontend/**
- component_id: nodes_packages
name: Nodes
paths:
Expand Down
10 changes: 3 additions & 7 deletions packages/design-system/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
const sharedOptions = require('@n8n_io/eslint-config/shared');
const { createFrontendEslintConfig } = require('@n8n/frontend-eslint-config');

/**
* @type {import('@types/eslint').ESLint.ConfigData}
*/
module.exports = {
extends: ['@n8n_io/eslint-config/frontend'],

...sharedOptions(__dirname, 'frontend'),

module.exports = createFrontendEslintConfig(__dirname, {
rules: {
// TODO: Remove these
'import/no-default-export': 'warn',
Expand Down Expand Up @@ -44,4 +40,4 @@ module.exports = {
},
},
],
};
});
8 changes: 6 additions & 2 deletions packages/design-system/package.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"name": "n8n-design-system",
"version": "1.67.0",
"main": "src/main.ts",
"import": "src/main.ts",
"main": "src/index.ts",
"import": "src/index.ts",
"scripts": {
"dev": "pnpm run storybook",
"clean": "rimraf dist .turbo",
Expand All @@ -19,6 +19,9 @@
"lintfix": "eslint src --ext .js,.ts,.vue --fix"
},
"devDependencies": {
"@n8n/frontend-eslint-config": "workspace:*",
"@n8n/frontend-typescript-config": "workspace:*",
"@n8n/frontend-vitest-config": "workspace:*",
"@n8n/storybook": "workspace:*",
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/user-event": "^14.6.0",
Expand All @@ -41,6 +44,7 @@
"vue-tsc": "catalog:frontend"
},
"dependencies": {
"@n8n/composables": "workspace:*",
"@fortawesome/fontawesome-svg-core": "^1.2.36",
"@fortawesome/free-solid-svg-icons": "^5.15.4",
"@fortawesome/vue-fontawesome": "^3.0.3",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script setup lang="ts">
import { useDeviceSupport } from '@n8n/composables/useDeviceSupport';
import { computed } from 'vue';
import { useDeviceSupport } from '../../composables/useDeviceSupport';
import type { KeyboardShortcut } from '../../types/keyboardshortcut';
const props = defineProps<KeyboardShortcut>();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { render } from '@testing-library/vue';

import { N8nAvatar, N8nUserInfo } from 'n8n-design-system/main';

import UserStack from './UserStack.vue';
import { N8nAvatar, N8nUserInfo } from '../index';

describe('UserStack', () => {
it('should render flat user list', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import * as locale from './locale';

export { useDeviceSupport } from './composables/useDeviceSupport';
export * from './components';
export * from './plugin';
export * from './types';
Expand Down
23 changes: 7 additions & 16 deletions packages/design-system/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,29 +1,20 @@
{
"extends": "../../tsconfig.json",
"extends": "@n8n/frontend-typescript-config",
"compilerOptions": {
"rootDir": ".",
"outDir": "dist",
"target": "esnext",
"module": "esnext",
"importHelpers": true,
"allowJs": true,
"incremental": false,
"allowSyntheticDefaultImports": true,
"baseUrl": ".",
"types": ["vitest/globals"],
"rootDirs": [".", "../../frontend/@n8n/composables/src"],
"outDir": "dist",
"types": ["vite/client", "vitest/globals"],
"typeRoots": [
"./node_modules/@testing-library",
"./node_modules/@types",
"../../node_modules",
"../../node_modules/@types"
],
"paths": {
"n8n-design-system/*": ["./src/*"]
},
"lib": ["esnext", "dom", "dom.iterable", "scripthost"],
// TODO: remove all options below this line
"noImplicitAny": false,
"noImplicitReturns": false
"n8n-design-system*": ["./src*"],
"@n8n/composables*": ["../frontend/@n8n/composables/src*"]
}
},
"include": ["src/**/*.ts", "src/**/*.vue"]
}
30 changes: 4 additions & 26 deletions packages/design-system/vite.config.mts
Original file line number Diff line number Diff line change
@@ -1,35 +1,12 @@
import vue from '@vitejs/plugin-vue';
import { resolve } from 'path';
import { defineConfig, mergeConfig } from 'vite';
import { type UserConfig } from 'vitest';
import { defineConfig as defineVitestConfig } from 'vitest/config';
import components from 'unplugin-vue-components/vite';
import icons from 'unplugin-icons/vite';
import iconsResolver from 'unplugin-icons/resolver';
import { vitestConfig } from '@n8n/frontend-vitest-config';

export const vitestConfig = defineVitestConfig({
test: {
silent: true,
globals: true,
environment: 'jsdom',
setupFiles: ['./src/__tests__/setup.ts'],
...(process.env.COVERAGE_ENABLED === 'true'
? {
coverage: {
enabled: true,
provider: 'v8',
reporter: process.env.CI === 'true' ? 'cobertura' : 'text-summary',
all: true,
},
}
: {}),
css: {
modules: {
classNameStrategy: 'non-scoped',
},
},
},
}) as UserConfig;
const frontendDir = resolve(__dirname, '..', 'frontend');

export default mergeConfig(
defineConfig({
Expand All @@ -53,12 +30,13 @@ export default mergeConfig(
alias: {
'@': resolve(__dirname, 'src'),
'n8n-design-system': resolve(__dirname, 'src'),
'@n8n/composables(.*)': resolve(frontendDir, '@n8n', 'composables', 'src$1'),
lodash: 'lodash-es',
},
},
build: {
lib: {
entry: resolve(__dirname, 'src', 'main.ts'),
entry: resolve(__dirname, 'src', 'index.ts'),
name: 'N8nDesignSystem',
fileName: (format) => `n8n-design-system.${format}.js`,
},
Expand Down
10 changes: 3 additions & 7 deletions packages/editor-ui/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
const sharedOptions = require('@n8n_io/eslint-config/shared');
const { createFrontendEslintConfig } = require('@n8n/frontend-eslint-config');

/**
* @type {import('@types/eslint').ESLint.ConfigData}
*/
module.exports = {
extends: ['@n8n_io/eslint-config/frontend'],

...sharedOptions(__dirname, 'frontend'),

module.exports = createFrontendEslintConfig(__dirname, {
rules: {
'n8n-local-rules/dangerously-use-html-string-missing': 'error',

Expand Down Expand Up @@ -41,4 +37,4 @@ module.exports = {
'@typescript-eslint/no-redundant-type-constituents': 'warn',
'@typescript-eslint/no-unsafe-enum-comparison': 'warn',
},
};
});
4 changes: 4 additions & 0 deletions packages/editor-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"@n8n/chat": "workspace:*",
"@n8n/codemirror-lang": "workspace:*",
"@n8n/codemirror-lang-sql": "^1.0.2",
"@n8n/composables": "workspace:*",
"@n8n/permissions": "workspace:*",
"@replit/codemirror-indentation-markers": "^6.5.3",
"@sentry/vue": "catalog:frontend",
Expand Down Expand Up @@ -92,6 +93,9 @@
"xss": "catalog:"
},
"devDependencies": {
"@n8n/frontend-eslint-config": "workspace:*",
"@n8n/frontend-vitest-config": "workspace:*",
"@n8n/frontend-typescript-config": "workspace:*",
"@faker-js/faker": "^8.0.2",
"@iconify/json": "^2.2.228",
"@pinia/testing": "^0.1.6",
Expand Down
2 changes: 1 addition & 1 deletion packages/editor-ui/src/components/CanvasControls.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { onBeforeMount, onBeforeUnmount } from 'vue';
import { storeToRefs } from 'pinia';
import { useCanvasStore } from '@/stores/canvas.store';
import KeyboardShortcutTooltip from '@/components/KeyboardShortcutTooltip.vue';
import { useDeviceSupport } from 'n8n-design-system';
import { useDeviceSupport } from '@n8n/composables/useDeviceSupport';
import { useI18n } from '@/composables/useI18n';
const canvasStore = useCanvasStore();
Expand Down
3 changes: 2 additions & 1 deletion packages/editor-ui/src/components/Node.vue
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ import { getTriggerNodeServiceName } from '@/utils/nodeTypesUtils';
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
import type { BrowserJsPlumbInstance } from '@jsplumb/browser-ui';
import { get } from 'lodash-es';
import { N8nIconButton, useDeviceSupport } from 'n8n-design-system';
import { N8nIconButton } from 'n8n-design-system';
import { useDeviceSupport } from '@n8n/composables/useDeviceSupport';
type Props = {
name: string;
Expand Down
2 changes: 1 addition & 1 deletion packages/editor-ui/src/components/NodeDetailsView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import { useNDVStore } from '@/stores/ndv.store';
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
import { useUIStore } from '@/stores/ui.store';
import { useSettingsStore } from '@/stores/settings.store';
import { useDeviceSupport } from 'n8n-design-system';
import { useDeviceSupport } from '@n8n/composables/useDeviceSupport';
import { useNodeHelpers } from '@/composables/useNodeHelpers';
import { useMessage } from '@/composables/useMessage';
import { useExternalHooks } from '@/composables/useExternalHooks';
Expand Down
2 changes: 1 addition & 1 deletion packages/editor-ui/src/components/Sticky.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { useWorkflowsStore } from '@/stores/workflows.store';
import { useNDVStore } from '@/stores/ndv.store';
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
import { useContextMenu } from '@/composables/useContextMenu';
import { useDeviceSupport } from 'n8n-design-system';
import { useDeviceSupport } from '@n8n/composables/useDeviceSupport';
import { GRID_SIZE } from '@/utils/nodeViewUtils';
import { useToast } from '@/composables/useToast';
import { assert } from '@/utils/assert';
Expand Down
2 changes: 1 addition & 1 deletion packages/editor-ui/src/components/canvas/Canvas.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { createPinia, setActivePinia } from 'pinia';
import type { CanvasConnection, CanvasNode } from '@/types';
import { createCanvasConnection, createCanvasNodeElement } from '@/__tests__/data';
import { NodeConnectionType } from 'n8n-workflow';
import type { useDeviceSupport } from 'n8n-design-system';
import type { useDeviceSupport } from '@n8n/composables/useDeviceSupport';

const matchMedia = global.window.matchMedia;
// @ts-expect-error Initialize window object
Expand Down
3 changes: 2 additions & 1 deletion packages/editor-ui/src/components/canvas/Canvas.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ import Node from './elements/nodes/CanvasNode.vue';
import Edge from './elements/edges/CanvasEdge.vue';
import { computed, onMounted, onUnmounted, provide, ref, toRef, useCssModule, watch } from 'vue';
import type { EventBus } from 'n8n-design-system';
import { createEventBus, useDeviceSupport } from 'n8n-design-system';
import { createEventBus } from 'n8n-design-system';
import { useDeviceSupport } from '@n8n/composables/useDeviceSupport';
import { useContextMenu, type ContextMenuAction } from '@/composables/useContextMenu';
import { useKeybindings } from '@/composables/useKeybindings';
import ContextMenu from '@/components/ContextMenu/ContextMenu.vue';
Expand Down
2 changes: 1 addition & 1 deletion packages/editor-ui/src/composables/useCanvasMouseSelect.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { INodeUi, XYPosition } from '@/Interface';

import { useDeviceSupport } from 'n8n-design-system';
import { useDeviceSupport } from '@n8n/composables/useDeviceSupport';
import { useUIStore } from '@/stores/ui.store';
import { useWorkflowsStore } from '@/stores/workflows.store';
import { getMousePosition, getRelativePosition } from '@/utils/nodeViewUtils';
Expand Down
2 changes: 1 addition & 1 deletion packages/editor-ui/src/composables/useCanvasPanning.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { ref, unref } from 'vue';

import { getMousePosition } from '@/utils/nodeViewUtils';
import { useUIStore } from '@/stores/ui.store';
import { useDeviceSupport } from 'n8n-design-system';
import { useDeviceSupport } from '@n8n/composables/useDeviceSupport';
import { MOUSE_EVENT_BUTTON, MOUSE_EVENT_BUTTONS } from '@/constants';

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/editor-ui/src/composables/useDebugInfo.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ vi.mock('@/stores/settings.store', () => ({
useSettingsStore,
}));

vi.mock('n8n-design-system', () => ({
vi.mock('@n8n/composables/useDeviceSupport', () => ({
useDeviceSupport: () => ({
isTouchDevice: false,
userAgent: 'Mozilla/5.0',
Expand Down
2 changes: 1 addition & 1 deletion packages/editor-ui/src/composables/useDebugInfo.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useRootStore } from '@/stores/root.store';
import { useSettingsStore } from '@/stores/settings.store';
import { useDeviceSupport } from 'n8n-design-system';
import { useDeviceSupport } from '@n8n/composables/useDeviceSupport';
import type { WorkflowSettings } from 'n8n-workflow';

type DebugInfo = {
Expand Down
2 changes: 1 addition & 1 deletion packages/editor-ui/src/composables/useHistoryHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { useHistoryStore } from '@/stores/history.store';
import { useUIStore } from '@/stores/ui.store';

import { onMounted, onUnmounted, nextTick } from 'vue';
import { useDeviceSupport } from 'n8n-design-system';
import { useDeviceSupport } from '@n8n/composables/useDeviceSupport';
import { getNodeViewTab } from '@/utils/canvasUtils';
import type { RouteLocationNormalizedLoaded } from 'vue-router';
import { useTelemetry } from './useTelemetry';
Expand Down
2 changes: 1 addition & 1 deletion packages/editor-ui/src/composables/useKeybindings.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useActiveElement, useEventListener } from '@vueuse/core';
import { useDeviceSupport } from 'n8n-design-system';
import { useDeviceSupport } from '@n8n/composables/useDeviceSupport';
import type { MaybeRef, Ref } from 'vue';
import { computed, unref } from 'vue';

Expand Down
2 changes: 1 addition & 1 deletion packages/editor-ui/src/composables/useNodeBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import type { BrowserJsPlumbInstance } from '@jsplumb/browser-ui';
import type { Endpoint, EndpointOptions } from '@jsplumb/core';
import * as NodeViewUtils from '@/utils/nodeViewUtils';
import type { EndpointSpec } from '@jsplumb/common';
import { useDeviceSupport } from 'n8n-design-system';
import { useDeviceSupport } from '@n8n/composables/useDeviceSupport';
import type { N8nEndpointLabelLength } from '@/plugins/jsplumb/N8nPlusEndpointType';
import { isValidNodeConnectionType } from '@/utils/typeGuards';
import { useI18n } from '@/composables/useI18n';
Expand Down
2 changes: 1 addition & 1 deletion packages/editor-ui/src/views/NodeView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ import { useExternalHooks } from '@/composables/useExternalHooks';
import { useClipboard } from '@/composables/useClipboard';
import { usePinnedData } from '@/composables/usePinnedData';
import { useSourceControlStore } from '@/stores/sourceControl.store';
import { useDeviceSupport } from 'n8n-design-system';
import { useDeviceSupport } from '@n8n/composables/useDeviceSupport';
import { useDebounce } from '@/composables/useDebounce';
import { useExecutionsStore } from '@/stores/executions.store';
import { useCanvasPanning } from '@/composables/useCanvasPanning';
Expand Down
23 changes: 10 additions & 13 deletions packages/editor-ui/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,29 +1,26 @@
{
"extends": "../../tsconfig.json",
"extends": "@n8n/frontend-typescript-config",
"compilerOptions": {
"rootDirs": [".", "../design-system/src", "../@n8n/chat/src"],
"outDir": "dist",
"target": "esnext",
"module": "esnext",
"allowJs": true,
"importHelpers": true,
"incremental": false,
"allowSyntheticDefaultImports": true,
"resolveJsonModule": true,
"baseUrl": ".",
"rootDirs": [
".",
"../../frontend/@n8n/composables/src",
"../design-system/src",
"../@n8n/chat/src"
],
"outDir": "dist",
"types": [
"vitest/globals",
"unplugin-icons/types/vue",
"../design-system/src/shims-modules.d.ts"
],
"paths": {
"@/*": ["./src/*"],
"n8n-design-system": ["../design-system/src/main.ts"],
"n8n-design-system/*": ["../design-system/src/*"],
"n8n-design-system*": ["../design-system/src*"],
"@n8n/composables*": ["../frontend/@n8n/composables/src*"],
"@n8n/chat/*": ["../@n8n/chat/src/*"],
"@n8n/api-types*": ["../@n8n/api-types/src*"]
},
"lib": ["esnext", "dom", "dom.iterable", "scripthost"],
// TODO: remove all options below this line
"useUnknownInCatchVariables": false
},
Expand Down
Loading

0 comments on commit ef87da4

Please sign in to comment.