mirror of
https://github.com/n8n-io/n8n.git
synced 2024-09-11 13:15:28 +03:00
feat: migrate editor-ui to Vite.js and various DX improvements (N8N-2277) (#4061)
* feat: Added vite.js dependencies. * chore: Removed tests folder to follow same structure as design-system * chore: Removed unused testing config. * chore: Created vite.js index.html * refactor: Updated scss structure and imports. * refactor: Updated workflow building. * fix: Cleared up all workflow dependency cycles. Added proper package.json imports config. * feat: Got a working build using Vite. Need to fix issues next. * fix: Progress! Getting process.env error. * fix: Changed process.env to import.meta.env. * fix: Fixed circular imports that used require(). Fixed monaco editor. * chore: Removed commented code. * chore: Cleaned up package.json * feat: Made necessary changes to replace base path in css files. * feat: Serve CSS files for `editor-ui` Vite migration (#4069) ⚡ Serve CSS files for Vite migration * chore: Fixed package-lock.json. * fix: Fixed build after centralized tsconfig update. * fix: Removed lodash-es replacement. * fix: Commented out vitest test command. * style: Fixed linting issues. * fix: Added lodash-es hotfix back. * chore: Updated package-lock.json * refactor: Renamed all n8n scss variables to no longer be defined as private. * feat(editor): add application-wide el-button replacement. * fix(editor): Fix import in page alert after merge. * chore(editor): update package-lock.json. * fix: Case sensitive lodash-es replacement for vue-agile. * fix: add alias for lodash-es camelcase import. * fix: add patch-package support for fixing quill * feat: add patch-package on postinstall * fix: update quill patch path. * refactor: rename quill patch * fix: update quill version. * fix: update quill patch * fix: fix linting rules after installing eslint in design-system * fix: update date picker button to have primary color * test: update callout component snapshots * fix(editor): fix linting issues in editor after enabling eslint * fix(cli): add /assets/* to auth ignore endpoints in server * chore: update package-lock.json * chore: update package-lock.json * fix(editor): fix linting issues * feat: add vite-legacy support * fix: update workflow package interface imports to type imports. * chore: update package-lock.json * fix(editor) fix importing translations other than english * fix(editor): remove test command until vitest is added * fix: increase memory allocation for vite build * fix: add patch-package patches to n8n-custom docker build * fix: add performance and load time improvements * fix: add proper typing to setNodeType * chore: update package-lock.json * style: use generic type for reduce in setNodeType Co-authored-by: Iván Ovejero <ivov.src@gmail.com>
This commit is contained in:
parent
e709cb5fe2
commit
27e2ce0470
@ -9,6 +9,7 @@ RUN \
|
||||
|
||||
COPY turbo.json package.json package-lock.json tsconfig.json ./
|
||||
COPY packages ./packages
|
||||
COPY patches ./patches
|
||||
|
||||
RUN chown -R node:node .
|
||||
RUN npm config set legacy-peer-deps true
|
||||
|
15668
package-lock.json
generated
15668
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -11,6 +11,7 @@
|
||||
"lint": "turbo run lint",
|
||||
"lintfix": "turbo run lintfix",
|
||||
"optimize-svg": "find ./packages -name '*.svg' ! -name 'pipedrive.svg' -print0 | xargs -0 -P16 -L20 npx svgo",
|
||||
"postinstall": "patch-package",
|
||||
"start": "run-script-os",
|
||||
"start:default": "cd packages/cli/bin && ./n8n",
|
||||
"start:tunnel": "./packages/cli/bin/n8n start --tunnel",
|
||||
@ -21,6 +22,7 @@
|
||||
"worker": "./packages/cli/bin/n8n worker"
|
||||
},
|
||||
"devDependencies": {
|
||||
"patch-package": "^6.4.7",
|
||||
"rimraf": "^3.0.2",
|
||||
"run-script-os": "^1.0.7",
|
||||
"turbo": "1.2.15"
|
||||
|
@ -147,6 +147,7 @@ import {
|
||||
WebhookServer,
|
||||
WorkflowExecuteAdditionalData,
|
||||
} from '.';
|
||||
import glob from 'fast-glob';
|
||||
import { ResponseError } from './ResponseHelper';
|
||||
|
||||
require('body-parser-xml')(bodyParser);
|
||||
@ -389,6 +390,7 @@ class App {
|
||||
const excludeEndpoints = config.getEnv('security.excludeEndpoints');
|
||||
|
||||
const ignoredEndpoints = [
|
||||
'assets',
|
||||
'healthz',
|
||||
'metrics',
|
||||
this.endpointWebhook,
|
||||
@ -1753,11 +1755,28 @@ class App {
|
||||
const editorUiPath = require.resolve('n8n-editor-ui');
|
||||
const filePath = pathJoin(pathDirname(editorUiPath), 'dist', 'index.html');
|
||||
const n8nPath = config.getEnv('path');
|
||||
const basePathRegEx = /\/%BASE_PATH%\//g;
|
||||
|
||||
let readIndexFile = readFileSync(filePath, 'utf8');
|
||||
readIndexFile = readIndexFile.replace(/\/%BASE_PATH%\//g, n8nPath);
|
||||
readIndexFile = readIndexFile.replace(basePathRegEx, n8nPath);
|
||||
readIndexFile = readIndexFile.replace(/\/favicon.ico/g, `${n8nPath}favicon.ico`);
|
||||
|
||||
const cssPath = pathJoin(pathDirname(editorUiPath), 'dist', '**/*.css');
|
||||
const cssFiles: Record<string, string> = {};
|
||||
glob.sync(cssPath).forEach((filePath) => {
|
||||
let readFile = readFileSync(filePath, 'utf8');
|
||||
readFile = readFile.replace(basePathRegEx, n8nPath);
|
||||
cssFiles[filePath.replace(pathJoin(pathDirname(editorUiPath), 'dist'), '')] = readFile;
|
||||
});
|
||||
|
||||
const jsPath = pathJoin(pathDirname(editorUiPath), 'dist', '**/*.js');
|
||||
const jsFiles: Record<string, string> = {};
|
||||
glob.sync(jsPath).forEach((filePath) => {
|
||||
let readFile = readFileSync(filePath, 'utf8');
|
||||
readFile = readFile.replace(basePathRegEx, n8nPath);
|
||||
jsFiles[filePath.replace(pathJoin(pathDirname(editorUiPath), 'dist'), '')] = readFile;
|
||||
});
|
||||
|
||||
const hooksUrls = config.getEnv('externalFrontendHooksUrls');
|
||||
|
||||
let scriptsString = '';
|
||||
@ -1793,6 +1812,14 @@ class App {
|
||||
res.send(readIndexFile);
|
||||
});
|
||||
|
||||
this.app.get('/assets/*.css', async (req: express.Request, res: express.Response) => {
|
||||
res.type('text/css').send(cssFiles[req.url]);
|
||||
});
|
||||
|
||||
this.app.get('/assets/*.js', async (req: express.Request, res: express.Response) => {
|
||||
res.type('text/javascript').send(jsFiles[req.url]);
|
||||
});
|
||||
|
||||
// Serve the website
|
||||
this.app.use(
|
||||
'/',
|
||||
|
@ -1,36 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const gulp = require('gulp');
|
||||
const sass = require('gulp-dart-sass');
|
||||
const autoprefixer = require('gulp-autoprefixer');
|
||||
const cleanCSS = require('gulp-clean-css');
|
||||
|
||||
gulp.task('build:theme', gulp.series([compileTheme, copyThemeFonts]));
|
||||
|
||||
gulp.task(
|
||||
'watch:theme',
|
||||
gulp.series([
|
||||
'build:theme',
|
||||
() => {
|
||||
gulp.watch('./theme/src/**/*.scss', gulp.series(['build:theme']));
|
||||
},
|
||||
]),
|
||||
);
|
||||
|
||||
function compileTheme() {
|
||||
return gulp
|
||||
.src('./theme/src/index.scss')
|
||||
.pipe(sass.sync())
|
||||
.pipe(
|
||||
autoprefixer({
|
||||
browsers: ['ie > 9', 'last 2 versions'],
|
||||
cascade: false,
|
||||
}),
|
||||
)
|
||||
.pipe(cleanCSS())
|
||||
.pipe(gulp.dest('./theme/dist'));
|
||||
}
|
||||
|
||||
function copyThemeFonts() {
|
||||
return gulp.src('./theme/src/fonts/**').pipe(gulp.dest('./theme/dist/fonts'));
|
||||
}
|
@ -13,19 +13,15 @@
|
||||
"url": "git+https://github.com/n8n-io/n8n.git"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "npm run build:theme",
|
||||
"build:vue": "vite build",
|
||||
"build": "vite build",
|
||||
"build:vue:typecheck": "vue-tsc --emitDeclarationOnly",
|
||||
"dev": "npm run watch:theme",
|
||||
"test": "vitest run",
|
||||
"test:ci": "vitest run --coverage",
|
||||
"test:dev": "vitest",
|
||||
"build:storybook": "build-storybook",
|
||||
"storybook": "start-storybook -p 6006",
|
||||
"lint": "tslint -p tsconfig.json -c tslint.json && eslint .",
|
||||
"lintfix": "tslint --fix -p tsconfig.json -c tslint.json && eslint . --fix",
|
||||
"build:theme": "gulp build:theme",
|
||||
"watch:theme": "gulp watch:theme"
|
||||
"lintfix": "tslint --fix -p tsconfig.json -c tslint.json && eslint . --fix"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@fortawesome/fontawesome-svg-core": "1.x",
|
||||
@ -54,10 +50,9 @@
|
||||
"babel-loader": "^8.2.2",
|
||||
"c8": "7.11.0",
|
||||
"core-js": "^3.6.5",
|
||||
"gulp": "^4.0.0",
|
||||
"gulp-autoprefixer": "^4.0.0",
|
||||
"gulp-clean-css": "^4.3.0",
|
||||
"gulp-dart-sass": "^1.0.2",
|
||||
"eslint": "^8.0.0",
|
||||
"eslint-plugin-prettier": "^3.4.0",
|
||||
"eslint-plugin-vue": "^7.16.0",
|
||||
"jsdom": "19.0.0",
|
||||
"markdown-it": "^12.3.2",
|
||||
"markdown-it-emoji": "^2.0.0",
|
||||
|
@ -47,9 +47,9 @@ import Vue from 'vue';
|
||||
export default Vue.extend({
|
||||
name: 'n8n-action-toggle',
|
||||
components: {
|
||||
ElDropdown,
|
||||
ElDropdownMenu,
|
||||
ElDropdownItem,
|
||||
ElDropdown, // eslint-disable-line @typescript-eslint/no-unsafe-assignment
|
||||
ElDropdownMenu, // eslint-disable-line @typescript-eslint/no-unsafe-assignment
|
||||
ElDropdownItem, // eslint-disable-line @typescript-eslint/no-unsafe-assignment
|
||||
N8nIcon,
|
||||
},
|
||||
props: {
|
||||
|
@ -45,7 +45,7 @@ export default Vue.extend({
|
||||
},
|
||||
},
|
||||
components: {
|
||||
Avatar,
|
||||
Avatar, // eslint-disable-line @typescript-eslint/no-unsafe-assignment
|
||||
},
|
||||
computed: {
|
||||
initials() {
|
||||
|
@ -96,25 +96,25 @@ 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']}` : ''}` +
|
||||
`${this.outline ? ` ${this.$style.outline}` : ''}` +
|
||||
`${this.loading ? ` ${this.$style.loading}` : ''}` +
|
||||
`${this.float ? ` ${this.$style[`float-${this.float}`]}` : ''}` +
|
||||
`${this.text ? ` ${this.$style['text']}` : ''}` +
|
||||
`${this.disabled ? ` ${this.$style['disabled']}` : ''}` +
|
||||
`${this.block ? ` ${this.$style['block']}` : ''}` +
|
||||
`${this.active ? ` ${this.$style['active']}` : ''}` +
|
||||
`${this.icon || this.loading ? ` ${this.$style['icon']}` : ''}` +
|
||||
`${this.square ? ` ${this.$style['square']}` : ''}`;
|
||||
`${this.text ? ` ${this.$style.text}` : ''}` +
|
||||
`${this.disabled ? ` ${this.$style.disabled}` : ''}` +
|
||||
`${this.block ? ` ${this.$style.block}` : ''}` +
|
||||
`${this.active ? ` ${this.$style.active}` : ''}` +
|
||||
`${this.icon || this.loading ? ` ${this.$style.icon}` : ''}` +
|
||||
`${this.square ? ` ${this.$style.square}` : ''}`;
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" module>
|
||||
@import '../../../theme/src/mixins/utils';
|
||||
@import '../../../theme/src/common/var';
|
||||
@import '../../css/mixins/utils';
|
||||
@import '../../css/common/var';
|
||||
|
||||
.button {
|
||||
display: inline-block;
|
||||
|
@ -0,0 +1,3 @@
|
||||
import ElButton from "./ElButton.vue";
|
||||
|
||||
export default ElButton;
|
@ -19,7 +19,6 @@
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import N8nIcon from '../N8nIcon';
|
||||
import N8nText from '../N8nText';
|
||||
|
||||
const CALLOUT_DEFAULT_ICONS: { [key: string]: string } = {
|
||||
info: 'info-circle',
|
||||
@ -32,7 +31,6 @@ export default Vue.extend({
|
||||
name: 'n8n-callout',
|
||||
components: {
|
||||
N8nIcon,
|
||||
N8nText,
|
||||
},
|
||||
props: {
|
||||
theme: {
|
||||
@ -43,14 +41,14 @@ export default Vue.extend({
|
||||
},
|
||||
icon: {
|
||||
type: String,
|
||||
default: 'info-circle'
|
||||
default: 'info-circle',
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
classes(): string[] {
|
||||
return [
|
||||
'n8n-callout',
|
||||
this.$style['callout'],
|
||||
this.$style.callout,
|
||||
this.$style[this.theme],
|
||||
];
|
||||
},
|
||||
@ -61,7 +59,7 @@ export default Vue.extend({
|
||||
|
||||
return this.icon;
|
||||
},
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
|
@ -6,7 +6,7 @@ exports[`components > N8nCallout > should render additional slots correctly 1`]
|
||||
<div class=\\"_icon_p74de_40\\">
|
||||
<n8n-icon-stub icon=\\"code-branch\\" size=\\"large\\"></n8n-icon-stub>
|
||||
</div>
|
||||
<n8n-text-stub size=\\"small\\" tag=\\"span\\">This is a secondary callout.</n8n-text-stub> <n8n-link-stub size=\\"small\\">Do something!</n8n-link-stub>
|
||||
<n8n-text-stub size=\\"small\\">This is a secondary callout.</n8n-text-stub> <n8n-link-stub size=\\"small\\">Do something!</n8n-link-stub>
|
||||
</div>
|
||||
<n8n-link-stub theme=\\"secondary\\" size=\\"small\\" bold=\\"true\\" underline=\\"true\\" to=\\"https://n8n.io\\">Learn more</n8n-link-stub>
|
||||
</div>"
|
||||
@ -18,7 +18,7 @@ exports[`components > N8nCallout > should render custom theme correctly 1`] = `
|
||||
<div class=\\"_icon_p74de_40\\">
|
||||
<n8n-icon-stub icon=\\"code-branch\\" size=\\"large\\"></n8n-icon-stub>
|
||||
</div>
|
||||
<n8n-text-stub size=\\"small\\" tag=\\"span\\">This is a secondary callout.</n8n-text-stub>
|
||||
<n8n-text-stub size=\\"small\\">This is a secondary callout.</n8n-text-stub>
|
||||
</div>
|
||||
</div>"
|
||||
`;
|
||||
@ -29,7 +29,7 @@ exports[`components > N8nCallout > should render danger theme correctly 1`] = `
|
||||
<div class=\\"_icon_p74de_40\\">
|
||||
<n8n-icon-stub icon=\\"times-circle\\" size=\\"large\\"></n8n-icon-stub>
|
||||
</div>
|
||||
<n8n-text-stub size=\\"small\\" tag=\\"span\\">This is a danger callout.</n8n-text-stub>
|
||||
<n8n-text-stub size=\\"small\\">This is a danger callout.</n8n-text-stub>
|
||||
</div>
|
||||
</div>"
|
||||
`;
|
||||
@ -40,7 +40,7 @@ exports[`components > N8nCallout > should render info theme correctly 1`] = `
|
||||
<div class=\\"_icon_p74de_40\\">
|
||||
<n8n-icon-stub icon=\\"info-circle\\" size=\\"large\\"></n8n-icon-stub>
|
||||
</div>
|
||||
<n8n-text-stub size=\\"small\\" tag=\\"span\\">This is an info callout.</n8n-text-stub>
|
||||
<n8n-text-stub size=\\"small\\">This is an info callout.</n8n-text-stub>
|
||||
</div>
|
||||
</div>"
|
||||
`;
|
||||
@ -51,7 +51,7 @@ exports[`components > N8nCallout > should render secondary theme correctly 1`] =
|
||||
<div class=\\"_icon_p74de_40\\">
|
||||
<n8n-icon-stub icon=\\"info-circle\\" size=\\"medium\\"></n8n-icon-stub>
|
||||
</div>
|
||||
<n8n-text-stub size=\\"small\\" tag=\\"span\\">This is a secondary callout.</n8n-text-stub>
|
||||
<n8n-text-stub size=\\"small\\">This is a secondary callout.</n8n-text-stub>
|
||||
</div>
|
||||
</div>"
|
||||
`;
|
||||
@ -62,7 +62,7 @@ exports[`components > N8nCallout > should render success theme correctly 1`] = `
|
||||
<div class=\\"_icon_p74de_40\\">
|
||||
<n8n-icon-stub icon=\\"check-circle\\" size=\\"large\\"></n8n-icon-stub>
|
||||
</div>
|
||||
<n8n-text-stub size=\\"small\\" tag=\\"span\\">This is a success callout.</n8n-text-stub>
|
||||
<n8n-text-stub size=\\"small\\">This is a success callout.</n8n-text-stub>
|
||||
</div>
|
||||
</div>"
|
||||
`;
|
||||
@ -73,7 +73,7 @@ exports[`components > N8nCallout > should render warning theme correctly 1`] = `
|
||||
<div class=\\"_icon_p74de_40\\">
|
||||
<n8n-icon-stub icon=\\"exclamation-triangle\\" size=\\"large\\"></n8n-icon-stub>
|
||||
</div>
|
||||
<n8n-text-stub size=\\"small\\" tag=\\"span\\">This is a warning callout.</n8n-text-stub>
|
||||
<n8n-text-stub size=\\"small\\">This is a warning callout.</n8n-text-stub>
|
||||
</div>
|
||||
</div>"
|
||||
`;
|
||||
|
@ -24,7 +24,7 @@ import N8nInputLabel from '../N8nInputLabel';
|
||||
export default Vue.extend({
|
||||
name: 'n8n-checkbox',
|
||||
components: {
|
||||
ElCheckbox,
|
||||
ElCheckbox, // eslint-disable-line @typescript-eslint/no-unsafe-assignment
|
||||
N8nInputLabel,
|
||||
},
|
||||
props: {
|
||||
@ -59,7 +59,7 @@ export default Vue.extend({
|
||||
onChange(event: Event) {
|
||||
this.$emit("input", event);
|
||||
},
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
|
@ -179,7 +179,7 @@ export default mixins(Locale).extend({
|
||||
},
|
||||
methods: {
|
||||
getValidationError(): ReturnType<IValidator['validate']> {
|
||||
const rules = (this.validationRules || []) as (Rule | RuleGroup)[];
|
||||
const rules = (this.validationRules || []) as Array<Rule | RuleGroup>;
|
||||
const validators = {
|
||||
...VALIDATORS,
|
||||
...(this.validators || {}),
|
||||
|
@ -67,7 +67,7 @@ export default Vue.extend({
|
||||
});
|
||||
|
||||
if (this.eventBus) {
|
||||
this.eventBus.$on('submit', this.onSubmit);
|
||||
this.eventBus.$on('submit', this.onSubmit); // eslint-disable-line @typescript-eslint/unbound-method
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@ -75,11 +75,11 @@ export default Vue.extend({
|
||||
return (this.inputs as IFormInput[]).filter(
|
||||
(input) => typeof input.shouldDisplay === 'function'
|
||||
? input.shouldDisplay(this.values)
|
||||
: true
|
||||
: true,
|
||||
);
|
||||
},
|
||||
isReadyToSubmit(): boolean {
|
||||
for (let key in this.validity) {
|
||||
for (const key in this.validity) {
|
||||
if (!this.validity[key]) {
|
||||
return false;
|
||||
}
|
||||
@ -92,9 +92,9 @@ export default Vue.extend({
|
||||
onInput(name: string, value: any) {
|
||||
this.values = {
|
||||
...this.values,
|
||||
[name]: value,
|
||||
[name]: value, // eslint-disable-line @typescript-eslint/no-unsafe-assignment
|
||||
};
|
||||
this.$emit('input', {name, value});
|
||||
this.$emit('input', {name, value}); // eslint-disable-line @typescript-eslint/no-unsafe-assignment
|
||||
},
|
||||
onValidate(name: string, valid: boolean) {
|
||||
Vue.set(this.validity, name, valid);
|
||||
@ -102,7 +102,7 @@ export default Vue.extend({
|
||||
onSubmit() {
|
||||
this.showValidationWarnings = true;
|
||||
if (this.isReadyToSubmit) {
|
||||
const toSubmit = (this.filteredInputs as IFormInput[]).reduce<{ [key: string]: unknown }>((accu, input) => {
|
||||
const toSubmit = (this.filteredInputs ).reduce<{ [key: string]: unknown }>((accu, input) => {
|
||||
if (this.values[input.name]) {
|
||||
accu[input.name] = this.values[input.name];
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ export default Vue.extend({
|
||||
applied.push(this.bold? 'bold': 'regular');
|
||||
|
||||
return applied.map((c) => (this.$style as { [key: string]: string })[c]);
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
@ -29,7 +29,7 @@ import Vue from 'vue';
|
||||
export default Vue.extend({
|
||||
name: 'n8n-input',
|
||||
components: {
|
||||
ElInput,
|
||||
ElInput, // eslint-disable-line @typescript-eslint/no-unsafe-assignment
|
||||
},
|
||||
props: {
|
||||
value: {
|
||||
|
@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import N8nInputNumber from 'element-ui/lib/input-number';
|
||||
|
||||
N8nInputNumber.name = 'n8n-input-number';
|
||||
N8nInputNumber.name = 'n8n-input-number'; // eslint-disable-line @typescript-eslint/no-unsafe-member-access
|
||||
|
||||
export default N8nInputNumber;
|
||||
</script>
|
||||
|
@ -48,8 +48,8 @@ import Vue from 'vue';
|
||||
export default Vue.extend({
|
||||
name: 'n8n-loading',
|
||||
components: {
|
||||
ElSkeleton,
|
||||
ElSkeletonItem,
|
||||
ElSkeleton, // eslint-disable-line @typescript-eslint/no-unsafe-assignment
|
||||
ElSkeletonItem, // eslint-disable-line @typescript-eslint/no-unsafe-assignment
|
||||
},
|
||||
props: {
|
||||
animated: {
|
||||
|
@ -25,9 +25,13 @@
|
||||
<script lang="ts">
|
||||
import N8nLoading from '../N8nLoading';
|
||||
import Markdown from 'markdown-it';
|
||||
const markdownLink = require('markdown-it-link-attributes');
|
||||
const markdownEmoji = require('markdown-it-emoji');
|
||||
const markdownTasklists = require('markdown-it-task-lists');
|
||||
|
||||
// @ts-ignore
|
||||
import markdownLink from 'markdown-it-link-attributes';
|
||||
// @ts-ignore
|
||||
import markdownEmoji from 'markdown-it-emoji';
|
||||
// @ts-ignore
|
||||
import markdownTasklists from 'markdown-it-task-lists';
|
||||
|
||||
import xss, { friendlyAttrValue } from 'xss';
|
||||
import { escapeMarkdown } from '../../utils/markdown';
|
||||
@ -143,8 +147,8 @@ export default Vue.extend({
|
||||
}
|
||||
// Return nothing, means keep the default handling measure
|
||||
},
|
||||
onTag: function (tag, html, options) {
|
||||
if (tag === 'img' && html.includes(`alt="workflow-screenshot"`)) {
|
||||
onTag (tag, code, options) {
|
||||
if (tag === 'img' && code.includes(`alt="workflow-screenshot"`)) {
|
||||
return '';
|
||||
}
|
||||
// return nothing, keep tag
|
||||
@ -156,10 +160,10 @@ export default Vue.extend({
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
md: new Markdown(this.options.markdown)
|
||||
.use(markdownLink, this.options.linkAttributes)
|
||||
md: new Markdown(this.options.markdown) // eslint-disable-line @typescript-eslint/no-unsafe-member-access
|
||||
.use(markdownLink, this.options.linkAttributes) // eslint-disable-line @typescript-eslint/no-unsafe-member-access
|
||||
.use(markdownEmoji)
|
||||
.use(markdownTasklists, this.options.tasklists),
|
||||
.use(markdownTasklists, this.options.tasklists), // eslint-disable-line @typescript-eslint/no-unsafe-member-access
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
@ -177,8 +181,8 @@ export default Vue.extend({
|
||||
}
|
||||
}
|
||||
this.$emit('markdown-click', clickedLink, event);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
|
@ -37,7 +37,7 @@ export default Vue.extend({
|
||||
},
|
||||
},
|
||||
components: {
|
||||
ElMenu,
|
||||
ElMenu, // eslint-disable-line @typescript-eslint/no-unsafe-assignment
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import ElMenuItem from 'element-ui/lib/menu-item';
|
||||
|
||||
ElMenuItem.name = 'n8n-menu-item';
|
||||
ElMenuItem.name = 'n8n-menu-item'; // eslint-disable-line @typescript-eslint/no-unsafe-member-access
|
||||
|
||||
export default ElMenuItem;
|
||||
</script>
|
||||
|
@ -58,7 +58,7 @@ export default Vue.extend({
|
||||
classes(): string[] {
|
||||
return [
|
||||
'notice',
|
||||
this.$style['notice'],
|
||||
this.$style.notice,
|
||||
this.$style[this.theme],
|
||||
];
|
||||
},
|
||||
|
@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import ElOption from 'element-ui/lib/option';
|
||||
|
||||
ElOption.name = 'n8n-option';
|
||||
ElOption.name = 'n8n-option'; // eslint-disable-line @typescript-eslint/no-unsafe-member-access
|
||||
|
||||
export default ElOption;
|
||||
</script>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import ElPopover from 'element-ui/lib/popover';
|
||||
|
||||
ElPopover.name = 'n8n-popover';
|
||||
ElPopover.name = 'n8n-popover'; // eslint-disable-line @typescript-eslint/no-unsafe-member-access
|
||||
|
||||
export default ElPopover;
|
||||
</script>
|
||||
|
@ -12,6 +12,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
/* eslint-disable @typescript-eslint/unbound-method */
|
||||
import Vue from 'vue';
|
||||
|
||||
function closestNumber(value: number, divisor: number): number {
|
||||
@ -94,7 +95,7 @@ export default Vue.extend({
|
||||
enabledDirections() {
|
||||
const availableDirections = Object.keys(directionsCursorMaps);
|
||||
|
||||
if(this.isResizingEnabled === false) return [];
|
||||
if(!this.isResizingEnabled) return [];
|
||||
if(this.supportedDirections.length === 0) return availableDirections;
|
||||
|
||||
return this.supportedDirections;
|
||||
|
@ -39,7 +39,7 @@ export default Vue.extend({
|
||||
return false;
|
||||
}
|
||||
if (typeof this.to === 'string') {
|
||||
return this.to.startsWith('/');
|
||||
return (this.to as string).startsWith('/');
|
||||
}
|
||||
|
||||
return this.to !== undefined;
|
||||
@ -49,7 +49,7 @@ export default Vue.extend({
|
||||
return this.newWindow;
|
||||
}
|
||||
if (typeof this.to === 'string') {
|
||||
return !this.to.startsWith('/');
|
||||
return !(this.to as string).startsWith('/');
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
@ -38,7 +38,7 @@ export interface IProps {
|
||||
export default Vue.extend({
|
||||
name: 'n8n-select',
|
||||
components: {
|
||||
ElSelect,
|
||||
ElSelect, // eslint-disable-line @typescript-eslint/no-unsafe-assignment
|
||||
},
|
||||
props: {
|
||||
value: {
|
||||
|
@ -23,13 +23,13 @@ export default Vue.extend({
|
||||
props: {
|
||||
size: {
|
||||
type: String,
|
||||
validator: function (value: string): boolean {
|
||||
validator (value: string): boolean {
|
||||
return ['small', 'medium', 'large'].includes(value);
|
||||
},
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
validator: function (value: string): boolean {
|
||||
validator (value: string): boolean {
|
||||
return ['dots', 'ring'].includes(value);
|
||||
},
|
||||
default: 'dots',
|
||||
|
@ -144,8 +144,8 @@ export default mixins(Locale).extend({
|
||||
},
|
||||
styles(): { height: string, width: string } {
|
||||
return {
|
||||
height: this.resHeight + 'px',
|
||||
width: this.resWidth + 'px',
|
||||
height: `${this.resHeight}px`,
|
||||
width: `${this.resWidth}px`,
|
||||
};
|
||||
},
|
||||
shouldShowFooter(): boolean {
|
||||
|
@ -57,7 +57,8 @@ export default Vue.extend({
|
||||
const width = container.clientWidth;
|
||||
const scrollWidth = container.scrollWidth;
|
||||
// @ts-ignore
|
||||
this.scrollPosition = event.srcElement.scrollLeft;
|
||||
this.scrollPosition = event.srcElement.scrollLeft; // eslint-disable-line @typescript-eslint/no-unsafe-assignment
|
||||
|
||||
this.canScrollRight = scrollWidth - width > this.scrollPosition;
|
||||
});
|
||||
|
||||
|
@ -55,7 +55,7 @@ export default Vue.extend({
|
||||
applied.push(this.bold? 'bold': 'regular');
|
||||
|
||||
return applied.map((c) => (this.$style as { [key: string]: string })[c]);
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import ElTooltip from 'element-ui/lib/tooltip';
|
||||
|
||||
ElTooltip.name = 'n8n-tooltip';
|
||||
ElTooltip.name = 'n8n-tooltip'; // eslint-disable-line @typescript-eslint/no-unsafe-member-access
|
||||
|
||||
export default ElTooltip;
|
||||
</script>
|
||||
|
@ -29,6 +29,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
/* tslint:disable: @typescript-eslint/no-unsafe-assignment */
|
||||
import Vue from 'vue';
|
||||
import N8nUserInfo from '../N8nUserInfo';
|
||||
import { IUser } from '../../types';
|
||||
@ -42,8 +43,8 @@ export default mixins(Locale).extend({
|
||||
name: 'n8n-user-select',
|
||||
components: {
|
||||
N8nUserInfo,
|
||||
ElSelect,
|
||||
ElOption,
|
||||
ElSelect, // eslint-disable-line @typescript-eslint/no-unsafe-assignment
|
||||
ElOption, // eslint-disable-line @typescript-eslint/no-unsafe-assignment
|
||||
},
|
||||
props: {
|
||||
users: {
|
||||
@ -104,7 +105,7 @@ export default mixins(Locale).extend({
|
||||
});
|
||||
},
|
||||
sortedUsers(): IUser[] {
|
||||
return [...(this.fitleredUsers as IUser[])].sort((a: IUser, b: IUser) => {
|
||||
return [...(this.fitleredUsers )].sort((a: IUser, b: IUser) => {
|
||||
if (a.lastName && b.lastName && a.lastName !== b.lastName) {
|
||||
return a.lastName > b.lastName ? 1 : -1;
|
||||
}
|
||||
|
@ -36,6 +36,11 @@ import Locale from '../../mixins/locale';
|
||||
import mixins from 'vue-typed-mixins';
|
||||
import { t } from '../../locale';
|
||||
|
||||
export interface IUserListAction {
|
||||
label: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export default mixins(Locale).extend({
|
||||
name: 'n8n-users-list',
|
||||
components: {
|
||||
@ -102,19 +107,19 @@ export default mixins(Locale).extend({
|
||||
}
|
||||
}
|
||||
|
||||
return a.email! > b.email! ? 1 : -1;
|
||||
return a.email > b.email ? 1 : -1;
|
||||
});
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
getActions(user: IUser): Array<{ label: string, value: string }> {
|
||||
const DELETE = {
|
||||
label: this.deleteLabel,
|
||||
getActions(user: IUser): IUserListAction[] {
|
||||
const DELETE: IUserListAction = {
|
||||
label: this.deleteLabel as string,
|
||||
value: 'delete',
|
||||
};
|
||||
|
||||
const REINVITE = {
|
||||
label: this.reinviteLabel,
|
||||
const REINVITE: IUserListAction = {
|
||||
label: this.reinviteLabel as string,
|
||||
value: 'reinvite',
|
||||
};
|
||||
|
||||
|
@ -64,7 +64,7 @@ export default Vue.extend({
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.$props.enabled) {
|
||||
this.$data.observer.disconnect();
|
||||
this.$data.observer.disconnect(); // eslint-disable-line
|
||||
}
|
||||
},
|
||||
});
|
||||
|
3
packages/design-system/src/css/base.scss
Normal file
3
packages/design-system/src/css/base.scss
Normal file
@ -0,0 +1,3 @@
|
||||
@forward "common/var.scss";
|
||||
@import "common/transition.scss";
|
||||
@import "icon.scss";
|
@ -10,3 +10,12 @@
|
||||
@use "./input.scss";
|
||||
@use "./scrollbar.scss";
|
||||
@use "./popper";
|
||||
|
||||
.el-picker-panel__footer {
|
||||
.el-picker-panel__link-btn {
|
||||
&:last-child {
|
||||
background: var(--color-primary);
|
||||
color: var(--color-foreground-xlight)
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user