mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
fix: fix design for popper components
This commit is contained in:
parent
73ffba931e
commit
fd0896478a
|
@ -2,7 +2,7 @@ const { mergeConfig } = require('vite');
|
|||
const { resolve } = require('path');
|
||||
|
||||
module.exports = {
|
||||
stories: ['../src/**/*.stories.@(js|jsx|ts|tsx)'],
|
||||
stories: ['../src/**/*.stories.@(js|jsx|ts|tsx|mdx)'],
|
||||
addons: [
|
||||
'@storybook/addon-styling',
|
||||
'@storybook/addon-links',
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
@use './fonts.scss';
|
||||
|
||||
@use '../src/css/base.scss'; // with (
|
||||
@use '../src/css/base.scss'; // @TODO CHECK IF NEEDED with (
|
||||
// $font-path: 'element-ui/lib/theme-chalk/fonts'
|
||||
//);
|
||||
|
||||
|
@ -10,3 +10,8 @@
|
|||
.multi-container > * {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
#storybook-root > div:not([class]) > *,
|
||||
#storybook-root > * {
|
||||
margin: var(--spacing-5xs);
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ const TemplateForSlots: StoryFn = (args, { argTypes }) => ({
|
|||
template: `<div style="position: relative; width: 100%; height: 300px;">
|
||||
<n8n-alert v-bind="args">
|
||||
<template #title>Title</template>
|
||||
<template>Description</template>
|
||||
Description
|
||||
<template #aside><button>Button</button></template>
|
||||
<template #icon>
|
||||
<n8n-icon icon="grin-stars" size="xlarge" />
|
||||
|
|
|
@ -51,10 +51,10 @@ const template: StoryFn<Args> = (args, { argTypes }) => ({
|
|||
template: `
|
||||
<n8n-callout v-bind="args">
|
||||
${args.default}
|
||||
<template #actions v-if="actions">
|
||||
<template #actions v-if="args.actions">
|
||||
${args.actions}
|
||||
</template>
|
||||
<template #trailingContent v-if="trailingContent">
|
||||
<template #trailingContent v-if="args.trailingContent">
|
||||
${args.trailingContent}
|
||||
</template>
|
||||
</n8n-callout>
|
||||
|
|
|
@ -10,6 +10,7 @@ export default {
|
|||
};
|
||||
|
||||
export const Default: StoryFn = (args, { argTypes }) => ({
|
||||
setup: () => ({ args }),
|
||||
props: Object.keys(argTypes),
|
||||
components: {
|
||||
N8nCard,
|
||||
|
@ -18,6 +19,7 @@ export const Default: StoryFn = (args, { argTypes }) => ({
|
|||
});
|
||||
|
||||
export const Hoverable: StoryFn = (args, { argTypes }) => ({
|
||||
setup: () => ({ args }),
|
||||
props: Object.keys(argTypes),
|
||||
components: {
|
||||
N8nCard,
|
||||
|
@ -37,6 +39,7 @@ Hoverable.args = {
|
|||
};
|
||||
|
||||
export const WithSlots: StoryFn = (args, { argTypes }) => ({
|
||||
setup: () => ({ args }),
|
||||
props: Object.keys(argTypes),
|
||||
components: {
|
||||
N8nCard,
|
||||
|
@ -45,21 +48,21 @@ export const WithSlots: StoryFn = (args, { argTypes }) => ({
|
|||
N8nText,
|
||||
},
|
||||
template: `<n8n-card v-bind="args">
|
||||
<template slot="prepend">
|
||||
<template #prepend>
|
||||
<n8n-icon icon="check" size="large" />
|
||||
</template>
|
||||
<template slot="header">
|
||||
<template #header>
|
||||
<strong>Card header</strong>
|
||||
</template>
|
||||
<n8n-text color="text-light" size="medium" class="mt-2xs mb-2xs">
|
||||
This is the card body.
|
||||
</n8n-text>
|
||||
<template slot="footer">
|
||||
<template #footer>
|
||||
<n8n-text size="medium">
|
||||
Card footer
|
||||
</n8n-text>
|
||||
</template>
|
||||
<template slot="append">
|
||||
<template #append>
|
||||
<n8n-button>Click me</n8n-button>
|
||||
</template>
|
||||
</n8n-card>`,
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
<slot name="footer" />
|
||||
</div>
|
||||
</div>
|
||||
<div :class="$style.actions" v-if="$slots.append">
|
||||
<div v-if="$slots.append">
|
||||
<slot name="append" />
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -14,6 +14,7 @@ const methods = {
|
|||
};
|
||||
|
||||
const DefaultTemplate: StoryFn = (args, { argTypes }) => ({
|
||||
setup: () => ({ args }),
|
||||
props: Object.keys(argTypes),
|
||||
components: {
|
||||
N8nCheckbox,
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
:disabled="disabled"
|
||||
:indeterminate="indeterminate"
|
||||
:modelValue="modelValue"
|
||||
@change="onChange"
|
||||
@update:modelValue="onUpdateModelValue"
|
||||
>
|
||||
<slot></slot>
|
||||
<n8n-input-label
|
||||
|
@ -57,8 +57,8 @@ export default defineComponent({
|
|||
},
|
||||
},
|
||||
methods: {
|
||||
onChange(event: Event) {
|
||||
this.$emit('update:modelValue', event);
|
||||
onUpdateModelValue(value: boolean) {
|
||||
this.$emit('update:modelValue', value);
|
||||
},
|
||||
onLabelClick() {
|
||||
const checkboxComponent = this.$refs.checkbox as ElCheckbox;
|
||||
|
|
|
@ -13,7 +13,7 @@ export default {
|
|||
|
||||
const methods = {
|
||||
onSubmit: action('submit'),
|
||||
onUpdateModelValue: action('update:modelValue'),
|
||||
onChange: action('change'),
|
||||
};
|
||||
|
||||
const Template: StoryFn = (args, { argTypes }) => ({
|
||||
|
@ -22,8 +22,7 @@ const Template: StoryFn = (args, { argTypes }) => ({
|
|||
components: {
|
||||
N8nFormBox,
|
||||
},
|
||||
template:
|
||||
'<n8n-form-box v-bind="args" @submit="onSubmit" @update:modelValue="onUpdateModelValue" />',
|
||||
template: '<n8n-form-box v-bind="args" @submit="onSubmit" @change="onChange" />',
|
||||
methods,
|
||||
});
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@ export default defineComponent({
|
|||
},
|
||||
methods: {
|
||||
onUpdateModelValue(e: { name: string; value: string }) {
|
||||
this.$emit('update:modelValue', e);
|
||||
this.$emit('change', e);
|
||||
},
|
||||
onSubmit(e: { [key: string]: string }) {
|
||||
this.$emit('submit', e);
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
:modelValue="modelValue"
|
||||
:active-color="activeColor"
|
||||
:inactive-color="inactiveColor"
|
||||
@change="onUpdateModelValue"
|
||||
@update:modelValue="onUpdateModelValue"
|
||||
></el-switch>
|
||||
</n8n-input-label>
|
||||
<n8n-input-label
|
||||
|
|
|
@ -12,7 +12,7 @@ export default {
|
|||
};
|
||||
|
||||
const methods = {
|
||||
onUpdateModelValue: action('update:modelValue'),
|
||||
onChange: action('change'),
|
||||
onSubmit: action('submit'),
|
||||
};
|
||||
|
||||
|
@ -22,8 +22,7 @@ const Template: StoryFn = (args, { argTypes }) => ({
|
|||
components: {
|
||||
N8nFormInputs,
|
||||
},
|
||||
template:
|
||||
'<n8n-form-inputs v-bind="args" @submit="onSubmit" @update:modelValue="onUpdateModelValue" />',
|
||||
template: '<n8n-form-inputs v-bind="args" @submit="onSubmit" @change="onChange" />',
|
||||
methods,
|
||||
});
|
||||
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
:showValidationWarnings="showValidationWarnings"
|
||||
@update:modelValue="(value) => onUpdateModelValue(input.name, value)"
|
||||
@validate="(value) => onValidate(input.name, value)"
|
||||
@change="(value) => onUpdateModelValue(input.name, value)"
|
||||
@enter="onSubmit"
|
||||
/>
|
||||
</div>
|
||||
|
@ -113,7 +112,7 @@ export default defineComponent({
|
|||
...this.values,
|
||||
[name]: value,
|
||||
};
|
||||
this.$emit('update:modelValue', { name, value });
|
||||
this.$emit('change', { name, value });
|
||||
},
|
||||
onValidate(name: string, valid: boolean) {
|
||||
this.validity = {
|
||||
|
|
|
@ -16,6 +16,7 @@ const methods = {
|
|||
};
|
||||
|
||||
export const Default: StoryFn = (args, { argTypes }) => ({
|
||||
setup: () => ({ args }),
|
||||
props: Object.keys(argTypes),
|
||||
components: {
|
||||
N8nInfoAccordion,
|
||||
|
|
|
@ -43,8 +43,8 @@ import N8nText from '../N8nText';
|
|||
import N8nIcon from '../N8nIcon';
|
||||
import type { PropType } from 'vue';
|
||||
import { defineComponent } from 'vue';
|
||||
import type { EventBus } from '@/utils';
|
||||
import { createEventBus } from '@/utils';
|
||||
import type { EventBus } from '../../utils';
|
||||
import { createEventBus } from '../../utils';
|
||||
|
||||
export interface IAccordionItem {
|
||||
id: string;
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
import { ElInput } from 'element-plus';
|
||||
import type { PropType } from 'vue';
|
||||
import { defineComponent } from 'vue';
|
||||
import { uid } from '@/utils';
|
||||
import { uid } from '../../utils';
|
||||
|
||||
type InputRef = InstanceType<typeof ElInput>;
|
||||
|
||||
|
@ -69,7 +69,7 @@ export default defineComponent({
|
|||
},
|
||||
rows: {
|
||||
type: Number,
|
||||
default: 3,
|
||||
default: 2,
|
||||
},
|
||||
maxlength: {
|
||||
type: Number,
|
||||
|
|
|
@ -180,26 +180,26 @@ export default defineComponent({
|
|||
<style module lang="scss">
|
||||
// Element menu-item overrides
|
||||
:global(.el-menu-item),
|
||||
:global(.el-submenu__title) {
|
||||
:global(.el-sub-menu__title) {
|
||||
--menu-font-color: var(--color-text-base);
|
||||
--menu-item-active-background-color: var(--color-foreground-base);
|
||||
--menu-item-active-font-color: var(--color-text-dark);
|
||||
--menu-item-hover-fill: var(--color-foreground-base);
|
||||
--menu-item-hover-font-color: var(--color-text-dark);
|
||||
--menu-item-height: 35px;
|
||||
--submenu-item-height: 27px;
|
||||
--sub-menu-item-height: 27px;
|
||||
}
|
||||
|
||||
.submenu {
|
||||
background: none !important;
|
||||
|
||||
&.compact :global(.el-submenu__title) {
|
||||
&.compact :global(.el-sub-menu__title) {
|
||||
i {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
:global(.el-submenu__title) {
|
||||
:global(.el-sub-menu__title) {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-radius: var(--border-radius-base) !important;
|
||||
|
@ -221,7 +221,7 @@ export default defineComponent({
|
|||
}
|
||||
|
||||
.menuItem {
|
||||
height: var(--submenu-item-height) !important;
|
||||
height: var(--sub-menu-item-height) !important;
|
||||
min-width: auto !important;
|
||||
margin: var(--spacing-2xs) 0 !important;
|
||||
padding-left: var(--spacing-l) !important;
|
||||
|
@ -248,7 +248,7 @@ export default defineComponent({
|
|||
svg {
|
||||
color: var(--color-text-dark) !important;
|
||||
}
|
||||
&:global(.el-submenu) {
|
||||
&:global(.el-sub-menu) {
|
||||
background-color: unset !important;
|
||||
}
|
||||
}
|
||||
|
@ -256,7 +256,7 @@ export default defineComponent({
|
|||
|
||||
.active {
|
||||
&,
|
||||
& :global(.el-submenu__title) {
|
||||
& :global(.el-sub-menu__title) {
|
||||
background-color: var(--color-foreground-base);
|
||||
border-radius: var(--border-radius-base);
|
||||
.icon {
|
||||
|
|
|
@ -7,12 +7,27 @@ export default {
|
|||
};
|
||||
|
||||
const Template: StoryFn = (args, { argTypes }) => ({
|
||||
setup: () => ({ args }),
|
||||
setup: () => {
|
||||
const onUpdateCurrentPage = (currentPage: number) => {
|
||||
args.currentPage = currentPage;
|
||||
};
|
||||
|
||||
const onUpdatePageSize = (pageSize: number) => {
|
||||
args.pageSize = pageSize;
|
||||
};
|
||||
|
||||
return { onUpdateCurrentPage, onUpdatePageSize, args };
|
||||
},
|
||||
props: Object.keys(argTypes),
|
||||
components: {
|
||||
N8nPagination,
|
||||
},
|
||||
template: '<n8n-pagination v-bind="args" />',
|
||||
template: `
|
||||
<n8n-pagination
|
||||
v-bind="args"
|
||||
v-model:current-page="args.currentPage"
|
||||
v-model:page-size="args.pageSize"
|
||||
/>`,
|
||||
});
|
||||
|
||||
export const Pagination: StoryFn = Template.bind({});
|
||||
|
|
|
@ -13,5 +13,9 @@ export default defineComponent({
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<el-pagination background layout="prev, pager, next" v-bind="{ ...$props, ...$attrs }" />
|
||||
<el-pagination
|
||||
class="is-background"
|
||||
layout="prev, pager, next"
|
||||
v-bind="{ ...$props, ...$attrs }"
|
||||
/>
|
||||
</template>
|
||||
|
|
|
@ -9,13 +9,7 @@
|
|||
}"
|
||||
aria-checked="true"
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
tabindex="-1"
|
||||
autocomplete="off"
|
||||
:class="$style.input"
|
||||
:modelValue="value"
|
||||
/>
|
||||
<input type="radio" tabindex="-1" autocomplete="off" :class="$style.input" :value="value" />
|
||||
<div
|
||||
:class="{
|
||||
[$style.button]: true,
|
||||
|
|
|
@ -196,12 +196,9 @@
|
|||
|
||||
@include mixins.e(main-wrapper) {
|
||||
margin-bottom: 6px;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
display: flex;
|
||||
flex-direction: row-reverse;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
@include mixins.e(btns) {
|
||||
|
|
|
@ -2,11 +2,15 @@
|
|||
@use './common/var';
|
||||
@use './popper';
|
||||
|
||||
@use 'element-plus/theme-chalk/src/dropdown-menu';
|
||||
|
||||
@include mixins.b(dropdown) {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
color: var(--color-text-dark);
|
||||
font-size: var.$font-size-base;
|
||||
display: inline-flex;
|
||||
line-height: 1;
|
||||
vertical-align: top;
|
||||
|
||||
.el-button-group {
|
||||
display: block;
|
||||
|
@ -69,7 +73,6 @@
|
|||
}
|
||||
|
||||
@include mixins.b(dropdown-menu) {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 10;
|
||||
|
@ -79,6 +82,8 @@
|
|||
border: 1px solid var(--border-color-light);
|
||||
border-radius: var(--border-radius-base);
|
||||
box-shadow: var.$dropdown-menu-box-shadow;
|
||||
position: relative;
|
||||
list-style: none;
|
||||
|
||||
@include mixins.e(item) {
|
||||
list-style: none;
|
||||
|
|
|
@ -80,5 +80,6 @@
|
|||
// @use "./cascader-panel.scss";
|
||||
// @use "./avatar.scss";
|
||||
@use './drawer.scss';
|
||||
@use './popper.scss';
|
||||
// @use "./popconfirm.scss";
|
||||
@use './utilities/index.scss';
|
||||
|
|
|
@ -245,12 +245,23 @@
|
|||
min-width: 200px;
|
||||
}
|
||||
@include mixins.e(icon-arrow) {
|
||||
right: 20px;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 20px;
|
||||
margin-top: -7px;
|
||||
margin-top: -6px;
|
||||
transition: transform 0.3s;
|
||||
margin-right: 0;
|
||||
font-size: 12px;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
|
||||
svg {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
position: relative;
|
||||
display: block;
|
||||
margin-top: -2px;
|
||||
}
|
||||
}
|
||||
@include mixins.when(active) {
|
||||
.el-sub-menu__title {
|
||||
|
|
|
@ -65,17 +65,29 @@
|
|||
|
||||
.btn-prev,
|
||||
.btn-next {
|
||||
background: center center no-repeat;
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 16px;
|
||||
background-color: var.$pagination-background-color;
|
||||
cursor: pointer;
|
||||
margin: 0;
|
||||
color: var.$pagination-button-color;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.el-icon {
|
||||
display: block;
|
||||
font-size: 12px;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
font-weight: bold;
|
||||
|
||||
svg {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
display: block;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -220,7 +232,7 @@
|
|||
border: 1px solid var(--color-foreground-base);
|
||||
}
|
||||
|
||||
&.active {
|
||||
&.is-active {
|
||||
border: 1px solid var(--color-primary);
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
@ -240,11 +252,13 @@
|
|||
@include mixins.b(pager) {
|
||||
user-select: none;
|
||||
list-style: none;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
font-size: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
|
||||
|
||||
.more::before {
|
||||
line-height: 30px;
|
||||
|
@ -284,7 +298,7 @@
|
|||
cursor: pointer;
|
||||
}
|
||||
|
||||
&.active + li {
|
||||
&.is-active + li {
|
||||
border-left: 0;
|
||||
}
|
||||
|
||||
|
@ -292,9 +306,231 @@
|
|||
color: var.$pagination-hover-color;
|
||||
}
|
||||
|
||||
&.active {
|
||||
&.is-active {
|
||||
color: var.$pagination-hover-color;
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//@mixin pagination-button {
|
||||
// display: flex;
|
||||
// justify-content: center;
|
||||
// align-items: center;
|
||||
// font-size: getCssVar('pagination-font-size');
|
||||
// min-width: getCssVar('pagination-button-width');
|
||||
// height: getCssVar('pagination-button-height');
|
||||
// line-height: getCssVar('pagination-button-height');
|
||||
// color: getCssVar('pagination-button-color');
|
||||
// background: getCssVar('pagination-bg-color');
|
||||
// padding: 0 4px;
|
||||
// border: none;
|
||||
// border-radius: getCssVar('pagination-border-radius');
|
||||
// cursor: pointer;
|
||||
// text-align: center;
|
||||
// box-sizing: border-box;
|
||||
//
|
||||
// * {
|
||||
// pointer-events: none;
|
||||
// }
|
||||
//
|
||||
// &:focus {
|
||||
// outline: none;
|
||||
// }
|
||||
//
|
||||
// &:hover {
|
||||
// color: getCssVar('pagination-hover-color');
|
||||
// }
|
||||
//
|
||||
// &.is-active {
|
||||
// color: getCssVar('pagination-hover-color');
|
||||
// cursor: default;
|
||||
// font-weight: bold;
|
||||
//
|
||||
// &.is-disabled {
|
||||
// font-weight: bold;
|
||||
// color: getCssVar('text-color', 'secondary');
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// &:disabled,
|
||||
// &.is-disabled {
|
||||
// color: getCssVar('pagination-button-disabled-color');
|
||||
// background-color: getCssVar('pagination-button-disabled-bg-color');
|
||||
// cursor: not-allowed;
|
||||
// }
|
||||
//
|
||||
// &:focus-visible {
|
||||
// outline: 1px solid getCssVar('pagination-hover-color');
|
||||
// outline-offset: -1px;
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//@include b(pagination) {
|
||||
// @include set-component-css-var('pagination', $pagination);
|
||||
//
|
||||
// white-space: nowrap;
|
||||
// color: getCssVar('pagination-text-color');
|
||||
// font-size: getCssVar('pagination-font-size');
|
||||
// font-weight: normal;
|
||||
// display: flex;
|
||||
// align-items: center;
|
||||
//
|
||||
// .#{$namespace}-input__inner {
|
||||
// text-align: center;
|
||||
// -moz-appearance: textfield;
|
||||
// }
|
||||
//
|
||||
// .#{$namespace}-select .#{$namespace}-input {
|
||||
// width: 128px;
|
||||
// }
|
||||
//
|
||||
// button {
|
||||
// @include pagination-button;
|
||||
// }
|
||||
//
|
||||
// .btn-prev,
|
||||
// .btn-next {
|
||||
// .#{$namespace}-icon {
|
||||
// display: block;
|
||||
// font-size: 12px;
|
||||
// font-weight: bold;
|
||||
// width: inherit;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// & > * {
|
||||
// @include when(first) {
|
||||
// margin-left: 0 !important;
|
||||
// }
|
||||
// @include when(last) {
|
||||
// margin-right: 0 !important;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// .btn-prev {
|
||||
// margin-left: getCssVar('pagination-item-gap');
|
||||
// }
|
||||
//
|
||||
// @include e(sizes) {
|
||||
// margin-left: getCssVar('pagination-item-gap');
|
||||
// font-weight: normal;
|
||||
// color: getCssVar('text-color', 'regular');
|
||||
// }
|
||||
//
|
||||
// @include e(total) {
|
||||
// margin-left: getCssVar('pagination-item-gap');
|
||||
// font-weight: normal;
|
||||
// color: getCssVar('text-color', 'regular');
|
||||
//
|
||||
// &[disabled='true'] {
|
||||
// color: getCssVar('text-color', 'placeholder');
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @include e(jump) {
|
||||
// display: flex;
|
||||
// align-items: center;
|
||||
// margin-left: getCssVar('pagination-item-gap');
|
||||
// font-weight: normal;
|
||||
// color: getCssVar('text-color', 'regular');
|
||||
//
|
||||
// &[disabled='true'] {
|
||||
// color: getCssVar('text-color', 'placeholder');
|
||||
// }
|
||||
//
|
||||
// @include e(goto) {
|
||||
// margin-right: 8px;
|
||||
// }
|
||||
//
|
||||
// @include e(editor) {
|
||||
// text-align: center;
|
||||
// box-sizing: border-box;
|
||||
//
|
||||
// &.#{$namespace}-input {
|
||||
// width: 56px;
|
||||
// }
|
||||
//
|
||||
// .#{$namespace}-input__inner::-webkit-inner-spin-button,
|
||||
// .#{$namespace}-input__inner::-webkit-outer-spin-button {
|
||||
// -webkit-appearance: none;
|
||||
// margin: 0;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @include e(classifier) {
|
||||
// margin-left: 8px;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @include e(rightwrapper) {
|
||||
// flex: 1;
|
||||
// display: flex;
|
||||
// align-items: center;
|
||||
// justify-content: flex-end;
|
||||
// }
|
||||
//
|
||||
// @include when(background) {
|
||||
// .btn-prev,
|
||||
// .btn-next,
|
||||
// .#{$namespace}-pager li {
|
||||
// margin: 0 4px;
|
||||
// background-color: getCssVar('pagination-button-bg-color');
|
||||
//
|
||||
// &.is-active {
|
||||
// background-color: getCssVar('color-primary');
|
||||
// color: getCssVar('color-white');
|
||||
// }
|
||||
//
|
||||
// &:disabled,
|
||||
// &.is-disabled {
|
||||
// color: getCssVar('text-color', 'placeholder');
|
||||
// background-color: getCssVar('disabled-bg-color');
|
||||
//
|
||||
// &.is-active {
|
||||
// color: getCssVar('text-color', 'secondary');
|
||||
// background-color: getCssVar('fill-color', 'dark');
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// .btn-prev {
|
||||
// margin-left: getCssVar('pagination-item-gap');
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @include m(small) {
|
||||
// .btn-prev,
|
||||
// .btn-next,
|
||||
// .#{$namespace}-pager li {
|
||||
// height: getCssVar('pagination-button-height-small');
|
||||
// line-height: getCssVar('pagination-button-height-small');
|
||||
// font-size: getCssVar('pagination-font-size-small');
|
||||
// min-width: getCssVar('pagination-button-width-small');
|
||||
// }
|
||||
//
|
||||
// span:not([class*='suffix']),
|
||||
// button {
|
||||
// font-size: getCssVar('pagination-font-size-small');
|
||||
// }
|
||||
//
|
||||
// .#{$namespace}-select .#{$namespace}-input {
|
||||
// width: 100px;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//@include b(pager) {
|
||||
// user-select: none;
|
||||
// list-style: none;
|
||||
// font-size: 0;
|
||||
// padding: 0;
|
||||
// margin: 0;
|
||||
// display: flex;
|
||||
// align-items: center;
|
||||
//
|
||||
// li {
|
||||
// @include pagination-button;
|
||||
// }
|
||||
//}
|
||||
|
|
|
@ -2,33 +2,55 @@
|
|||
@use './common/var';
|
||||
|
||||
@include mixins.b(popper) {
|
||||
.popper__arrow,
|
||||
.popper__arrow::after {
|
||||
position: absolute;
|
||||
z-index: 2000;
|
||||
min-width: 10px;
|
||||
word-wrap: break-word;
|
||||
visibility: visible;
|
||||
|
||||
.el-select-dropdown,
|
||||
.el-dropdown-menu {
|
||||
position: relative;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&:not(.el-select__popper):not(.el-dropdown__popper) {
|
||||
padding: var.$tooltip-padding;
|
||||
font-size: var.$tooltip-font-size;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.el-popper__arrow {
|
||||
position: absolute;
|
||||
display: block;
|
||||
width: 0;
|
||||
height: 0;
|
||||
z-index: 1010;
|
||||
border-color: transparent;
|
||||
border-style: solid;
|
||||
}
|
||||
|
||||
.popper__arrow {
|
||||
border-width: var.$popover-arrow-size;
|
||||
filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.03));
|
||||
}
|
||||
|
||||
.popper__arrow::after {
|
||||
.el-popper__arrow::after {
|
||||
display: block;
|
||||
position: absolute;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-color: transparent;
|
||||
border-style: solid;
|
||||
content: ' ';
|
||||
border-width: var.$popover-arrow-size;
|
||||
}
|
||||
|
||||
&[x-placement^='top'] {
|
||||
margin-bottom: #{var.$popover-arrow-size + 6};
|
||||
&[data-popper-placement^='top'] {
|
||||
//margin-bottom: #{var.$popover-arrow-size + 6};
|
||||
}
|
||||
|
||||
&[x-placement^='top'] .popper__arrow {
|
||||
&[data-popper-placement^='top'] .el-popper__arrow {
|
||||
bottom: -(var.$popover-arrow-size);
|
||||
left: 50%;
|
||||
margin-left: var.$popover-arrow-size;
|
||||
margin-right: #{var.$tooltip-arrow-size * 0.5};
|
||||
border-top-color: var.$popover-border-color;
|
||||
border-bottom-width: 0;
|
||||
|
@ -41,11 +63,11 @@
|
|||
}
|
||||
}
|
||||
|
||||
&[x-placement^='bottom'] {
|
||||
margin-top: #{var.$popover-arrow-size + 6};
|
||||
&[data-popper-placement^='bottom'] {
|
||||
//margin-top: #{var.$popover-arrow-size + 6};
|
||||
}
|
||||
|
||||
&[x-placement^='bottom'] .popper__arrow {
|
||||
&[data-popper-placement^='bottom'] .el-popper__arrow {
|
||||
top: -(var.$popover-arrow-size);
|
||||
left: 50%;
|
||||
margin-right: #{var.$tooltip-arrow-size * 0.5};
|
||||
|
@ -60,11 +82,11 @@
|
|||
}
|
||||
}
|
||||
|
||||
&[x-placement^='right'] {
|
||||
&[data-popper-placement^='right'] {
|
||||
margin-left: #{var.$popover-arrow-size + 6};
|
||||
}
|
||||
|
||||
&[x-placement^='right'] .popper__arrow {
|
||||
&[data-popper-placement^='right'] .el-popper__arrow {
|
||||
top: 50%;
|
||||
left: -(var.$popover-arrow-size);
|
||||
margin-bottom: #{var.$tooltip-arrow-size * 0.5};
|
||||
|
@ -79,13 +101,13 @@
|
|||
}
|
||||
}
|
||||
|
||||
&[x-placement^='left'] {
|
||||
&[data-popper-placement^='left'] {
|
||||
margin-right: #{var.$popover-arrow-size + 6};
|
||||
}
|
||||
|
||||
&[x-placement^='left'] .popper__arrow {
|
||||
&[data-popper-placement^='left'] .el-popper__arrow {
|
||||
top: 50%;
|
||||
right: -(var.$popover-arrow-size);
|
||||
//right: -(var.$popover-arrow-size);
|
||||
margin-bottom: #{var.$tooltip-arrow-size * 0.5};
|
||||
border-right-width: 0;
|
||||
border-left-color: var.$popover-border-color;
|
||||
|
@ -98,4 +120,42 @@
|
|||
border-left-color: var.$popover-background-color;
|
||||
}
|
||||
}
|
||||
|
||||
@include mixins.when(dark) {
|
||||
background: var.$tooltip-fill;
|
||||
color: var.$tooltip-color;
|
||||
|
||||
&[data-popper-placement^='top'] .el-popper__arrow {
|
||||
border-top-color: transparent;
|
||||
|
||||
&::after {
|
||||
border-top-color: var.$tooltip-border-color;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
&[data-popper-placement^='bottom'] .el-popper__arrow {
|
||||
border-bottom-color: transparent;
|
||||
|
||||
&::after {
|
||||
border-bottom-color: var.$tooltip-border-color;
|
||||
}
|
||||
}
|
||||
|
||||
&[data-popper-placement^='right'] .el-popper__arrow {
|
||||
border-right-color: transparent;
|
||||
|
||||
&::after {
|
||||
border-right-color: var.$tooltip-border-color;
|
||||
}
|
||||
}
|
||||
|
||||
&[data-popper-placement^='left'] .el-popper__arrow {
|
||||
border-left-color: transparent;
|
||||
|
||||
&::after {
|
||||
border-left-color: var.$tooltip-border-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
font-weight: var(--font-weight-bold);
|
||||
}
|
||||
|
||||
.popper__arrow,
|
||||
.popper__arrow::after {
|
||||
.el-popper__arrow,
|
||||
.el-popper__arrow::after {
|
||||
position: absolute;
|
||||
display: block;
|
||||
width: 0;
|
||||
|
@ -33,20 +33,20 @@
|
|||
border-style: solid;
|
||||
}
|
||||
|
||||
.popper__arrow {
|
||||
.el-popper__arrow {
|
||||
border-width: var.$tooltip-arrow-size;
|
||||
}
|
||||
|
||||
.popper__arrow::after {
|
||||
.el-popper__arrow::after {
|
||||
content: ' ';
|
||||
border-width: 5px;
|
||||
}
|
||||
|
||||
&[x-placement^='top'] {
|
||||
&[data-popper-placement^='top'] {
|
||||
margin-bottom: #{var.$tooltip-arrow-size + 6px};
|
||||
}
|
||||
|
||||
&[x-placement^='top'] .popper__arrow {
|
||||
&[data-popper-placement^='top'] .el-popper__arrow {
|
||||
bottom: -(var.$tooltip-arrow-size);
|
||||
border-top-color: var.$tooltip-border-color;
|
||||
border-bottom-width: 0;
|
||||
|
@ -59,11 +59,11 @@
|
|||
}
|
||||
}
|
||||
|
||||
&[x-placement^='bottom'] {
|
||||
&[data-popper-placement^='bottom'] {
|
||||
margin-top: #{var.$tooltip-arrow-size + 6px};
|
||||
}
|
||||
|
||||
&[x-placement^='bottom'] .popper__arrow {
|
||||
&[data-popper-placement^='bottom'] .el-popper__arrow {
|
||||
top: -(var.$tooltip-arrow-size);
|
||||
border-top-width: 0;
|
||||
border-bottom-color: var.$tooltip-border-color;
|
||||
|
@ -76,11 +76,11 @@
|
|||
}
|
||||
}
|
||||
|
||||
&[x-placement^='right'] {
|
||||
&[data-popper-placement^='right'] {
|
||||
margin-left: #{var.$tooltip-arrow-size + 6px};
|
||||
}
|
||||
|
||||
&[x-placement^='right'] .popper__arrow {
|
||||
&[data-popper-placement^='right'] .el-popper__arrow {
|
||||
left: -(var.$tooltip-arrow-size);
|
||||
border-right-color: var.$tooltip-border-color;
|
||||
border-left-width: 0;
|
||||
|
@ -93,11 +93,11 @@
|
|||
}
|
||||
}
|
||||
|
||||
&[x-placement^='left'] {
|
||||
&[data-popper-placement^='left'] {
|
||||
margin-right: #{var.$tooltip-arrow-size + 6px};
|
||||
}
|
||||
|
||||
&[x-placement^='left'] .popper__arrow {
|
||||
&[data-popper-placement^='left'] .el-popper__arrow {
|
||||
right: -(var.$tooltip-arrow-size);
|
||||
border-right-width: 0;
|
||||
border-left-color: var.$tooltip-border-color;
|
||||
|
@ -111,34 +111,34 @@
|
|||
}
|
||||
}
|
||||
|
||||
@include mixins.when(dark) {
|
||||
@include mixins.when(is-dark) {
|
||||
background: var.$tooltip-fill;
|
||||
color: var.$tooltip-color;
|
||||
}
|
||||
|
||||
@include mixins.when(light) {
|
||||
@include mixins.when(is-light) {
|
||||
background: var.$tooltip-color;
|
||||
border: 1px solid var.$tooltip-fill;
|
||||
|
||||
&[x-placement^='top'] .popper__arrow {
|
||||
&[data-popper-placement^='top'] .el-popper__arrow {
|
||||
border-top-color: var.$tooltip-fill;
|
||||
&::after {
|
||||
border-top-color: var.$tooltip-color;
|
||||
}
|
||||
}
|
||||
&[x-placement^='bottom'] .popper__arrow {
|
||||
&[data-popper-placement^='bottom'] .el-popper__arrow {
|
||||
border-bottom-color: var.$tooltip-fill;
|
||||
&::after {
|
||||
border-bottom-color: var.$tooltip-color;
|
||||
}
|
||||
}
|
||||
&[x-placement^='left'] .popper__arrow {
|
||||
&[data-popper-placement^='left'] .el-popper__arrow {
|
||||
border-left-color: var.$tooltip-fill;
|
||||
&::after {
|
||||
border-left-color: var.$tooltip-color;
|
||||
}
|
||||
}
|
||||
&[x-placement^='right'] .popper__arrow {
|
||||
&[data-popper-placement^='right'] .el-popper__arrow {
|
||||
border-right-color: var.$tooltip-fill;
|
||||
&::after {
|
||||
border-right-color: var.$tooltip-color;
|
||||
|
|
|
@ -17,7 +17,9 @@
|
|||
</div>
|
||||
<div id="content" :class="$style.content">
|
||||
<keep-alive include="NodeView" :max="1">
|
||||
<router-view />
|
||||
<main>
|
||||
<router-view />
|
||||
</main>
|
||||
</keep-alive>
|
||||
</div>
|
||||
<Modals />
|
||||
|
@ -51,7 +53,7 @@ import {
|
|||
} from '@/stores';
|
||||
import { useHistoryHelper } from '@/composables/useHistoryHelper';
|
||||
import { newVersions } from '@/mixins/newVersions';
|
||||
import { useRoute } from 'vue-router/composables';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { useExternalHooks } from '@/composables';
|
||||
|
||||
export default defineComponent({
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import '@testing-library/jest-dom';
|
||||
import { configure } from '@testing-library/vue';
|
||||
import Vue from 'vue';
|
||||
import '../plugins';
|
||||
import { I18nPlugin } from '@/plugins/i18n';
|
||||
import { config } from '@vue/test-utils';
|
||||
|
@ -10,18 +9,17 @@ import { FontAwesomePlugin } from '@/plugins/icons';
|
|||
|
||||
configure({ testIdAttribute: 'data-test-id' });
|
||||
|
||||
Vue.config.productionTip = false;
|
||||
Vue.config.devtools = false;
|
||||
// Vue.config.productionTip = false;
|
||||
// Vue.config.devtools = false;
|
||||
|
||||
Vue.use(I18nPlugin);
|
||||
Vue.use(FontAwesomePlugin);
|
||||
Vue.use(GlobalComponentsPlugin);
|
||||
Vue.use(GlobalDirectivesPlugin);
|
||||
config.plugins.VueWrapper.install(I18nPlugin);
|
||||
config.plugins.VueWrapper.install(FontAwesomePlugin);
|
||||
config.plugins.VueWrapper.install(GlobalComponentsPlugin);
|
||||
config.plugins.VueWrapper.install(GlobalDirectivesPlugin);
|
||||
|
||||
// TODO: Investigate why this is needed
|
||||
// Without having this 3rd party library imported like this, any component test using 'vue-json-pretty' fail with:
|
||||
// [Vue warn]: Failed to mount component: template or render function not defined.
|
||||
// Vue.component('vue-json-pretty', require('vue-json-pretty').default);
|
||||
config.stubs['vue-json-pretty'] = require('vue-json-pretty').default;
|
||||
|
||||
window.ResizeObserver =
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
:inputs="config"
|
||||
:eventBus="formBus"
|
||||
:columnView="true"
|
||||
@update:modelValue="onInput"
|
||||
@change="onInput"
|
||||
@submit="onSubmit"
|
||||
/>
|
||||
</template>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import Vue, { defineComponent } from 'vue';
|
||||
import { defineComponent } from 'vue';
|
||||
import { autocompletion } from '@codemirror/autocomplete';
|
||||
import { localCompletionSource } from '@codemirror/lang-javascript';
|
||||
import type { Completion, CompletionContext, CompletionResult } from '@codemirror/autocomplete';
|
||||
|
@ -16,11 +16,8 @@ import { itemFieldCompletions } from './completions/itemField.completions';
|
|||
import { jsonFieldCompletions } from './completions/jsonField.completions';
|
||||
import { variablesCompletions } from './completions/variables.completions';
|
||||
|
||||
import type { CodeNodeEditorMixin } from './types';
|
||||
|
||||
export const completerExtension = defineComponent({
|
||||
mixins: [
|
||||
Vue as CodeNodeEditorMixin,
|
||||
baseCompletions,
|
||||
requireCompletions,
|
||||
executionCompletions,
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import Vue from 'vue';
|
||||
import { defineComponent } from 'vue';
|
||||
import { NODE_TYPES_EXCLUDED_FROM_AUTOCOMPLETION } from '../constants';
|
||||
import { addVarType } from '../utils';
|
||||
import type { Completion, CompletionContext, CompletionResult } from '@codemirror/autocomplete';
|
||||
import type { INodeUi } from '@/Interface';
|
||||
import type { CodeNodeEditorMixin } from '../types';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useWorkflowsStore } from '@/stores/workflows.store';
|
||||
|
||||
|
@ -13,7 +12,7 @@ function getAutoCompletableNodeNames(nodes: INodeUi[]) {
|
|||
.map((node: INodeUi) => node.name);
|
||||
}
|
||||
|
||||
export const baseCompletions = (Vue as CodeNodeEditorMixin).extend({
|
||||
export const baseCompletions = defineComponent({
|
||||
computed: {
|
||||
...mapStores(useWorkflowsStore),
|
||||
},
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import Vue from 'vue';
|
||||
import { defineComponent } from 'vue';
|
||||
import { addVarType, escape } from '../utils';
|
||||
import type { Completion, CompletionContext, CompletionResult } from '@codemirror/autocomplete';
|
||||
import type { CodeNodeEditorMixin } from '../types';
|
||||
|
||||
export const executionCompletions = (Vue as CodeNodeEditorMixin).extend({
|
||||
export const executionCompletions = defineComponent({
|
||||
methods: {
|
||||
/**
|
||||
* Complete `$execution.` to `.id .mode .resumeUrl`
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import Vue from 'vue';
|
||||
import { defineComponent } from 'vue';
|
||||
import { addVarType, escape } from '../utils';
|
||||
import type { Completion, CompletionContext, CompletionResult } from '@codemirror/autocomplete';
|
||||
import type { CodeNodeEditorMixin } from '../types';
|
||||
|
||||
export const itemFieldCompletions = (Vue as CodeNodeEditorMixin).extend({
|
||||
export const itemFieldCompletions = defineComponent({
|
||||
methods: {
|
||||
/**
|
||||
* - Complete `x.first().` to `.json .binary`
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import Vue from 'vue';
|
||||
import { escape } from '../utils';
|
||||
import type { Completion, CompletionContext, CompletionResult } from '@codemirror/autocomplete';
|
||||
import type { CodeNodeEditorMixin } from '../types';
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
export const itemIndexCompletions = (Vue as CodeNodeEditorMixin).extend({
|
||||
export const itemIndexCompletions = defineComponent({
|
||||
methods: {
|
||||
/**
|
||||
* - Complete `$input.` to `.first() .last() .all() .itemMatching()` in all-items mode.
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
import Vue from 'vue';
|
||||
import { defineComponent } from 'vue';
|
||||
import { escape, toVariableOption } from '../utils';
|
||||
import type { Completion, CompletionContext, CompletionResult } from '@codemirror/autocomplete';
|
||||
import type { IDataObject, IPinData, IRunData } from 'n8n-workflow';
|
||||
import type { CodeNodeEditorMixin } from '../types';
|
||||
import { mapStores } from 'pinia';
|
||||
import { useWorkflowsStore } from '@/stores/workflows.store';
|
||||
import { useNDVStore } from '@/stores/ndv.store';
|
||||
import { isAllowedInDotNotation } from '@/plugins/codemirror/completions/utils';
|
||||
|
||||
export const jsonFieldCompletions = (Vue as CodeNodeEditorMixin).extend({
|
||||
export const jsonFieldCompletions = defineComponent({
|
||||
computed: {
|
||||
...mapStores(useNDVStore, useWorkflowsStore),
|
||||
},
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import Vue from 'vue';
|
||||
import { escape } from '../utils';
|
||||
import type { Completion, CompletionContext, CompletionResult } from '@codemirror/autocomplete';
|
||||
import type { CodeNodeEditorMixin } from '../types';
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
export const luxonCompletions = (Vue as CodeNodeEditorMixin).extend({
|
||||
export const luxonCompletions = defineComponent({
|
||||
methods: {
|
||||
/**
|
||||
* Complete `$today.` with luxon `DateTime` instance methods.
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
import Vue from 'vue';
|
||||
import { addVarType } from '../utils';
|
||||
import type { Completion, CompletionContext, CompletionResult } from '@codemirror/autocomplete';
|
||||
import type { CodeNodeEditorMixin } from '../types';
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
const DEFAULT_MATCHER = '$prevNode';
|
||||
|
||||
const escape = (str: string) => str.replace('$', '\\$');
|
||||
|
||||
export const prevNodeCompletions = (Vue as CodeNodeEditorMixin).extend({
|
||||
export const prevNodeCompletions = defineComponent({
|
||||
methods: {
|
||||
/**
|
||||
* Complete `$prevNode.` to `.name .outputIndex .runIndex`.
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
import Vue from 'vue';
|
||||
import { defineComponent } from 'vue';
|
||||
import { AUTOCOMPLETABLE_BUILT_IN_MODULES_JS } from '../constants';
|
||||
import type { Completion, CompletionContext, CompletionResult } from '@codemirror/autocomplete';
|
||||
import type { CodeNodeEditorMixin } from '../types';
|
||||
import { useSettingsStore } from '@/stores/settings.store';
|
||||
|
||||
export const requireCompletions = (Vue as CodeNodeEditorMixin).extend({
|
||||
export const requireCompletions = defineComponent({
|
||||
methods: {
|
||||
/**
|
||||
* Complete `req` to `require('moduleName')` based on modules available in context.
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
import Vue from 'vue';
|
||||
import { addVarType } from '../utils';
|
||||
import type { Completion, CompletionContext, CompletionResult } from '@codemirror/autocomplete';
|
||||
import type { CodeNodeEditorMixin } from '../types';
|
||||
import { useEnvironmentsStore } from '@/stores';
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
const escape = (str: string) => str.replace('$', '\\$');
|
||||
|
||||
export const variablesCompletions = (Vue as CodeNodeEditorMixin).extend({
|
||||
export const variablesCompletions = defineComponent({
|
||||
methods: {
|
||||
/**
|
||||
* Complete `$workflow.` to `.id .name .active`.
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
import Vue from 'vue';
|
||||
import { defineComponent } from 'vue';
|
||||
import { addVarType } from '../utils';
|
||||
import type { Completion, CompletionContext, CompletionResult } from '@codemirror/autocomplete';
|
||||
import type { CodeNodeEditorMixin } from '../types';
|
||||
|
||||
const escape = (str: string) => str.replace('$', '\\$');
|
||||
|
||||
export const workflowCompletions = (Vue as CodeNodeEditorMixin).extend({
|
||||
export const workflowCompletions = defineComponent({
|
||||
methods: {
|
||||
/**
|
||||
* Complete `$workflow.` to `.id .name .active`.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import Vue from 'vue';
|
||||
import { defineComponent } from 'vue';
|
||||
import type { Diagnostic } from '@codemirror/lint';
|
||||
import { linter as createLinter } from '@codemirror/lint';
|
||||
import { jsonParseLinter } from '@codemirror/lang-json';
|
||||
|
@ -10,9 +10,9 @@ import type { CodeNodeEditorLanguage } from 'n8n-workflow';
|
|||
import { DEFAULT_LINTER_DELAY_IN_MS, DEFAULT_LINTER_SEVERITY } from './constants';
|
||||
import { OFFSET_FOR_SCRIPT_WRAPPER } from './constants';
|
||||
import { walk } from './utils';
|
||||
import type { CodeNodeEditorMixin, RangeNode } from './types';
|
||||
import type { RangeNode } from './types';
|
||||
|
||||
export const linterExtension = (Vue as CodeNodeEditorMixin).extend({
|
||||
export const linterExtension = defineComponent({
|
||||
methods: {
|
||||
createLinter(language: CodeNodeEditorLanguage) {
|
||||
switch (language) {
|
||||
|
|
|
@ -2,9 +2,10 @@ import type { EditorView } from '@codemirror/view';
|
|||
import type { I18nClass } from '@/plugins/i18n';
|
||||
import type { Workflow, CodeExecutionMode, CodeNodeEditorLanguage } from 'n8n-workflow';
|
||||
import type { Node } from 'estree';
|
||||
import type { DefineComponent } from 'vue';
|
||||
|
||||
export type CodeNodeEditorMixin = Vue.VueConstructor<
|
||||
Vue & {
|
||||
export type CodeNodeEditorMixin = InstanceType<
|
||||
DefineComponent & {
|
||||
$locale: I18nClass;
|
||||
editor: EditorView | null;
|
||||
mode: CodeExecutionMode;
|
||||
|
|
|
@ -15,9 +15,7 @@
|
|||
v-if="mode === COMMUNITY_PACKAGE_MANAGE_ACTIONS.UPDATE"
|
||||
>
|
||||
<n8n-info-tip theme="info" type="note" :bold="false">
|
||||
<template>
|
||||
<span v-text="getModalContent.description"></span>
|
||||
</template>
|
||||
<span v-text="getModalContent.description"></span>
|
||||
</n8n-info-tip>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -15,11 +15,11 @@
|
|||
<CredentialIcon :credentialTypeName="defaultCredentialTypeName" />
|
||||
</div>
|
||||
<InlineNameEdit
|
||||
:name="credentialName"
|
||||
:modelValue="credentialName"
|
||||
:subtitle="credentialType ? credentialType.displayName : ''"
|
||||
:readonly="!credentialPermissions.updateName || !credentialType"
|
||||
type="Credential"
|
||||
@input="onNameEdit"
|
||||
@update:modelValue="onNameEdit"
|
||||
data-test-id="credential-name"
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
<script lang="ts" setup>
|
||||
import { computed, reactive, onBeforeMount, ref } from 'vue';
|
||||
import debounce from 'lodash/debounce';
|
||||
import type { PopoverPlacement } from 'element-ui/types/popover';
|
||||
import type {
|
||||
ExecutionFilterType,
|
||||
ExecutionFilterMetadata,
|
||||
|
@ -15,10 +14,11 @@ import { useSettingsStore } from '@/stores/settings.store';
|
|||
import { useUsageStore } from '@/stores/usage.store';
|
||||
import { useUIStore } from '@/stores/ui.store';
|
||||
import { useTelemetry } from '@/composables';
|
||||
import type { Placement } from '@floating-ui/core';
|
||||
|
||||
export type ExecutionFilterProps = {
|
||||
workflows?: IWorkflowShortResponse[];
|
||||
popoverPlacement?: PopoverPlacement;
|
||||
popoverPlacement?: Placement;
|
||||
};
|
||||
|
||||
const DATE_TIME_MASK = 'yyyy-MM-dd HH:mm';
|
||||
|
@ -30,7 +30,7 @@ const uiStore = useUIStore();
|
|||
const telemetry = useTelemetry();
|
||||
|
||||
const props = withDefaults(defineProps<ExecutionFilterProps>(), {
|
||||
popoverPlacement: 'bottom',
|
||||
popoverPlacement: 'bottom' as Placement,
|
||||
});
|
||||
const emit = defineEmits<{
|
||||
(event: 'filterChanged', value: ExecutionFilterType): void;
|
||||
|
@ -244,7 +244,7 @@ onBeforeMount(() => {
|
|||
<div :class="$style.group">
|
||||
<n8n-tooltip placement="right">
|
||||
<template #content>
|
||||
<i18n tag="span" path="executionsFilter.customData.docsTooltip">
|
||||
<i18n-t tag="span" path="executionsFilter.customData.docsTooltip">
|
||||
<template #link>
|
||||
<a
|
||||
target="_blank"
|
||||
|
@ -253,7 +253,7 @@ onBeforeMount(() => {
|
|||
{{ locale.baseText('executionsFilter.customData.docsTooltip.link') }}
|
||||
</a>
|
||||
</template>
|
||||
</i18n>
|
||||
</i18n-t>
|
||||
</template>
|
||||
<span :class="$style.label">
|
||||
{{ locale.baseText('executionsFilter.savedData') }}
|
||||
|
@ -266,7 +266,7 @@ onBeforeMount(() => {
|
|||
}}</label>
|
||||
<n8n-tooltip :disabled="isAdvancedExecutionFilterEnabled" placement="top">
|
||||
<template #content>
|
||||
<i18n tag="span" path="executionsFilter.customData.inputTooltip">
|
||||
<i18n-t tag="span" path="executionsFilter.customData.inputTooltip">
|
||||
<template #link>
|
||||
<a
|
||||
href="#"
|
||||
|
@ -275,7 +275,7 @@ onBeforeMount(() => {
|
|||
>{{ locale.baseText('executionsFilter.customData.inputTooltip.link') }}</a
|
||||
>
|
||||
</template>
|
||||
</i18n>
|
||||
</i18n-t>
|
||||
</template>
|
||||
<n8n-input
|
||||
id="execution-filter-saved-data-key"
|
||||
|
@ -284,8 +284,8 @@ onBeforeMount(() => {
|
|||
size="medium"
|
||||
:disabled="!isAdvancedExecutionFilterEnabled"
|
||||
:placeholder="locale.baseText('executionsFilter.savedDataKeyPlaceholder')"
|
||||
:value="filter.metadata[0]?.key"
|
||||
@input="onFilterMetaChange(0, 'key', $event)"
|
||||
:modelValue="filter.metadata[0]?.key"
|
||||
@update:modelValue="onFilterMetaChange(0, 'key', $event)"
|
||||
data-test-id="execution-filter-saved-data-key-input"
|
||||
/>
|
||||
</n8n-tooltip>
|
||||
|
@ -294,13 +294,13 @@ onBeforeMount(() => {
|
|||
}}</label>
|
||||
<n8n-tooltip :disabled="isAdvancedExecutionFilterEnabled" placement="top">
|
||||
<template #content>
|
||||
<i18n tag="span" path="executionsFilter.customData.inputTooltip">
|
||||
<i18n-t tag="span" path="executionsFilter.customData.inputTooltip">
|
||||
<template #link>
|
||||
<a href="#" @click.prevent="goToUpgrade">{{
|
||||
locale.baseText('executionsFilter.customData.inputTooltip.link')
|
||||
}}</a>
|
||||
</template>
|
||||
</i18n>
|
||||
</i18n-t>
|
||||
</template>
|
||||
<n8n-input
|
||||
id="execution-filter-saved-data-value"
|
||||
|
|
|
@ -93,7 +93,7 @@
|
|||
<span v-if="isRunning(execution)" :class="$style.spinner">
|
||||
<font-awesome-icon icon="spinner" spin />
|
||||
</span>
|
||||
<i18n
|
||||
<i18n-t
|
||||
v-if="!isWaitTillIndefinite(execution)"
|
||||
:path="getStatusTextTranslationPath(execution)"
|
||||
>
|
||||
|
@ -115,7 +115,7 @@
|
|||
</span>
|
||||
<execution-time v-else :start-time="execution.startedAt" />
|
||||
</template>
|
||||
</i18n>
|
||||
</i18n-t>
|
||||
<n8n-tooltip v-else placement="top">
|
||||
<template #content>
|
||||
<span>{{ getStatusTooltipText(execution) }}</span>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
</n8n-text>
|
||||
</div>
|
||||
<div v-else-if="!isTrialExpired && trialHasExecutionsLeft" :class="$style.usageText">
|
||||
<i18n path="executionUsage.currentUsage">
|
||||
<i18n-t path="executionUsage.currentUsage">
|
||||
<template #text>
|
||||
<n8n-text size="small" color="text-dark">
|
||||
{{ locale.baseText('executionUsage.currentUsage.text') }}
|
||||
|
@ -21,7 +21,7 @@
|
|||
}}
|
||||
</n8n-text>
|
||||
</template>
|
||||
</i18n>
|
||||
</i18n-t>
|
||||
</div>
|
||||
<div v-else-if="!trialHasExecutionsLeft" :class="$style.usageText">
|
||||
<n8n-text size="small">
|
||||
|
|
|
@ -135,7 +135,7 @@ import type { IExecutionUIData } from '@/mixins/executionsHelpers';
|
|||
import { executionHelpers } from '@/mixins/executionsHelpers';
|
||||
import { MODAL_CONFIRM, VIEWS } from '@/constants';
|
||||
import { useUIStore } from '@/stores/ui.store';
|
||||
import { Dropdown as ElDropdown } from 'element-ui';
|
||||
import { ElDropdown } from 'element-plus';
|
||||
|
||||
type RetryDropdownRef = InstanceType<typeof ElDropdown> & { hide: () => void };
|
||||
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
</div>
|
||||
<div :class="$style.controls">
|
||||
<el-checkbox
|
||||
:value="autoRefresh"
|
||||
@input="$emit('update:autoRefresh', $event)"
|
||||
:modelValue="autoRefresh"
|
||||
@update:modelValue="$emit('update:autoRefresh', $event)"
|
||||
data-test-id="auto-refresh-checkbox"
|
||||
>
|
||||
{{ $locale.baseText('executionsList.autoRefresh') }}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<template>
|
||||
<ExpandableInputBase :value="value" :placeholder="placeholder">
|
||||
<ExpandableInputBase :value="modelValue" :placeholder="placeholder">
|
||||
<input
|
||||
class="el-input__inner"
|
||||
:value="value"
|
||||
:value="modelValue"
|
||||
:placeholder="placeholder"
|
||||
:maxlength="maxlength"
|
||||
@input="onInput"
|
||||
|
@ -25,7 +25,7 @@ export default defineComponent({
|
|||
name: 'ExpandableInputEdit',
|
||||
components: { ExpandableInputBase },
|
||||
props: {
|
||||
value: {},
|
||||
modelValue: {},
|
||||
placeholder: {},
|
||||
maxlength: {},
|
||||
autofocus: {},
|
||||
|
@ -50,7 +50,7 @@ export default defineComponent({
|
|||
}
|
||||
},
|
||||
onInput() {
|
||||
this.$emit('input', (this.$refs.input as HTMLInputElement).value);
|
||||
this.$emit('update:modelValue', (this.$refs.input as HTMLInputElement).value);
|
||||
},
|
||||
onEnter() {
|
||||
this.$emit('enter', (this.$refs.input as HTMLInputElement).value);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<div v-if="dialogVisible" @keydown.stop>
|
||||
<el-dialog
|
||||
:visible="dialogVisible"
|
||||
custom-class="expression-dialog classic"
|
||||
class="expression-dialog classic"
|
||||
append-to-body
|
||||
width="80%"
|
||||
:title="$locale.baseText('expressionEdit.editExpression')"
|
||||
|
@ -44,7 +44,7 @@
|
|||
</div>
|
||||
<div class="expression-editor ph-no-capture">
|
||||
<ExpressionEditorModalInput
|
||||
:value="value"
|
||||
:modelValue="modelValue"
|
||||
:isReadOnly="isReadOnly"
|
||||
:path="path"
|
||||
@change="valueChanged"
|
||||
|
@ -97,7 +97,7 @@ import type { Segment } from '@/types/expressions';
|
|||
export default defineComponent({
|
||||
name: 'ExpressionEdit',
|
||||
mixins: [externalHooks, genericHelpers, debounceHelper],
|
||||
props: ['dialogVisible', 'parameter', 'path', 'value', 'eventSource'],
|
||||
props: ['dialogVisible', 'parameter', 'path', 'modelValue', 'eventSource'],
|
||||
components: {
|
||||
ExpressionEditorModalInput,
|
||||
ExpressionEditorModalOutput,
|
||||
|
@ -121,7 +121,7 @@ export default defineComponent({
|
|||
|
||||
if (forceUpdate === true) {
|
||||
this.updateDisplayValue();
|
||||
this.$emit('valueChanged', this.latestValue);
|
||||
this.$emit('update:modelValue', this.latestValue);
|
||||
} else {
|
||||
void this.callDebounced('updateDisplayValue', { debounceTime: 500 });
|
||||
}
|
||||
|
@ -132,10 +132,10 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
closeDialog() {
|
||||
if (this.latestValue !== this.value) {
|
||||
if (this.latestValue !== this.modelValue) {
|
||||
// Handle the close externally as the visible parameter is an external prop
|
||||
// and is so not allowed to be changed here.
|
||||
this.$emit('valueChanged', this.latestValue);
|
||||
this.$emit('update:modelValue', this.latestValue);
|
||||
}
|
||||
this.$emit('closeDialog');
|
||||
return false;
|
||||
|
@ -146,7 +146,7 @@ export default defineComponent({
|
|||
(this.$refs.inputFieldExpression as any).itemSelected(eventData);
|
||||
void this.$externalHooks().run('expressionEdit.itemSelected', {
|
||||
parameter: this.parameter,
|
||||
value: this.value,
|
||||
value: this.modelValue,
|
||||
selectedItem: eventData,
|
||||
});
|
||||
|
||||
|
@ -216,8 +216,8 @@ export default defineComponent({
|
|||
},
|
||||
watch: {
|
||||
dialogVisible(newValue) {
|
||||
this.displayValue = this.value;
|
||||
this.latestValue = this.value;
|
||||
this.displayValue = this.modelValue;
|
||||
this.latestValue = this.modelValue;
|
||||
|
||||
const resolvedExpressionValue =
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
|
@ -226,14 +226,14 @@ export default defineComponent({
|
|||
void this.$externalHooks().run('expressionEdit.dialogVisibleChanged', {
|
||||
dialogVisible: newValue,
|
||||
parameter: this.parameter,
|
||||
value: this.value,
|
||||
value: this.modelValue,
|
||||
resolvedExpressionValue,
|
||||
});
|
||||
|
||||
if (!newValue) {
|
||||
const telemetryPayload = createExpressionTelemetryPayload(
|
||||
this.segments,
|
||||
this.value,
|
||||
this.modelValue,
|
||||
this.workflowsStore.workflowId,
|
||||
this.ndvStore.sessionId,
|
||||
this.ndvStore.activeNode?.type ?? '',
|
||||
|
@ -288,7 +288,7 @@ export default defineComponent({
|
|||
margin-top: 1em;
|
||||
}
|
||||
|
||||
::v-deep .expression-dialog {
|
||||
:deep(.expression-dialog) {
|
||||
.el-dialog__header {
|
||||
padding: 0;
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ export default defineComponent({
|
|||
name: 'ExpressionEditorModalInput',
|
||||
mixins: [expressionManager, completionManager, workflowHelpers],
|
||||
props: {
|
||||
value: {
|
||||
modelValue: {
|
||||
type: String,
|
||||
},
|
||||
path: {
|
||||
|
@ -89,7 +89,7 @@ export default defineComponent({
|
|||
this.editor = new EditorView({
|
||||
parent: this.$refs.root as HTMLDivElement,
|
||||
state: EditorState.create({
|
||||
doc: this.value.startsWith('=') ? this.value.slice(1) : this.value,
|
||||
doc: this.modelValue.startsWith('=') ? this.modelValue.slice(1) : this.modelValue,
|
||||
extensions,
|
||||
}),
|
||||
});
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<ExpressionFunctionIcon />
|
||||
</div>
|
||||
<InlineExpressionEditorInput
|
||||
:value="value"
|
||||
:modelValue="modelValue"
|
||||
:isReadOnly="isReadOnly"
|
||||
:targetItem="hoveringItem"
|
||||
:isSingleLine="isForRecordLocator"
|
||||
|
@ -37,7 +37,7 @@
|
|||
</n8n-text>
|
||||
<n8n-text :class="$style.body">
|
||||
<InlineExpressionEditorOutput
|
||||
:value="value"
|
||||
:value="modelValue"
|
||||
:isReadOnly="isReadOnly"
|
||||
:segments="segments"
|
||||
/>
|
||||
|
@ -99,7 +99,7 @@ export default defineComponent({
|
|||
path: {
|
||||
type: String,
|
||||
},
|
||||
value: {
|
||||
modelValue: {
|
||||
type: String,
|
||||
},
|
||||
isReadOnly: {
|
||||
|
@ -158,7 +158,7 @@ export default defineComponent({
|
|||
if (wasFocused) {
|
||||
const telemetryPayload = createExpressionTelemetryPayload(
|
||||
this.segments,
|
||||
this.value,
|
||||
this.modelValue,
|
||||
this.workflowsStore.workflowId,
|
||||
this.ndvStore.sessionId,
|
||||
this.ndvStore.activeNode?.type ?? '',
|
||||
|
@ -172,9 +172,9 @@ export default defineComponent({
|
|||
|
||||
this.segments = segments;
|
||||
|
||||
if (value === '=' + this.value) return; // prevent report on change of target item
|
||||
if (value === '=' + this.modelValue) return; // prevent report on change of target item
|
||||
|
||||
this.$emit('valueChanged', value);
|
||||
this.$emit('update:modelValue', value);
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -337,11 +337,9 @@ export default defineComponent({
|
|||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
::v-deep {
|
||||
.button {
|
||||
--button-background-color: var(--color-background-base);
|
||||
--button-border-color: var(--color-foreground-base);
|
||||
}
|
||||
:deep (.button) {
|
||||
--button-background-color: var(--color-background-base);
|
||||
--button-border-color: var(--color-foreground-base);
|
||||
}
|
||||
|
||||
.fixed-collection-parameter {
|
||||
|
|
|
@ -25,7 +25,7 @@ export default defineComponent({
|
|||
name: 'InlineExpressionEditorInput',
|
||||
mixins: [completionManager, expressionManager, workflowHelpers],
|
||||
props: {
|
||||
value: {
|
||||
modelValue: {
|
||||
type: String,
|
||||
},
|
||||
isReadOnly: {
|
||||
|
@ -46,7 +46,7 @@ export default defineComponent({
|
|||
effects: editableConf.reconfigure(EditorView.editable.of(!newValue)),
|
||||
});
|
||||
},
|
||||
value(newValue) {
|
||||
modelValue(newValue) {
|
||||
const isInternalChange = newValue === this.editor?.state.doc.toString();
|
||||
|
||||
if (isInternalChange) return;
|
||||
|
@ -66,7 +66,7 @@ export default defineComponent({
|
|||
changes: {
|
||||
from: 0,
|
||||
to: this.editor.state.doc.length,
|
||||
insert: this.value,
|
||||
insert: this.modelValue,
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -133,7 +133,7 @@ export default defineComponent({
|
|||
this.editor = new EditorView({
|
||||
parent: this.$refs.root as HTMLDivElement,
|
||||
state: EditorState.create({
|
||||
doc: this.value.startsWith('=') ? this.value.slice(1) : this.value,
|
||||
doc: this.modelValue.startsWith('=') ? this.modelValue.slice(1) : this.modelValue,
|
||||
extensions,
|
||||
}),
|
||||
});
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="ph-no-capture" :class="$style.container">
|
||||
<span v-if="readonly" :class="$style.headline">
|
||||
{{ name }}
|
||||
{{ modelValue }}
|
||||
</span>
|
||||
<div
|
||||
v-else
|
||||
|
@ -11,12 +11,12 @@
|
|||
v-click-outside="disableNameEdit"
|
||||
>
|
||||
<div v-if="!isNameEdit">
|
||||
<span>{{ name }}</span>
|
||||
<span>{{ modelValue }}</span>
|
||||
<i><font-awesome-icon icon="pen" /></i>
|
||||
</div>
|
||||
<div v-else :class="$style.nameInput">
|
||||
<n8n-input
|
||||
:modelValue="name"
|
||||
:modelValue="modelValue"
|
||||
size="xlarge"
|
||||
ref="nameInput"
|
||||
@update:modelValue="onNameEdit"
|
||||
|
@ -38,7 +38,7 @@ import { useToast } from '@/composables';
|
|||
export default defineComponent({
|
||||
name: 'InlineNameEdit',
|
||||
props: {
|
||||
name: {
|
||||
modelValue: {
|
||||
type: String,
|
||||
},
|
||||
subtitle: {
|
||||
|
@ -64,7 +64,7 @@ export default defineComponent({
|
|||
},
|
||||
methods: {
|
||||
onNameEdit(value: string) {
|
||||
this.$emit('input', value);
|
||||
this.$emit('update:modelValue', value);
|
||||
},
|
||||
enableNameEdit() {
|
||||
this.isNameEdit = true;
|
||||
|
@ -77,8 +77,8 @@ export default defineComponent({
|
|||
}, 0);
|
||||
},
|
||||
disableNameEdit() {
|
||||
if (!this.name) {
|
||||
this.$emit('input', `Untitled ${this.type}`);
|
||||
if (!this.modelValue) {
|
||||
this.$emit('update:modelValue', `Untitled ${this.type}`);
|
||||
|
||||
this.showToast({
|
||||
title: 'Error',
|
||||
|
|
|
@ -3,11 +3,11 @@
|
|||
<span v-if="isEditEnabled && !disabled">
|
||||
<ExpandableInputEdit
|
||||
:placeholder="placeholder"
|
||||
:value="newValue"
|
||||
:modelValue="newValue"
|
||||
:maxlength="maxLength"
|
||||
:autofocus="true"
|
||||
:eventBus="inputBus"
|
||||
@input="onInput"
|
||||
@update:modelValue="onInput"
|
||||
@esc="onEscape"
|
||||
@blur="onBlur"
|
||||
@enter="submit"
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
:inputs="config"
|
||||
:eventBus="formBus"
|
||||
:columnView="true"
|
||||
@update:modelValue="onInput"
|
||||
@change="onInput"
|
||||
@submit="onSubmit"
|
||||
/>
|
||||
</template>
|
||||
|
|
|
@ -58,67 +58,65 @@
|
|||
<span v-else class="tags"></span>
|
||||
|
||||
<PushConnectionTracker class="actions">
|
||||
<template>
|
||||
<span class="activator">
|
||||
<WorkflowActivator :workflow-active="isWorkflowActive" :workflow-id="currentWorkflowId" />
|
||||
</span>
|
||||
<enterprise-edition :features="[EnterpriseEditionFeature.Sharing]">
|
||||
<n8n-button
|
||||
type="secondary"
|
||||
class="mr-2xs"
|
||||
@click="onShareButtonClick"
|
||||
data-test-id="workflow-share-button"
|
||||
>
|
||||
{{ $locale.baseText('workflowDetails.share') }}
|
||||
</n8n-button>
|
||||
<template #fallback>
|
||||
<n8n-tooltip>
|
||||
<n8n-button type="secondary" :class="['mr-2xs', $style.disabledShareButton]">
|
||||
{{ $locale.baseText('workflowDetails.share') }}
|
||||
</n8n-button>
|
||||
<template #content>
|
||||
<i18n
|
||||
:path="
|
||||
contextBasedTranslationKeys.workflows.sharing.unavailable.description.tooltip
|
||||
"
|
||||
tag="span"
|
||||
>
|
||||
<template #action>
|
||||
<a @click="goToUpgrade">
|
||||
{{
|
||||
$locale.baseText(
|
||||
contextBasedTranslationKeys.workflows.sharing.unavailable.button,
|
||||
)
|
||||
}}
|
||||
</a>
|
||||
</template>
|
||||
</i18n>
|
||||
</template>
|
||||
</n8n-tooltip>
|
||||
</template>
|
||||
</enterprise-edition>
|
||||
<SaveButton
|
||||
type="primary"
|
||||
:saved="!this.isDirty && !this.isNewWorkflow"
|
||||
:disabled="isWorkflowSaving || readOnly"
|
||||
data-test-id="workflow-save-button"
|
||||
@click="onSaveButtonClick"
|
||||
<span class="activator">
|
||||
<WorkflowActivator :workflow-active="isWorkflowActive" :workflow-id="currentWorkflowId" />
|
||||
</span>
|
||||
<enterprise-edition :features="[EnterpriseEditionFeature.Sharing]">
|
||||
<n8n-button
|
||||
type="secondary"
|
||||
class="mr-2xs"
|
||||
@click="onShareButtonClick"
|
||||
data-test-id="workflow-share-button"
|
||||
>
|
||||
{{ $locale.baseText('workflowDetails.share') }}
|
||||
</n8n-button>
|
||||
<template #fallback>
|
||||
<n8n-tooltip>
|
||||
<n8n-button type="secondary" :class="['mr-2xs', $style.disabledShareButton]">
|
||||
{{ $locale.baseText('workflowDetails.share') }}
|
||||
</n8n-button>
|
||||
<template #content>
|
||||
<i18n-t
|
||||
:path="
|
||||
contextBasedTranslationKeys.workflows.sharing.unavailable.description.tooltip
|
||||
"
|
||||
tag="span"
|
||||
>
|
||||
<template #action>
|
||||
<a @click="goToUpgrade">
|
||||
{{
|
||||
$locale.baseText(
|
||||
contextBasedTranslationKeys.workflows.sharing.unavailable.button,
|
||||
)
|
||||
}}
|
||||
</a>
|
||||
</template>
|
||||
</i18n-t>
|
||||
</template>
|
||||
</n8n-tooltip>
|
||||
</template>
|
||||
</enterprise-edition>
|
||||
<SaveButton
|
||||
type="primary"
|
||||
:saved="!this.isDirty && !this.isNewWorkflow"
|
||||
:disabled="isWorkflowSaving || readOnly"
|
||||
data-test-id="workflow-save-button"
|
||||
@click="onSaveButtonClick"
|
||||
/>
|
||||
<div :class="$style.workflowMenuContainer">
|
||||
<input
|
||||
:class="$style.hiddenInput"
|
||||
type="file"
|
||||
ref="importFile"
|
||||
data-test-id="workflow-import-input"
|
||||
@change="handleFileImport()"
|
||||
/>
|
||||
<div :class="$style.workflowMenuContainer">
|
||||
<input
|
||||
:class="$style.hiddenInput"
|
||||
type="file"
|
||||
ref="importFile"
|
||||
data-test-id="workflow-import-input"
|
||||
@change="handleFileImport()"
|
||||
/>
|
||||
<n8n-action-dropdown
|
||||
:items="workflowMenuItems"
|
||||
data-test-id="workflow-menu"
|
||||
@select="onWorkflowMenuSelect"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<n8n-action-dropdown
|
||||
:items="workflowMenuItems"
|
||||
data-test-id="workflow-menu"
|
||||
@select="onWorkflowMenuSelect"
|
||||
/>
|
||||
</div>
|
||||
</PushConnectionTracker>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -152,7 +150,7 @@ import type { IUser, IWorkflowDataUpdate, IWorkflowDb, IWorkflowToShare } from '
|
|||
|
||||
import { saveAs } from 'file-saver';
|
||||
import { useTitleChange, useToast, useMessage } from '@/composables';
|
||||
import type { MessageBoxInputData } from 'element-ui/types/message-box';
|
||||
import type { MessageBoxInputData } from 'element-plus';
|
||||
import {
|
||||
useUIStore,
|
||||
useSettingsStore,
|
||||
|
|
|
@ -110,7 +110,7 @@ import { workflowRun } from '@/mixins/workflowRun';
|
|||
import { ABOUT_MODAL_KEY, VERSIONS_MODAL_KEY, VIEWS } from '@/constants';
|
||||
import { userHelpers } from '@/mixins/userHelpers';
|
||||
import { debounceHelper } from '@/mixins/debounce';
|
||||
import Vue, { defineComponent } from 'vue';
|
||||
import { defineComponent } from 'vue';
|
||||
import { mapStores } from 'pinia';
|
||||
import {
|
||||
useUIStore,
|
||||
|
@ -341,7 +341,7 @@ export default defineComponent({
|
|||
} else {
|
||||
this.uiStore.sidebarMenuCollapsed = false;
|
||||
}
|
||||
await Vue.nextTick();
|
||||
await this.$nextTick();
|
||||
this.fullyExpanded = !this.isCollapsed;
|
||||
},
|
||||
created() {
|
||||
|
@ -453,22 +453,21 @@ export default defineComponent({
|
|||
});
|
||||
},
|
||||
findFirstAccessibleSettingsRoute() {
|
||||
// Get all settings rotes by filtering them by pageCategory property
|
||||
const settingsRoutes = this.$router
|
||||
.getRoutes()
|
||||
.filter(
|
||||
(category) =>
|
||||
category.meta.telemetry && category.meta.telemetry.pageCategory === 'settings',
|
||||
)
|
||||
.map((route) => route.name || '');
|
||||
let defaultSettingsRoute = null;
|
||||
.find((route) => route.path === '/settings')!
|
||||
.children.map((route) => route.name || '');
|
||||
|
||||
let defaultSettingsRoute = null;
|
||||
for (const route of settingsRoutes) {
|
||||
if (this.canUserAccessRouteByName(route)) {
|
||||
defaultSettingsRoute = route;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
console.log(defaultSettingsRoute);
|
||||
|
||||
return defaultSettingsRoute;
|
||||
},
|
||||
onResize(event: UIEvent) {
|
||||
|
@ -481,7 +480,7 @@ export default defineComponent({
|
|||
checkWidthAndAdjustSidebar(width: number) {
|
||||
if (width < 900) {
|
||||
this.uiStore.sidebarMenuCollapsed = true;
|
||||
Vue.nextTick(() => {
|
||||
this.$nextTick(() => {
|
||||
this.fullyExpanded = !this.isCollapsed;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<script lang="ts" setup>
|
||||
import { computed, ref } from 'vue';
|
||||
import { useRouter } from 'vue-router/composables';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { createEventBus } from 'n8n-design-system/utils';
|
||||
import { useI18n, useLoadingService, useMessage, useToast } from '@/composables';
|
||||
import { useUIStore, useUsersStore, useVersionControlStore } from '@/stores';
|
||||
|
|
|
@ -2,10 +2,14 @@
|
|||
<el-dialog
|
||||
:visible="uiStore.isModalOpen(this.name)"
|
||||
:before-close="closeDialog"
|
||||
:class="{ 'dialog-wrapper': true, [$style.center]: center, scrollable: scrollable }"
|
||||
:class="{
|
||||
'dialog-wrapper': true,
|
||||
[$style.center]: center,
|
||||
scrollable: scrollable,
|
||||
[getCustomClass()]: true,
|
||||
}"
|
||||
:width="width"
|
||||
:show-close="showClose"
|
||||
:custom-class="getCustomClass()"
|
||||
:close-on-click-modal="closeOnClickModal"
|
||||
:close-on-press-escape="closeOnPressEscape"
|
||||
:style="styles"
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
:modal="modal"
|
||||
:wrapperClosable="wrapperClosable"
|
||||
>
|
||||
<template #title>
|
||||
<template #header>
|
||||
<slot name="header" />
|
||||
</template>
|
||||
<template>
|
||||
|
|
|
@ -230,31 +230,30 @@ export default defineComponent({
|
|||
}
|
||||
}
|
||||
|
||||
::v-deep {
|
||||
.button {
|
||||
--button-background-color: var(--color-background-base);
|
||||
--button-border-color: var(--color-foreground-base);
|
||||
}
|
||||
:deep(.button) {
|
||||
--button-background-color: var(--color-background-base);
|
||||
--button-border-color: var(--color-foreground-base);
|
||||
}
|
||||
|
||||
.duplicate-parameter-item {
|
||||
position: relative;
|
||||
:deep(.duplicate-parameter-item) {
|
||||
position: relative;
|
||||
|
||||
.multi > .delete-item {
|
||||
top: 0.1em;
|
||||
}
|
||||
}
|
||||
|
||||
.duplicate-parameter-input-item {
|
||||
margin: 0.5em 0 0.25em 2em;
|
||||
}
|
||||
|
||||
.duplicate-parameter-item + .duplicate-parameter-item {
|
||||
.collection-parameter-wrapper {
|
||||
border-top: 1px dashed #999;
|
||||
margin-top: var(--spacing-xs);
|
||||
}
|
||||
.multi > .delete-item {
|
||||
top: 0.1em;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.duplicate-parameter-input-item) {
|
||||
margin: 0.5em 0 0.25em 2em;
|
||||
}
|
||||
|
||||
:deep(.duplicate-parameter-item + .duplicate-parameter-item) {
|
||||
.collection-parameter-wrapper {
|
||||
border-top: 1px dashed #999;
|
||||
margin-top: var(--spacing-xs);
|
||||
}
|
||||
}
|
||||
|
||||
.no-items-exist {
|
||||
margin: var(--spacing-xs) 0;
|
||||
}
|
||||
|
|
|
@ -169,7 +169,7 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue, { defineComponent } from 'vue';
|
||||
import { defineComponent } from 'vue';
|
||||
import { mapStores } from 'pinia';
|
||||
import {
|
||||
CUSTOM_API_CALL_KEY,
|
||||
|
@ -574,7 +574,7 @@ export default defineComponent({
|
|||
workflow_id: this.workflowsStore.workflowId,
|
||||
});
|
||||
|
||||
Vue.nextTick(() => {
|
||||
this.$nextTick(() => {
|
||||
// Wait a tick else vue causes problems because the data is gone
|
||||
this.$emit('removeNode', this.data.name);
|
||||
});
|
||||
|
@ -585,7 +585,7 @@ export default defineComponent({
|
|||
button_name: 'duplicate',
|
||||
workflow_id: this.workflowsStore.workflowId,
|
||||
});
|
||||
Vue.nextTick(() => {
|
||||
this.$nextTick(() => {
|
||||
// Wait a tick else vue causes problems because the data is gone
|
||||
this.$emit('duplicateNode', this.data.name);
|
||||
});
|
||||
|
|
|
@ -28,16 +28,18 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<node-creator
|
||||
:active="createNodeActive"
|
||||
@nodeTypeSelected="nodeTypeSelected"
|
||||
@closeNodeCreator="closeNodeCreator"
|
||||
/>
|
||||
<Suspense>
|
||||
<NodeCreator
|
||||
:active="createNodeActive"
|
||||
@nodeTypeSelected="nodeTypeSelected"
|
||||
@closeNodeCreator="closeNodeCreator"
|
||||
/>
|
||||
</Suspense>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { defineAsyncComponent, defineComponent } from 'vue';
|
||||
import { getMidCanvasPosition } from '@/utils/nodeViewUtils';
|
||||
import {
|
||||
DEFAULT_STICKY_HEIGHT,
|
||||
|
@ -48,10 +50,14 @@ import {
|
|||
import { mapStores } from 'pinia';
|
||||
import { useUIStore } from '@/stores/ui.store';
|
||||
|
||||
const NodeCreator = defineAsyncComponent(
|
||||
() => import('@/components/Node/NodeCreator/NodeCreator.vue'),
|
||||
);
|
||||
|
||||
export default defineComponent({
|
||||
name: 'node-creation',
|
||||
components: {
|
||||
NodeCreator: async () => import('@/components/Node/NodeCreator/NodeCreator.vue'),
|
||||
NodeCreator,
|
||||
},
|
||||
props: {
|
||||
nodeViewScale: {
|
||||
|
|
|
@ -124,8 +124,8 @@ function onBackButton() {
|
|||
? searchPlaceholder
|
||||
: $locale.baseText('nodeCreator.searchBar.searchNodes')
|
||||
"
|
||||
@input="onSearch"
|
||||
:value="activeViewStack.search"
|
||||
:modelValue="activeViewStack.search"
|
||||
@update:modelValue="onSearch"
|
||||
/>
|
||||
<div :class="$style.renderedItems">
|
||||
<!-- Actions mode -->
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
<template>
|
||||
<div :class="$style.searchContainer" data-test-id="search-bar">
|
||||
<div :class="{ [$style.prefix]: true, [$style.active]: value.length > 0 }">
|
||||
<div :class="{ [$style.prefix]: true, [$style.active]: modelValue.length > 0 }">
|
||||
<font-awesome-icon icon="search" size="sm" />
|
||||
</div>
|
||||
<div :class="$style.text">
|
||||
<input
|
||||
:placeholder="placeholder"
|
||||
:value="value"
|
||||
@input="onInput"
|
||||
:value="modelValue"
|
||||
:class="$style.input"
|
||||
ref="inputRef"
|
||||
autofocus
|
||||
data-test-id="node-creator-search-bar"
|
||||
tabindex="0"
|
||||
@input="onInput"
|
||||
/>
|
||||
</div>
|
||||
<div :class="$style.suffix" v-if="value.length > 0" @click="clear">
|
||||
<div :class="$style.suffix" v-if="modelValue.length > 0" @click="clear">
|
||||
<button :class="[$style.clear, $style.clickable]">
|
||||
<font-awesome-icon icon="times-circle" />
|
||||
</button>
|
||||
|
@ -30,16 +30,16 @@ import { runExternalHook } from '@/utils';
|
|||
|
||||
export interface Props {
|
||||
placeholder: string;
|
||||
value: string;
|
||||
modelValue: string;
|
||||
}
|
||||
|
||||
withDefaults(defineProps<Props>(), {
|
||||
placeholder: '',
|
||||
value: '',
|
||||
modelValue: '',
|
||||
});
|
||||
|
||||
const emit = defineEmits<{
|
||||
(event: 'input', value: string): void;
|
||||
(event: 'update:modelValue', value: string): void;
|
||||
}>();
|
||||
|
||||
const state = reactive({
|
||||
|
@ -52,11 +52,11 @@ function focus() {
|
|||
|
||||
function onInput(event: Event) {
|
||||
const input = event.target as HTMLInputElement;
|
||||
emit('input', input.value);
|
||||
emit('update:modelValue', input.value);
|
||||
}
|
||||
|
||||
function clear() {
|
||||
emit('input', '');
|
||||
emit('update:modelValue', '');
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { ref, set } from 'vue';
|
||||
import { ref } from 'vue';
|
||||
import { defineStore } from 'pinia';
|
||||
|
||||
export type KeyboardKey = (typeof WATCHED_KEYS)[number];
|
||||
|
@ -125,7 +125,7 @@ export const useKeyboardNavigation = defineStore('nodeCreatorKeyboardNavigation'
|
|||
function registerKeyHook(name: string, hook: KeyHook) {
|
||||
hook.keyboardKeys.forEach((keyboardKey) => {
|
||||
if (WATCHED_KEYS.includes(keyboardKey)) {
|
||||
set(keysHooks.value, name, hook);
|
||||
keysHooks.value = { ...keysHooks.value, [name]: hook };
|
||||
} else {
|
||||
throw new Error(`Key ${keyboardKey} is not supported`);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { computed, ref, set } from 'vue';
|
||||
import { computed, ref } from 'vue';
|
||||
import { defineStore } from 'pinia';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import type { INodeCreateElement, NodeFilterType, SimplifiedNodeType } from '@/Interface';
|
||||
|
@ -167,7 +167,10 @@ export const useViewStacks = defineStore('nodeCreatorViewStacks', () => {
|
|||
// For each key in the stack, update the matched stack
|
||||
Object.keys(stack).forEach((key) => {
|
||||
const typedKey = key as keyof ViewStack;
|
||||
set(viewStacks.value[matchedIndex], key, stack[typedKey]);
|
||||
viewStacks.value[matchedIndex] = {
|
||||
...viewStacks.value[matchedIndex],
|
||||
[key]: stack[typedKey],
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -3,8 +3,7 @@
|
|||
:visible="(!!activeNode || renaming) && !isActiveStickyNode"
|
||||
:before-close="close"
|
||||
:show-close="false"
|
||||
custom-class="data-display-wrapper"
|
||||
class="ndv-wrapper"
|
||||
class="data-display-wrapper ndv-wrapper"
|
||||
width="auto"
|
||||
append-to-body
|
||||
data-test-id="ndv"
|
||||
|
|
|
@ -9,11 +9,12 @@
|
|||
<div :class="$style.header">
|
||||
<div class="header-side-menu">
|
||||
<NodeTitle
|
||||
v-if="node"
|
||||
class="node-name"
|
||||
:value="node && node.name"
|
||||
:modelValue="node.name"
|
||||
:nodeType="nodeType"
|
||||
:isReadOnly="isReadOnly"
|
||||
@input="nameChanged"
|
||||
@update:modelValue="nameChanged"
|
||||
></NodeTitle>
|
||||
<div v-if="isExecutable">
|
||||
<NodeExecuteButton
|
||||
|
@ -46,7 +47,7 @@
|
|||
</div>
|
||||
<div v-if="isCommunityNode" :class="$style.descriptionContainer">
|
||||
<div class="mb-l">
|
||||
<i18n
|
||||
<i18n-t
|
||||
path="nodeSettings.communityNodeUnknown.description"
|
||||
tag="span"
|
||||
@click="onMissingNodeTextClick"
|
||||
|
@ -58,7 +59,7 @@
|
|||
>{{ node.type.split('.')[0] }}</a
|
||||
>
|
||||
</template>
|
||||
</i18n>
|
||||
</i18n-t>
|
||||
</div>
|
||||
<n8n-link
|
||||
:to="COMMUNITY_NODES_INSTALLATION_DOCS_URL"
|
||||
|
@ -67,7 +68,7 @@
|
|||
{{ $locale.baseText('nodeSettings.communityNodeUnknown.installLink.text') }}
|
||||
</n8n-link>
|
||||
</div>
|
||||
<i18n v-else path="nodeSettings.nodeTypeUnknown.description" tag="span">
|
||||
<i18n-t v-else path="nodeSettings.nodeTypeUnknown.description" tag="span">
|
||||
<template #action>
|
||||
<a
|
||||
:href="CUSTOM_NODES_DOCS_URL"
|
||||
|
@ -75,7 +76,7 @@
|
|||
v-text="$locale.baseText('nodeSettings.nodeTypeUnknown.description.customNode')"
|
||||
/>
|
||||
</template>
|
||||
</i18n>
|
||||
</i18n-t>
|
||||
</div>
|
||||
<div class="node-parameters-wrapper" data-test-id="node-parameters" v-if="node && nodeValid">
|
||||
<n8n-notice
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<span :class="$style.container" data-test-id="node-title-container" @click="onEdit">
|
||||
<span :class="$style.iconWrapper"><NodeIcon :nodeType="nodeType" :size="18" /></span>
|
||||
<n8n-popover placement="right" width="200" :value="editName" :disabled="!editable">
|
||||
<n8n-popover placement="right" width="200" :modelValue="editName" :disabled="!editable">
|
||||
<div
|
||||
:class="$style.editContainer"
|
||||
@keydown.enter="onRename"
|
||||
|
@ -29,7 +29,7 @@
|
|||
</div>
|
||||
<template #reference>
|
||||
<div class="ph-no-capture" :class="{ [$style.title]: true, [$style.hoverable]: editable }">
|
||||
{{ value }}
|
||||
{{ modelValue }}
|
||||
<div :class="$style.editIconContainer">
|
||||
<font-awesome-icon :class="$style.editIcon" icon="pencil-alt" v-if="editable" />
|
||||
</div>
|
||||
|
@ -49,8 +49,9 @@ export default defineComponent({
|
|||
NodeIcon,
|
||||
},
|
||||
props: {
|
||||
value: {
|
||||
modelValue: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
nodeType: {},
|
||||
readOnly: {
|
||||
|
@ -71,7 +72,7 @@ export default defineComponent({
|
|||
},
|
||||
methods: {
|
||||
onEdit() {
|
||||
this.newName = this.value;
|
||||
this.newName = this.modelValue;
|
||||
this.editName = true;
|
||||
this.$nextTick(() => {
|
||||
const inputRef = this.$refs.input as HTMLInputElement | undefined;
|
||||
|
@ -82,7 +83,7 @@ export default defineComponent({
|
|||
},
|
||||
onRename() {
|
||||
if (this.newName.trim() !== '') {
|
||||
this.$emit('input', this.newName.trim());
|
||||
this.$emit('update:modelValue', this.newName.trim());
|
||||
}
|
||||
|
||||
this.editName = false;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import type { ElNotificationComponent } from 'element-ui/types/notification';
|
||||
import type { NotificationInstance } from 'element-plus';
|
||||
import { sanitizeHtml } from '@/utils';
|
||||
import { useToast } from '@/composables';
|
||||
|
||||
|
@ -26,7 +26,7 @@ export default defineComponent({
|
|||
},
|
||||
data() {
|
||||
return {
|
||||
alert: null as null | ElNotificationComponent,
|
||||
alert: null as null | NotificationInstance,
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<div @keydown.stop :class="parameterInputClasses">
|
||||
<expression-edit
|
||||
:dialogVisible="expressionEditDialogVisible"
|
||||
:value="
|
||||
:modelValue="
|
||||
isResourceLocatorParameter && typeof value !== 'string' ? (value ? value.value : '') : value
|
||||
"
|
||||
:parameter="parameter"
|
||||
|
@ -10,14 +10,14 @@
|
|||
:eventSource="eventSource || 'ndv'"
|
||||
:isReadOnly="isReadOnly"
|
||||
@closeDialog="closeExpressionEditDialog"
|
||||
@valueChanged="expressionUpdated"
|
||||
@update:modelValue="expressionUpdated"
|
||||
></expression-edit>
|
||||
<div class="parameter-input ignore-key-press" :style="parameterInputWrapperStyle">
|
||||
<resource-locator
|
||||
v-if="isResourceLocatorParameter"
|
||||
ref="resourceLocator"
|
||||
:parameter="parameter"
|
||||
:value="value"
|
||||
:modelValue="value"
|
||||
:dependentParametersValues="dependentParametersValues"
|
||||
:displayTitle="displayTitle"
|
||||
:expressionDisplayValue="expressionDisplayValue"
|
||||
|
@ -29,7 +29,7 @@
|
|||
:node="node"
|
||||
:path="path"
|
||||
:event-bus="eventBus"
|
||||
@input="valueChanged"
|
||||
@update:modelValue="valueChanged"
|
||||
@modalOpenerClick="openExpressionEditorModal"
|
||||
@focus="setFocus"
|
||||
@blur="onBlur"
|
||||
|
@ -37,11 +37,11 @@
|
|||
/>
|
||||
<ExpressionParameterInput
|
||||
v-else-if="isValueExpression || forceShowExpression"
|
||||
:value="expressionDisplayValue"
|
||||
:modelValue="expressionDisplayValue"
|
||||
:title="displayTitle"
|
||||
:isReadOnly="isReadOnly"
|
||||
:path="path"
|
||||
@valueChanged="expressionUpdated"
|
||||
@update:modelValue="expressionUpdated"
|
||||
@modalOpenerClick="openExpressionEditorModal"
|
||||
@focus="setFocus"
|
||||
@blur="onBlur"
|
||||
|
@ -390,7 +390,6 @@ import { useNodeTypesStore } from '@/stores/nodeTypes.store';
|
|||
import { useCredentialsStore } from '@/stores/credentials.store';
|
||||
import { useSettingsStore } from '@/stores/settings.store';
|
||||
import { htmlEditorEventBus } from '@/event-bus';
|
||||
import Vue from 'vue';
|
||||
import type { EventBus } from 'n8n-design-system/utils';
|
||||
import { createEventBus } from 'n8n-design-system/utils';
|
||||
|
||||
|
@ -976,7 +975,7 @@ export default defineComponent({
|
|||
this.nodeName = this.node.name;
|
||||
}
|
||||
|
||||
Vue.nextTick(() => {
|
||||
this.$nextTick(() => {
|
||||
// @ts-ignore
|
||||
if (this.$refs.inputField?.focus && this.$refs.inputField?.$el) {
|
||||
// @ts-ignore
|
||||
|
@ -1217,7 +1216,7 @@ export default defineComponent({
|
|||
display: inline-block;
|
||||
}
|
||||
|
||||
::v-deep .color-input {
|
||||
:deep(.color-input) {
|
||||
display: flex;
|
||||
|
||||
.el-color-picker__trigger {
|
||||
|
|
|
@ -19,40 +19,38 @@
|
|||
@menu-expanded="onMenuExpanded"
|
||||
/>
|
||||
</template>
|
||||
<template>
|
||||
<parameter-input-wrapper
|
||||
ref="param"
|
||||
inputSize="large"
|
||||
:parameter="parameter"
|
||||
:value="value"
|
||||
:path="parameter.name"
|
||||
:hideIssues="true"
|
||||
:documentationUrl="documentationUrl"
|
||||
:errorHighlight="showRequiredErrors"
|
||||
:isForCredential="true"
|
||||
:eventSource="eventSource"
|
||||
:hint="!showRequiredErrors ? hint : ''"
|
||||
:event-bus="eventBus"
|
||||
@focus="onFocus"
|
||||
@blur="onBlur"
|
||||
@textInput="valueChanged"
|
||||
@valueChanged="valueChanged"
|
||||
/>
|
||||
<div :class="$style.errors" v-if="showRequiredErrors">
|
||||
<n8n-text color="danger" size="small">
|
||||
{{ $locale.baseText('parameterInputExpanded.thisFieldIsRequired') }}
|
||||
<n8n-link
|
||||
v-if="documentationUrl"
|
||||
:to="documentationUrl"
|
||||
size="small"
|
||||
:underline="true"
|
||||
@click="onDocumentationUrlClick"
|
||||
>
|
||||
{{ $locale.baseText('parameterInputExpanded.openDocs') }}
|
||||
</n8n-link>
|
||||
</n8n-text>
|
||||
</div>
|
||||
</template>
|
||||
<parameter-input-wrapper
|
||||
ref="param"
|
||||
inputSize="large"
|
||||
:parameter="parameter"
|
||||
:value="value"
|
||||
:path="parameter.name"
|
||||
:hideIssues="true"
|
||||
:documentationUrl="documentationUrl"
|
||||
:errorHighlight="showRequiredErrors"
|
||||
:isForCredential="true"
|
||||
:eventSource="eventSource"
|
||||
:hint="!showRequiredErrors ? hint : ''"
|
||||
:event-bus="eventBus"
|
||||
@focus="onFocus"
|
||||
@blur="onBlur"
|
||||
@textInput="valueChanged"
|
||||
@valueChanged="valueChanged"
|
||||
/>
|
||||
<div :class="$style.errors" v-if="showRequiredErrors">
|
||||
<n8n-text color="danger" size="small">
|
||||
{{ $locale.baseText('parameterInputExpanded.thisFieldIsRequired') }}
|
||||
<n8n-link
|
||||
v-if="documentationUrl"
|
||||
:to="documentationUrl"
|
||||
size="small"
|
||||
:underline="true"
|
||||
@click="onDocumentationUrlClick"
|
||||
>
|
||||
{{ $locale.baseText('parameterInputExpanded.openDocs') }}
|
||||
</n8n-link>
|
||||
</n8n-text>
|
||||
</div>
|
||||
</n8n-input-label>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
:data-test-id="`resource-locator-${parameter.name}`"
|
||||
>
|
||||
<resource-locator-dropdown
|
||||
:value="value ? value.value : ''"
|
||||
:modelValue="modelValue ? modelValue.value : ''"
|
||||
:show="showResourceDropdown"
|
||||
:filterable="isSearchable"
|
||||
:filterRequired="requiresSearchFilter"
|
||||
|
@ -16,7 +16,7 @@
|
|||
:errorView="currentQueryError"
|
||||
:width="width"
|
||||
:event-bus="eventBus"
|
||||
@input="onListItemSelected"
|
||||
@update:modelValue="onListItemSelected"
|
||||
@hide="onDropdownHide"
|
||||
@filter="onSearchFilter"
|
||||
@loadMore="loadResourcesDebounced"
|
||||
|
@ -88,10 +88,10 @@
|
|||
>
|
||||
<ExpressionParameterInput
|
||||
v-if="isValueExpression || forceShowExpression"
|
||||
:value="expressionDisplayValue"
|
||||
:modelValue="expressionDisplayValue"
|
||||
:path="path"
|
||||
isForRecordLocator
|
||||
@valueChanged="onInputChange"
|
||||
@update:modelValue="onInputChange"
|
||||
@modalOpenerClick="$emit('modalOpenerClick')"
|
||||
ref="input"
|
||||
/>
|
||||
|
@ -200,7 +200,7 @@ export default defineComponent({
|
|||
type: Object as PropType<INodeProperties>,
|
||||
required: true,
|
||||
},
|
||||
value: {
|
||||
modelValue: {
|
||||
type: [Object, String] as PropType<
|
||||
INodeParameterResourceLocator | NodeParameterValue | undefined
|
||||
>,
|
||||
|
@ -281,16 +281,16 @@ export default defineComponent({
|
|||
return getAppNameFromNodeName(nodeType?.displayName || '');
|
||||
},
|
||||
selectedMode(): string {
|
||||
if (typeof this.value !== 'object') {
|
||||
if (typeof this.modelValue !== 'object') {
|
||||
// legacy mode
|
||||
return '';
|
||||
}
|
||||
|
||||
if (!this.value) {
|
||||
if (!this.modelValue) {
|
||||
return this.parameter.modes ? this.parameter.modes[0].name : '';
|
||||
}
|
||||
|
||||
return this.value.mode;
|
||||
return this.modelValue.mode;
|
||||
},
|
||||
isListMode(): boolean {
|
||||
return this.selectedMode === 'list';
|
||||
|
@ -335,19 +335,19 @@ export default defineComponent({
|
|||
return hasOnlyListMode(this.parameter);
|
||||
},
|
||||
valueToDisplay(): NodeParameterValue {
|
||||
if (typeof this.value !== 'object') {
|
||||
return this.value;
|
||||
if (typeof this.modelValue !== 'object') {
|
||||
return this.modelValue;
|
||||
}
|
||||
|
||||
if (this.isListMode) {
|
||||
return this.value ? this.value.cachedResultName || this.value.value : '';
|
||||
return this.modelValue ? this.modelValue.cachedResultName || this.modelValue.value : '';
|
||||
}
|
||||
|
||||
return this.value ? this.value.value : '';
|
||||
return this.modelValue ? this.modelValue.value : '';
|
||||
},
|
||||
urlValue(): string | null {
|
||||
if (this.isListMode && typeof this.value === 'object') {
|
||||
return (this.value && this.value.cachedResultUrl) || null;
|
||||
if (this.isListMode && typeof this.modelValue === 'object') {
|
||||
return (this.modelValue && this.modelValue.cachedResultUrl) || null;
|
||||
}
|
||||
|
||||
if (this.selectedMode === 'url') {
|
||||
|
@ -454,10 +454,10 @@ export default defineComponent({
|
|||
if (
|
||||
mode.extractValue &&
|
||||
mode.extractValue.regex &&
|
||||
isResourceLocatorValue(this.value) &&
|
||||
this.value.__regex !== mode.extractValue.regex
|
||||
isResourceLocatorValue(this.modelValue) &&
|
||||
this.modelValue.__regex !== mode.extractValue.regex
|
||||
) {
|
||||
this.$emit('input', { ...this.value, __regex: mode.extractValue.regex });
|
||||
this.$emit('update:modelValue', { ...this.modelValue, __regex: mode.extractValue.regex });
|
||||
}
|
||||
},
|
||||
dependentParametersValues(currentValue, oldValue) {
|
||||
|
@ -465,12 +465,12 @@ export default defineComponent({
|
|||
// Reset value if dependent parameters change
|
||||
if (
|
||||
isUpdated &&
|
||||
this.value &&
|
||||
isResourceLocatorValue(this.value) &&
|
||||
this.value.value !== ''
|
||||
this.modelValue &&
|
||||
isResourceLocatorValue(this.modelValue) &&
|
||||
this.modelValue.value !== ''
|
||||
) {
|
||||
this.$emit('input', {
|
||||
...this.value,
|
||||
this.$emit('update:modelValue', {
|
||||
...this.modelValue,
|
||||
cachedResultName: '',
|
||||
cachedResultUrl: '',
|
||||
value: '',
|
||||
|
@ -590,17 +590,26 @@ export default defineComponent({
|
|||
params.cachedResultUrl = resource.url;
|
||||
}
|
||||
}
|
||||
this.$emit('input', params);
|
||||
this.$emit('update:modelValue', params);
|
||||
},
|
||||
onModeSelected(value: string): void {
|
||||
if (typeof this.value !== 'object') {
|
||||
this.$emit('input', { __rl: true, value: this.value, mode: value });
|
||||
} else if (value === 'url' && this.value && this.value.cachedResultUrl) {
|
||||
this.$emit('input', { __rl: true, mode: value, value: this.value.cachedResultUrl });
|
||||
} else if (value === 'id' && this.selectedMode === 'list' && this.value && this.value.value) {
|
||||
this.$emit('input', { __rl: true, mode: value, value: this.value.value });
|
||||
if (typeof this.modelValue !== 'object') {
|
||||
this.$emit('update:modelValue', { __rl: true, value: this.modelValue, mode: value });
|
||||
} else if (value === 'url' && this.modelValue && this.modelValue.cachedResultUrl) {
|
||||
this.$emit('update:modelValue', {
|
||||
__rl: true,
|
||||
mode: value,
|
||||
value: this.modelValue.cachedResultUrl,
|
||||
});
|
||||
} else if (
|
||||
value === 'id' &&
|
||||
this.selectedMode === 'list' &&
|
||||
this.modelValue &&
|
||||
this.modelValue.value
|
||||
) {
|
||||
this.$emit('update:modelValue', { __rl: true, mode: value, value: this.modelValue.value });
|
||||
} else {
|
||||
this.$emit('input', { __rl: true, mode: value, value: '' });
|
||||
this.$emit('update:modelValue', { __rl: true, mode: value, value: '' });
|
||||
}
|
||||
|
||||
this.trackEvent('User changed resource locator mode', { mode: value });
|
||||
|
@ -728,9 +737,10 @@ export default defineComponent({
|
|||
}
|
||||
|
||||
if (mode) {
|
||||
this.$emit('input', {
|
||||
this.$emit('update:modelValue', {
|
||||
__rl: true,
|
||||
value: this.value && typeof this.value === 'object' ? this.value.value : '',
|
||||
value:
|
||||
this.modelValue && typeof this.modelValue === 'object' ? this.modelValue.value : '',
|
||||
mode: mode.name,
|
||||
});
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
placement="bottom"
|
||||
:width="width"
|
||||
:popper-class="$style.popover"
|
||||
:value="show"
|
||||
:modelValue="show"
|
||||
trigger="manual"
|
||||
data-test-id="resource-locator-dropdown"
|
||||
v-click-outside="onClickOutside"
|
||||
|
@ -16,7 +16,7 @@
|
|||
size="medium"
|
||||
:modelValue="filter"
|
||||
:clearable="true"
|
||||
@input="onFilterInput"
|
||||
@update:modelValue="onFilterInput"
|
||||
ref="search"
|
||||
:placeholder="$locale.baseText('resourceLocator.search.placeholder')"
|
||||
>
|
||||
|
@ -45,7 +45,7 @@
|
|||
:key="result.value"
|
||||
:class="{
|
||||
[$style.resourceItem]: true,
|
||||
[$style.selected]: result.value === value,
|
||||
[$style.selected]: result.value === modelValue,
|
||||
[$style.hovering]: hoverIndex === i,
|
||||
}"
|
||||
class="ph-no-capture"
|
||||
|
@ -91,7 +91,7 @@ const SCROLL_MARGIN_PX = 10;
|
|||
export default defineComponent({
|
||||
name: 'resource-locator-dropdown',
|
||||
props: {
|
||||
value: {
|
||||
modelValue: {
|
||||
type: [String, Number],
|
||||
},
|
||||
show: {
|
||||
|
@ -149,7 +149,7 @@ export default defineComponent({
|
|||
}
|
||||
seen.add(item.value);
|
||||
|
||||
if (this.value && item.value === this.value) {
|
||||
if (this.modelValue && item.value === this.modelValue) {
|
||||
acc.selected = item;
|
||||
} else {
|
||||
acc.notSelected.push(item);
|
||||
|
@ -210,7 +210,7 @@ export default defineComponent({
|
|||
}
|
||||
}
|
||||
} else if (e.key === 'Enter') {
|
||||
this.$emit('input', this.sortedResources[this.hoverIndex].value);
|
||||
this.$emit('update:modelValue', this.sortedResources[this.hoverIndex].value);
|
||||
}
|
||||
},
|
||||
onFilterInput(value: string) {
|
||||
|
@ -220,7 +220,7 @@ export default defineComponent({
|
|||
this.$emit('hide');
|
||||
},
|
||||
onItemClick(selected: string) {
|
||||
this.$emit('input', selected);
|
||||
this.$emit('update:modelValue', selected);
|
||||
},
|
||||
onItemHover(index: number) {
|
||||
this.hoverIndex = index;
|
||||
|
|
|
@ -65,14 +65,14 @@
|
|||
<n8n-tooltip placement="bottom-end">
|
||||
<template #content>
|
||||
<div>
|
||||
<i18n path="dataMapping.tableView.tableColumnsExceeded.tooltip">
|
||||
<i18n-t path="dataMapping.tableView.tableColumnsExceeded.tooltip">
|
||||
<template #columnLimit>{{ columnLimit }}</template>
|
||||
<template #link>
|
||||
<a @click="switchToJsonView">{{
|
||||
$locale.baseText('dataMapping.tableView.tableColumnsExceeded.tooltip.link')
|
||||
}}</a>
|
||||
</template>
|
||||
</i18n>
|
||||
</i18n-t>
|
||||
</div>
|
||||
</template>
|
||||
<span>
|
||||
|
|
|
@ -1,18 +1,15 @@
|
|||
<script lang="ts" setup>
|
||||
import { Notification } from 'element-ui';
|
||||
import { useSSOStore } from '@/stores/sso.store';
|
||||
import { useToast } from '@/composables';
|
||||
|
||||
const ssoStore = useSSOStore();
|
||||
const toast = useToast();
|
||||
|
||||
const onSSOLogin = async () => {
|
||||
try {
|
||||
window.location.href = await ssoStore.getSSORedirectUrl();
|
||||
} catch (error) {
|
||||
Notification.error({
|
||||
title: 'Error',
|
||||
message: error.message,
|
||||
position: 'bottom-right',
|
||||
});
|
||||
toast.showError(error, 'Error', error.message);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -22,12 +22,12 @@
|
|||
<div :class="$style.header">
|
||||
<div :class="$style.destinationInfo">
|
||||
<InlineNameEdit
|
||||
:name="headerLabel"
|
||||
:modelValue="headerLabel"
|
||||
:subtitle="!isTypeAbstract ? $locale.baseText(typeLabelName) : 'Select type'"
|
||||
:readonly="isTypeAbstract"
|
||||
type="Credential"
|
||||
data-test-id="subtitle-showing-type"
|
||||
@input="onLabelChange"
|
||||
@update:modelValue="onLabelChange"
|
||||
/>
|
||||
</div>
|
||||
<div :class="$style.destinationActions">
|
||||
|
@ -158,7 +158,7 @@
|
|||
<event-selection
|
||||
class=""
|
||||
:destinationId="destination.id"
|
||||
@input="onInput"
|
||||
@update:modelValue="onInput"
|
||||
@change="valueChanged"
|
||||
:readonly="!isInstanceOwner"
|
||||
/>
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
>
|
||||
<!-- <template #header> -->
|
||||
<checkbox
|
||||
:value="group.selected"
|
||||
:modelValue="group.selected"
|
||||
:indeterminate="!group.selected && group.indeterminate"
|
||||
@input="onInput"
|
||||
@update:modelValue="onInput"
|
||||
@change="onCheckboxChecked(group.name, $event)"
|
||||
:disabled="readonly"
|
||||
>
|
||||
|
@ -28,8 +28,8 @@
|
|||
</checkbox>
|
||||
<checkbox
|
||||
v-if="group.name === 'n8n.audit'"
|
||||
:value="logStreamingStore.items[destinationId]?.destination.anonymizeAuditMessages"
|
||||
@input="onInput"
|
||||
:modelValue="logStreamingStore.items[destinationId]?.destination.anonymizeAuditMessages"
|
||||
@update:modelValue="onInput"
|
||||
@change="anonymizeAuditMessagesChanged"
|
||||
:disabled="readonly"
|
||||
>
|
||||
|
@ -49,10 +49,10 @@
|
|||
:class="`${$style.eventListItem} ${group.selected ? $style.eventListItemDisabled : ''}`"
|
||||
>
|
||||
<checkbox
|
||||
:value="event.selected || group.selected"
|
||||
:modelValue="event.selected || group.selected"
|
||||
:indeterminate="event.indeterminate"
|
||||
:disabled="group.selected || readonly"
|
||||
@input="onInput"
|
||||
@update:modelValue="onInput"
|
||||
@change="onCheckboxChecked(event.name, $event)"
|
||||
>
|
||||
{{ event.label }}
|
||||
|
@ -69,7 +69,7 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Checkbox } from 'element-ui';
|
||||
import { ElCheckbox as Checkbox } from 'element-plus';
|
||||
import { mapStores } from 'pinia';
|
||||
import type { BaseTextKey } from '@/plugins/i18n';
|
||||
import { useLogStreamingStore } from '@/stores/logStreaming.store';
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import Vue, { defineComponent } from 'vue';
|
||||
import { defineComponent } from 'vue';
|
||||
import { mapStores } from 'pinia';
|
||||
|
||||
import { externalHooks } from '@/mixins/externalHooks';
|
||||
|
@ -163,7 +163,7 @@ export default defineComponent({
|
|||
},
|
||||
methods: {
|
||||
deleteNode() {
|
||||
Vue.nextTick(() => {
|
||||
this.$nextTick(() => {
|
||||
// Wait a tick else vue causes problems because the data is gone
|
||||
this.$emit('removeNode', this.data.name);
|
||||
});
|
||||
|
|
|
@ -250,7 +250,7 @@ export default defineComponent({
|
|||
<style lang="scss" scoped>
|
||||
$--max-input-height: 60px;
|
||||
|
||||
::v-deep .el-select {
|
||||
:deep(.el-select) {
|
||||
.el-select__tags {
|
||||
max-height: $--max-input-height;
|
||||
overflow-y: scroll;
|
||||
|
|
|
@ -107,7 +107,7 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import type { Table as ElTable } from 'element-ui';
|
||||
import type { ElTable } from 'element-plus';
|
||||
import { MAX_TAG_NAME_LENGTH } from '@/constants';
|
||||
import type { ITagRow } from '@/Interface';
|
||||
import { defineComponent } from 'vue';
|
||||
|
@ -248,7 +248,7 @@ export default defineComponent({
|
|||
margin-left: 2px;
|
||||
}
|
||||
|
||||
::v-deep tr.disabled {
|
||||
:deep(tr.disabled) {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,9 +13,7 @@
|
|||
{{ `${$locale.baseText('versionCard.version')} ${version.name}` }}
|
||||
</div>
|
||||
<WarningTooltip v-if="version.hasSecurityIssue">
|
||||
<template>
|
||||
<span v-html="$locale.baseText('versionCard.thisVersionHasASecurityIssue')"></span>
|
||||
</template>
|
||||
<span v-html="$locale.baseText('versionCard.thisVersionHasASecurityIssue')"></span>
|
||||
</WarningTooltip>
|
||||
<Badge
|
||||
v-if="version.hasSecurityFix"
|
||||
|
|
|
@ -8,7 +8,7 @@ import type { VersionControlAggregatedFile } from '@/Interface';
|
|||
import { useI18n, useLoadingService, useToast } from '@/composables';
|
||||
import { useVersionControlStore } from '@/stores/versionControl.store';
|
||||
import { useUIStore } from '@/stores';
|
||||
import { useRoute } from 'vue-router/composables';
|
||||
import { useRoute } from 'vue-router';
|
||||
|
||||
const props = defineProps({
|
||||
data: {
|
||||
|
|
|
@ -162,7 +162,7 @@ export default defineComponent({
|
|||
margin-left: 0.5em;
|
||||
}
|
||||
|
||||
::v-deep .el-loading-spinner {
|
||||
:deep(.el-loading-spinner) {
|
||||
margin-top: -10px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -70,14 +70,14 @@
|
|||
</n8n-users-list>
|
||||
<template #fallback>
|
||||
<n8n-text>
|
||||
<i18n
|
||||
<i18n-t
|
||||
:path="
|
||||
uiStore.contextBasedTranslationKeys.workflows.sharing.unavailable.description
|
||||
"
|
||||
tag="span"
|
||||
>
|
||||
<template #action />
|
||||
</i18n>
|
||||
</i18n-t>
|
||||
</n8n-text>
|
||||
</template>
|
||||
</enterprise-edition>
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
</n8n-button>
|
||||
</template>
|
||||
<div :class="$style['filters-dropdown']" data-test-id="resources-list-filters-dropdown">
|
||||
<slot :filters="value" :setKeyValue="setKeyValue" />
|
||||
<slot :filters="modelValue" :setKeyValue="setKeyValue" />
|
||||
<enterprise-edition
|
||||
class="mb-s"
|
||||
:features="[EnterpriseEditionFeature.Sharing]"
|
||||
|
@ -32,7 +32,7 @@
|
|||
<n8n-user-select
|
||||
:users="ownedByUsers"
|
||||
:currentUserId="usersStore.currentUser.id"
|
||||
:modelValue="value.ownedBy"
|
||||
:modelValue="modelValue.ownedBy"
|
||||
size="medium"
|
||||
@update:modelValue="setKeyValue('ownedBy', $event)"
|
||||
/>
|
||||
|
@ -48,7 +48,7 @@
|
|||
<n8n-user-select
|
||||
:users="sharedWithUsers"
|
||||
:currentUserId="usersStore.currentUser.id"
|
||||
:modelValue="value.sharedWith"
|
||||
:modelValue="modelValue.sharedWith"
|
||||
size="medium"
|
||||
@update:modelValue="setKeyValue('sharedWith', $event)"
|
||||
/>
|
||||
|
@ -74,7 +74,7 @@ export type IResourceFiltersType = Record<string, boolean | string | string[]>;
|
|||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
value: {
|
||||
modelValue: {
|
||||
type: Object as PropType<IResourceFiltersType>,
|
||||
default: () => ({}),
|
||||
},
|
||||
|
@ -99,12 +99,12 @@ export default defineComponent({
|
|||
...mapStores(useUsersStore),
|
||||
ownedByUsers(): IUser[] {
|
||||
return this.usersStore.allUsers.map((user) =>
|
||||
user.id === this.value.sharedWith ? { ...user, disabled: true } : user,
|
||||
user.id === this.modelValue.sharedWith ? { ...user, disabled: true } : user,
|
||||
);
|
||||
},
|
||||
sharedWithUsers(): IUser[] {
|
||||
return this.usersStore.allUsers.map((user) =>
|
||||
user.id === this.value.ownedBy ? { ...user, disabled: true } : user,
|
||||
user.id === this.modelValue.ownedBy ? { ...user, disabled: true } : user,
|
||||
);
|
||||
},
|
||||
filtersLength(): number {
|
||||
|
@ -116,7 +116,9 @@ export default defineComponent({
|
|||
}
|
||||
|
||||
length += (
|
||||
Array.isArray(this.value[key]) ? this.value[key].length > 0 : this.value[key] !== ''
|
||||
Array.isArray(this.modelValue[key])
|
||||
? this.modelValue[key].length > 0
|
||||
: this.modelValue[key] !== ''
|
||||
)
|
||||
? 1
|
||||
: 0;
|
||||
|
@ -131,23 +133,23 @@ export default defineComponent({
|
|||
methods: {
|
||||
setKeyValue(key: string, value: unknown) {
|
||||
const filters = {
|
||||
...this.value,
|
||||
...this.modelValue,
|
||||
[key]: value,
|
||||
};
|
||||
|
||||
this.$emit('input', filters);
|
||||
this.$emit('update:modelValue', filters);
|
||||
},
|
||||
resetFilters() {
|
||||
if (this.reset) {
|
||||
this.reset();
|
||||
} else {
|
||||
const filters = { ...this.value };
|
||||
const filters = { ...this.modelValue };
|
||||
|
||||
(this.keys as string[]).forEach((key) => {
|
||||
filters[key] = Array.isArray(this.value[key]) ? [] : '';
|
||||
filters[key] = Array.isArray(this.modelValue[key]) ? [] : '';
|
||||
});
|
||||
|
||||
this.$emit('input', filters);
|
||||
this.$emit('update:modelValue', filters);
|
||||
}
|
||||
},
|
||||
},
|
||||
|
|
|
@ -88,9 +88,9 @@
|
|||
v-if="showFiltersDropdown"
|
||||
:keys="filterKeys"
|
||||
:reset="resetFilters"
|
||||
:value="filters"
|
||||
:modelValue="filters"
|
||||
:shareable="shareable"
|
||||
@input="$emit('update:filters', $event)"
|
||||
@update:modelValue="$emit('update:filters', $event)"
|
||||
@update:filtersLength="onUpdateFiltersLength"
|
||||
>
|
||||
<template #default="resourceFiltersSlotProps">
|
||||
|
|
|
@ -23,7 +23,7 @@ vi.mock('@/stores/history.store', () => {
|
|||
};
|
||||
});
|
||||
vi.mock('@/stores/ui.store');
|
||||
vi.mock('vue-router/composables', () => ({
|
||||
vi.mock('vue-router', () => ({
|
||||
useRoute: () => ({}),
|
||||
}));
|
||||
|
||||
|
|
|
@ -224,6 +224,7 @@ export default function useCanvasMouseSelect() {
|
|||
});
|
||||
|
||||
return {
|
||||
selectActive,
|
||||
getMousePositionWithinNodeView,
|
||||
mouseUpMouseSelect,
|
||||
mouseDownMouseSelect,
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Creates event listeners for `data-action` attribute to allow for actions to be called from locale without using
|
||||
* unsafe onclick attribute
|
||||
*/
|
||||
import { reactive, del, computed, onMounted, onUnmounted, getCurrentInstance } from 'vue';
|
||||
import { reactive, computed, onMounted, onUnmounted, getCurrentInstance } from 'vue';
|
||||
import { globalLinkActionsEventBus } from '@/event-bus';
|
||||
|
||||
const state = reactive({
|
||||
|
@ -14,7 +14,8 @@ export default () => {
|
|||
state.customActions[key] = action;
|
||||
}
|
||||
function unregisterCustomAction(key: string) {
|
||||
del(state.customActions, key);
|
||||
const { [key]: _, ...rest } = state.customActions;
|
||||
state.customActions = rest;
|
||||
}
|
||||
function delegateClick(e: MouseEvent) {
|
||||
const clickedElement = e.target;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { ref } from 'vue';
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
import { Loading } from 'element-ui';
|
||||
import { ElLoading as Loading } from 'element-plus';
|
||||
|
||||
interface LoadingService {
|
||||
text: string;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import type { ElMessageBoxOptions } from 'element-ui/types/message-box';
|
||||
import { Message, MessageBox } from 'element-ui';
|
||||
import type { ElMessageBoxOptions } from 'element-plus';
|
||||
import { ElMessageBox as MessageBox } from 'element-plus';
|
||||
|
||||
export function useMessage() {
|
||||
const handleCancelOrClose = (e: unknown) => {
|
||||
|
@ -65,6 +65,6 @@ export function useMessage() {
|
|||
alert,
|
||||
confirm,
|
||||
prompt,
|
||||
message: Message,
|
||||
message: MessageBox,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,18 +1,17 @@
|
|||
import { Notification } from 'element-ui';
|
||||
import type { ElNotificationComponent, ElNotificationOptions } from 'element-ui/types/notification';
|
||||
import type { MessageType } from 'element-ui/types/message';
|
||||
import { ElNotification as Notification } from 'element-plus';
|
||||
import type { NotificationInstance, NotificationOptions, MessageBoxState } from 'element-plus';
|
||||
import { sanitizeHtml } from '@/utils';
|
||||
import { useTelemetry } from '@/composables/useTelemetry';
|
||||
import { useWorkflowsStore } from '@/stores/workflows.store';
|
||||
import { useI18n } from './useI18n';
|
||||
import { useExternalHooks } from './useExternalHooks';
|
||||
|
||||
const messageDefaults: Partial<Omit<ElNotificationOptions, 'message'>> = {
|
||||
const messageDefaults: Partial<Omit<NotificationOptions, 'message'>> = {
|
||||
dangerouslyUseHTMLString: true,
|
||||
position: 'bottom-right',
|
||||
};
|
||||
|
||||
const stickyNotificationQueue: ElNotificationComponent[] = [];
|
||||
const stickyNotificationQueue: NotificationInstance[] = [];
|
||||
|
||||
export function useToast() {
|
||||
const telemetry = useTelemetry();
|
||||
|
@ -21,7 +20,7 @@ export function useToast() {
|
|||
const { i18n } = useI18n();
|
||||
|
||||
function showMessage(
|
||||
messageData: Omit<ElNotificationOptions, 'message'> & { message?: string },
|
||||
messageData: Omit<NotificationOptions, 'message'> & { message?: string },
|
||||
track = true,
|
||||
) {
|
||||
messageData = { ...messageDefaults, ...messageData };
|
||||
|
@ -29,7 +28,8 @@ export function useToast() {
|
|||
? sanitizeHtml(messageData.message)
|
||||
: messageData.message;
|
||||
|
||||
const notification = Notification(messageData as ElNotificationOptions);
|
||||
// @TODO Check if still working
|
||||
const notification = Notification(messageData as NotificationOptions);
|
||||
|
||||
if (messageData.duration === 0) {
|
||||
stickyNotificationQueue.push(notification);
|
||||
|
@ -55,11 +55,11 @@ export function useToast() {
|
|||
duration?: number;
|
||||
customClass?: string;
|
||||
closeOnClick?: boolean;
|
||||
type?: MessageType;
|
||||
type?: MessageBoxState['type'];
|
||||
dangerouslyUseHTMLString?: boolean;
|
||||
}) {
|
||||
// eslint-disable-next-line prefer-const
|
||||
let notification: ElNotificationComponent;
|
||||
let notification: NotificationInstance;
|
||||
if (config.closeOnClick) {
|
||||
const cb = config.onClick;
|
||||
config.onClick = () => {
|
||||
|
@ -138,7 +138,7 @@ export function useToast() {
|
|||
});
|
||||
}
|
||||
|
||||
function showAlert(config: ElNotificationOptions): ElNotificationComponent {
|
||||
function showAlert(config: NotificationOptions): NotificationInstance {
|
||||
return Notification(config);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// The Vue build version to load with the `import` command
|
||||
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
|
||||
import Vue from 'vue';
|
||||
import { createApp } from 'vue';
|
||||
|
||||
import 'vue-json-pretty/lib/styles.css';
|
||||
import '@jsplumb/browser-ui/css/jsplumbtoolkit.css';
|
||||
|
@ -26,24 +26,30 @@ import { runExternalHook } from '@/utils';
|
|||
import { createPinia, PiniaVuePlugin } from 'pinia';
|
||||
import { useWebhooksStore } from '@/stores';
|
||||
|
||||
Vue.config.productionTip = false;
|
||||
|
||||
Vue.use(TelemetryPlugin);
|
||||
Vue.use(PiniaVuePlugin);
|
||||
|
||||
Vue.use(I18nPlugin);
|
||||
Vue.use(FontAwesomePlugin);
|
||||
Vue.use(GlobalComponentsPlugin);
|
||||
Vue.use(GlobalDirectivesPlugin);
|
||||
|
||||
const pinia = createPinia();
|
||||
|
||||
new Vue({
|
||||
i18n: i18nInstance,
|
||||
router,
|
||||
pinia,
|
||||
render: (h) => h(App),
|
||||
}).$mount('#app');
|
||||
const app = createApp(App);
|
||||
|
||||
// Vue.config.productionTip = false;
|
||||
|
||||
app.use(TelemetryPlugin);
|
||||
app.use(PiniaVuePlugin);
|
||||
app.use(I18nPlugin);
|
||||
app.use(FontAwesomePlugin);
|
||||
app.use(GlobalComponentsPlugin);
|
||||
app.use(GlobalDirectivesPlugin);
|
||||
app.use(pinia);
|
||||
app.use(router);
|
||||
app.use(i18nInstance);
|
||||
|
||||
app.mount('#app');
|
||||
|
||||
// new Vue({
|
||||
// i18n: i18nInstance,
|
||||
// router,
|
||||
// pinia,
|
||||
// render: (h) => h(App),
|
||||
// }).$mount('#app');
|
||||
|
||||
router.afterEach((to, from) => {
|
||||
void runExternalHook('main.routeChange', useWebhooksStore(), { from, to });
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import Vue from 'vue';
|
||||
import { defineComponent } from 'vue';
|
||||
import type { INodeUi } from '@/Interface';
|
||||
import type { INodeTypeDescription, IPinData } from 'n8n-workflow';
|
||||
import { stringSizeInBytes } from '@/utils';
|
||||
|
@ -13,7 +13,7 @@ export interface IPinDataContext {
|
|||
$showError(error: Error, title: string): void;
|
||||
}
|
||||
|
||||
export const pinData = (Vue as Vue.VueConstructor<Vue & IPinDataContext>).extend({
|
||||
export const pinData = defineComponent({
|
||||
setup() {
|
||||
return {
|
||||
...useToast(),
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue