diff --git a/.editorconfig b/.editorconfig index fdda2197f7..e856ea3dfa 100644 --- a/.editorconfig +++ b/.editorconfig @@ -15,3 +15,6 @@ indent_size = 2 [*.yml] indent_style = space indent_size = 2 + +[*.ts] +quote_type = single diff --git a/.prettierignore b/.prettierignore index 63e74dec4c..02a74339d6 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,7 +1,6 @@ dist packages/editor-ui -packages/design-system -package*.json +package.json !packages/nodes-base/src !packages/nodes-base/test diff --git a/packages/@n8n_io/eslint-config/base.js b/packages/@n8n_io/eslint-config/base.js index 179ff58a79..6eefc50042 100644 --- a/packages/@n8n_io/eslint-config/base.js +++ b/packages/@n8n_io/eslint-config/base.js @@ -9,11 +9,9 @@ const config = (module.exports = { }, ignorePatterns: [ - '.eslintrc.js', // TODO: remove this 'node_modules/**', 'dist/**', 'test/**', // TODO: remove this - 'jest.config.js', // TODO: remove this ], plugins: [ diff --git a/packages/@n8n_io/eslint-config/frontend.js b/packages/@n8n_io/eslint-config/frontend.js index 5566730fe0..e82df9033c 100644 --- a/packages/@n8n_io/eslint-config/frontend.js +++ b/packages/@n8n_io/eslint-config/frontend.js @@ -14,10 +14,15 @@ module.exports = { parser: 'vue-eslint-parser', parserOptions: { - parser: '@typescript-eslint/parser', + parser: { + ts: '@typescript-eslint/parser', + js: '@typescript-eslint/parser', + vue: 'vue-eslint-parser', + template: 'vue-eslint-parser', + }, }, - ignorePatterns: ['**/*.js', '**/*.d.ts', 'vite.config.ts'], + ignorePatterns: ['**/*.js', '**/*.d.ts', 'vite.config.ts', '**/*.ts.snap'], rules: { 'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', diff --git a/packages/design-system/.editorconfig b/packages/design-system/.editorconfig deleted file mode 100644 index 9e24325d41..0000000000 --- a/packages/design-system/.editorconfig +++ /dev/null @@ -1,15 +0,0 @@ -root = true - -[*] -charset = utf-8 -indent_style = tab -end_of_line = lf -insert_final_newline = true -trim_trailing_whitespace = true - -[package.json] -indent_style = space -indent_size = 2 - -[*.ts] -quote_type = single diff --git a/packages/design-system/.eslintrc.js b/packages/design-system/.eslintrc.js index 502408aeed..280597fb81 100644 --- a/packages/design-system/.eslintrc.js +++ b/packages/design-system/.eslintrc.js @@ -6,23 +6,50 @@ module.exports = { parserOptions: { project: ['./tsconfig.json'], + tsconfigRootDir: __dirname, + extraFileExtensions: ['.vue'], }, rules: { // TODO: Remove these 'import/no-default-export': 'off', - 'import/no-extraneous-dependencies': 'off', 'import/order': 'off', - 'prettier/prettier': 'off', - '@typescript-eslint/member-delimiter-style': 'off', - '@typescript-eslint/naming-convention': 'off', - '@typescript-eslint/no-explicit-any': 'off', - '@typescript-eslint/no-unsafe-argument': 'off', - '@typescript-eslint/no-unsafe-return': 'off', - '@typescript-eslint/no-unused-vars': 'off', - '@typescript-eslint/prefer-nullish-coalescing': 'off', - '@typescript-eslint/prefer-optional-chain': 'off', - '@typescript-eslint/restrict-template-expressions': 'off', - '@typescript-eslint/ban-ts-comment': ['warn', { 'ts-ignore': true }], - } + '@typescript-eslint/no-explicit-any': 'warn', + '@typescript-eslint/no-unsafe-argument': 'warn', + '@typescript-eslint/no-unsafe-return': 'warn', + '@typescript-eslint/no-unsafe-member-access': 'warn', + }, + + overrides: [ + { + files: ['src/**/*.stories.{js,ts}'], + rules: { + 'import/no-extraneous-dependencies': ['error', { devDependencies: true }], + }, + }, + { + files: ['src/**/*.stories.{js,ts}', 'src/**/*.vue', 'src/**/*.spec.ts'], + rules: { + '@typescript-eslint/naming-convention': [ + 'warn', + { + selector: ['variable', 'property'], + format: ['PascalCase', 'camelCase', 'UPPER_CASE'], + }, + ], + }, + }, + { + files: ['src/components/N8nFormInput/validators.ts'], + rules: { + '@typescript-eslint/naming-convention': [ + 'error', + { + selector: ['property'], + format: ['camelCase', 'UPPER_CASE'], + }, + ], + }, + }, + ], }; diff --git a/packages/design-system/.gitignore b/packages/design-system/.gitignore index 20687473be..8db271232f 100644 --- a/packages/design-system/.gitignore +++ b/packages/design-system/.gitignore @@ -1 +1,2 @@ +coverage storybook-static diff --git a/packages/design-system/.prettierignore b/packages/design-system/.prettierignore new file mode 100644 index 0000000000..9961be877c --- /dev/null +++ b/packages/design-system/.prettierignore @@ -0,0 +1,3 @@ +coverage +dist +package.json diff --git a/packages/design-system/.storybook/main.js b/packages/design-system/.storybook/main.js index 5ec41a5774..e4413680bc 100644 --- a/packages/design-system/.storybook/main.js +++ b/packages/design-system/.storybook/main.js @@ -14,7 +14,7 @@ module.exports = { postcssLoaderOptions: { implementation: require('postcss'), }, - } + }, }, 'storybook-addon-designs', 'storybook-addon-themes', diff --git a/packages/design-system/.storybook/storybook.scss b/packages/design-system/.storybook/storybook.scss index 59849fa048..125f7d57a8 100644 --- a/packages/design-system/.storybook/storybook.scss +++ b/packages/design-system/.storybook/storybook.scss @@ -1,11 +1,11 @@ -@use "./fonts.scss"; +@use './fonts.scss'; -@use "~/src/css/base.scss" with ( - $font-path: '~element-ui/lib/theme-chalk/fonts', +@use '~/src/css/base.scss' with ( + $font-path: '~element-ui/lib/theme-chalk/fonts' ); -@use "~/src/css/reset.scss"; -@use "~/src/css/index.scss"; +@use '~/src/css/reset.scss'; +@use '~/src/css/index.scss'; .multi-container > * { margin-bottom: 10px; diff --git a/packages/design-system/package.json b/packages/design-system/package.json index e268f1c671..aa60fe6c82 100644 --- a/packages/design-system/package.json +++ b/packages/design-system/package.json @@ -21,15 +21,22 @@ "test:dev": "vitest", "build:storybook": "build-storybook", "storybook": "start-storybook -p 6006", - "format": "prettier **/**.{ts,vue} --write", - "lint": "tslint -p tsconfig.json -c tslint.json && eslint .", - "lintfix": "tslint --fix -p tsconfig.json -c tslint.json && eslint . --fix" + "format": "prettier **/**.{js,ts,vue,css,scss,mdx,html} --write .", + "lint": "eslint --ext .js,.ts,.vue src", + "lintfix": "eslint --ext .js,.ts,.vue src --fix" }, "peerDependencies": { "@fortawesome/fontawesome-svg-core": "1.x", "@fortawesome/free-solid-svg-icons": "5.x", "@fortawesome/vue-fontawesome": "2.x", - "core-js": "3.x" + "core-js": "3.x", + "markdown-it": "^12.3.2", + "markdown-it-emoji": "^2.0.0", + "markdown-it-link-attributes": "^4.0.0", + "markdown-it-task-lists": "^2.1.1", + "vue": "^2.7", + "vue-typed-mixins": "^0.2.0", + "xss": "^1.0.10" }, "devDependencies": { "@fortawesome/fontawesome-svg-core": "^1.2.35", @@ -43,14 +50,12 @@ "@testing-library/jest-dom": "^5.16.4", "@testing-library/vue": "^5.8.3", "@types/markdown-it": "^12.2.3", + "@types/markdown-it-emoji": "^2.0.2", + "@types/markdown-it-link-attributes": "^3.0.1", "@types/sanitize-html": "^2.6.2", "c8": "7.11.0", "core-js": "^3.6.5", "jsdom": "19.0.0", - "markdown-it": "^12.3.2", - "markdown-it-emoji": "^2.0.0", - "markdown-it-link-attributes": "^4.0.0", - "markdown-it-task-lists": "^2.1.1", "node-notifier": ">=8.0.1", "sass": "^1.55.0", "sass-loader": "^10.1.1", @@ -60,16 +65,13 @@ "vite": "^2.9.5", "@vitejs/plugin-vue2": "^1.1.2", "vitest": "^0.9.3", - "vue": "^2.7", "vue-class-component": "^7.2.3", "vue-loader": "^15.9.7", "vue-property-decorator": "^9.1.2", "vue-template-compiler": "^2.7", "vue-tsc": "^0.34.8", - "vue-typed-mixins": "^0.2.0", "vue2-boring-avatars": "0.3.4", - "webpack": "^4.46.0", - "xss": "^1.0.10" + "webpack": "^4.46.0" }, "dependencies": { "element-ui": "~2.15.7", diff --git a/packages/design-system/src/components/N8nActionBox/ActionBox.stories.ts b/packages/design-system/src/components/N8nActionBox/ActionBox.stories.ts index 57fb3726c4..dfc6d27cf7 100644 --- a/packages/design-system/src/components/N8nActionBox/ActionBox.stories.ts +++ b/packages/design-system/src/components/N8nActionBox/ActionBox.stories.ts @@ -1,8 +1,6 @@ -/* tslint:disable:variable-name */ - import N8nActionBox from './ActionBox.vue'; import { action } from '@storybook/addon-actions'; -import {StoryFn} from "@storybook/vue"; +import type { StoryFn } from '@storybook/vue'; export default { title: 'Atoms/ActionBox', @@ -35,8 +33,9 @@ const Template: StoryFn = (args, { argTypes }) => ({ export const ActionBox = Template.bind({}); ActionBox.args = { - emoji: "😿", - heading: "Headline you need to know", - description: "Long description that you should know something is the way it is because of how it is. ", - buttonText: "Do something", + emoji: '😿', + heading: 'Headline you need to know', + description: + 'Long description that you should know something is the way it is because of how it is. ', + buttonText: 'Do something', }; diff --git a/packages/design-system/src/components/N8nActionBox/ActionBox.vue b/packages/design-system/src/components/N8nActionBox/ActionBox.vue index f2853deb89..a2233d83fd 100644 --- a/packages/design-system/src/components/N8nActionBox/ActionBox.vue +++ b/packages/design-system/src/components/N8nActionBox/ActionBox.vue @@ -118,5 +118,4 @@ export default Vue.extend({ width: 100%; text-align: left; } - diff --git a/packages/design-system/src/components/N8nActionBox/__tests__/ActionBox.spec.ts b/packages/design-system/src/components/N8nActionBox/__tests__/ActionBox.spec.ts index 90cc3e55a9..635836bd1d 100644 --- a/packages/design-system/src/components/N8nActionBox/__tests__/ActionBox.spec.ts +++ b/packages/design-system/src/components/N8nActionBox/__tests__/ActionBox.spec.ts @@ -1,21 +1,17 @@ -import {render} from '@testing-library/vue'; +import { render } from '@testing-library/vue'; import N8NActionBox from '../ActionBox.vue'; describe('N8NActionBox', () => { it('should render correctly', () => { const wrapper = render(N8NActionBox, { props: { - emoji: "😿", - heading: "Headline you need to know", - description: "Long description that you should know something is the way it is because of how it is. ", - buttonText: "Do something", + emoji: '😿', + heading: 'Headline you need to know', + description: + 'Long description that you should know something is the way it is because of how it is. ', + buttonText: 'Do something', }, - stubs: [ - 'n8n-heading', - 'n8n-text', - 'n8n-button', - 'n8n-callout', - ], + stubs: ['n8n-heading', 'n8n-text', 'n8n-button', 'n8n-callout'], }); expect(wrapper.html()).toMatchSnapshot(); }); diff --git a/packages/design-system/src/components/N8nActionDropdown/ActionDropdown.stories.ts b/packages/design-system/src/components/N8nActionDropdown/ActionDropdown.stories.ts index 149d255ba0..472506702c 100644 --- a/packages/design-system/src/components/N8nActionDropdown/ActionDropdown.stories.ts +++ b/packages/design-system/src/components/N8nActionDropdown/ActionDropdown.stories.ts @@ -1,5 +1,5 @@ -import N8nActionDropdown from "./ActionDropdown.vue"; -import { StoryFn } from '@storybook/vue'; +import N8nActionDropdown from './ActionDropdown.vue'; +import type { StoryFn } from '@storybook/vue'; export default { title: 'Atoms/ActionDropdown', diff --git a/packages/design-system/src/components/N8nActionDropdown/ActionDropdown.vue b/packages/design-system/src/components/N8nActionDropdown/ActionDropdown.vue index 13663cfb17..40855b19dc 100644 --- a/packages/design-system/src/components/N8nActionDropdown/ActionDropdown.vue +++ b/packages/design-system/src/components/N8nActionDropdown/ActionDropdown.vue @@ -1,8 +1,13 @@ diff --git a/packages/design-system/src/components/N8nActionToggle/ActionToggle.stories.js b/packages/design-system/src/components/N8nActionToggle/ActionToggle.stories.js index f51148a3b1..176121f3b1 100644 --- a/packages/design-system/src/components/N8nActionToggle/ActionToggle.stories.js +++ b/packages/design-system/src/components/N8nActionToggle/ActionToggle.stories.js @@ -28,7 +28,8 @@ const Template = (args, { argTypes }) => ({ components: { N8nActionToggle, }, - template: '
', + template: + '
', methods, }); diff --git a/packages/design-system/src/components/N8nActionToggle/ActionToggle.vue b/packages/design-system/src/components/N8nActionToggle/ActionToggle.vue index 6efe41185d..1bed9e6888 100644 --- a/packages/design-system/src/components/N8nActionToggle/ActionToggle.vue +++ b/packages/design-system/src/components/N8nActionToggle/ActionToggle.vue @@ -8,11 +8,8 @@ @command="onCommand" @visible-change="onVisibleChange" > - - + + - {{action.label}} + {{ action.label }}
- ['mini', 'small', 'medium'].includes(value), + validator: (value: string): boolean => ['mini', 'small', 'medium'].includes(value), }, iconSize: { type: String, @@ -75,8 +71,7 @@ export default Vue.extend({ theme: { type: String, default: 'default', - validator: (value: string): boolean => - ['default', 'dark'].includes(value), + validator: (value: string): boolean => ['default', 'dark'].includes(value), }, }, methods: { diff --git a/packages/design-system/src/components/N8nAvatar/Avatar.vue b/packages/design-system/src/components/N8nAvatar/Avatar.vue index 9b109fbb75..c382239617 100644 --- a/packages/design-system/src/components/N8nAvatar/Avatar.vue +++ b/packages/design-system/src/components/N8nAvatar/Avatar.vue @@ -1,5 +1,5 @@ diff --git a/packages/design-system/src/components/N8nButton/Button.stories.ts b/packages/design-system/src/components/N8nButton/Button.stories.ts index c56532d98a..7a46ae1c64 100644 --- a/packages/design-system/src/components/N8nButton/Button.stories.ts +++ b/packages/design-system/src/components/N8nButton/Button.stories.ts @@ -1,7 +1,6 @@ -/* tslint:disable:variable-name */ import N8nButton from './Button.vue'; import { action } from '@storybook/addon-actions'; -import { StoryFn } from "@storybook/vue"; +import type { StoryFn } from '@storybook/vue'; export default { title: 'Atoms/Button', @@ -63,22 +62,6 @@ const AllSizesTemplate: StoryFn = (args, { argTypes }) => ({ methods, }); -const AllColorsTemplate: StoryFn = (args, { argTypes }) => ({ - props: Object.keys(argTypes), - components: { - N8nButton, - }, - template: `
- - - - - - -
`, - methods, -}); - const AllColorsAndSizesTemplate: StoryFn = (args, { argTypes }) => ({ props: Object.keys(argTypes), components: { @@ -170,4 +153,3 @@ Square.args = { label: '48', square: true, }; - diff --git a/packages/design-system/src/components/N8nButton/Button.vue b/packages/design-system/src/components/N8nButton/Button.vue index c4cb3e4818..828ab31425 100644 --- a/packages/design-system/src/components/N8nButton/Button.vue +++ b/packages/design-system/src/components/N8nButton/Button.vue @@ -8,15 +8,8 @@ v-on="$listeners" > - - + + {{ label }} @@ -76,13 +69,12 @@ export default Vue.extend({ }, float: { type: String, - validator: (value: string): boolean => - ['left', 'right'].includes(value), + validator: (value: string): boolean => ['left', 'right'].includes(value), + }, + square: { + type: Boolean, + default: false, }, - square: { - type: Boolean, - default: false, - }, }, components: { N8nSpinner, @@ -96,7 +88,8 @@ export default Vue.extend({ return this.disabled ? 'true' : 'false'; }, classes(): string { - return `button ${this.$style.button} ${this.$style[this.type]}` + + return ( + `button ${this.$style.button} ${this.$style[this.type]}` + `${this.size ? ` ${this.$style[this.size]}` : ''}` + `${this.outline ? ` ${this.$style.outline}` : ''}` + `${this.loading ? ` ${this.$style.loading}` : ''}` + @@ -106,7 +99,8 @@ export default Vue.extend({ `${this.block ? ` ${this.$style.block}` : ''}` + `${this.active ? ` ${this.$style.active}` : ''}` + `${this.icon || this.loading ? ` ${this.$style.icon}` : ''}` + - `${this.square ? ` ${this.$style.square}` : ''}`; + `${this.square ? ` ${this.$style.square}` : ''}` + ); }, }, }); @@ -150,7 +144,8 @@ export default Vue.extend({ outline: $focus-outline-width solid $button-focus-outline-color; } - &:active, &.active { + &:active, + &.active { color: $button-active-color; border-color: $button-active-border-color; background-color: $button-active-background-color; @@ -213,7 +208,12 @@ $loading-overlay-background-color: rgba(255, 255, 255, 0); --button-hover-color: var(--color-text-dark); --button-hover-border-color: var(--color-neutral-800); - --button-focus-outline-color: hsla(var(--color-neutral-h), var(--color-neutral-s), var(--color-neutral-l), 0.2); + --button-focus-outline-color: hsla( + var(--color-neutral-h), + var(--color-neutral-s), + var(--color-neutral-l), + 0.2 + ); } .success { @@ -227,7 +227,12 @@ $loading-overlay-background-color: rgba(255, 255, 255, 0); --button-hover-background-color: var(--color-success-450); --button-hover-border-color: var(--color-success-450); - --button-focus-outline-color: hsla(var(--color-success-h), var(--color-success-s), var(--color-success-l), 0.33); + --button-focus-outline-color: hsla( + var(--color-success-h), + var(--color-success-s), + var(--color-success-l), + 0.33 + ); } .warning { @@ -241,7 +246,12 @@ $loading-overlay-background-color: rgba(255, 255, 255, 0); --button-hover-background-color: var(--color-warning-650); --button-hover-border-color: var(--color-warning-650); - --button-focus-outline-color: hsla(var(--color-warning-h), var(--color-warning-s), var(--color-warning-l), 0.33); + --button-focus-outline-color: hsla( + var(--color-warning-h), + var(--color-warning-s), + var(--color-warning-l), + 0.33 + ); } .danger { @@ -256,7 +266,12 @@ $loading-overlay-background-color: rgba(255, 255, 255, 0); --button-hover-background-color: var(--color-danger-700); --button-hover-border-color: var(--color-danger-700); - --button-focus-outline-color: hsla(var(--color-danger-h), var(--color-danger-s), var(--color-danger-l), 0.33); + --button-focus-outline-color: hsla( + var(--color-danger-h), + var(--color-danger-s), + var(--color-danger-l), + 0.33 + ); } /** @@ -440,7 +455,7 @@ $loading-overlay-background-color: rgba(255, 255, 255, 0); .icon { display: inline-flex; - justify-content: center; + justify-content: center; svg { display: block; diff --git a/packages/design-system/src/components/N8nButton/__tests__/Button.spec.ts b/packages/design-system/src/components/N8nButton/__tests__/Button.spec.ts index 050609656e..98f3212caf 100644 --- a/packages/design-system/src/components/N8nButton/__tests__/Button.spec.ts +++ b/packages/design-system/src/components/N8nButton/__tests__/Button.spec.ts @@ -1,6 +1,6 @@ -import {render} from '@testing-library/vue'; -import N8nButton from "../Button.vue"; -import ElButton from "../overrides/ElButton.vue"; +import { render } from '@testing-library/vue'; +import N8nButton from '../Button.vue'; +import ElButton from '../overrides/ElButton.vue'; const slots = { default: 'Button', diff --git a/packages/design-system/src/components/N8nButton/__tests__/__snapshots__/Button.spec.ts.snap b/packages/design-system/src/components/N8nButton/__tests__/__snapshots__/Button.spec.ts.snap index 38e7cb08e9..a5302043c8 100644 --- a/packages/design-system/src/components/N8nButton/__tests__/__snapshots__/Button.spec.ts.snap +++ b/packages/design-system/src/components/N8nButton/__tests__/__snapshots__/Button.spec.ts.snap @@ -1,17 +1,17 @@ // Vitest Snapshot v1 -exports[`components > N8nButton > overrides > should render correctly 1`] = `""`; +exports[`components > N8nButton > overrides > should render correctly 1`] = `""`; -exports[`components > N8nButton > props > icon > should render icon button 1`] = `""`; +exports[`components > N8nButton > props > icon > should render icon button 1`] = `""`; -exports[`components > N8nButton > props > loading > should render loading spinner 1`] = `""`; +exports[`components > N8nButton > props > loading > should render loading spinner 1`] = `""`; exports[`components > N8nButton > props > square > should render square button 1`] = ` -"" `; exports[`components > N8nButton > should render correctly 1`] = ` -"" `; diff --git a/packages/design-system/src/components/N8nButton/overrides/ElButton.ts b/packages/design-system/src/components/N8nButton/overrides/ElButton.ts index 9526a789c1..88c583bba1 100644 --- a/packages/design-system/src/components/N8nButton/overrides/ElButton.ts +++ b/packages/design-system/src/components/N8nButton/overrides/ElButton.ts @@ -1,3 +1,3 @@ -import ElButton from "./ElButton.vue"; +import ElButton from './ElButton.vue'; export default ElButton; diff --git a/packages/design-system/src/components/N8nButton/overrides/ElButton.vue b/packages/design-system/src/components/N8nButton/overrides/ElButton.vue index 0ef69b3ee7..b8c592606e 100644 --- a/packages/design-system/src/components/N8nButton/overrides/ElButton.vue +++ b/packages/design-system/src/components/N8nButton/overrides/ElButton.vue @@ -1,10 +1,6 @@ diff --git a/packages/design-system/src/components/N8nCallout/Callout.stories.ts b/packages/design-system/src/components/N8nCallout/Callout.stories.ts index ea7f49b43c..bb9df493d5 100644 --- a/packages/design-system/src/components/N8nCallout/Callout.stories.ts +++ b/packages/design-system/src/components/N8nCallout/Callout.stories.ts @@ -1,8 +1,7 @@ import N8nCallout from './Callout.vue'; import N8nLink from '../N8nLink'; import N8nText from '../N8nText'; -import { StoryFn } from '@storybook/vue'; - +import type { StoryFn } from '@storybook/vue'; export default { title: 'Atoms/Callout', @@ -33,7 +32,15 @@ export default { }, }; -const template : StoryFn = (args, { argTypes }) => ({ +interface Args { + theme: string; + icon: string; + default: string; + actions: string; + trailingContent: string; +} + +const template: StoryFn = (args, { argTypes }) => ({ props: Object.keys(argTypes), components: { N8nLink, @@ -79,7 +86,6 @@ customCallout.args = { `, }; - export const secondaryCallout = template.bind({}); secondaryCallout.args = { theme: 'secondary', diff --git a/packages/design-system/src/components/N8nCallout/Callout.vue b/packages/design-system/src/components/N8nCallout/Callout.vue index f850d38f7c..a401837526 100644 --- a/packages/design-system/src/components/N8nCallout/Callout.vue +++ b/packages/design-system/src/components/N8nCallout/Callout.vue @@ -1,12 +1,8 @@