mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 18:12:04 +00:00
feat: Replace Vue.extend with defineComponent in design system (no-changelog) (#5918)
* refactor: replace new Vue() with custom event bus (no-changelog) * fix: export types from design system main * fix: update component types * fix: update form inputs event bus * refactor: replace global Vue references in design-system * refactor: update prop types * feat: improve types * fix: further type improvements * fix: further types improvements * fix: further type improvements * test: fix test snapshots * test: fix snapshot * chore: fix linting issues * test: fix personalization modal snapshot
This commit is contained in:
@@ -16,7 +16,7 @@
|
||||
"scripts": {
|
||||
"clean": "rimraf dist .turbo",
|
||||
"build": "vite build",
|
||||
"typecheck": "vue-tsc --emitDeclarationOnly",
|
||||
"typecheck": "vue-tsc --declaration --emitDeclarationOnly",
|
||||
"test": "vitest run --coverage",
|
||||
"test:dev": "vitest",
|
||||
"build:storybook": "storybook build",
|
||||
|
||||
@@ -42,9 +42,9 @@ import N8nButton from '../N8nButton';
|
||||
import N8nHeading from '../N8nHeading';
|
||||
import N8nText from '../N8nText';
|
||||
import N8nCallout from '../N8nCallout';
|
||||
import Vue from 'vue';
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
export default Vue.extend({
|
||||
export default defineComponent({
|
||||
name: 'n8n-action-box',
|
||||
components: {
|
||||
N8nButton,
|
||||
|
||||
@@ -18,14 +18,7 @@
|
||||
:disabled="item.disabled"
|
||||
:divided="item.divided"
|
||||
>
|
||||
<div
|
||||
:class="{
|
||||
[$style.itemContainer]: true,
|
||||
[$style.hasCustomStyling]: item.customClass !== undefined,
|
||||
[item.customClass]: item.customClass !== undefined,
|
||||
}"
|
||||
:data-test-id="`workflow-menu-item-${item.id}`"
|
||||
>
|
||||
<div :class="getItemClasses(item)" :data-test-id="`workflow-menu-item-${item.id}`">
|
||||
<span v-if="item.icon" :class="$style.icon">
|
||||
<n8n-icon :icon="item.icon" :size="iconSize" />
|
||||
</span>
|
||||
@@ -41,7 +34,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue, { PropType } from 'vue';
|
||||
import { defineComponent, PropType } from 'vue';
|
||||
import {
|
||||
Dropdown as ElDropdown,
|
||||
DropdownMenu as ElDropdownMenu,
|
||||
@@ -49,7 +42,7 @@ import {
|
||||
} from 'element-ui';
|
||||
import N8nIcon from '../N8nIcon';
|
||||
|
||||
interface IActionDropdownItem {
|
||||
export interface IActionDropdownItem {
|
||||
id: string;
|
||||
label: string;
|
||||
icon?: string;
|
||||
@@ -64,7 +57,7 @@ interface IActionDropdownItem {
|
||||
// by Element UI dropdown component).
|
||||
// It can be used in different parts of editor UI while ActionToggle
|
||||
// is designed to be used in card components.
|
||||
export default Vue.extend({
|
||||
export default defineComponent({
|
||||
name: 'n8n-action-dropdown',
|
||||
components: {
|
||||
ElDropdown,
|
||||
@@ -99,6 +92,13 @@ export default Vue.extend({
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
getItemClasses(item: IActionDropdownItem): Record<string, boolean> {
|
||||
return {
|
||||
[this.$style.itemContainer]: true,
|
||||
[this.$style.hasCustomStyling]: item.customClass !== undefined,
|
||||
...(item.customClass !== undefined ? { [item.customClass]: true } : {}),
|
||||
};
|
||||
},
|
||||
onSelect(action: string): void {
|
||||
this.$emit('select', action);
|
||||
},
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
@visible-change="onVisibleChange"
|
||||
>
|
||||
<span :class="{ [$style.button]: true, [$style[theme]]: !!theme }">
|
||||
<component :is="$options.components.N8nIcon" icon="ellipsis-v" :size="iconSize" />
|
||||
<n8n-icon icon="ellipsis-v" :size="iconSize" />
|
||||
</span>
|
||||
|
||||
<template #dropdown>
|
||||
@@ -22,9 +22,8 @@
|
||||
>
|
||||
{{ action.label }}
|
||||
<div :class="$style.iconContainer">
|
||||
<component
|
||||
<n8n-icon
|
||||
v-if="action.type === 'external-link'"
|
||||
:is="$options.components.N8nIcon"
|
||||
icon="external-link-alt"
|
||||
size="xsmall"
|
||||
color="text-base"
|
||||
@@ -38,22 +37,16 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import { defineComponent, PropType } from 'vue';
|
||||
import {
|
||||
Dropdown as ElDropdown,
|
||||
DropdownMenu as ElDropdownMenu,
|
||||
DropdownItem as ElDropdownItem,
|
||||
} from 'element-ui';
|
||||
import N8nIcon from '../N8nIcon';
|
||||
import type { UserAction } from '@/types';
|
||||
|
||||
interface Action {
|
||||
label: string;
|
||||
value: string;
|
||||
disabled: boolean;
|
||||
type?: 'external-link';
|
||||
}
|
||||
|
||||
export default Vue.extend({
|
||||
export default defineComponent({
|
||||
name: 'n8n-action-toggle',
|
||||
components: {
|
||||
ElDropdown,
|
||||
@@ -63,7 +56,7 @@ export default Vue.extend({
|
||||
},
|
||||
props: {
|
||||
actions: {
|
||||
type: Array<Action>,
|
||||
type: Array as PropType<UserAction[]>,
|
||||
default: () => [],
|
||||
},
|
||||
placement: {
|
||||
|
||||
@@ -21,9 +21,9 @@ const sizes: { [size: string]: number } = {
|
||||
medium: 40,
|
||||
};
|
||||
|
||||
import Vue from 'vue';
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
export default Vue.extend({
|
||||
export default defineComponent({
|
||||
name: 'n8n-avatar',
|
||||
props: {
|
||||
firstName: {
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
<script lang="ts">
|
||||
import N8nText from '../N8nText';
|
||||
|
||||
import Vue from 'vue';
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
export default Vue.extend({
|
||||
export default defineComponent({
|
||||
props: {
|
||||
theme: {
|
||||
type: String,
|
||||
|
||||
@@ -18,11 +18,11 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import { defineComponent } from 'vue';
|
||||
import N8nIcon from '../N8nIcon';
|
||||
import N8nSpinner from '../N8nSpinner';
|
||||
|
||||
export default Vue.extend({
|
||||
export default defineComponent({
|
||||
name: 'n8n-button',
|
||||
props: {
|
||||
label: {
|
||||
@@ -81,11 +81,11 @@ export default Vue.extend({
|
||||
N8nIcon,
|
||||
},
|
||||
computed: {
|
||||
ariaBusy(): string {
|
||||
return this.loading ? 'true' : 'false';
|
||||
ariaBusy(): 'true' | undefined {
|
||||
return this.loading ? 'true' : undefined;
|
||||
},
|
||||
ariaDisabled(): string {
|
||||
return this.disabled ? 'true' : 'false';
|
||||
ariaDisabled(): 'true' | undefined {
|
||||
return this.disabled ? 'true' : undefined;
|
||||
},
|
||||
classes(): string {
|
||||
return (
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
// Vitest Snapshot v1
|
||||
|
||||
exports[`components > N8nButton > overrides > should render as \`secondary\` when \`text\` is given as type 1`] = `"<button aria-disabled=\\"false\\" aria-busy=\\"false\\" aria-live=\\"polite\\" class=\\"button button secondary medium icon\\" icon=\\"plus-circle\\"><span class=\\"icon\\"><n8n-icon-stub icon=\\"plus-circle\\" size=\\"medium\\"></n8n-icon-stub></span><span>Button</span></button>"`;
|
||||
exports[`components > N8nButton > overrides > should render as \`secondary\` when \`text\` is given as type 1`] = `"<button aria-live=\\"polite\\" class=\\"button button secondary medium icon\\" icon=\\"plus-circle\\"><span class=\\"icon\\"><n8n-icon-stub icon=\\"plus-circle\\" size=\\"medium\\"></n8n-icon-stub></span><span>Button</span></button>"`;
|
||||
|
||||
exports[`components > N8nButton > overrides > should render as \`tertiary\` when \`info\` is given as type 1`] = `"<button aria-disabled=\\"false\\" aria-busy=\\"false\\" aria-live=\\"polite\\" class=\\"button button tertiary medium icon\\" icon=\\"plus-circle\\"><span class=\\"icon\\"><n8n-icon-stub icon=\\"plus-circle\\" size=\\"medium\\"></n8n-icon-stub></span><span>Button</span></button>"`;
|
||||
exports[`components > N8nButton > overrides > should render as \`tertiary\` when \`info\` is given as type 1`] = `"<button aria-live=\\"polite\\" class=\\"button button tertiary medium icon\\" icon=\\"plus-circle\\"><span class=\\"icon\\"><n8n-icon-stub icon=\\"plus-circle\\" size=\\"medium\\"></n8n-icon-stub></span><span>Button</span></button>"`;
|
||||
|
||||
exports[`components > N8nButton > overrides > should use default (\`primary\`) type when no type is given 1`] = `"<button aria-disabled=\\"false\\" aria-busy=\\"false\\" aria-live=\\"polite\\" class=\\"button button primary medium icon\\" icon=\\"plus-circle\\"><span class=\\"icon\\"><n8n-icon-stub icon=\\"plus-circle\\" size=\\"medium\\"></n8n-icon-stub></span><span>Button</span></button>"`;
|
||||
exports[`components > N8nButton > overrides > should use default (\`primary\`) type when no type is given 1`] = `"<button aria-live=\\"polite\\" class=\\"button button primary medium icon\\" icon=\\"plus-circle\\"><span class=\\"icon\\"><n8n-icon-stub icon=\\"plus-circle\\" size=\\"medium\\"></n8n-icon-stub></span><span>Button</span></button>"`;
|
||||
|
||||
exports[`components > N8nButton > overrides > should use given (\`secondary\`) type 1`] = `"<button aria-disabled=\\"false\\" aria-busy=\\"false\\" aria-live=\\"polite\\" class=\\"button button secondary medium icon\\" icon=\\"plus-circle\\"><span class=\\"icon\\"><n8n-icon-stub icon=\\"plus-circle\\" size=\\"medium\\"></n8n-icon-stub></span><span>Button</span></button>"`;
|
||||
exports[`components > N8nButton > overrides > should use given (\`secondary\`) type 1`] = `"<button aria-live=\\"polite\\" class=\\"button button secondary medium icon\\" icon=\\"plus-circle\\"><span class=\\"icon\\"><n8n-icon-stub icon=\\"plus-circle\\" size=\\"medium\\"></n8n-icon-stub></span><span>Button</span></button>"`;
|
||||
|
||||
exports[`components > N8nButton > props > icon > should render icon button 1`] = `"<button aria-disabled=\\"false\\" aria-busy=\\"false\\" aria-live=\\"polite\\" class=\\"button button primary medium icon\\"><span class=\\"icon\\"><n8n-icon-stub icon=\\"plus-circle\\" size=\\"medium\\"></n8n-icon-stub></span><span>Button</span></button>"`;
|
||||
exports[`components > N8nButton > props > icon > should render icon button 1`] = `"<button aria-live=\\"polite\\" class=\\"button button primary medium icon\\"><span class=\\"icon\\"><n8n-icon-stub icon=\\"plus-circle\\" size=\\"medium\\"></n8n-icon-stub></span><span>Button</span></button>"`;
|
||||
|
||||
exports[`components > N8nButton > props > loading > should render loading spinner 1`] = `"<button disabled=\\"disabled\\" aria-disabled=\\"false\\" aria-busy=\\"true\\" aria-live=\\"polite\\" class=\\"button button primary medium loading icon\\"><span class=\\"icon\\"><n8n-spinner-stub size=\\"medium\\" type=\\"dots\\"></n8n-spinner-stub></span><span>Button</span></button>"`;
|
||||
exports[`components > N8nButton > props > loading > should render loading spinner 1`] = `"<button disabled=\\"disabled\\" aria-busy=\\"true\\" aria-live=\\"polite\\" class=\\"button button primary medium loading icon\\"><span class=\\"icon\\"><n8n-spinner-stub size=\\"medium\\" type=\\"dots\\"></n8n-spinner-stub></span><span>Button</span></button>"`;
|
||||
|
||||
exports[`components > N8nButton > props > square > should render square button 1`] = `
|
||||
"<button aria-disabled=\\"false\\" aria-busy=\\"false\\" aria-live=\\"polite\\" class=\\"button button primary medium square\\">
|
||||
"<button aria-live=\\"polite\\" class=\\"button button primary medium square\\">
|
||||
<!----><span>48</span></button>"
|
||||
`;
|
||||
|
||||
exports[`components > N8nButton > should render correctly 1`] = `
|
||||
"<button aria-disabled=\\"false\\" aria-busy=\\"false\\" aria-live=\\"polite\\" class=\\"button button primary medium\\">
|
||||
"<button aria-live=\\"polite\\" class=\\"button button primary medium\\">
|
||||
<!----><span>Button</span></button>"
|
||||
`;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import { defineComponent } from 'vue';
|
||||
import N8nButton from '../Button.vue';
|
||||
|
||||
const classToTypeMap = {
|
||||
@@ -13,7 +13,7 @@ const classToTypeMap = {
|
||||
'el-picker-panel__link-btn': 'secondary',
|
||||
};
|
||||
|
||||
export default Vue.extend({
|
||||
export default defineComponent({
|
||||
components: {
|
||||
N8nButton,
|
||||
},
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import { defineComponent } from 'vue';
|
||||
import N8nText from '../N8nText';
|
||||
import N8nIcon from '../N8nIcon';
|
||||
|
||||
@@ -27,7 +27,7 @@ const CALLOUT_DEFAULT_ICONS: { [key: string]: string } = {
|
||||
danger: 'times-circle',
|
||||
};
|
||||
|
||||
export default Vue.extend({
|
||||
export default defineComponent({
|
||||
name: 'n8n-callout',
|
||||
components: {
|
||||
N8nText,
|
||||
|
||||
@@ -21,9 +21,9 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
export default Vue.extend({
|
||||
export default defineComponent({
|
||||
name: 'n8n-card',
|
||||
inheritAttrs: true,
|
||||
props: {
|
||||
|
||||
@@ -19,11 +19,11 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import { defineComponent } from 'vue';
|
||||
import { Checkbox as ElCheckbox } from 'element-ui';
|
||||
import N8nInputLabel from '../N8nInputLabel';
|
||||
|
||||
export default Vue.extend({
|
||||
export default defineComponent({
|
||||
name: 'n8n-checkbox',
|
||||
components: {
|
||||
ElCheckbox,
|
||||
|
||||
@@ -112,7 +112,7 @@ export default defineComponent({
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="row in visibleRows" :key="row.id" :class="getTrClass(row)">
|
||||
<tr v-for="row in visibleRows" :key="row.id" :class="getTrClass()">
|
||||
<td v-for="column in columns" :key="column.id">
|
||||
<component v-if="column.render" :is="column.render" :row="row" :column="column" />
|
||||
<span v-else>{{ getTdValue(row, column) }}</span>
|
||||
|
||||
@@ -16,70 +16,70 @@ exports[`components > N8nDatatable > should render correctly 1`] = `
|
||||
<td><span>1</span></td>
|
||||
<td><span>Richard Hendricks</span></td>
|
||||
<td><span>29</span></td>
|
||||
<td><button aria-disabled=\\"false\\" aria-busy=\\"false\\" aria-live=\\"polite\\" class=\\"button button primary medium\\" column=\\"[object Object]\\">
|
||||
<td><button aria-live=\\"polite\\" class=\\"button button primary medium\\" column=\\"[object Object]\\">
|
||||
<!----><span>Button 1</span></button></td>
|
||||
</tr>
|
||||
<tr class=\\"datatableRow\\">
|
||||
<td><span>2</span></td>
|
||||
<td><span>Bertram Gilfoyle</span></td>
|
||||
<td><span>44</span></td>
|
||||
<td><button aria-disabled=\\"false\\" aria-busy=\\"false\\" aria-live=\\"polite\\" class=\\"button button primary medium\\" column=\\"[object Object]\\">
|
||||
<td><button aria-live=\\"polite\\" class=\\"button button primary medium\\" column=\\"[object Object]\\">
|
||||
<!----><span>Button 2</span></button></td>
|
||||
</tr>
|
||||
<tr class=\\"datatableRow\\">
|
||||
<td><span>3</span></td>
|
||||
<td><span>Dinesh Chugtai</span></td>
|
||||
<td><span>31</span></td>
|
||||
<td><button aria-disabled=\\"false\\" aria-busy=\\"false\\" aria-live=\\"polite\\" class=\\"button button primary medium\\" column=\\"[object Object]\\">
|
||||
<td><button aria-live=\\"polite\\" class=\\"button button primary medium\\" column=\\"[object Object]\\">
|
||||
<!----><span>Button 3</span></button></td>
|
||||
</tr>
|
||||
<tr class=\\"datatableRow\\">
|
||||
<td><span>4</span></td>
|
||||
<td><span>Jared Dunn </span></td>
|
||||
<td><span>38</span></td>
|
||||
<td><button aria-disabled=\\"false\\" aria-busy=\\"false\\" aria-live=\\"polite\\" class=\\"button button primary medium\\" column=\\"[object Object]\\">
|
||||
<td><button aria-live=\\"polite\\" class=\\"button button primary medium\\" column=\\"[object Object]\\">
|
||||
<!----><span>Button 4</span></button></td>
|
||||
</tr>
|
||||
<tr class=\\"datatableRow\\">
|
||||
<td><span>5</span></td>
|
||||
<td><span>Richard Hendricks</span></td>
|
||||
<td><span>29</span></td>
|
||||
<td><button aria-disabled=\\"false\\" aria-busy=\\"false\\" aria-live=\\"polite\\" class=\\"button button primary medium\\" column=\\"[object Object]\\">
|
||||
<td><button aria-live=\\"polite\\" class=\\"button button primary medium\\" column=\\"[object Object]\\">
|
||||
<!----><span>Button 5</span></button></td>
|
||||
</tr>
|
||||
<tr class=\\"datatableRow\\">
|
||||
<td><span>6</span></td>
|
||||
<td><span>Bertram Gilfoyle</span></td>
|
||||
<td><span>44</span></td>
|
||||
<td><button aria-disabled=\\"false\\" aria-busy=\\"false\\" aria-live=\\"polite\\" class=\\"button button primary medium\\" column=\\"[object Object]\\">
|
||||
<td><button aria-live=\\"polite\\" class=\\"button button primary medium\\" column=\\"[object Object]\\">
|
||||
<!----><span>Button 6</span></button></td>
|
||||
</tr>
|
||||
<tr class=\\"datatableRow\\">
|
||||
<td><span>7</span></td>
|
||||
<td><span>Dinesh Chugtai</span></td>
|
||||
<td><span>31</span></td>
|
||||
<td><button aria-disabled=\\"false\\" aria-busy=\\"false\\" aria-live=\\"polite\\" class=\\"button button primary medium\\" column=\\"[object Object]\\">
|
||||
<td><button aria-live=\\"polite\\" class=\\"button button primary medium\\" column=\\"[object Object]\\">
|
||||
<!----><span>Button 7</span></button></td>
|
||||
</tr>
|
||||
<tr class=\\"datatableRow\\">
|
||||
<td><span>8</span></td>
|
||||
<td><span>Jared Dunn </span></td>
|
||||
<td><span>38</span></td>
|
||||
<td><button aria-disabled=\\"false\\" aria-busy=\\"false\\" aria-live=\\"polite\\" class=\\"button button primary medium\\" column=\\"[object Object]\\">
|
||||
<td><button aria-live=\\"polite\\" class=\\"button button primary medium\\" column=\\"[object Object]\\">
|
||||
<!----><span>Button 8</span></button></td>
|
||||
</tr>
|
||||
<tr class=\\"datatableRow\\">
|
||||
<td><span>9</span></td>
|
||||
<td><span>Richard Hendricks</span></td>
|
||||
<td><span>29</span></td>
|
||||
<td><button aria-disabled=\\"false\\" aria-busy=\\"false\\" aria-live=\\"polite\\" class=\\"button button primary medium\\" column=\\"[object Object]\\">
|
||||
<td><button aria-live=\\"polite\\" class=\\"button button primary medium\\" column=\\"[object Object]\\">
|
||||
<!----><span>Button 9</span></button></td>
|
||||
</tr>
|
||||
<tr class=\\"datatableRow\\">
|
||||
<td><span>10</span></td>
|
||||
<td><span>Bertram Gilfoyle</span></td>
|
||||
<td><span>44</span></td>
|
||||
<td><button aria-disabled=\\"false\\" aria-busy=\\"false\\" aria-live=\\"polite\\" class=\\"button button primary medium\\" column=\\"[object Object]\\">
|
||||
<td><button aria-live=\\"polite\\" class=\\"button button primary medium\\" column=\\"[object Object]\\">
|
||||
<!----><span>Button 10</span></button></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
@@ -38,14 +38,14 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import { defineComponent } from 'vue';
|
||||
import N8nFormInputs from '../N8nFormInputs';
|
||||
import N8nHeading from '../N8nHeading';
|
||||
import N8nLink from '../N8nLink';
|
||||
import N8nButton from '../N8nButton';
|
||||
import { createEventBus } from '../../utils';
|
||||
|
||||
export default Vue.extend({
|
||||
export default defineComponent({
|
||||
name: 'n8n-form-box',
|
||||
components: {
|
||||
N8nHeading,
|
||||
@@ -56,12 +56,11 @@ export default Vue.extend({
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
inputs: {
|
||||
type: Array,
|
||||
default() {
|
||||
return [];
|
||||
},
|
||||
default: () => [],
|
||||
},
|
||||
buttonText: {
|
||||
type: String,
|
||||
@@ -75,9 +74,11 @@ export default Vue.extend({
|
||||
},
|
||||
redirectText: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
redirectLink: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
data() {
|
||||
|
||||
@@ -92,7 +92,7 @@ import N8nSelect from '../N8nSelect';
|
||||
import N8nOption from '../N8nOption';
|
||||
import N8nInputLabel from '../N8nInputLabel';
|
||||
import N8nCheckbox from '../N8nCheckbox';
|
||||
import ElSwitch from 'element-ui/lib/switch';
|
||||
import { Switch as ElSwitch } from 'element-ui';
|
||||
|
||||
import { getValidationError, VALIDATORS } from './validators';
|
||||
import { Rule, RuleGroup, IValidator, Validatable, FormState } from '../../types';
|
||||
|
||||
@@ -3,106 +3,120 @@ import { IValidator, RuleGroup, Validatable } from '../../types';
|
||||
export const emailRegex =
|
||||
/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
||||
|
||||
export const VALIDATORS: { [key: string]: IValidator | RuleGroup } = {
|
||||
REQUIRED: {
|
||||
validate: (value: Validatable) => {
|
||||
if (typeof value === 'string' && !!value.trim()) {
|
||||
return false;
|
||||
}
|
||||
export const requiredValidator: IValidator<{}> = {
|
||||
validate: (value: Validatable) => {
|
||||
if (typeof value === 'string' && !!value.trim()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (typeof value === 'number' || typeof value === 'boolean') {
|
||||
return false;
|
||||
}
|
||||
if (typeof value === 'number' || typeof value === 'boolean') {
|
||||
return false;
|
||||
}
|
||||
|
||||
return {
|
||||
messageKey: 'formInput.validator.fieldRequired',
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
export const minLengthValidator: IValidator<{ minimum: number }> = {
|
||||
validate: (value: Validatable, config: { minimum: number }) => {
|
||||
if (typeof value === 'string' && value.length < config.minimum) {
|
||||
return {
|
||||
messageKey: 'formInput.validator.fieldRequired',
|
||||
messageKey: 'formInput.validator.minCharactersRequired',
|
||||
options: config,
|
||||
};
|
||||
},
|
||||
},
|
||||
MIN_LENGTH: {
|
||||
validate: (value: Validatable, config: { minimum: number }) => {
|
||||
if (typeof value === 'string' && value.length < config.minimum) {
|
||||
return {
|
||||
messageKey: 'formInput.validator.minCharactersRequired',
|
||||
options: config,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
};
|
||||
|
||||
export const maxLengthValidator: IValidator<{ maximum: number }> = {
|
||||
validate: (value: Validatable, config: { maximum: number }) => {
|
||||
if (typeof value === 'string' && value.length > config.maximum) {
|
||||
return {
|
||||
messageKey: 'formInput.validator.maxCharactersRequired',
|
||||
options: config,
|
||||
};
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
};
|
||||
|
||||
export const containsNumberValidator: IValidator<{ minimum: number }> = {
|
||||
validate: (value: Validatable, config: { minimum: number }) => {
|
||||
if (typeof value !== 'string') {
|
||||
return false;
|
||||
},
|
||||
},
|
||||
MAX_LENGTH: {
|
||||
validate: (value: Validatable, config: { maximum: number }) => {
|
||||
if (typeof value === 'string' && value.length > config.maximum) {
|
||||
return {
|
||||
messageKey: 'formInput.validator.maxCharactersRequired',
|
||||
options: config,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const numberCount = (value.match(/\d/g) || []).length;
|
||||
if (numberCount < config.minimum) {
|
||||
return {
|
||||
messageKey: 'formInput.validator.numbersRequired',
|
||||
options: config,
|
||||
};
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
};
|
||||
|
||||
export const emailValidator: IValidator<{}> = {
|
||||
validate: (value: Validatable) => {
|
||||
if (!emailRegex.test(String(value).trim().toLowerCase())) {
|
||||
return {
|
||||
messageKey: 'formInput.validator.validEmailRequired',
|
||||
};
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
};
|
||||
|
||||
export const containsUpperCaseValidator: IValidator<{ minimum: number }> = {
|
||||
validate: (value: Validatable, config: { minimum: number }) => {
|
||||
if (typeof value !== 'string') {
|
||||
return false;
|
||||
},
|
||||
}
|
||||
|
||||
const uppercaseCount = (value.match(/[A-Z]/g) || []).length;
|
||||
if (uppercaseCount < config.minimum) {
|
||||
return {
|
||||
messageKey: 'formInput.validator.uppercaseCharsRequired',
|
||||
options: config,
|
||||
};
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
CONTAINS_NUMBER: {
|
||||
validate: (value: Validatable, config: { minimum: number }) => {
|
||||
if (typeof value !== 'string') {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
const numberCount = (value.match(/\d/g) || []).length;
|
||||
if (numberCount < config.minimum) {
|
||||
return {
|
||||
messageKey: 'formInput.validator.numbersRequired',
|
||||
options: config,
|
||||
};
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
},
|
||||
VALID_EMAIL: {
|
||||
validate: (value: Validatable) => {
|
||||
if (!emailRegex.test(String(value).trim().toLowerCase())) {
|
||||
return {
|
||||
messageKey: 'formInput.validator.validEmailRequired',
|
||||
};
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
},
|
||||
CONTAINS_UPPERCASE: {
|
||||
validate: (value: Validatable, config: { minimum: number }) => {
|
||||
if (typeof value !== 'string') {
|
||||
return false;
|
||||
}
|
||||
|
||||
const uppercaseCount = (value.match(/[A-Z]/g) || []).length;
|
||||
if (uppercaseCount < config.minimum) {
|
||||
return {
|
||||
messageKey: 'formInput.validator.uppercaseCharsRequired',
|
||||
options: config,
|
||||
};
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
},
|
||||
DEFAULT_PASSWORD_RULES: {
|
||||
rules: [
|
||||
{
|
||||
rules: [
|
||||
{ name: 'MIN_LENGTH', config: { minimum: 8 } },
|
||||
{ name: 'CONTAINS_NUMBER', config: { minimum: 1 } },
|
||||
{ name: 'CONTAINS_UPPERCASE', config: { minimum: 1 } },
|
||||
],
|
||||
defaultError: {
|
||||
messageKey: 'formInput.validator.defaultPasswordRequirements',
|
||||
},
|
||||
export const defaultPasswordRules: RuleGroup = {
|
||||
rules: [
|
||||
{
|
||||
rules: [
|
||||
{ name: 'MIN_LENGTH', config: { minimum: 8 } },
|
||||
{ name: 'CONTAINS_NUMBER', config: { minimum: 1 } },
|
||||
{ name: 'CONTAINS_UPPERCASE', config: { minimum: 1 } },
|
||||
],
|
||||
defaultError: {
|
||||
messageKey: 'formInput.validator.defaultPasswordRequirements',
|
||||
},
|
||||
{ name: 'MAX_LENGTH', config: { maximum: 64 } },
|
||||
],
|
||||
},
|
||||
},
|
||||
{ name: 'MAX_LENGTH', config: { maximum: 64 } },
|
||||
],
|
||||
};
|
||||
|
||||
export const VALIDATORS = {
|
||||
REQUIRED: requiredValidator,
|
||||
MIN_LENGTH: minLengthValidator,
|
||||
MAX_LENGTH: maxLengthValidator,
|
||||
CONTAINS_NUMBER: containsNumberValidator,
|
||||
VALID_EMAIL: emailValidator,
|
||||
CONTAINS_UPPERCASE: containsUpperCaseValidator,
|
||||
DEFAULT_PASSWORD_RULES: defaultPasswordRules,
|
||||
};
|
||||
|
||||
export const getValidationError = <T extends Validatable, C>(
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<div
|
||||
v-for="(input, index) in filteredInputs"
|
||||
:key="input.name"
|
||||
:class="{ [`mt-${verticalSpacing}`]: index > 0 }"
|
||||
:class="{ [`mt-${verticalSpacing}`]: verticalSpacing && index > 0 }"
|
||||
>
|
||||
<n8n-text
|
||||
color="text-base"
|
||||
@@ -37,13 +37,13 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue, { PropType } from 'vue';
|
||||
import { defineComponent, PropType } from 'vue';
|
||||
import N8nFormInput from '../N8nFormInput';
|
||||
import type { IFormInput } from '../../types';
|
||||
import ResizeObserver from '../ResizeObserver';
|
||||
import { EventBus } from '@/utils';
|
||||
import { createEventBus, EventBus } from '../../utils';
|
||||
|
||||
export default Vue.extend({
|
||||
export default defineComponent({
|
||||
name: 'n8n-form-inputs',
|
||||
components: {
|
||||
N8nFormInput,
|
||||
@@ -51,13 +51,12 @@ export default Vue.extend({
|
||||
},
|
||||
props: {
|
||||
inputs: {
|
||||
type: Array,
|
||||
default() {
|
||||
return [[]];
|
||||
},
|
||||
type: Array as PropType<IFormInput[]>,
|
||||
default: (): IFormInput[] => [],
|
||||
},
|
||||
eventBus: {
|
||||
type: Object as PropType<EventBus>,
|
||||
default: (): EventBus => createEventBus(),
|
||||
},
|
||||
columnView: {
|
||||
type: Boolean,
|
||||
@@ -65,8 +64,8 @@ export default Vue.extend({
|
||||
},
|
||||
verticalSpacing: {
|
||||
type: String,
|
||||
required: false,
|
||||
validator: (value: string): boolean => ['xs', 's', 'm', 'm', 'l', 'xl'].includes(value),
|
||||
default: '',
|
||||
validator: (value: string): boolean => ['', 'xs', 's', 'm', 'm', 'l', 'xl'].includes(value),
|
||||
},
|
||||
},
|
||||
data() {
|
||||
@@ -77,19 +76,19 @@ export default Vue.extend({
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
(this.inputs as IFormInput[]).forEach((input) => {
|
||||
this.inputs.forEach((input) => {
|
||||
if (input.hasOwnProperty('initialValue')) {
|
||||
Vue.set(this.values, input.name, input.initialValue);
|
||||
this.$set(this.values, input.name, input.initialValue);
|
||||
}
|
||||
});
|
||||
|
||||
if (this.eventBus) {
|
||||
this.eventBus.on('submit', this.onSubmit); // eslint-disable-line @typescript-eslint/unbound-method
|
||||
this.eventBus.on('submit', () => this.onSubmit());
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
filteredInputs(): IFormInput[] {
|
||||
return (this.inputs as IFormInput[]).filter((input) =>
|
||||
return this.inputs.filter((input) =>
|
||||
typeof input.shouldDisplay === 'function' ? input.shouldDisplay(this.values) : true,
|
||||
);
|
||||
},
|
||||
@@ -107,15 +106,16 @@ export default Vue.extend({
|
||||
onInput(name: string, value: unknown) {
|
||||
this.values = {
|
||||
...this.values,
|
||||
[name]: value, // eslint-disable-line @typescript-eslint/no-unsafe-assignment
|
||||
[name]: value,
|
||||
};
|
||||
this.$emit('input', { name, value }); // eslint-disable-line @typescript-eslint/no-unsafe-assignment
|
||||
this.$emit('input', { name, value });
|
||||
},
|
||||
onValidate(name: string, valid: boolean) {
|
||||
Vue.set(this.validity, name, valid);
|
||||
this.$set(this.validity, name, valid);
|
||||
},
|
||||
onSubmit() {
|
||||
this.showValidationWarnings = true;
|
||||
|
||||
if (this.isReadyToSubmit) {
|
||||
const toSubmit = this.filteredInputs.reduce<{ [key: string]: unknown }>((accu, input) => {
|
||||
if (this.values[input.name]) {
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
export default Vue.extend({
|
||||
export default defineComponent({
|
||||
name: 'n8n-heading',
|
||||
props: {
|
||||
tag: {
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
|
||||
import N8nText from '../N8nText';
|
||||
|
||||
import Vue from 'vue';
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
export default Vue.extend({
|
||||
export default defineComponent({
|
||||
name: 'n8n-icon',
|
||||
components: {
|
||||
FontAwesomeIcon,
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
<script lang="ts">
|
||||
import N8nButton from '../N8nButton';
|
||||
|
||||
import Vue from 'vue';
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
export default Vue.extend({
|
||||
export default defineComponent({
|
||||
name: 'n8n-icon-button',
|
||||
components: {
|
||||
N8nButton,
|
||||
|
||||
@@ -41,15 +41,17 @@
|
||||
<script lang="ts">
|
||||
import N8nText from '../N8nText';
|
||||
import N8nIcon from '../N8nIcon';
|
||||
import Vue, { PropType } from 'vue';
|
||||
import { defineComponent, PropType } from 'vue';
|
||||
|
||||
interface IAccordionItem {
|
||||
export interface IAccordionItem {
|
||||
id: string;
|
||||
label: string;
|
||||
icon: string;
|
||||
iconColor?: string;
|
||||
tooltip?: string;
|
||||
}
|
||||
|
||||
export default Vue.extend({
|
||||
export default defineComponent({
|
||||
name: 'n8n-info-accordion',
|
||||
components: {
|
||||
N8nText,
|
||||
@@ -64,9 +66,7 @@ export default Vue.extend({
|
||||
},
|
||||
items: {
|
||||
type: Array as PropType<IAccordionItem[]>,
|
||||
default() {
|
||||
return [];
|
||||
},
|
||||
default: () => [],
|
||||
},
|
||||
initiallyExpanded: {
|
||||
type: Boolean,
|
||||
@@ -92,7 +92,7 @@ export default Vue.extend({
|
||||
toggle() {
|
||||
this.expanded = !this.expanded;
|
||||
},
|
||||
onClick(e) {
|
||||
onClick(e: MouseEvent) {
|
||||
this.$emit('click', e);
|
||||
},
|
||||
onTooltipClick(item: string, event: MouseEvent) {
|
||||
|
||||
@@ -35,9 +35,9 @@
|
||||
import N8nIcon from '../N8nIcon';
|
||||
import N8nTooltip from '../N8nTooltip';
|
||||
|
||||
import Vue from 'vue';
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
export default Vue.extend({
|
||||
export default defineComponent({
|
||||
name: 'n8n-info-tip',
|
||||
components: {
|
||||
N8nIcon,
|
||||
|
||||
@@ -25,9 +25,9 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { Input as ElInput } from 'element-ui';
|
||||
import Vue from 'vue';
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
export default Vue.extend({
|
||||
export default defineComponent({
|
||||
name: 'n8n-input',
|
||||
components: {
|
||||
ElInput,
|
||||
|
||||
@@ -47,9 +47,9 @@ import N8nIcon from '../N8nIcon';
|
||||
|
||||
import { addTargetBlank } from '../utils/helpers';
|
||||
|
||||
import Vue from 'vue';
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
export default Vue.extend({
|
||||
export default defineComponent({
|
||||
name: 'n8n-input-label',
|
||||
components: {
|
||||
N8nText,
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import { defineComponent } from 'vue';
|
||||
import N8nText from '../N8nText';
|
||||
import N8nRoute from '../N8nRoute';
|
||||
|
||||
export default Vue.extend({
|
||||
export default defineComponent({
|
||||
name: 'n8n-link',
|
||||
props: {
|
||||
size: {
|
||||
|
||||
@@ -38,9 +38,9 @@
|
||||
<script lang="ts">
|
||||
import { Skeleton as ElSkeleton, SkeletonItem as ElSkeletonItem } from 'element-ui';
|
||||
|
||||
import Vue from 'vue';
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
export default Vue.extend({
|
||||
export default defineComponent({
|
||||
name: 'n8n-loading',
|
||||
components: {
|
||||
ElSkeleton,
|
||||
|
||||
@@ -19,14 +19,14 @@
|
||||
|
||||
<script lang="ts">
|
||||
import N8nLoading from '../N8nLoading';
|
||||
import Markdown from 'markdown-it';
|
||||
import Markdown, { PluginSimple } from 'markdown-it';
|
||||
|
||||
import markdownLink from 'markdown-it-link-attributes';
|
||||
import markdownEmoji from 'markdown-it-emoji';
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
import markdownTasklists from 'markdown-it-task-lists';
|
||||
|
||||
import { defineComponent, PropType } from 'vue';
|
||||
|
||||
import xss, { friendlyAttrValue } from 'xss';
|
||||
import { escapeMarkdown } from '../../utils/markdown';
|
||||
|
||||
@@ -49,20 +49,18 @@ const DEFAULT_OPTIONS_TASKLISTS = {
|
||||
labelAfter: true,
|
||||
} as const;
|
||||
|
||||
interface IImage {
|
||||
export interface IImage {
|
||||
id: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
interface Options {
|
||||
export interface Options {
|
||||
markdown: typeof DEFAULT_OPTIONS_MARKDOWN;
|
||||
linkAttributes: typeof DEFAULT_OPTIONS_LINK_ATTRIBUTES;
|
||||
tasklists: typeof DEFAULT_OPTIONS_TASKLISTS;
|
||||
}
|
||||
|
||||
import Vue, { PropType } from 'vue';
|
||||
|
||||
export default Vue.extend({
|
||||
export default defineComponent({
|
||||
components: {
|
||||
N8nLoading,
|
||||
},
|
||||
@@ -70,15 +68,19 @@ export default Vue.extend({
|
||||
props: {
|
||||
content: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
withMultiBreaks: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
images: {
|
||||
type: Array<IImage>,
|
||||
type: Array as PropType<IImage[]>,
|
||||
default: () => [],
|
||||
},
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
loadingBlocks: {
|
||||
type: Number,
|
||||
@@ -86,7 +88,7 @@ export default Vue.extend({
|
||||
},
|
||||
loadingRows: {
|
||||
type: Number,
|
||||
default: () => 3,
|
||||
default: 3,
|
||||
},
|
||||
theme: {
|
||||
type: String,
|
||||
@@ -94,15 +96,21 @@ export default Vue.extend({
|
||||
},
|
||||
options: {
|
||||
type: Object as PropType<Options>,
|
||||
default() {
|
||||
return {
|
||||
markdown: DEFAULT_OPTIONS_MARKDOWN,
|
||||
linkAttributes: DEFAULT_OPTIONS_LINK_ATTRIBUTES,
|
||||
tasklists: DEFAULT_OPTIONS_TASKLISTS,
|
||||
};
|
||||
},
|
||||
default: (): Options => ({
|
||||
markdown: DEFAULT_OPTIONS_MARKDOWN,
|
||||
linkAttributes: DEFAULT_OPTIONS_LINK_ATTRIBUTES,
|
||||
tasklists: DEFAULT_OPTIONS_TASKLISTS,
|
||||
}),
|
||||
},
|
||||
},
|
||||
data(): { md: Markdown } {
|
||||
return {
|
||||
md: new Markdown(this.options.markdown)
|
||||
.use(markdownLink, this.options.linkAttributes)
|
||||
.use(markdownEmoji)
|
||||
.use(markdownTasklists as PluginSimple, this.options.tasklists),
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
htmlContent(): string {
|
||||
if (!this.content) {
|
||||
@@ -154,14 +162,6 @@ export default Vue.extend({
|
||||
return safeHtml;
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
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), // eslint-disable-line @typescript-eslint/no-unsafe-member-access
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
onClick(event: MouseEvent) {
|
||||
let clickedLink = null;
|
||||
|
||||
@@ -54,11 +54,10 @@
|
||||
<script lang="ts">
|
||||
import { Menu as ElMenu } from 'element-ui';
|
||||
import N8nMenuItem from '../N8nMenuItem';
|
||||
import { defineComponent, PropType } from 'vue';
|
||||
import type { IMenuItem, RouteObject } from '../../types';
|
||||
|
||||
import Vue, { PropType } from 'vue';
|
||||
import { IMenuItem } from '../../types';
|
||||
|
||||
export default Vue.extend({
|
||||
export default defineComponent({
|
||||
name: 'n8n-menu',
|
||||
components: {
|
||||
ElMenu,
|
||||
@@ -93,6 +92,7 @@ export default Vue.extend({
|
||||
},
|
||||
items: {
|
||||
type: Array as PropType<IMenuItem[]>,
|
||||
default: (): IMenuItem[] => [],
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
@@ -104,9 +104,9 @@ export default Vue.extend({
|
||||
const found = this.items.find((item) => {
|
||||
return (
|
||||
(Array.isArray(item.activateOnRouteNames) &&
|
||||
item.activateOnRouteNames.includes(this.$route.name || '')) ||
|
||||
item.activateOnRouteNames.includes(this.currentRoute.name || '')) ||
|
||||
(Array.isArray(item.activateOnRoutePaths) &&
|
||||
item.activateOnRoutePaths.includes(this.$route.path))
|
||||
item.activateOnRoutePaths.includes(this.currentRoute.path))
|
||||
);
|
||||
});
|
||||
this.activeTab = found ? found.id : '';
|
||||
@@ -127,6 +127,14 @@ export default Vue.extend({
|
||||
(item: IMenuItem) => item.position === 'bottom' && item.available !== false,
|
||||
);
|
||||
},
|
||||
currentRoute(): RouteObject {
|
||||
return (
|
||||
(this as typeof this & { $route: RouteObject }).$route || {
|
||||
name: '',
|
||||
path: '',
|
||||
}
|
||||
);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onSelect(event: MouseEvent, option: string): void {
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
}"
|
||||
data-test-id="menu-item"
|
||||
:index="child.id"
|
||||
@click="onItemClick(child)"
|
||||
@click="onItemClick(child, $event)"
|
||||
>
|
||||
<n8n-icon v-if="child.icon" :class="$style.icon" :icon="child.icon" />
|
||||
<span :class="$style.label">{{ child.label }}</span>
|
||||
@@ -56,7 +56,7 @@
|
||||
}"
|
||||
data-test-id="menu-item"
|
||||
:index="item.id"
|
||||
@click="onItemClick(item)"
|
||||
@click="onItemClick(item, $event)"
|
||||
>
|
||||
<n8n-icon
|
||||
v-if="item.icon"
|
||||
@@ -74,10 +74,10 @@
|
||||
import { Submenu as ElSubmenu, MenuItem as ElMenuItem } from 'element-ui';
|
||||
import N8nTooltip from '../N8nTooltip';
|
||||
import N8nIcon from '../N8nIcon';
|
||||
import { IMenuItem } from '../../types';
|
||||
import Vue, { PropType } from 'vue';
|
||||
import { defineComponent, PropType } from 'vue';
|
||||
import type { IMenuItem, RouteObject } from '../../types';
|
||||
|
||||
export default Vue.extend({
|
||||
export default defineComponent({
|
||||
name: 'n8n-menu-item',
|
||||
components: {
|
||||
ElSubmenu,
|
||||
@@ -117,6 +117,14 @@ export default Vue.extend({
|
||||
? this.item.children.filter((child) => child.available !== false)
|
||||
: [];
|
||||
},
|
||||
currentRoute(): RouteObject {
|
||||
return (
|
||||
(this as typeof this & { $route: RouteObject }).$route || {
|
||||
name: '',
|
||||
path: '',
|
||||
}
|
||||
);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
isItemActive(item: IMenuItem): boolean {
|
||||
@@ -130,12 +138,12 @@ export default Vue.extend({
|
||||
if (item.activateOnRoutePaths) {
|
||||
return (
|
||||
Array.isArray(item.activateOnRoutePaths) &&
|
||||
item.activateOnRoutePaths.includes(this.$route.path)
|
||||
item.activateOnRoutePaths.includes(this.currentRoute.path)
|
||||
);
|
||||
} else if (item.activateOnRouteNames) {
|
||||
return (
|
||||
Array.isArray(item.activateOnRouteNames) &&
|
||||
item.activateOnRouteNames.includes(this.$route.name || '')
|
||||
item.activateOnRouteNames.includes(this.currentRoute.name || '')
|
||||
);
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -36,11 +36,11 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import { defineComponent } from 'vue';
|
||||
import N8nTooltip from '../N8nTooltip';
|
||||
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
|
||||
|
||||
export default Vue.extend({
|
||||
export default defineComponent({
|
||||
name: 'n8n-node-icon',
|
||||
components: {
|
||||
N8nTooltip,
|
||||
@@ -78,12 +78,13 @@ export default Vue.extend({
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
iconStyleData(): object {
|
||||
iconStyleData(): Record<string, string> {
|
||||
if (!this.size) {
|
||||
return {
|
||||
color: this.color || '',
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
color: this.color || '',
|
||||
width: `${this.size}px`,
|
||||
@@ -92,7 +93,11 @@ export default Vue.extend({
|
||||
'line-height': `${this.size}px`,
|
||||
};
|
||||
},
|
||||
fontStyleData(): object {
|
||||
fontStyleData(): Record<string, string> {
|
||||
if (!this.size) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return {
|
||||
'max-width': `${this.size}px`,
|
||||
};
|
||||
|
||||
@@ -16,13 +16,13 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import { defineComponent } from 'vue';
|
||||
import sanitizeHtml from 'sanitize-html';
|
||||
import N8nText from '../../components/N8nText';
|
||||
import Locale from '../../mixins/locale';
|
||||
import { uid } from '../../utils';
|
||||
|
||||
export default Vue.extend({
|
||||
export default defineComponent({
|
||||
name: 'n8n-notice',
|
||||
directives: {},
|
||||
mixins: [Locale],
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Vue from 'vue';
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
export default Vue.extend({
|
||||
export default defineComponent({
|
||||
name: 'n8n-pulse',
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
:class="{
|
||||
'n8n-radio-button': true,
|
||||
[$style.container]: true,
|
||||
[$style.hoverable]: !this.disabled,
|
||||
[$style.hoverable]: !disabled,
|
||||
}"
|
||||
aria-checked="true"
|
||||
>
|
||||
@@ -26,9 +26,9 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
export default Vue.extend({
|
||||
export default defineComponent({
|
||||
name: 'n8n-radio-button',
|
||||
props: {
|
||||
label: {
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
:active="value === option.value"
|
||||
:size="size"
|
||||
:disabled="disabled || option.disabled"
|
||||
@click="(e) => onClick(option, e)"
|
||||
@click="() => onClick(option)"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
@@ -18,15 +18,24 @@
|
||||
<script lang="ts">
|
||||
import RadioButton from './RadioButton.vue';
|
||||
|
||||
import Vue from 'vue';
|
||||
import { defineComponent, PropType } from 'vue';
|
||||
|
||||
export default Vue.extend({
|
||||
export interface RadioOption {
|
||||
label: string;
|
||||
value: string;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: 'n8n-radio-buttons',
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
},
|
||||
options: {},
|
||||
options: {
|
||||
type: Array as PropType<RadioOption[]>,
|
||||
default: (): RadioOption[] => [],
|
||||
},
|
||||
size: {
|
||||
type: String,
|
||||
},
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
PropType,
|
||||
nextTick,
|
||||
watch,
|
||||
ComponentPublicInstance,
|
||||
} from 'vue';
|
||||
|
||||
export default defineComponent({
|
||||
@@ -36,7 +37,7 @@ export default defineComponent({
|
||||
const wrapperRef = ref<HTMLElement | null>(null);
|
||||
const scrollerRef = ref<HTMLElement | null>(null);
|
||||
const itemsRef = ref<HTMLElement | null>(null);
|
||||
const itemRefs = ref<Record<string, HTMLElement | null>>({});
|
||||
const itemRefs = ref<Record<string, Element | ComponentPublicInstance | null>>({});
|
||||
|
||||
const scrollTop = ref(0);
|
||||
const wrapperHeight = ref(0);
|
||||
@@ -174,7 +175,7 @@ export default defineComponent({
|
||||
function onUpdateItemSize(item: { [key: string]: string }) {
|
||||
nextTick(() => {
|
||||
const itemId = item[props.itemKey];
|
||||
const itemRef = itemRefs.value[itemId];
|
||||
const itemRef = itemRefs.value[itemId] as HTMLElement;
|
||||
const previousSize = itemSizeCache.value[itemId];
|
||||
const size = itemRef ? itemRef.offsetHeight : props.itemSize;
|
||||
const difference = size - previousSize;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
v-for="direction in enabledDirections"
|
||||
:key="direction"
|
||||
:data-dir="direction"
|
||||
:class="[$style.resizer, $style[direction]]"
|
||||
:class="{ [$style.resizer]: true, [$style[direction]]: true }"
|
||||
@mousedown="resizerMove"
|
||||
/>
|
||||
<slot></slot>
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
<script lang="ts">
|
||||
/* eslint-disable @typescript-eslint/unbound-method */
|
||||
import Vue from 'vue';
|
||||
import { defineComponent, PropType } from 'vue';
|
||||
|
||||
function closestNumber(value: number, divisor: number): number {
|
||||
const q = value / divisor;
|
||||
@@ -46,7 +46,7 @@ const directionsCursorMaps: { [key: string]: string } = {
|
||||
bottomRight: 'se-resize',
|
||||
};
|
||||
|
||||
export default Vue.extend({
|
||||
export default defineComponent({
|
||||
name: 'n8n-resize',
|
||||
props: {
|
||||
isResizingEnabled: {
|
||||
@@ -55,15 +55,19 @@ export default Vue.extend({
|
||||
},
|
||||
height: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
width: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
minHeight: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
minWidth: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
scale: {
|
||||
type: Number,
|
||||
@@ -71,10 +75,11 @@ export default Vue.extend({
|
||||
},
|
||||
gridSize: {
|
||||
type: Number,
|
||||
default: 20,
|
||||
},
|
||||
supportedDirections: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
type: Array as PropType<string[]>,
|
||||
default: (): string[] => [],
|
||||
},
|
||||
},
|
||||
data() {
|
||||
@@ -90,7 +95,7 @@ export default Vue.extend({
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
enabledDirections() {
|
||||
enabledDirections(): string[] {
|
||||
const availableDirections = Object.keys(directionsCursorMaps);
|
||||
|
||||
if (!this.isResizingEnabled) return [];
|
||||
|
||||
@@ -10,9 +10,9 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
export default Vue.extend({
|
||||
export default defineComponent({
|
||||
name: 'n8n-route',
|
||||
props: {
|
||||
to: {
|
||||
@@ -25,12 +25,13 @@ export default Vue.extend({
|
||||
},
|
||||
computed: {
|
||||
useRouterLink() {
|
||||
if (this.newWindow === true) {
|
||||
if (this.newWindow) {
|
||||
// router-link does not support click events and opening in new window
|
||||
return false;
|
||||
}
|
||||
|
||||
if (typeof this.to === 'string') {
|
||||
return (this.to as string).startsWith('/');
|
||||
return this.to.startsWith('/');
|
||||
}
|
||||
|
||||
return this.to !== undefined;
|
||||
@@ -39,8 +40,9 @@ export default Vue.extend({
|
||||
if (this.newWindow !== undefined) {
|
||||
return this.newWindow;
|
||||
}
|
||||
|
||||
if (typeof this.to === 'string') {
|
||||
return !(this.to as string).startsWith('/');
|
||||
return !this.to.startsWith('/');
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { Select as ElSelect } from 'element-ui';
|
||||
import Vue from 'vue';
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
export interface IProps {
|
||||
size?: string;
|
||||
@@ -41,7 +41,7 @@ export interface IProps {
|
||||
popperClass?: string;
|
||||
}
|
||||
|
||||
export default Vue.extend({
|
||||
export default defineComponent({
|
||||
name: 'n8n-select',
|
||||
components: {
|
||||
ElSelect,
|
||||
|
||||
@@ -13,9 +13,9 @@
|
||||
<script lang="ts">
|
||||
import N8nIcon from '../N8nIcon';
|
||||
|
||||
import Vue from 'vue';
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
export default Vue.extend({
|
||||
export default defineComponent({
|
||||
name: 'n8n-spinner',
|
||||
components: {
|
||||
N8nIcon,
|
||||
|
||||
@@ -66,10 +66,11 @@ import N8nMarkdown from '../N8nMarkdown';
|
||||
import N8nResizeWrapper from '../N8nResizeWrapper';
|
||||
import N8nText from '../N8nText';
|
||||
import Locale from '../../mixins/locale';
|
||||
import mixins from 'vue-typed-mixins';
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
export default mixins(Locale).extend({
|
||||
export default defineComponent({
|
||||
name: 'n8n-sticky',
|
||||
mixins: [Locale],
|
||||
props: {
|
||||
content: {
|
||||
type: String,
|
||||
|
||||
@@ -47,10 +47,19 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import { defineComponent, PropType } from 'vue';
|
||||
import N8nIcon from '../N8nIcon';
|
||||
|
||||
export default Vue.extend({
|
||||
export interface N8nTabOptions {
|
||||
value: string;
|
||||
label?: string;
|
||||
icon?: string;
|
||||
href?: string;
|
||||
tooltip?: string;
|
||||
align?: 'left' | 'right';
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
name: 'N8nTabs',
|
||||
components: {
|
||||
N8nIcon,
|
||||
@@ -92,7 +101,10 @@ export default Vue.extend({
|
||||
},
|
||||
props: {
|
||||
value: {},
|
||||
options: {},
|
||||
options: {
|
||||
type: Array as PropType<N8nTabOptions[]>,
|
||||
default: (): N8nTabOptions[] => [],
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleTooltipClick(tab: string, event: MouseEvent) {
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
export default Vue.extend({
|
||||
export default defineComponent({
|
||||
name: 'n8n-tag',
|
||||
props: {
|
||||
text: {
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
size="small"
|
||||
@click.stop.prevent="onExpand"
|
||||
>
|
||||
{{ t('tags.showMore', hiddenTagsLength) }}
|
||||
{{ t('tags.showMore', `${hiddenTagsLength}`) }}
|
||||
</n8n-link>
|
||||
</div>
|
||||
</template>
|
||||
@@ -22,16 +22,16 @@
|
||||
import N8nTag from '../N8nTag';
|
||||
import N8nLink from '../N8nLink';
|
||||
import Locale from '../../mixins/locale';
|
||||
import { PropType } from 'vue';
|
||||
import mixins from 'vue-typed-mixins';
|
||||
import { defineComponent, PropType } from 'vue';
|
||||
|
||||
interface ITag {
|
||||
export interface ITag {
|
||||
id: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export default mixins(Locale).extend({
|
||||
export default defineComponent({
|
||||
name: 'n8n-tags',
|
||||
mixins: [Locale],
|
||||
components: {
|
||||
N8nTag,
|
||||
N8nLink,
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
export default Vue.extend({
|
||||
import { defineComponent } from 'vue';
|
||||
export default defineComponent({
|
||||
name: 'n8n-text',
|
||||
props: {
|
||||
bold: {
|
||||
|
||||
@@ -20,12 +20,12 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue, { PropType } from 'vue';
|
||||
import { defineComponent, PropType } from 'vue';
|
||||
import { Tooltip as ElTooltip } from 'element-ui';
|
||||
import type { IN8nButton } from '@/types';
|
||||
import N8nButton from '../N8nButton';
|
||||
|
||||
export default Vue.extend({
|
||||
export default defineComponent({
|
||||
name: 'n8n-tooltip',
|
||||
inheritAttrs: false,
|
||||
components: {
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
<template>
|
||||
<div class="n8n-tree">
|
||||
<div
|
||||
v-for="(label, i) in Object.keys(value || {})"
|
||||
:key="i"
|
||||
:class="{ [nodeClass]: !!nodeClass, [$style.indent]: depth > 0 }"
|
||||
>
|
||||
<div v-for="(label, i) in Object.keys(value)" :key="i" :class="classes">
|
||||
<div :class="$style.simple" v-if="isSimple(value[label])">
|
||||
<slot
|
||||
v-if="$scopedSlots.label"
|
||||
@@ -41,15 +37,18 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import { defineComponent, PropType } from 'vue';
|
||||
|
||||
export default Vue.extend({
|
||||
export default defineComponent({
|
||||
name: 'n8n-tree',
|
||||
components: {},
|
||||
props: {
|
||||
value: {},
|
||||
value: {
|
||||
type: Object as PropType<Record<string, unknown>>,
|
||||
default: () => ({}),
|
||||
},
|
||||
path: {
|
||||
type: Array,
|
||||
type: Array as PropType<string[]>,
|
||||
default: () => [],
|
||||
},
|
||||
depth: {
|
||||
@@ -58,6 +57,12 @@ export default Vue.extend({
|
||||
},
|
||||
nodeClass: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
classes(): Record<string, boolean> {
|
||||
return { [this.nodeClass]: !!this.nodeClass, [this.$style.indent]: this.depth > 0 };
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<div>
|
||||
<n8n-text :bold="true" color="text-dark">
|
||||
{{ firstName }} {{ lastName }}
|
||||
{{ isCurrentUser ? this.t('nds.userInfo.you') : '' }}
|
||||
{{ isCurrentUser ? t('nds.userInfo.you') : '' }}
|
||||
</n8n-text>
|
||||
<span v-if="disabled" :class="$style.pendingBadge">
|
||||
<n8n-badge :bold="true">Disabled</n8n-badge>
|
||||
@@ -31,15 +31,15 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import 'vue';
|
||||
import N8nText from '../N8nText';
|
||||
import N8nAvatar from '../N8nAvatar';
|
||||
import N8nBadge from '../N8nBadge';
|
||||
import Locale from '../../mixins/locale';
|
||||
import mixins from 'vue-typed-mixins';
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
export default mixins(Locale).extend({
|
||||
export default defineComponent({
|
||||
name: 'n8n-users-info',
|
||||
mixins: [Locale],
|
||||
components: {
|
||||
N8nAvatar,
|
||||
N8nText,
|
||||
|
||||
@@ -30,41 +30,39 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import 'vue';
|
||||
import mixins from 'vue-typed-mixins';
|
||||
import { Select as ElSelect, Option as ElOption } from 'element-ui';
|
||||
import N8nUserInfo from '../N8nUserInfo';
|
||||
import N8nSelect from '../N8nSelect';
|
||||
import N8nOption from '../N8nOption';
|
||||
import { IUser } from '../../types';
|
||||
import Locale from '../../mixins/locale';
|
||||
import { t } from '../../locale';
|
||||
import { defineComponent, PropType } from 'vue';
|
||||
|
||||
export default mixins(Locale).extend({
|
||||
export default defineComponent({
|
||||
name: 'n8n-user-select',
|
||||
mixins: [Locale],
|
||||
components: {
|
||||
N8nUserInfo,
|
||||
ElSelect,
|
||||
ElOption,
|
||||
N8nSelect,
|
||||
N8nOption,
|
||||
},
|
||||
props: {
|
||||
users: {
|
||||
type: Array,
|
||||
default() {
|
||||
return [];
|
||||
},
|
||||
type: Array as PropType<IUser[]>,
|
||||
default: () => [],
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
ignoreIds: {
|
||||
type: Array,
|
||||
default() {
|
||||
return [];
|
||||
},
|
||||
type: Array as PropType<string[]>,
|
||||
default: () => [],
|
||||
validator: (ids: string[]) => !ids.find((id) => typeof id !== 'string'),
|
||||
},
|
||||
currentUserId: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
@@ -72,6 +70,7 @@ export default mixins(Locale).extend({
|
||||
},
|
||||
size: {
|
||||
type: String,
|
||||
default: '',
|
||||
validator: (value: string): boolean => ['mini', 'small', 'medium', 'large'].includes(value),
|
||||
},
|
||||
},
|
||||
@@ -82,12 +81,12 @@ export default mixins(Locale).extend({
|
||||
},
|
||||
computed: {
|
||||
filteredUsers(): IUser[] {
|
||||
return (this.users as IUser[]).filter((user) => {
|
||||
return this.users.filter((user) => {
|
||||
if (user.isPendingUser || !user.email) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.ignoreIds && this.ignoreIds.includes(user.id)) {
|
||||
if (this.ignoreIds.includes(user.id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,16 +32,16 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { IUser, IUserListAction } from '../../types';
|
||||
import type { IUser, UserAction } from '../../types';
|
||||
import N8nActionToggle from '../N8nActionToggle';
|
||||
import N8nBadge from '../N8nBadge';
|
||||
import N8nUserInfo from '../N8nUserInfo';
|
||||
import Locale from '../../mixins/locale';
|
||||
import mixins from 'vue-typed-mixins';
|
||||
import { PropType } from 'vue';
|
||||
import { defineComponent, PropType } from 'vue';
|
||||
|
||||
export default mixins(Locale).extend({
|
||||
export default defineComponent({
|
||||
name: 'n8n-users-list',
|
||||
mixins: [Locale],
|
||||
components: {
|
||||
N8nActionToggle,
|
||||
N8nBadge,
|
||||
@@ -63,7 +63,7 @@ export default mixins(Locale).extend({
|
||||
type: String,
|
||||
},
|
||||
actions: {
|
||||
type: Array as PropType<IUserListAction[]>,
|
||||
type: Array as PropType<UserAction[]>,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
@@ -107,7 +107,7 @@ export default mixins(Locale).extend({
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
getActions(user: IUser): IUserListAction[] {
|
||||
getActions(user: IUser): UserAction[] {
|
||||
if (user.isOwner) {
|
||||
return [];
|
||||
}
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
export default Vue.extend({
|
||||
export default defineComponent({
|
||||
name: 'ResizeObserver',
|
||||
props: {
|
||||
enabled: {
|
||||
@@ -62,7 +62,7 @@ export default Vue.extend({
|
||||
});
|
||||
});
|
||||
|
||||
this.$data.observer = observer;
|
||||
this.observer = observer;
|
||||
|
||||
if (this.$refs.root) {
|
||||
observer.observe(this.$refs.root as HTMLDivElement);
|
||||
@@ -70,7 +70,7 @@ export default Vue.extend({
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.enabled) {
|
||||
this.$data.observer.disconnect(); // eslint-disable-line
|
||||
this.observer?.disconnect(); // eslint-disable-line
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -11,7 +11,7 @@ const RE_NARGS = /(%|)\{([0-9a-zA-Z_]+)\}/g;
|
||||
* https://github.com/ElemeFE/element/blob/dev/src/locale/format.js
|
||||
* https://github.com/Matt-Esch/string-template/index.js
|
||||
*/
|
||||
export default function (Vue) {
|
||||
export default function () {
|
||||
/**
|
||||
* template
|
||||
*
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import defaultLang from '../locale/lang/en';
|
||||
import Vue from 'vue';
|
||||
import Format from './format';
|
||||
|
||||
import ElementLocale from 'element-ui/lib/locale';
|
||||
import ElementLang from 'element-ui/lib/locale/lang/en';
|
||||
ElementLocale.use(ElementLang);
|
||||
|
||||
const format = Format(Vue);
|
||||
const format = Format();
|
||||
let lang = defaultLang;
|
||||
|
||||
let i18nHandler;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Vue from 'vue';
|
||||
import type { PluginObject } from 'vue';
|
||||
import N8nActionBox from '../components/N8nActionBox';
|
||||
import N8nActionDropdown from '../components/N8nActionDropdown';
|
||||
import N8nActionToggle from '../components/N8nActionToggle';
|
||||
@@ -47,8 +47,8 @@ import N8nUsersList from '../components/N8nUsersList';
|
||||
import N8nResizeWrapper from '../components/N8nResizeWrapper';
|
||||
import N8nRecycleScroller from '../components/N8nRecycleScroller';
|
||||
|
||||
export default {
|
||||
install: (app: typeof Vue) => {
|
||||
const n8nComponentsPlugin: PluginObject<{}> = {
|
||||
install: (app) => {
|
||||
app.component('n8n-info-accordion', N8nInfoAccordion);
|
||||
app.component('n8n-action-box', N8nActionBox);
|
||||
app.component('n8n-action-dropdown', N8nActionDropdown);
|
||||
@@ -98,3 +98,5 @@ export default {
|
||||
app.component('n8n-recycle-scroller', N8nRecycleScroller);
|
||||
},
|
||||
};
|
||||
|
||||
export default n8nComponentsPlugin;
|
||||
|
||||
4
packages/design-system/src/shims-markdown-it.d.ts
vendored
Normal file
4
packages/design-system/src/shims-markdown-it.d.ts
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
declare module 'markdown-it-task-lists' {
|
||||
import type { PluginSimple } from 'markdown-it';
|
||||
export default plugin as PluginSimple<{}>;
|
||||
}
|
||||
@@ -10,7 +10,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import { defineComponent, PropType } from 'vue';
|
||||
|
||||
function hslToHex(h: number, s: number, l: number): string {
|
||||
l /= 100;
|
||||
@@ -36,7 +36,7 @@ function getHex(hsl: string): string {
|
||||
return hslToHex(colors[0], colors[1], colors[2]);
|
||||
}
|
||||
|
||||
export default Vue.extend({
|
||||
export default defineComponent({
|
||||
name: 'color-circles',
|
||||
data() {
|
||||
return {
|
||||
@@ -46,16 +46,16 @@ export default Vue.extend({
|
||||
},
|
||||
props: {
|
||||
colors: {
|
||||
type: Array,
|
||||
type: Array as PropType<string[]>,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
created() {
|
||||
const setColors = () => {
|
||||
(this.colors as string[]).forEach((color: string) => {
|
||||
this.colors.forEach((color) => {
|
||||
const style = getComputedStyle(document.body);
|
||||
|
||||
Vue.set(this.hsl, color, style.getPropertyValue(color));
|
||||
this.$set(this.hsl, color, style.getPropertyValue(color));
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -18,33 +18,34 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import { defineComponent, PropType } from 'vue';
|
||||
|
||||
export default Vue.extend({
|
||||
export default defineComponent({
|
||||
name: 'sizes',
|
||||
data() {
|
||||
return {
|
||||
observer: null as null | MutationObserver,
|
||||
sizes: {},
|
||||
sizes: {} as Record<string, { rem: string; px: number }>,
|
||||
};
|
||||
},
|
||||
props: {
|
||||
variables: {
|
||||
type: Array,
|
||||
type: Array as PropType<string[]>,
|
||||
required: true,
|
||||
},
|
||||
attr: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
created() {
|
||||
const setSizes = () => {
|
||||
(this.variables as string[]).forEach((variable: string) => {
|
||||
this.variables.forEach((variable: string) => {
|
||||
const style = getComputedStyle(document.body);
|
||||
const rem = style.getPropertyValue(variable);
|
||||
const px = parseFloat(rem.replace('rem', '')) * 16;
|
||||
|
||||
Vue.set(this.sizes, variable, { rem, px });
|
||||
this.$set(this.sizes, variable, { rem, px });
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -16,32 +16,33 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
import { defineComponent, PropType } from 'vue';
|
||||
|
||||
export default Vue.extend({
|
||||
export default defineComponent({
|
||||
name: 'variable-table',
|
||||
data() {
|
||||
return {
|
||||
observer: null as null | MutationObserver,
|
||||
values: {},
|
||||
values: {} as Record<string, string>,
|
||||
};
|
||||
},
|
||||
props: {
|
||||
variables: {
|
||||
type: Array,
|
||||
type: Array as PropType<string[]>,
|
||||
required: true,
|
||||
},
|
||||
attr: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
created() {
|
||||
const setValues = () => {
|
||||
(this.variables as string[]).forEach((variable: string) => {
|
||||
this.variables.forEach((variable) => {
|
||||
const style = getComputedStyle(document.body);
|
||||
const value = style.getPropertyValue(variable);
|
||||
|
||||
Vue.set(this.values, variable, value);
|
||||
this.$set(this.values, variable, value);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -8,10 +8,11 @@
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import Vue from 'vue';
|
||||
|
||||
export default Vue.extend({
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'SpacingPreview',
|
||||
props: {
|
||||
property: {
|
||||
|
||||
@@ -7,10 +7,10 @@ export type RuleGroup = {
|
||||
|
||||
export type Validatable = string | number | boolean | null | undefined;
|
||||
|
||||
export type IValidator = {
|
||||
export type IValidator<T = unknown> = {
|
||||
validate: (
|
||||
value: Validatable,
|
||||
config: unknown,
|
||||
config: T,
|
||||
) => false | { messageKey: string; options?: unknown } | null;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
export * from './button';
|
||||
export * from './form';
|
||||
export * from './user';
|
||||
export * from './menu';
|
||||
export * from './router';
|
||||
export * from './user';
|
||||
|
||||
4
packages/design-system/src/types/router.ts
Normal file
4
packages/design-system/src/types/router.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export interface RouteObject {
|
||||
name: string;
|
||||
path: string;
|
||||
}
|
||||
@@ -11,14 +11,10 @@ export interface IUser {
|
||||
signInType: string;
|
||||
}
|
||||
|
||||
export interface IUserListAction {
|
||||
label: string;
|
||||
value: string;
|
||||
guard?: (user: IUser) => boolean;
|
||||
}
|
||||
|
||||
export interface IUserListAction {
|
||||
export interface UserAction {
|
||||
label: string;
|
||||
value: string;
|
||||
disabled: boolean;
|
||||
type?: 'external-link';
|
||||
guard?: (user: IUser) => boolean;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,13 @@
|
||||
export type CallbackFn = Function;
|
||||
export type UnregisterFn = () => void;
|
||||
|
||||
export function createEventBus() {
|
||||
export interface EventBus {
|
||||
on: (eventName: string, fn: CallbackFn) => UnregisterFn;
|
||||
off: (eventName: string, fn: CallbackFn) => void;
|
||||
emit: <T = Event>(eventName: string, event?: T) => void;
|
||||
}
|
||||
|
||||
export function createEventBus(): EventBus {
|
||||
const handlers = new Map<string, CallbackFn[]>();
|
||||
|
||||
function off(eventName: string, fn: CallbackFn) {
|
||||
@@ -43,5 +49,3 @@ export function createEventBus() {
|
||||
emit,
|
||||
};
|
||||
}
|
||||
|
||||
export type EventBus = ReturnType<typeof createEventBus>;
|
||||
|
||||
@@ -22,9 +22,7 @@ export default Vue.extend({
|
||||
},
|
||||
stickyOffset: {
|
||||
type: Array as PropType<number[]>,
|
||||
default() {
|
||||
return [0, 0];
|
||||
},
|
||||
default: () => [0, 0],
|
||||
},
|
||||
},
|
||||
data() {
|
||||
|
||||
@@ -195,15 +195,13 @@ export default mixins(debounceHelper, workflowHelpers, nodeHelpers).extend({
|
||||
inputSize: {
|
||||
type: String,
|
||||
default: 'small',
|
||||
validator: (size) => {
|
||||
validator: (size: string) => {
|
||||
return ['mini', 'small', 'medium', 'large', 'xlarge'].includes(size);
|
||||
},
|
||||
},
|
||||
parameterIssues: {
|
||||
type: Array as PropType<string[]>,
|
||||
default() {
|
||||
return [];
|
||||
},
|
||||
default: () => [],
|
||||
},
|
||||
displayTitle: {
|
||||
type: String,
|
||||
|
||||
@@ -70,7 +70,7 @@ exports[`PersonalizationModal.vue > should render correctly 1`] = `
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
<div class=\\"mt-undefined\\">
|
||||
<div class=\\"\\">
|
||||
<div class=\\"container\\" data-test-id=\\"role\\"><label for=\\"role\\" class=\\"inputLabel heading medium\\">
|
||||
<div class=\\"title\\"><span class=\\"n8n-text size-medium bold\\"> Which role best describes you? <!----></span></div>
|
||||
<!---->
|
||||
@@ -122,7 +122,7 @@ exports[`PersonalizationModal.vue > should render correctly 1`] = `
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
<div class=\\"mt-undefined\\">
|
||||
<div class=\\"\\">
|
||||
<div class=\\"container\\" data-test-id=\\"automationBeneficiary\\"><label for=\\"automationBeneficiary\\" class=\\"inputLabel heading medium\\">
|
||||
<div class=\\"title\\"><span class=\\"n8n-text size-medium bold\\"> Who will your automations mainly be for? <!----></span></div>
|
||||
<!---->
|
||||
@@ -168,7 +168,7 @@ exports[`PersonalizationModal.vue > should render correctly 1`] = `
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
<div class=\\"mt-undefined\\">
|
||||
<div class=\\"\\">
|
||||
<div class=\\"container\\" data-test-id=\\"companySize\\"><label for=\\"companySize\\" class=\\"inputLabel heading medium\\">
|
||||
<div class=\\"title\\"><span class=\\"n8n-text size-medium bold\\"> How big is your company? <!----></span></div>
|
||||
<!---->
|
||||
@@ -217,7 +217,7 @@ exports[`PersonalizationModal.vue > should render correctly 1`] = `
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
<div class=\\"mt-undefined\\">
|
||||
<div class=\\"\\">
|
||||
<div class=\\"container\\" data-test-id=\\"reportedSource\\"><label for=\\"reportedSource\\" class=\\"inputLabel heading medium\\">
|
||||
<div class=\\"title\\"><span class=\\"n8n-text size-medium bold\\"> How did you hear about n8n? <!----></span></div>
|
||||
<!---->
|
||||
@@ -273,7 +273,7 @@ exports[`PersonalizationModal.vue > should render correctly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
<div class=\\"footer\\">
|
||||
<div><button aria-disabled=\\"false\\" aria-busy=\\"false\\" aria-live=\\"polite\\" class=\\"button button primary medium float-right\\">
|
||||
<div><button aria-live=\\"polite\\" class=\\"button button primary medium float-right\\">
|
||||
<!----><span>Get started</span></button></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user