merge in master

This commit is contained in:
Mutasem 2022-08-08 10:33:29 +02:00
commit 4a1da92013
58 changed files with 97412 additions and 48548 deletions

View file

@ -45,8 +45,8 @@ jobs:
name: npm install and build
run: |
cd n8n
npm install -g npm@latest
npm install
npm run bootstrap
npm run build --if-present
env:
CI: true

View file

@ -21,8 +21,8 @@ jobs:
node-version: ${{ matrix.node-version }}
- name: npm install, build, and test
run: |
npm install -g npm@latest
npm install
npm run bootstrap
npm run build --if-present
npm test
npm run lint

2
.gitignore vendored
View file

@ -4,7 +4,6 @@ node_modules
tmp
dist
npm-debug.log*
lerna-debug.log
yarn.lock
google-generated-credentials.json
_START_PACKAGE
@ -15,3 +14,4 @@ _START_PACKAGE
.idea
nodelinter.config.json
packages/*/package-lock.json
packages/*/.turbo

View file

@ -33,7 +33,7 @@ The most important directories:
- [/packages/cli](/packages/cli) - CLI code to run front- & backend
- [/packages/core](/packages/core) - Core code which handles workflow
execution, active webhooks and
workflows. **Contact n8n before
workflows. **Contact n8n before
starting on any changes here**
- [/packages/design-system](/packages/design-system) - Vue frontend components
- [/packages/editor-ui](/packages/editor-ui) - Vue frontend workflow editor
@ -72,19 +72,13 @@ Windows:
npm install -g windows-build-tools
```
#### lerna
#### npm workspaces
n8n is split up in different modules which are all in a single mono repository.
To facilitate those modules management, [lerna](https://lerna.js.org) gets
used. It automatically sets up file-links between modules which depend on each
To facilitate the module management, [npm workspaces](https://docs.npmjs.com/cli/v7/using-npm/workspaces) are
used. This automatically sets up file-links between modules which depend on each
other.
So for the setup to work correctly lerna has to be installed globally like this:
```
npm install -g lerna
```
### Actual n8n setup
> **IMPORTANT**: All the steps below have to get executed at least once to get the development setup up and running!
@ -94,27 +88,27 @@ checked out and set up:
1. [Fork](https://guides.github.com/activities/forking/#fork) the n8n repository
1. Clone your forked repository
2. Clone your forked repository
```
git clone https://github.com/<your_github_username>/n8n.git
```
1. Add the original n8n repository as `upstream` to your forked repository
3. Add the original n8n repository as `upstream` to your forked repository
```
git remote add upstream https://github.com/n8n-io/n8n.git
```
1. Go into repository folder
4. Go into repository folder
```
cd n8n
```
1. Install all dependencies of all modules and link them together:
5. Install all dependencies of all modules and link them together:
```
lerna bootstrap --hoist
npm install
```
1. Build all the code:
6. Build all the code:
```
npm run build
```

View file

@ -5,12 +5,12 @@ FROM node:16-alpine as builder
USER root
# Install all needed dependencies
RUN apk --update add --virtual build-dependencies python3 build-base ca-certificates && \
npm_config_user=root npm install -g lerna run-script-os
RUN apk --update add --virtual build-dependencies python3 build-base ca-certificates git && \
npm_config_user=root npm install -g npm@latest run-script-os turbo
WORKDIR /data
COPY lerna.json .
COPY turbo.json .
COPY package.json .
COPY package-lock.json .
COPY packages/cli/ ./packages/cli/
@ -22,8 +22,7 @@ COPY packages/workflow/ ./packages/workflow/
RUN rm -rf node_modules packages/*/node_modules packages/*/dist
RUN npm config set legacy-peer-deps true
RUN npm install --production --loglevel notice
RUN lerna bootstrap --hoist -- --production
RUN npm install --loglevel notice
RUN npm run build
@ -37,7 +36,7 @@ RUN apk add --update graphicsmagick tzdata tini su-exec git
WORKDIR /data
# Install all needed dependencies
RUN npm_config_user=root npm install -g full-icu
RUN npm_config_user=root npm install -g npm@latest full-icu
# Install fonts
RUN apk --no-cache add --virtual fonts msttcorefonts-installer fontconfig && \

View file

@ -11,7 +11,7 @@ RUN \
# Set a custom user to not have n8n run as root
USER root
RUN npm_config_user=root npm install -g full-icu n8n@${N8N_VERSION}
RUN npm_config_user=root npm install -g npm@latest full-icu n8n@${N8N_VERSION}
ENV NODE_ICU_DATA /usr/local/lib/node_modules/full-icu

View file

@ -16,7 +16,7 @@ RUN \
# Set a custom user to not have n8n run as root
USER root
RUN npm_config_user=root npm install -g n8n@${N8N_VERSION}
RUN npm_config_user=root npm install -g npm@latest n8n@${N8N_VERSION}
WORKDIR /data

View file

@ -14,7 +14,7 @@ USER root
# it needs to build it correctly.
RUN apk --update add --virtual build-dependencies python3 build-base ca-certificates && \
npm config set python "$(which python3)" && \
npm_config_user=root npm install -g full-icu n8n@${N8N_VERSION} && \
npm_config_user=root npm install -g npm@latest full-icu n8n@${N8N_VERSION} && \
apk del build-dependencies \
&& rm -rf /root /tmp/* /var/cache/apk/* && mkdir /root;

View file

@ -1,6 +0,0 @@
{
"packages": [
"packages/*"
],
"version": "independent"
}

145052
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -4,26 +4,28 @@
"private": true,
"homepage": "https://n8n.io",
"scripts": {
"bootstrap": "lerna bootstrap --hoist --no-ci",
"build": "lerna exec npm run build",
"dev": "lerna exec npm run dev --parallel",
"clean:dist": "lerna exec -- rimraf ./dist",
"format": "lerna exec npm run format",
"lint": "lerna exec npm run lint",
"lintfix": "lerna exec npm run lintfix",
"build": "turbo run build",
"dev": "turbo run dev --parallel",
"clean:dist": "npm exec -ws -- rimraf ./dist",
"format": "turbo run format",
"lint": "turbo run lint",
"lintfix": "turbo run lintfix",
"optimize-svg": "find ./packages -name '*.svg' ! -name 'pipedrive.svg' -print0 | xargs -0 -P16 -L20 npx svgo",
"start": "run-script-os",
"start:default": "cd packages/cli/bin && ./n8n",
"start:windows": "cd packages/cli/bin && n8n",
"test": "lerna run test",
"watch": "lerna run --parallel watch",
"test": "turbo run test",
"watch": "turbo run watch",
"webhook": "./packages/cli/bin/n8n webhook",
"worker": "./packages/cli/bin/n8n worker"
},
"devDependencies": {
"lerna": "^3.13.1",
"rimraf": "^3.0.2",
"run-script-os": "^1.0.7"
"run-script-os": "^1.0.7",
"turbo": "1.2.15"
},
"postcss": {}
"postcss": {},
"workspaces": [
"packages/*"
]
}

View file

@ -95,6 +95,9 @@ class LoadNodesAndCredentialsClass {
// In case "n8n" package is the root and the packages are
// in the "node_modules" folder underneath it.
path.join(__dirname, '..', '..', 'node_modules', 'n8n-workflow'),
// In case "n8n" package is installed using npm/yarn workspaces
// the node_modules folder is in the root of the workspace.
path.join(__dirname, '..', '..', '..', '..', 'node_modules', 'n8n-workflow'),
];
for (const checkPath of checkPaths) {
try {

View file

@ -1,29 +1,28 @@
<template functional>
<div :class="$style.container">
<div :class="$style.heading" v-if="props.heading">
<component :is="$options.components.N8nHeading" size="xlarge" align="center">{{ props.heading }}</component>
<template>
<div :class="['n8n-action-box', $style.container]">
<div :class="$style.heading" v-if="heading">
<n8n-heading size="xlarge" align="center">{{ heading }}</n8n-heading>
</div>
<div :class="$style.description" @click="(e) => listeners.descriptionClick && listeners.descriptionClick(e)">
<component :is="$options.components.N8nText" color="text-base">
<span v-html="props.description"></span>
</component>
<div :class="$style.description" @click="$emit('descriptionClick', $event)">
<n8n-text color="text-base">
<span v-html="description"></span>
</n8n-text>
</div>
<component v-if="props.buttonText" :is="$options.components.N8nButton" :label="props.buttonText" size="large"
@click="(e) => listeners.click && listeners.click(e)"
<n8n-button v-if="buttonText" :label="buttonText" size="large"
@click="$emit('click', $event)"
/>
<component
v-if="props.calloutText"
:is="$options.components.N8nCallout"
:theme="props.calloutTheme"
:icon="props.calloutIcon"
<n8n-callout
v-if="calloutText"
:theme="calloutTheme"
:icon="calloutIcon"
:class="$style.callout"
>
<template>
<component :is="$options.components.N8nText" color="text-base">
<span size="small" v-html="props.calloutText"></span>
</component>
<n8n-text color="text-base">
<span size="small" v-html="calloutText"></span>
</n8n-text>
</template>
</component>
</n8n-callout>
</div>
</template>
@ -32,8 +31,9 @@ import N8nButton from '../N8nButton';
import N8nHeading from '../N8nHeading';
import N8nText from '../N8nText';
import N8nCallout from '../N8nCallout';
import Vue from 'vue';
export default {
export default Vue.extend({
name: 'n8n-action-box',
components: {
N8nButton,
@ -62,7 +62,7 @@ export default {
type: String,
},
},
};
});
</script>
<style lang="scss" module>

View file

@ -1,19 +1,18 @@
<template functional>
<span :class="$style.container">
<component
v-if="props.firstName"
:is="$options.components.Avatar"
:size="$options.methods.getSize(props.size)"
:name="props.firstName + ' ' + props.lastName"
<template>
<span :class="['n8n-avatar', $style.container]" v-on="$listeners">
<avatar
v-if="firstName"
:size="getSize(size)"
:name="firstName + ' ' + lastName"
variant="marble"
:colors="$options.methods.getColors(props.colors)"
:colors="getColors(colors)"
/>
<div
v-else
:class="$style.empty"
:style="$options.methods.getBlankStyles(props.size)">
:class="[$style.empty, $style[size]]"
>
</div>
<span v-if="props.firstName" :class="$style.initials">{{$options.methods.getInitials(props)}}</span>
<span v-if="firstName" :class="$style.initials">{{initials}}</span>
</span>
</template>
@ -26,7 +25,9 @@ const sizes: {[size: string]: number} = {
medium: 40,
};
export default {
import Vue from 'vue';
export default Vue.extend({
name: 'n8n-avatar',
props: {
firstName: {
@ -46,14 +47,12 @@ export default {
components: {
Avatar,
},
computed: {
initials() {
return (this.firstName ? this.firstName.charAt(0): '') + (this.lastName? this.lastName.charAt(0): '');
},
},
methods: {
getInitials({firstName, lastName}) {
return firstName.charAt(0) + lastName.charAt(0);
},
getBlankStyles(size): {height: string, width: string} {
const px = sizes[size];
return { height: `${px}px`, width: `${px}px` };
},
getColors(colors): string[] {
const style = getComputedStyle(document.body);
return colors.map((color: string) => style.getPropertyValue(color));
@ -62,7 +61,7 @@ export default {
return sizes[size];
},
},
};
});
</script>
<style lang="scss" module>
@ -86,4 +85,19 @@ export default {
color: var(--color-text-xlight);
text-shadow: 0px 1px 6px rgba(25, 11, 9, 0.3);
}
.small {
height: 28px;
width: 28px;
}
.medium {
height: 40px;
width: 40px;
}
.large {
height: 48px;
width: 48px;
}
</style>

View file

@ -1,17 +1,19 @@
<template functional>
<template>
<span
:class="$style[props.theme]"
:class="['n8n-badge', $style[theme]]"
>
<component :is="$options.components.N8nText" :size="props.size" :bold="props.bold" :compact="true">
<n8n-text :size="size" :bold="bold" :compact="true">
<slot></slot>
</component>
</n8n-text>
</span>
</template>
<script lang="ts">
import N8nText from '../N8nText';
export default {
import Vue from 'vue';
export default Vue.extend({
props: {
theme: {
type: String,
@ -30,7 +32,7 @@ export default {
components: {
N8nText,
},
};
});
</script>
<style lang="scss" module>

View file

@ -1,7 +1,7 @@
// Vitest Snapshot v1
exports[`components > N8nBadge > props > should render default theme correctly 1`] = `"<span class=\\"_default_13dw2_9 _badge_13dw2_1\\"><span class=\\"_size-large_9dlpz_14 _bold_9dlpz_1\\" style=\\"line-height: 1;\\"><n8n-text-stub size=\\"medium\\" tag=\\"span\\">Default badge</n8n-text-stub></span></span>"`;
exports[`components > N8nBadge > props > should render default theme correctly 1`] = `"<span class=\\"n8n-badge _default_13dw2_9 _badge_13dw2_1\\"><n8n-text-stub bold=\\"true\\" size=\\"large\\" compact=\\"true\\" tag=\\"span\\"><n8n-text-stub size=\\"medium\\" tag=\\"span\\">Default badge</n8n-text-stub></n8n-text-stub></span>"`;
exports[`components > N8nBadge > props > should render secondary theme correctly 1`] = `"<span class=\\"_secondary_13dw2_16 _badge_13dw2_1\\"><span class=\\"_size-medium_9dlpz_19 _regular_9dlpz_5\\" style=\\"line-height: 1;\\"><n8n-text-stub size=\\"medium\\" tag=\\"span\\">Secondary badge</n8n-text-stub></span></span>"`;
exports[`components > N8nBadge > props > should render secondary theme correctly 1`] = `"<span class=\\"n8n-badge _secondary_13dw2_16 _badge_13dw2_1\\"><n8n-text-stub size=\\"medium\\" compact=\\"true\\" tag=\\"span\\"><n8n-text-stub size=\\"medium\\" tag=\\"span\\">Secondary badge</n8n-text-stub></n8n-text-stub></span>"`;
exports[`components > N8nBadge > props > should render with default values correctly 1`] = `"<span class=\\"_default_13dw2_9 _badge_13dw2_1\\"><span class=\\"_size-small_9dlpz_24 _regular_9dlpz_5\\" style=\\"line-height: 1;\\"><n8n-text-stub size=\\"medium\\" tag=\\"span\\">A Badge</n8n-text-stub></span></span>"`;
exports[`components > N8nBadge > props > should render with default values correctly 1`] = `"<span class=\\"n8n-badge _default_13dw2_9 _badge_13dw2_1\\"><n8n-text-stub size=\\"small\\" compact=\\"true\\" tag=\\"span\\"><n8n-text-stub size=\\"medium\\" tag=\\"span\\">A Badge</n8n-text-stub></n8n-text-stub></span>"`;

View file

@ -49,6 +49,7 @@ export default Vue.extend({
computed: {
classes(): string[] {
return [
'n8n-callout',
this.$style['callout'],
this.$style[this.theme],
];

View file

@ -1,7 +1,7 @@
// Vitest Snapshot v1
exports[`components > N8nCallout > should render additional slots correctly 1`] = `
"<div role=\\"alert\\" class=\\"_callout_p74de_1 _custom_p74de_16\\">
"<div role=\\"alert\\" class=\\"n8n-callout _callout_p74de_1 _custom_p74de_16\\">
<div class=\\"_message-section_p74de_12\\">
<div class=\\"_icon_p74de_40\\">
<n8n-icon-stub icon=\\"code-branch\\" size=\\"large\\"></n8n-icon-stub>
@ -13,7 +13,7 @@ exports[`components > N8nCallout > should render additional slots correctly 1`]
`;
exports[`components > N8nCallout > should render custom theme correctly 1`] = `
"<div role=\\"alert\\" class=\\"_callout_p74de_1 _custom_p74de_16\\">
"<div role=\\"alert\\" class=\\"n8n-callout _callout_p74de_1 _custom_p74de_16\\">
<div class=\\"_message-section_p74de_12\\">
<div class=\\"_icon_p74de_40\\">
<n8n-icon-stub icon=\\"code-branch\\" size=\\"large\\"></n8n-icon-stub>
@ -24,7 +24,7 @@ exports[`components > N8nCallout > should render custom theme correctly 1`] = `
`;
exports[`components > N8nCallout > should render danger theme correctly 1`] = `
"<div role=\\"alert\\" class=\\"_callout_p74de_1 _danger_p74de_34\\">
"<div role=\\"alert\\" class=\\"n8n-callout _callout_p74de_1 _danger_p74de_34\\">
<div class=\\"_message-section_p74de_12\\">
<div class=\\"_icon_p74de_40\\">
<n8n-icon-stub icon=\\"times-circle\\" size=\\"large\\"></n8n-icon-stub>
@ -35,7 +35,7 @@ exports[`components > N8nCallout > should render danger theme correctly 1`] = `
`;
exports[`components > N8nCallout > should render info theme correctly 1`] = `
"<div role=\\"alert\\" class=\\"_callout_p74de_1 _info_p74de_16\\">
"<div role=\\"alert\\" class=\\"n8n-callout _callout_p74de_1 _info_p74de_16\\">
<div class=\\"_message-section_p74de_12\\">
<div class=\\"_icon_p74de_40\\">
<n8n-icon-stub icon=\\"info-circle\\" size=\\"large\\"></n8n-icon-stub>
@ -46,7 +46,7 @@ exports[`components > N8nCallout > should render info theme correctly 1`] = `
`;
exports[`components > N8nCallout > should render secondary theme correctly 1`] = `
"<div role=\\"alert\\" class=\\"_callout_p74de_1 _secondary_p74de_44\\">
"<div role=\\"alert\\" class=\\"n8n-callout _callout_p74de_1 _secondary_p74de_44\\">
<div class=\\"_message-section_p74de_12\\">
<div class=\\"_icon_p74de_40\\">
<n8n-icon-stub icon=\\"info-circle\\" size=\\"medium\\"></n8n-icon-stub>
@ -57,7 +57,7 @@ exports[`components > N8nCallout > should render secondary theme correctly 1`] =
`;
exports[`components > N8nCallout > should render success theme correctly 1`] = `
"<div role=\\"alert\\" class=\\"_callout_p74de_1 _success_p74de_28\\">
"<div role=\\"alert\\" class=\\"n8n-callout _callout_p74de_1 _success_p74de_28\\">
<div class=\\"_message-section_p74de_12\\">
<div class=\\"_icon_p74de_40\\">
<n8n-icon-stub icon=\\"check-circle\\" size=\\"large\\"></n8n-icon-stub>
@ -68,7 +68,7 @@ exports[`components > N8nCallout > should render success theme correctly 1`] = `
`;
exports[`components > N8nCallout > should render warning theme correctly 1`] = `
"<div role=\\"alert\\" class=\\"_callout_p74de_1 _warning_p74de_22\\">
"<div role=\\"alert\\" class=\\"n8n-callout _callout_p74de_1 _warning_p74de_22\\">
<div class=\\"_message-section_p74de_12\\">
<div class=\\"_icon_p74de_40\\">
<n8n-icon-stub icon=\\"exclamation-triangle\\" size=\\"large\\"></n8n-icon-stub>

View file

@ -1,7 +1,7 @@
<template>
<el-checkbox
v-bind="$props"
:class="$style.n8nCheckbox"
:class="['n8n-checkbox', $style.n8nCheckbox]"
:disabled="disabled"
:indeterminate="indeterminate"
:value="value"

View file

@ -1,6 +1,6 @@
<template>
<div
:class="$style.container"
:class="['n8n-form-box', $style.container]"
>
<div
v-if="title"

View file

@ -1,11 +1,13 @@
<template functional>
<component :is="props.tag" :class="$options.methods.getClasses(props, $style)" :style="$options.methods.getStyles(props)">
<template>
<component :is="tag" :class="['n8n-heading', ...classes]" v-on="$listeners">
<slot></slot>
</component>
</template>
<script lang="ts">
export default {
import Vue from 'vue';
export default Vue.extend({
name: 'n8n-heading',
props: {
tag: {
@ -23,29 +25,31 @@ export default {
},
color: {
type: String,
validator: (value: string): boolean => ['primary', 'text-dark', 'text-base', 'text-light', 'text-xlight'].includes(value),
validator: (value: string): boolean => ['primary', 'text-dark', 'text-base', 'text-light', 'text-xlight', 'danger'].includes(value),
},
align: {
type: String,
validator: (value: string): boolean => ['right', 'left', 'center'].includes(value),
},
},
methods: {
getClasses(props: {size: string, bold: boolean}, $style: any) {
return {[$style[`size-${props.size}`]]: true, [$style.bold]: props.bold, [$style.regular]: !props.bold};
},
getStyles(props: {color: string}) {
const styles = {} as any;
if (props.color) {
styles.color = `var(--color-${props.color})`;
computed: {
classes() {
const applied = [];
if (this.align) {
applied.push(`align-${this.align}`);
}
if (props.align) {
styles['text-align'] = props.align;
if (this.color) {
applied.push(this.color);
}
return styles;
},
applied.push(`size-${this.size}`);
applied.push(this.bold? 'bold': 'regular');
return applied.map((c) => this.$style[c]);
}
},
};
});
</script>
<style lang="scss" module>
@ -82,4 +86,40 @@ export default {
line-height: var(--font-line-height-regular);
}
.primary {
color: var(--color-primary);
}
.text-dark {
color: var(--color-text-dark);
}
.text-base {
color: var(--color-text-base);
}
.text-light {
color: var(--color-text-light);
}
.text-xlight {
color: var(--color-text-xlight);
}
.danger {
color: var(--color-danger);
}
.align-left {
text-align: left;
}
.align-right {
text-align: right;
}
.align-center {
text-align: center;
}
</style>

View file

@ -1,24 +1,25 @@
<template functional>
<component
:is="$options.components.N8nText"
:size="props.size"
:color="props.color"
<template>
<n8n-text
:size="size"
:color="color"
:compact="true"
class="n8n-icon"
>
<component
:is="$options.components.FontAwesomeIcon"
:icon="props.icon"
:spin="props.spin"
:class="$style[props.size]"
<font-awesome-icon
:icon="icon"
:spin="spin"
:class="$style[size]"
/>
</component>
</n8n-text>
</template>
<script lang="ts">
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
import N8nText from '../N8nText';
export default {
import Vue from 'vue';
export default Vue.extend({
name: 'n8n-icon',
components: {
FontAwesomeIcon,
@ -40,7 +41,7 @@ export default {
type: String,
},
},
};
});
</script>

View file

@ -9,7 +9,9 @@
<script lang="ts">
import N8nButton from '../N8nButton';
export default {
import Vue from 'vue';
export default Vue.extend({
name: 'n8n-icon-button',
components: {
N8nButton,
@ -61,7 +63,7 @@ export default {
default: true,
},
},
};
});
</script>
<style lang="scss" module>

View file

@ -21,7 +21,9 @@
import N8nText from '../N8nText';
import N8nIcon from '../N8nIcon';
export default {
import Vue from 'vue';
export default Vue.extend({
name: 'n8n-info-accordion',
components: {
N8nText,
@ -53,7 +55,7 @@ export default {
this.$emit('click', e);
},
},
};
});
</script>
<style lang="scss" module>

View file

@ -1,5 +1,5 @@
<template>
<div :class="{[$style[theme]]: true, [$style[type]]: true, [$style.bold]: bold}">
<div :class="{'n8n-info-tip': true, [$style[theme]]: true, [$style[type]]: true, [$style.bold]: bold}">
<n8n-tooltip :placement="tooltipPlacement" :popper-class="$style.tooltipPopper" :disabled="type !== 'tooltip'">
<span :class="$style.iconText">
<n8n-icon :icon="theme.startsWith('info') ? 'info-circle': 'exclamation-triangle'" />
@ -14,7 +14,9 @@
import N8nIcon from '../N8nIcon';
import N8nTooltip from '../N8nTooltip';
export default {
import Vue from 'vue';
export default Vue.extend({
name: 'n8n-info-tip',
components: {
N8nIcon,
@ -42,7 +44,7 @@ export default {
default: 'top',
},
},
};
});
</script>
<style lang="scss" module>

View file

@ -1,32 +1,33 @@
<template functional>
<component
:is="$options.components.ElInput"
v-bind="props"
:size="$options.methods.getSize(props.size)"
:class="$style[$options.methods.getClass(props)]"
:ref="data.ref"
:autoComplete="props.autocomplete"
v-on="listeners"
<template>
<el-input
v-bind="$props"
:size="computedSize"
:class="['n8n-input', ...classes]"
:autoComplete="autocomplete"
ref="innerInput"
v-on="$listeners"
>
<template v-slot:prepend>
<template #prepend>
<slot name="prepend" />
</template>
<template v-slot:append>
<template #append>
<slot name="append" />
</template>
<template v-slot:prefix>
<template #prefix>
<slot name="prefix" />
</template>
<template v-slot:suffix>
<template #suffix>
<slot name="suffix" />
</template>
</component>
</el-input>
</template>
<script lang="ts">
import ElInput from 'element-ui/lib/input';
export default {
import Vue from 'vue';
export default Vue.extend({
name: 'n8n-input',
components: {
ElInput,
@ -68,23 +69,43 @@ export default {
default: 'off',
},
},
methods: {
getSize(size: string): string | undefined {
if (size === 'xlarge') {
computed: {
computedSize(): string | undefined {
if (this.size === 'xlarge') {
return undefined;
}
return size;
return this.size;
},
getClass(props: { size: string }): string {
if (props.size === 'xlarge') {
return 'xlarge';
classes(): string[] {
if (this.size === 'xlarge') {
return ['xlarge'];
}
return '';
return [];
},
},
};
methods: {
focus() {
if (this.$refs.innerInput.$el) {
// @ts-ignore
(this.$refs.innerInput.$el.querySelector(this.type === 'textarea' ? 'textarea' : 'input') as HTMLInputElement).focus();
}
},
blur() {
if (this.$refs.innerInput.$el) {
// @ts-ignore
(this.$refs.innerInput.$el.querySelector(this.type === 'textarea' ? 'textarea' : 'input') as HTMLInputElement).blur();
}
},
select() {
if (this.$refs.innerInput.$el) {
// @ts-ignore
(this.$refs.innerInput.$el.querySelector(this.type === 'textarea' ? 'textarea' : 'input') as HTMLInputElement).select();
}
},
},
});
</script>
<style lang="scss" module>

View file

@ -1,6 +1,7 @@
<template>
<div :class="$style.container">
<div v-if="label || $slots.options" :class="{
'n8n-input-label': true,
[this.$style.heading]: !!this.label,
[this.$style.underline]: this.underline,
[this.$style[this.size]]: true,
@ -34,7 +35,9 @@ import N8nIcon from '../N8nIcon';
import { addTargetBlank } from '../utils/helpers';
export default {
import Vue from 'vue';
export default Vue.extend({
name: 'n8n-input-label',
components: {
N8nText,
@ -74,7 +77,7 @@ export default {
methods: {
addTargetBlank,
},
};
});
</script>
<style lang="scss" module>

View file

@ -1,15 +1,16 @@
<template functional>
<component :is="$options.components.N8nRoute" :to="props.to" :newWindow="props.newWindow"
@click="listeners.click"
<template>
<n8n-route :to="to" :newWindow="newWindow"
v-on="$listeners"
class="n8n-link"
>
<span
:class="$style[`${props.underline ? `${props.theme}-underline` : props.theme}`]"
:class="$style[`${underline ? `${theme}-underline` : theme}`]"
>
<component :is="$options.components.N8nText" :size="props.size" :bold="props.bold">
<n8n-text :size="size" :bold="bold">
<slot></slot>
</component>
</n8n-text>
</span>
</component>
</n8n-route>
</template>
<script lang="ts">
@ -17,7 +18,9 @@ import Vue from 'vue';
import N8nText from '../N8nText';
import N8nRoute from '../N8nRoute';
export default {
import Vue from 'vue';
export default Vue.extend({
name: 'n8n-link',
props: {
size: {
@ -49,7 +52,7 @@ export default {
N8nText,
N8nRoute,
},
};
});
</script>
<style lang="scss" module>

View file

@ -1,5 +1,5 @@
<template>
<el-skeleton :loading="loading" :animated="animated">
<el-skeleton :loading="loading" :animated="animated" class="n8n-loading">
<template slot="template">
<el-skeleton-item
v-if="variant === 'button'"
@ -43,7 +43,9 @@
import ElSkeleton from 'element-ui/lib/skeleton';
import ElSkeletonItem from 'element-ui/lib/skeleton-item';
export default {
import Vue from 'vue';
export default Vue.extend({
name: 'n8n-loading',
components: {
ElSkeleton,
@ -72,7 +74,7 @@ export default {
validator: (value: string): boolean => ['p', 'h1', 'button', 'image'].includes(value),
},
},
};
});
</script>
<style lang="scss" module>

View file

@ -1,5 +1,5 @@
<template>
<div>
<div class="n8n-markdown">
<div
v-if="!loading"
ref="editor"
@ -55,7 +55,9 @@ interface IImage {
url: string;
}
export default {
import Vue from 'vue';
export default Vue.extend({
components: {
N8nLoading,
},
@ -175,7 +177,7 @@ export default {
this.$emit('markdown-click', clickedLink, event);
}
}
};
});
</script>
<style lang="scss" module>

View file

@ -1,20 +1,21 @@
<template functional>
<component
:is="$options.components.ElMenu"
:defaultActive="props.defaultActive"
:collapse="props.collapse"
:router="props.router"
:class="$style[props.type + (props.light ? '-light' : '')]"
@select="(e) => listeners.select && listeners.select(e)"
<template>
<el-menu
:defaultActive="defaultActive"
:collapse="collapse"
:router="router"
:class="['n8n-menu', $style[type + (light ? '-light' : '')]]"
v-on="$listeners"
>
<slot></slot>
</component>
</el-menu>
</template>
<script lang="ts">
import ElMenu from 'element-ui/lib/menu';
export default {
import Vue from 'vue';
export default Vue.extend({
name: 'n8n-menu',
props: {
type: {
@ -38,7 +39,7 @@ export default {
components: {
ElMenu,
},
};
});
</script>
<style lang="scss" module>

View file

@ -9,9 +9,11 @@
</template>
<script>
export default {
import Vue from 'vue';
export default Vue.extend({
name: 'n8n-pulse',
};
});
</script>
<style lang="scss" module>

View file

@ -1,12 +1,14 @@
<template>
<label role="radio" tabindex="-1" :class="{[$style.container]: true, [$style.hoverable]: !this.disabled}" aria-checked="true">
<label role="radio" tabindex="-1" :class="{'n8n-radio-button': true, [$style.container]: true, [$style.hoverable]: !this.disabled}" aria-checked="true">
<input type="radio" tabindex="-1" autocomplete="off" :class="$style.input" :value="value">
<div :class="{[$style.button]: true, [$style.active]: active, [$style[size]]: true, [$style.disabled]: disabled}" @click="$emit('click')">{{ label }}</div>
</label>
</template>
<script lang="ts">
export default {
import Vue from 'vue';
export default Vue.extend({
name: 'n8n-radio-button',
props: {
label: {
@ -31,7 +33,7 @@ export default {
type: Boolean,
},
},
};
});
</script>
<style lang="scss" module>

View file

@ -1,5 +1,5 @@
<template>
<div role="radiogroup" :class="{[$style.radioGroup]: true, [$style.disabled]: disabled}">
<div role="radiogroup" :class="{'n8n-radio-buttons': true, [$style.radioGroup]: true, [$style.disabled]: disabled}">
<RadioButton
v-for="option in options"
:key="option.value"
@ -15,7 +15,9 @@
<script lang="ts">
import RadioButton from './RadioButton.vue';
export default {
import Vue from 'vue';
export default Vue.extend({
name: 'n8n-radio-buttons',
props: {
value: {
@ -41,7 +43,7 @@ export default {
this.$emit('input', value);
},
},
};
});
</script>
<style lang="scss" module>

View file

@ -1,17 +1,17 @@
<template functional>
<template>
<span>
<router-link
v-if="$options.methods.useRouterLink(props)"
:to="props.to"
@click="(e) => listeners.click && listeners.click(e)"
v-if="useRouterLink"
:to="to"
v-on="$listeners"
>
<slot></slot>
</router-link>
<a
v-else
:href="props.to"
@click="(e) => listeners.click && listeners.click(e)"
:target="$options.methods.openNewWindow(props) ? '_blank': '_self'"
:href="to"
:target="openNewWindow ? '_blank': '_self'"
v-on="$listeners"
>
<slot></slot>
</a>
@ -21,7 +21,7 @@
<script lang="ts">
import Vue from 'vue';
export default {
export default Vue.extend({
name: 'n8n-route',
props: {
to: {
@ -32,28 +32,28 @@ export default {
default: undefined,
},
},
methods: {
useRouterLink(props: {to: object | string, newWindow: boolean | undefined}) {
if (props.newWindow === true) {
computed: {
useRouterLink() {
if (this.newWindow === true) {
// router-link does not support click events and opening in new window
return false;
}
if (typeof props.to === 'string') {
return props.to.startsWith('/');
if (typeof this.to === 'string') {
return this.to.startsWith('/');
}
return props.to !== undefined;
return this.to !== undefined;
},
openNewWindow(props: {to: string, newWindow: boolean | undefined}) {
if (props.newWindow !== undefined) {
return props.newWindow;
openNewWindow() {
if (this.newWindow !== undefined) {
return this.newWindow;
}
if (typeof props.to === 'string') {
return !props.to.startsWith('/');
if (typeof this.to === 'string') {
return !this.to.startsWith('/');
}
return true;
},
},
};
});
</script>

View file

@ -1,33 +1,33 @@
<template functional>
<div :class="{[$style.container]: true, [$style.withPrepend]: !!$slots.prepend}">
<template>
<div :class="{'n8n-select': true, [$style.container]: true, [$style.withPrepend]: !!$slots.prepend}">
<div v-if="$slots.prepend" :class="$style.prepend">
<slot name="prepend" />
</div>
<component
:is="$options.components.ElSelect"
v-bind="props"
:value="props.value"
:size="$options.methods.getSize(props.size)"
:class="$style[$options.methods.getClass(props)]"
:popper-class="$options.methods.getPopperClass(props, $style)"
v-on="listeners"
:ref="data.ref"
<el-select
v-bind="$props"
:value="value"
:size="computedSize"
:class="$style[classes]"
:popper-class="popperClass"
v-on="$listeners"
ref="innerSelect"
>
<template v-slot:prefix>
<template #prefix>
<slot name="prefix" />
</template>
<template v-slot:suffix>
<template #suffix>
<slot name="suffix" />
</template>
<template v-slot:default>
<template #default>
<slot></slot>
</template>
</component>
</el-select>
</div>
</template>
<script lang="ts">
import ElSelect from 'element-ui/lib/select';
import Vue from 'vue';
interface IProps {
size?: string;
@ -35,7 +35,7 @@ interface IProps {
popperClass?: string;
}
export default {
export default Vue.extend({
name: 'n8n-select',
components: {
ElSelect,
@ -86,31 +86,54 @@ export default {
type: String,
},
},
methods: {
getSize(size: string): string | undefined {
if (size === 'xlarge') {
computed: {
computedSize(): string | undefined {
if (this.size === 'xlarge') {
return undefined;
}
return size;
return this.size;
},
getClass(props: IProps): string {
if (props.size === 'xlarge') {
classes(): string {
if (this.size === 'xlarge') {
return 'xlarge';
}
return '';
},
getPopperClass(props: IProps, $style: any): string {
let classes = props.popperClass || '';
if (props.limitPopperWidth) {
classes = `${classes} ${$style.limitPopperWidth}`;
popperClasses(): string {
let classes = this.popperClass || '';
if (this.limitPopperWidth) {
classes = `${classes} ${this.$style.limitPopperWidth}`;
}
return classes;
},
},
};
methods: {
focus() {
const input = this.$refs.innerSelect;
if (input) {
input.focus();
}
},
blur() {
const input = this.$refs.innerSelect;
if (input) {
input.blur();
}
},
focusOnInput() {
const select = (this.$refs.innerSelect) as (Vue | undefined);
if (select) {
const input = select.$refs.input;
if (input) {
input.focus();
}
}
},
},
});
</script>
<style lang="scss" module>

View file

@ -1,11 +1,10 @@
<template functional>
<span>
<div v-if="props.type === 'ring'" class="lds-ring"><div></div><div></div><div></div><div></div></div>
<component
<template>
<span class="n8n-spinner">
<div v-if="type === 'ring'" class="lds-ring"><div></div><div></div><div></div><div></div></div>
<n8n-icon
v-else
:is="$options.components.N8nIcon"
icon="spinner"
:size="props.size"
:size="size"
spin
/>
</span>
@ -14,7 +13,9 @@
<script lang="ts">
import N8nIcon from '../N8nIcon';
export default {
import Vue from 'vue';
export default Vue.extend({
name: 'n8n-spinner',
components: {
N8nIcon,
@ -34,7 +35,7 @@ export default {
default: 'dots',
},
},
};
});
</script>
<style lang="scss">

View file

@ -1,11 +1,12 @@
<template functional>
<button :class="$style.button" @click="(e) => listeners.click && listeners.click(e)">
<span :class="$style.text" v-text="props.label" />
<template>
<button :class="['n8n-square-button', $style.button]" v-on="$listeners">
<span :class="$style.text">{{label}}</span>
</button>
</template>
<script lang="ts">
import Vue from 'vue';
export default Vue.extend({
name: 'n8n-square-button',
props: {

View file

@ -46,7 +46,9 @@ function getSize(delta, min, virtual, gridSize): number {
return min;
};
export default {
import Vue from 'vue';
export default Vue.extend({
name: 'n8n-resize',
props: {
isResizingEnabled: {
@ -152,7 +154,7 @@ export default {
this.dir = '';
},
},
};
});
</script>
<style lang="scss" module>

View file

@ -1,6 +1,6 @@
<template>
<div
:class="{[$style.sticky]: true, [$style.clickable]: !isResizing}"
:class="{'n8n-sticky': true, [$style.sticky]: true, [$style.clickable]: !isResizing}"
:style="styles"
@keydown.prevent
>
@ -183,8 +183,11 @@ export default mixins(Locale).extend({
watch: {
editMode(newMode, prevMode) {
setTimeout(() => {
if (newMode && !prevMode && this.$refs.input && this.$refs.input.$refs && this.$refs.input.$refs.textarea) {
const textarea = this.$refs.input.$refs.textarea;
if (newMode &&
!prevMode &&
this.$refs.input
) {
const textarea = this.$refs.input;
if (this.defaultText === this.content) {
textarea.select();
}

View file

@ -1,5 +1,5 @@
<template>
<div :class="$style.container">
<div :class="['n8n-tabs', $style.container]">
<div :class="$style.back" v-if="scrollPosition > 0" @click="scrollLeft">
<n8n-icon icon="chevron-left" size="small" />
</div>

View file

@ -1,16 +1,20 @@
<template functional>
<span :class="$style.tag" v-text="props.text" @click="(e) => listeners.click && listeners.click(e)" />
<template>
<span :class="['n8n-tag', $style.tag]" v-on="$listeners">
{{ text }}
</span>
</template>
<script lang="ts">
export default {
import Vue from 'vue';
export default Vue.extend({
name: 'n8n-tag',
props: {
text: {
type: String,
},
},
};
});
</script>
<style lang="scss" module>

View file

@ -1,13 +1,14 @@
<template functional>
<div :class="$style.tags">
<component :is="$options.components.N8nTag" v-for="tag in props.tags" :key="tag.id" :text="tag.name" @click="(e) => listeners.click && listeners.click(tag.id, e)"/>
<template>
<div :class="['n8n-tags', $style.tags]">
<n8n-tag v-for="tag in tags" :key="tag.id" :text="tag.name" @click="$emit('click', tag.id, $event)"/>
</div>
</template>
<script lang="ts">
import N8nTag from '../N8nTag';
import Vue from 'vue';
export default {
export default Vue.extend({
name: 'n8n-tags',
components: {
N8nTag,
@ -17,7 +18,7 @@ export default {
type: Array,
},
},
};
});
</script>
<style lang="scss" module>

View file

@ -1,11 +1,12 @@
<template functional>
<component :is="props.tag" :class="$options.methods.getClasses(props, $style, data)" :style="$options.methods.getStyles(props)" v-on="listeners">
<template>
<component :is="tag" :class="['n8n-text', ...classes]" v-on="$listeners">
<slot></slot>
</component>
</template>
<script lang="ts">
import Vue from 'vue';
export default Vue.extend({
name: 'n8n-text',
props: {
@ -20,7 +21,7 @@ export default Vue.extend({
},
color: {
type: String,
validator: (value: string): boolean => ['primary', 'text-dark', 'text-base', 'text-light', 'text-xlight'].includes(value),
validator: (value: string): boolean => ['primary', 'text-dark', 'text-base', 'text-light', 'text-xlight', 'danger'].includes(value),
},
align: {
type: String,
@ -35,28 +36,26 @@ export default Vue.extend({
default: 'span',
},
},
methods: {
getClasses(props: {size: string, bold: boolean}, $style: any, data: any) {
const classes = {[$style[`size-${props.size}`]]: true, [$style.bold]: props.bold, [$style.regular]: !props.bold};
if (data.staticClass) {
classes[data.staticClass] = true;
computed: {
classes() {
const applied = [];
if (this.align) {
applied.push(`align-${this.align}`);
}
if (this.color) {
applied.push(this.color);
}
return classes;
},
getStyles(props: {color: string, align: string, compact: false}) {
const styles = {} as any;
if (props.color) {
styles.color = `var(--color-${props.color})`;
if (this.compact) {
applied.push('compact');
}
if (props.compact) {
styles['line-height'] = 1;
}
if (props.align) {
styles['text-align'] = props.align;
}
return styles;
},
applied.push(`size-${this.size}`);
applied.push(this.bold? 'bold': 'regular');
return applied.map((c) => this.$style[c]);
}
},
});
</script>
@ -95,4 +94,44 @@ export default Vue.extend({
line-height: var(--font-line-height-compact);
}
.compact {
line-height: 1;
}
.primary {
color: var(--color-primary);
}
.text-dark {
color: var(--color-text-dark);
}
.text-base {
color: var(--color-text-base);
}
.text-light {
color: var(--color-text-light);
}
.text-xlight {
color: var(--color-text-xlight);
}
.danger {
color: var(--color-danger);
}
.align-left {
text-align: left;
}
.align-right {
text-align: right;
}
.align-center {
text-align: center;
}
</style>

View file

@ -94,7 +94,7 @@
"uuid": "^8.3.2",
"vue": "~2.6.11",
"vue-agile": "^2.0.0",
"vue-cli-plugin-webpack-bundle-analyzer": "^2.0.0",
"vue-cli-plugin-webpack-bundle-analyzer": "^4.0.0",
"vue-json-pretty": "1.7.1",
"vue-prism-editor": "^0.3.0",
"vue-router": "^3.0.6",

View file

@ -1,19 +1,19 @@
<template functional>
<template>
<fragment>
<el-tag
v-if="props.type === 'danger'"
v-if="type === 'danger'"
type="danger"
size="small"
:class="$style['danger']"
>
{{ props.text }}
{{ text }}
</el-tag>
<el-tag
v-else-if="props.type === 'warning'"
v-else-if="type === 'warning'"
size="small"
:class="$style['warning']"
>
{{ props.text }}
{{ text }}
</el-tag>
</fragment>
</template>
@ -48,4 +48,4 @@ export default {
color: $--badge-warning-color;
border: none;
}
</style>
</style>

View file

@ -1,28 +1,28 @@
<template functional>
<template>
<div
:class="{
container: true,
clickable: props.clickable,
active: props.active,
clickable: clickable,
active: active,
}"
@click="listeners.click"
v-on="$listeners"
>
<CategoryItem
v-if="props.item.type === 'category'"
:item="props.item"
v-if="item.type === 'category'"
:item="item"
/>
<SubcategoryItem
v-else-if="props.item.type === 'subcategory'"
:item="props.item"
v-else-if="item.type === 'subcategory'"
:item="item"
/>
<NodeItem
v-else-if="props.item.type === 'node'"
:nodeType="props.item.properties.nodeType"
:bordered="!props.lastNode"
@dragstart="listeners.dragstart"
@dragend="listeners.dragend"
v-else-if="item.type === 'node'"
:nodeType="item.properties.nodeType"
:bordered="!lastNode"
@dragstart="$listeners.dragstart"
@dragend="$listeners.dragend"
/>
</div>
</template>
@ -33,13 +33,15 @@ import NodeItem from './NodeItem.vue';
import CategoryItem from './CategoryItem.vue';
import SubcategoryItem from './SubcategoryItem.vue';
Vue.component('CategoryItem', CategoryItem);
Vue.component('SubcategoryItem', SubcategoryItem);
Vue.component('NodeItem', NodeItem);
export default {
export default Vue.extend({
name: 'CreatorItem',
components: {
CategoryItem,
SubcategoryItem,
NodeItem,
},
props: ['item', 'active', 'clickable', 'lastNode'],
};
});
</script>
<style lang="scss" scoped>

View file

@ -156,11 +156,6 @@ export default mixins(
);
return;
}
this.$showMessage({
title: this.$locale.baseText('ndv.execute.stopWaitingForWebhook.success'),
type: 'success',
});
},
async onClick() {

View file

@ -8,7 +8,7 @@
@keydown.stop
@keydown.esc="editName = false"
>
<n8n-text :class="$style.renameText" :bold="true" color="text-base" tag="div"
<n8n-text :bold="true" color="text-base" tag="div"
>{{ $locale.baseText('ndv.title.renameNode') }}</n8n-text>
<n8n-input ref="input" size="small" v-model="newName" />
<div :class="$style.editButtons">

View file

@ -845,9 +845,9 @@ export default mixins(
// Set focus on field
setTimeout(() => {
// @ts-ignore
if (this.$refs.inputField.$el) {
if (this.$refs.inputField) {
// @ts-ignore
(this.$refs.inputField.$el.querySelector(this.getStringInputType === 'textarea' ? 'textarea' : 'input') as HTMLInputElement).focus();
this.$refs.inputField.focus();
}
});

View file

@ -77,7 +77,8 @@ export default mixins(showMessage).extend({
};
},
mounted() {
const select = this.$refs.select as (Vue | undefined);
// @ts-ignore
const select = (this.$refs.select && this.$refs.select.$refs && this.$refs.select.$refs.innerSelect) as (Vue | undefined);
if (select) {
const input = select.$refs.input as (Element | undefined);
if (input) {
@ -200,10 +201,10 @@ export default mixins(showMessage).extend({
}
},
focusOnInput() {
const select = this.$refs.select as Vue;
const input = select && select.$refs.input as HTMLElement;
if (input && input.focus) {
input.focus();
const select = (this.$refs.select) as (Vue | undefined);
if (select) {
// @ts-ignore
select.focusOnInput();
this.focused = true;
}
},

View file

@ -1,4 +1,4 @@
<template functional>
<template>
<span :class="$style.trigger">
<svg width="36px" height="36px" viewBox="0 0 36 36" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Trigger node</title>

View file

@ -1,4 +1,4 @@
<template functional>
<template>
<n8n-tooltip content=" " placement="top" >
<div slot="content"><slot /></div>
<font-awesome-icon :class="$style['icon']" icon="exclamation-triangle"></font-awesome-icon>

View file

@ -87,10 +87,10 @@ import { ElMessageBoxOptions } from "element-ui/types/message-box";
Vue.use(Fragment.Plugin);
// n8n design system
Vue.use(N8nInfoAccordion);
Vue.use(N8nActionBox);
Vue.use(N8nActionToggle);
Vue.use(N8nAvatar);
Vue.component('n8n-info-accordion', N8nInfoAccordion);
Vue.component('n8n-action-box', N8nActionBox);
Vue.component('n8n-action-toggle', N8nActionToggle);
Vue.component('n8n-avatar', N8nAvatar);
Vue.component('n8n-button', N8nButton);
Vue.component('el-button', N8nElButton);
Vue.component('n8n-callout', N8nCallout);
@ -98,32 +98,32 @@ Vue.component('n8n-card', N8nCard);
Vue.component('n8n-form-box', N8nFormBox);
Vue.component('n8n-form-inputs', N8nFormInputs);
Vue.component('n8n-icon', N8nIcon);
Vue.use(N8nIconButton);
Vue.use(N8nInfoTip);
Vue.use(N8nInput);
Vue.use(N8nInputLabel);
Vue.use(N8nInputNumber);
Vue.component('n8n-icon-button', N8nIconButton);
Vue.component('n8n-info-tip', N8nInfoTip);
Vue.component('n8n-input', N8nInput);
Vue.component('n8n-input-label', N8nInputLabel);
Vue.component('n8n-input-number', N8nInputNumber);
Vue.component('n8n-loading', N8nLoading);
Vue.use(N8nHeading);
Vue.use(N8nLink);
Vue.component('n8n-heading', N8nHeading);
Vue.component('n8n-link', N8nLink);
Vue.component('n8n-markdown', N8nMarkdown);
Vue.use(N8nMenu);
Vue.use(N8nMenuItem);
Vue.component('n8n-menu', N8nMenu);
Vue.component('n8n-menu-item', N8nMenuItem);
Vue.component('n8n-node-icon', N8nNodeIcon);
Vue.component('n8n-notice', N8nNotice);
Vue.use(N8nOption);
Vue.use(N8nPulse);
Vue.use(N8nSelect);
Vue.use(N8nSpinner);
Vue.component('n8n-option', N8nOption);
Vue.component('n8n-pulse', N8nPulse);
Vue.component('n8n-select', N8nSelect);
Vue.component('n8n-spinner', N8nSpinner);
Vue.component('n8n-sticky', N8nSticky);
Vue.use(N8nRadioButtons);
Vue.component('n8n-radio-buttons', N8nRadioButtons);
Vue.component('n8n-square-button', N8nSquareButton);
Vue.use(N8nTags);
Vue.component('n8n-tags', N8nTags);
Vue.component('n8n-tabs', N8nTabs);
Vue.component('n8n-tree', N8nTree);
Vue.use(N8nTag);
Vue.component('n8n-tag', N8nTag);
Vue.component('n8n-text', N8nText);
Vue.use(N8nTooltip);
Vue.component('n8n-tooltip', N8nTooltip);
// element io
Vue.use(Dialog);

View file

@ -341,7 +341,6 @@
"ndv.execute.nodeIsDisabled": "Enable node to execute",
"ndv.execute.requiredFieldsMissing": "Complete required fields first",
"ndv.execute.stopWaitingForWebhook.error": "Problem deleting test webhook",
"ndv.execute.stopWaitingForWebhook.success": "Deleted test webhook",
"ndv.execute.workflowAlreadyRunning": "Workflow is already running",
"ndv.featureRequest": "I wish this node would...",
"ndv.input": "Input",
@ -551,7 +550,6 @@
"nodeView.showMessage.stopExecutionCatch.message": "It completed before it could be stopped",
"nodeView.showMessage.stopExecutionCatch.title": "Workflow finished executing",
"nodeView.showMessage.stopExecutionTry.title": "Execution stopped",
"nodeView.showMessage.stopWaitingForWebhook.title": "Webhook deleted",
"nodeView.stopCurrentExecution": "Stop current execution",
"nodeView.stopWaitingForWebhookCall": "Stop waiting for webhook call",
"nodeView.stoppingCurrentExecution": "Stopping current execution",

View file

@ -1242,11 +1242,6 @@ export default mixins(
);
return;
}
this.$showMessage({
title: this.$locale.baseText('nodeView.showMessage.stopWaitingForWebhook.title'),
type: 'success',
});
},
/**

View file

@ -19,6 +19,7 @@
"declaration": true,
"outDir": "./dist/",
"target": "es2019",
"moduleResolution": "node",
"sourceMap": true,
"useUnknownInCatchVariables": false,
},

16
turbo.json Normal file
View file

@ -0,0 +1,16 @@
{
"$schema": "https://turborepo.org/schema.json",
"pipeline": {
"build": {
"dependsOn": ["^build"]
},
"format": {},
"lint": {},
"lintfix": {},
"test": {},
"watch": {},
"dev": {
"cache": false
}
}
}