mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
feat: Replace Vue.extend with defineComponent in editor-ui (no-changelog) (#6033)
* refactor: replace Vue.extend with defineComponent in editor-ui * fix: change $externalHooks extractions from mixins * fix: refactor externalHooks mixin
This commit is contained in:
parent
8a38624cbc
commit
9c94050deb
|
@ -1,4 +1,6 @@
|
||||||
import { ISettingsState, UserManagementAuthenticationMethod } from '@/Interface';
|
import { ISettingsState, UserManagementAuthenticationMethod } from '@/Interface';
|
||||||
|
import { render } from '@testing-library/vue';
|
||||||
|
import { PiniaVuePlugin } from 'pinia';
|
||||||
|
|
||||||
export const retry = (assertion: () => any, { interval = 20, timeout = 200 } = {}) => {
|
export const retry = (assertion: () => any, { interval = 20, timeout = 200 } = {}) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
@ -18,6 +20,12 @@ export const retry = (assertion: () => any, { interval = 20, timeout = 200 } = {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type RenderParams = Parameters<typeof render>;
|
||||||
|
export const renderComponent = (Component: RenderParams[0], renderOptions: RenderParams[1] = {}) =>
|
||||||
|
render(Component, renderOptions, (vue) => {
|
||||||
|
vue.use(PiniaVuePlugin);
|
||||||
|
});
|
||||||
|
|
||||||
export const waitAllPromises = () => new Promise((resolve) => setTimeout(resolve));
|
export const waitAllPromises = () => new Promise((resolve) => setTimeout(resolve));
|
||||||
|
|
||||||
export const SETTINGS_STORE_DEFAULT_STATE: ISettingsState = {
|
export const SETTINGS_STORE_DEFAULT_STATE: ISettingsState = {
|
||||||
|
|
|
@ -54,7 +54,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import Modal from './Modal.vue';
|
import Modal from './Modal.vue';
|
||||||
import { ABOUT_MODAL_KEY } from '../constants';
|
import { ABOUT_MODAL_KEY } from '../constants';
|
||||||
import { mapStores } from 'pinia';
|
import { mapStores } from 'pinia';
|
||||||
|
@ -62,7 +62,7 @@ import { useSettingsStore } from '@/stores/settings';
|
||||||
import { useRootStore } from '@/stores/n8nRootStore';
|
import { useRootStore } from '@/stores/n8nRootStore';
|
||||||
import { createEventBus } from '@/event-bus';
|
import { createEventBus } from '@/event-bus';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'About',
|
name: 'About',
|
||||||
components: {
|
components: {
|
||||||
Modal,
|
Modal,
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
import Modal from '@/components/Modal.vue';
|
import Modal from '@/components/Modal.vue';
|
||||||
import {
|
import {
|
||||||
|
@ -51,7 +51,7 @@ import { useWorkflowsStore } from '@/stores/workflows';
|
||||||
import { useNodeTypesStore } from '@/stores/nodeTypes';
|
import { useNodeTypesStore } from '@/stores/nodeTypes';
|
||||||
import { createEventBus } from '@/event-bus';
|
import { createEventBus } from '@/event-bus';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'ActivationModal',
|
name: 'ActivationModal',
|
||||||
components: {
|
components: {
|
||||||
Modal,
|
Modal,
|
||||||
|
|
|
@ -23,12 +23,12 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import Modal from './Modal.vue';
|
import Modal from './Modal.vue';
|
||||||
import { ASK_AI_MODAL_KEY, ASK_AI_WAITLIST_URL } from '../constants';
|
import { ASK_AI_MODAL_KEY, ASK_AI_WAITLIST_URL } from '../constants';
|
||||||
import { createEventBus } from '@/event-bus';
|
import { createEventBus } from '@/event-bus';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'AskAI',
|
name: 'AskAI',
|
||||||
components: {
|
components: {
|
||||||
Modal,
|
Modal,
|
||||||
|
|
|
@ -36,9 +36,9 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'Banner',
|
name: 'Banner',
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -68,12 +68,12 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
import TimeAgo from '../TimeAgo.vue';
|
import TimeAgo from '../TimeAgo.vue';
|
||||||
import { INodeTypeDescription } from 'n8n-workflow';
|
import { INodeTypeDescription } from 'n8n-workflow';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'CredentialInfo',
|
name: 'CredentialInfo',
|
||||||
props: ['nodesWithAccess', 'nodeAccess', 'currentCredential', 'credentialPermissions'],
|
props: ['nodesWithAccess', 'nodeAccess', 'currentCredential', 'credentialPermissions'],
|
||||||
components: {
|
components: {
|
||||||
|
|
|
@ -24,12 +24,12 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { IParameterLabel } from 'n8n-workflow';
|
import { IParameterLabel } from 'n8n-workflow';
|
||||||
import { IUpdateInformation } from '@/Interface';
|
import { IUpdateInformation } from '@/Interface';
|
||||||
import ParameterInputExpanded from '../ParameterInputExpanded.vue';
|
import ParameterInputExpanded from '../ParameterInputExpanded.vue';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'CredentialsInput',
|
name: 'CredentialsInput',
|
||||||
props: [
|
props: [
|
||||||
'credentialProperties',
|
'credentialProperties',
|
||||||
|
|
|
@ -12,9 +12,9 @@ import { useRootStore } from '@/stores/n8nRootStore';
|
||||||
import { useNodeTypesStore } from '@/stores/nodeTypes';
|
import { useNodeTypesStore } from '@/stores/nodeTypes';
|
||||||
import { ICredentialType, INodeTypeDescription } from 'n8n-workflow';
|
import { ICredentialType, INodeTypeDescription } from 'n8n-workflow';
|
||||||
import { mapStores } from 'pinia';
|
import { mapStores } from 'pinia';
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
props: {
|
props: {
|
||||||
credentialTypeName: {
|
credentialTypeName: {
|
||||||
type: String,
|
type: String,
|
||||||
|
|
|
@ -56,7 +56,7 @@
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { ICredentialType } from 'n8n-workflow';
|
import { ICredentialType } from 'n8n-workflow';
|
||||||
import Vue from 'vue';
|
import Vue, { defineComponent } from 'vue';
|
||||||
import ScopesNotice from '@/components/ScopesNotice.vue';
|
import ScopesNotice from '@/components/ScopesNotice.vue';
|
||||||
import NodeCredentials from '@/components/NodeCredentials.vue';
|
import NodeCredentials from '@/components/NodeCredentials.vue';
|
||||||
import { mapStores } from 'pinia';
|
import { mapStores } from 'pinia';
|
||||||
|
@ -65,7 +65,7 @@ import { N8nSelect } from 'n8n-design-system';
|
||||||
|
|
||||||
type N8nSelectRef = InstanceType<typeof N8nSelect>;
|
type N8nSelectRef = InstanceType<typeof N8nSelect>;
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'CredentialsSelect',
|
name: 'CredentialsSelect',
|
||||||
components: {
|
components: {
|
||||||
ScopesNotice,
|
ScopesNotice,
|
||||||
|
|
|
@ -19,12 +19,12 @@
|
||||||
import { XYPosition } from '@/Interface';
|
import { XYPosition } from '@/Interface';
|
||||||
import { useNDVStore } from '@/stores/ndv';
|
import { useNDVStore } from '@/stores/ndv';
|
||||||
import { mapStores } from 'pinia';
|
import { mapStores } from 'pinia';
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import Teleport from 'vue2-teleport';
|
import Teleport from 'vue2-teleport';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'draggable',
|
name: 'draggable',
|
||||||
components: {
|
components: {
|
||||||
Teleport,
|
Teleport,
|
||||||
|
|
|
@ -7,9 +7,10 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { useNDVStore } from '@/stores/ndv';
|
import { useNDVStore } from '@/stores/ndv';
|
||||||
import { mapStores } from 'pinia';
|
import { mapStores } from 'pinia';
|
||||||
import Vue, { PropType } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
import type { PropType } from 'vue';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
props: {
|
props: {
|
||||||
type: {
|
type: {
|
||||||
type: String,
|
type: String,
|
||||||
|
|
|
@ -6,12 +6,12 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { EnterpriseEditionFeature } from '@/constants';
|
import { EnterpriseEditionFeature } from '@/constants';
|
||||||
import { mapStores } from 'pinia';
|
import { mapStores } from 'pinia';
|
||||||
import { useSettingsStore } from '@/stores/settings';
|
import { useSettingsStore } from '@/stores/settings';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'EnterpriseEdition',
|
name: 'EnterpriseEdition',
|
||||||
props: {
|
props: {
|
||||||
features: {
|
features: {
|
||||||
|
|
|
@ -7,13 +7,13 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import ExecutionsList from '@/components/ExecutionsList.vue';
|
import ExecutionsList from '@/components/ExecutionsList.vue';
|
||||||
import Modal from '@/components/Modal.vue';
|
import Modal from '@/components/Modal.vue';
|
||||||
import { EXECUTIONS_MODAL_KEY } from '@/constants';
|
import { EXECUTIONS_MODAL_KEY } from '@/constants';
|
||||||
import { createEventBus } from '@/event-bus';
|
import { createEventBus } from '@/event-bus';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'ExecutionsModal',
|
name: 'ExecutionsModal',
|
||||||
components: {
|
components: {
|
||||||
Modal,
|
Modal,
|
||||||
|
|
|
@ -27,10 +27,10 @@ import { PLACEHOLDER_EMPTY_WORKFLOW_ID, VIEWS } from '@/constants';
|
||||||
import { useUIStore } from '@/stores/ui';
|
import { useUIStore } from '@/stores/ui';
|
||||||
import { useWorkflowsStore } from '@/stores/workflows';
|
import { useWorkflowsStore } from '@/stores/workflows';
|
||||||
import { mapStores } from 'pinia';
|
import { mapStores } from 'pinia';
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import ExecutionsInfoAccordion from './ExecutionsInfoAccordion.vue';
|
import ExecutionsInfoAccordion from './ExecutionsInfoAccordion.vue';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'executions-landing-page',
|
name: 'executions-landing-page',
|
||||||
components: {
|
components: {
|
||||||
ExecutionsInfoAccordion,
|
ExecutionsInfoAccordion,
|
||||||
|
|
|
@ -70,7 +70,7 @@ import ExecutionFilter from '@/components/ExecutionFilter.vue';
|
||||||
import { VIEWS } from '@/constants';
|
import { VIEWS } from '@/constants';
|
||||||
import type { IExecutionsSummary } from 'n8n-workflow';
|
import type { IExecutionsSummary } from 'n8n-workflow';
|
||||||
import { Route } from 'vue-router';
|
import { Route } from 'vue-router';
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { PropType } from 'vue';
|
import { PropType } from 'vue';
|
||||||
import { mapStores } from 'pinia';
|
import { mapStores } from 'pinia';
|
||||||
import { useUIStore } from '@/stores/ui';
|
import { useUIStore } from '@/stores/ui';
|
||||||
|
@ -79,7 +79,7 @@ import { ExecutionFilterType } from '@/Interface';
|
||||||
|
|
||||||
type ExecutionCardRef = InstanceType<typeof ExecutionCard>;
|
type ExecutionCardRef = InstanceType<typeof ExecutionCard>;
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'executions-sidebar',
|
name: 'executions-sidebar',
|
||||||
components: {
|
components: {
|
||||||
ExecutionCard,
|
ExecutionCard,
|
||||||
|
|
|
@ -6,9 +6,9 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'ExpandableInputBase',
|
name: 'ExpandableInputBase',
|
||||||
props: ['value', 'placeholder', 'staticSize'],
|
props: ['value', 'placeholder', 'staticSize'],
|
||||||
computed: {
|
computed: {
|
||||||
|
|
|
@ -16,11 +16,12 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue, { PropType } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import ExpandableInputBase from './ExpandableInputBase.vue';
|
import ExpandableInputBase from './ExpandableInputBase.vue';
|
||||||
import { EventBus } from '@/event-bus';
|
import type { PropType } from 'vue';
|
||||||
|
import type { EventBus } from '@/event-bus';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
components: { ExpandableInputBase },
|
components: { ExpandableInputBase },
|
||||||
name: 'ExpandableInputEdit',
|
name: 'ExpandableInputEdit',
|
||||||
props: {
|
props: {
|
||||||
|
|
|
@ -12,10 +12,10 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import ExpandableInputBase from './ExpandableInputBase.vue';
|
import ExpandableInputBase from './ExpandableInputBase.vue';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
components: { ExpandableInputBase },
|
components: { ExpandableInputBase },
|
||||||
name: 'ExpandableInputPreview',
|
name: 'ExpandableInputPreview',
|
||||||
props: ['value'],
|
props: ['value'],
|
||||||
|
|
|
@ -3,9 +3,10 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue, { PropType } from 'vue';
|
|
||||||
import { EditorView } from '@codemirror/view';
|
import { EditorView } from '@codemirror/view';
|
||||||
import { EditorState } from '@codemirror/state';
|
import { EditorState } from '@codemirror/state';
|
||||||
|
import { defineComponent } from 'vue';
|
||||||
|
import type { PropType } from 'vue';
|
||||||
|
|
||||||
import { highlighter } from '@/plugins/codemirror/resolvableHighlighter';
|
import { highlighter } from '@/plugins/codemirror/resolvableHighlighter';
|
||||||
import { outputTheme } from './theme';
|
import { outputTheme } from './theme';
|
||||||
|
@ -13,7 +14,7 @@ import { outputTheme } from './theme';
|
||||||
import type { Plaintext, Resolved, Segment } from '@/types/expressions';
|
import type { Plaintext, Resolved, Segment } from '@/types/expressions';
|
||||||
import { forceParse } from '@/utils/forceParse';
|
import { forceParse } from '@/utils/forceParse';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'ExpressionEditorModalOutput',
|
name: 'ExpressionEditorModalOutput',
|
||||||
props: {
|
props: {
|
||||||
segments: {
|
segments: {
|
||||||
|
|
|
@ -66,7 +66,7 @@
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { mapStores } from 'pinia';
|
import { mapStores } from 'pinia';
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
import { useNDVStore } from '@/stores/ndv';
|
import { useNDVStore } from '@/stores/ndv';
|
||||||
import { useWorkflowsStore } from '@/stores/workflows';
|
import { useWorkflowsStore } from '@/stores/workflows';
|
||||||
|
@ -81,7 +81,7 @@ import type { TargetItem } from '@/Interface';
|
||||||
|
|
||||||
type InlineExpressionEditorInputRef = InstanceType<typeof InlineExpressionEditorInput>;
|
type InlineExpressionEditorInputRef = InstanceType<typeof InlineExpressionEditorInput>;
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'ExpressionParameterInput',
|
name: 'ExpressionParameterInput',
|
||||||
components: {
|
components: {
|
||||||
InlineExpressionEditorInput,
|
InlineExpressionEditorInput,
|
||||||
|
|
|
@ -35,9 +35,9 @@ import { useSettingsStore } from '@/stores/settings';
|
||||||
import { useUIStore } from '@/stores/ui';
|
import { useUIStore } from '@/stores/ui';
|
||||||
import { useUsersStore } from '@/stores/users';
|
import { useUsersStore } from '@/stores/users';
|
||||||
import { mapStores } from 'pinia';
|
import { mapStores } from 'pinia';
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'FeatureComingSoon',
|
name: 'FeatureComingSoon',
|
||||||
props: {
|
props: {
|
||||||
featureId: {
|
featureId: {
|
||||||
|
|
|
@ -112,21 +112,21 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue, { Component, PropType } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { IUpdateInformation } from '@/Interface';
|
import type { Component, PropType } from 'vue';
|
||||||
|
import type { IUpdateInformation } from '@/Interface';
|
||||||
|
|
||||||
import {
|
import { deepCopy, isINodePropertyCollectionList } from 'n8n-workflow';
|
||||||
|
import type {
|
||||||
INodeParameters,
|
INodeParameters,
|
||||||
INodeProperties,
|
INodeProperties,
|
||||||
INodePropertyCollection,
|
INodePropertyCollection,
|
||||||
NodeParameterValue,
|
NodeParameterValue,
|
||||||
deepCopy,
|
|
||||||
isINodePropertyCollectionList,
|
|
||||||
} from 'n8n-workflow';
|
} from 'n8n-workflow';
|
||||||
|
|
||||||
import { get } from 'lodash-es';
|
import { get } from 'lodash-es';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'FixedCollectionParameter',
|
name: 'FixedCollectionParameter',
|
||||||
props: {
|
props: {
|
||||||
nodeValues: {
|
nodeValues: {
|
||||||
|
|
|
@ -7,9 +7,9 @@
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { VIEWS } from '@/constants';
|
import { VIEWS } from '@/constants';
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'GoBackButton',
|
name: 'GoBackButton',
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
import { ITemplatesNode } from '@/Interface';
|
import { ITemplatesNode } from '@/Interface';
|
||||||
import { INodeTypeDescription } from 'n8n-workflow';
|
import { INodeTypeDescription } from 'n8n-workflow';
|
||||||
|
@ -54,7 +54,7 @@ interface NodeIconData {
|
||||||
fileBuffer?: string;
|
fileBuffer?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'HoverableNodeIcon',
|
name: 'HoverableNodeIcon',
|
||||||
props: {
|
props: {
|
||||||
circle: {
|
circle: {
|
||||||
|
|
|
@ -3,16 +3,18 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue, { PropType } from 'vue';
|
|
||||||
import { EditorView } from '@codemirror/view';
|
import { EditorView } from '@codemirror/view';
|
||||||
import { EditorState } from '@codemirror/state';
|
import { EditorState } from '@codemirror/state';
|
||||||
|
|
||||||
|
import { defineComponent } from 'vue';
|
||||||
|
import type { PropType } from 'vue';
|
||||||
|
|
||||||
import { highlighter } from '@/plugins/codemirror/resolvableHighlighter';
|
import { highlighter } from '@/plugins/codemirror/resolvableHighlighter';
|
||||||
import { outputTheme } from './theme';
|
import { outputTheme } from './theme';
|
||||||
|
|
||||||
import type { Plaintext, Resolved, Segment } from '@/types/expressions';
|
import type { Plaintext, Resolved, Segment } from '@/types/expressions';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'InlineExpressionEditorOutput',
|
name: 'InlineExpressionEditorOutput',
|
||||||
props: {
|
props: {
|
||||||
segments: {
|
segments: {
|
||||||
|
|
|
@ -21,12 +21,12 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import ExpandableInputEdit from '@/components/ExpandableInput/ExpandableInputEdit.vue';
|
import ExpandableInputEdit from '@/components/ExpandableInput/ExpandableInputEdit.vue';
|
||||||
import ExpandableInputPreview from '@/components/ExpandableInput/ExpandableInputPreview.vue';
|
import ExpandableInputPreview from '@/components/ExpandableInput/ExpandableInputPreview.vue';
|
||||||
import { createEventBus } from '@/event-bus';
|
import { createEventBus } from '@/event-bus';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'InlineTextEdit',
|
name: 'InlineTextEdit',
|
||||||
components: { ExpandableInputEdit, ExpandableInputPreview },
|
components: { ExpandableInputEdit, ExpandableInputPreview },
|
||||||
props: ['isEditEnabled', 'value', 'placeholder', 'maxLength', 'previewValue'],
|
props: ['isEditEnabled', 'value', 'placeholder', 'maxLength', 'previewValue'],
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'IntersectionObserver',
|
name: 'IntersectionObserver',
|
||||||
props: ['threshold', 'enabled'],
|
props: ['threshold', 'enabled'],
|
||||||
data() {
|
data() {
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { useRootStore } from '@/stores/n8nRootStore';
|
import { useRootStore } from '@/stores/n8nRootStore';
|
||||||
import { mapStores } from 'pinia';
|
import { mapStores } from 'pinia';
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
computed: {
|
computed: {
|
||||||
...mapStores(useRootStore),
|
...mapStores(useRootStore),
|
||||||
basePath(): string {
|
basePath(): string {
|
||||||
|
|
|
@ -12,13 +12,14 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue, { PropType } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { ITabBarItem } from '@/Interface';
|
import type { PropType } from 'vue';
|
||||||
|
import type { ITabBarItem } from '@/Interface';
|
||||||
import { MAIN_HEADER_TABS } from '@/constants';
|
import { MAIN_HEADER_TABS } from '@/constants';
|
||||||
import { mapStores } from 'pinia';
|
import { mapStores } from 'pinia';
|
||||||
import { useUIStore } from '@/stores/ui';
|
import { useUIStore } from '@/stores/ui';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'tab-bar',
|
name: 'tab-bar',
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -43,12 +43,13 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue, { PropType } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
import type { PropType } from 'vue';
|
||||||
import { useUIStore } from '@/stores/ui';
|
import { useUIStore } from '@/stores/ui';
|
||||||
import { mapStores } from 'pinia';
|
import { mapStores } from 'pinia';
|
||||||
import { EventBus } from '@/event-bus';
|
import type { EventBus } from '@/event-bus';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'Modal',
|
name: 'Modal',
|
||||||
props: {
|
props: {
|
||||||
name: {
|
name: {
|
||||||
|
|
|
@ -21,10 +21,11 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { useUIStore } from '@/stores/ui';
|
import { useUIStore } from '@/stores/ui';
|
||||||
import { mapStores } from 'pinia';
|
import { mapStores } from 'pinia';
|
||||||
import Vue, { PropType } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { EventBus } from '@/event-bus';
|
import type { PropType } from 'vue';
|
||||||
|
import type { EventBus } from '@/event-bus';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'ModalDrawer',
|
name: 'ModalDrawer',
|
||||||
props: {
|
props: {
|
||||||
name: {
|
name: {
|
||||||
|
|
|
@ -12,11 +12,11 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { useUIStore } from '@/stores/ui';
|
import { useUIStore } from '@/stores/ui';
|
||||||
import { mapStores } from 'pinia';
|
import { mapStores } from 'pinia';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'ModalRoot',
|
name: 'ModalRoot',
|
||||||
props: {
|
props: {
|
||||||
name: {
|
name: {
|
||||||
|
|
|
@ -119,7 +119,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import {
|
import {
|
||||||
ABOUT_MODAL_KEY,
|
ABOUT_MODAL_KEY,
|
||||||
CHANGE_PASSWORD_MODAL_KEY,
|
CHANGE_PASSWORD_MODAL_KEY,
|
||||||
|
@ -171,7 +171,7 @@ import WorkflowShareModal from './WorkflowShareModal.ee.vue';
|
||||||
import WorkflowSuccessModal from './UserActivationSurveyModal.vue';
|
import WorkflowSuccessModal from './UserActivationSurveyModal.vue';
|
||||||
import EventDestinationSettingsModal from '@/components/SettingsLogStreaming/EventDestinationSettingsModal.ee.vue';
|
import EventDestinationSettingsModal from '@/components/SettingsLogStreaming/EventDestinationSettingsModal.ee.vue';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'Modals',
|
name: 'Modals',
|
||||||
components: {
|
components: {
|
||||||
AboutModal,
|
AboutModal,
|
||||||
|
|
|
@ -84,15 +84,16 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue, { PropType } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { IUpdateInformation } from '@/Interface';
|
import type { PropType } from 'vue';
|
||||||
|
import type { IUpdateInformation } from '@/Interface';
|
||||||
import { deepCopy, INodeParameters, INodeProperties } from 'n8n-workflow';
|
import { deepCopy, INodeParameters, INodeProperties } from 'n8n-workflow';
|
||||||
import CollectionParameter from '@/components/CollectionParameter.vue';
|
import CollectionParameter from '@/components/CollectionParameter.vue';
|
||||||
import ParameterInputFull from '@/components/ParameterInputFull.vue';
|
import ParameterInputFull from '@/components/ParameterInputFull.vue';
|
||||||
|
|
||||||
import { get } from 'lodash-es';
|
import { get } from 'lodash-es';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'MultipleParameter',
|
name: 'MultipleParameter',
|
||||||
components: {
|
components: {
|
||||||
CollectionParameter,
|
CollectionParameter,
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { getMidCanvasPosition } from '@/utils/nodeViewUtils';
|
import { getMidCanvasPosition } from '@/utils/nodeViewUtils';
|
||||||
import {
|
import {
|
||||||
DEFAULT_STICKY_HEIGHT,
|
DEFAULT_STICKY_HEIGHT,
|
||||||
|
@ -48,7 +48,7 @@ import {
|
||||||
import { mapStores } from 'pinia';
|
import { mapStores } from 'pinia';
|
||||||
import { useUIStore } from '@/stores/ui';
|
import { useUIStore } from '@/stores/ui';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'node-creation',
|
name: 'node-creation',
|
||||||
components: {
|
components: {
|
||||||
NodeCreator: () => import('@/components/Node/NodeCreator/NodeCreator.vue'),
|
NodeCreator: () => import('@/components/Node/NodeCreator/NodeCreator.vue'),
|
||||||
|
|
|
@ -96,7 +96,6 @@ import {
|
||||||
nextTick,
|
nextTick,
|
||||||
} from 'vue';
|
} from 'vue';
|
||||||
import { camelCase } from 'lodash-es';
|
import { camelCase } from 'lodash-es';
|
||||||
import { externalHooks } from '@/mixins/externalHooks';
|
|
||||||
import { INodeTypeDescription } from 'n8n-workflow';
|
import { INodeTypeDescription } from 'n8n-workflow';
|
||||||
import ItemIterator from './ItemIterator.vue';
|
import ItemIterator from './ItemIterator.vue';
|
||||||
import SearchBar from './SearchBar.vue';
|
import SearchBar from './SearchBar.vue';
|
||||||
|
@ -114,6 +113,7 @@ import { sublimeSearch, matchesNodeType, matchesSelectType } from '@/utils';
|
||||||
import { useWorkflowsStore } from '@/stores/workflows';
|
import { useWorkflowsStore } from '@/stores/workflows';
|
||||||
import { useRootStore } from '@/stores/n8nRootStore';
|
import { useRootStore } from '@/stores/n8nRootStore';
|
||||||
import { useNodeCreatorStore } from '@/stores/nodeCreator';
|
import { useNodeCreatorStore } from '@/stores/nodeCreator';
|
||||||
|
import { useExternalHooks } from '@/composables';
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
showSubcategoryIcon?: boolean;
|
showSubcategoryIcon?: boolean;
|
||||||
|
@ -148,7 +148,7 @@ const emit = defineEmits<{
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const instance = getCurrentInstance();
|
const instance = getCurrentInstance();
|
||||||
const { $externalHooks } = new externalHooks();
|
const externalHooks = useExternalHooks();
|
||||||
|
|
||||||
const { defaultLocale } = useRootStore();
|
const { defaultLocale } = useRootStore();
|
||||||
const { workflowId } = useWorkflowsStore();
|
const { workflowId } = useWorkflowsStore();
|
||||||
|
@ -549,7 +549,7 @@ onUnmounted(() => {
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(filteredNodeTypes, (returnItems) => {
|
watch(filteredNodeTypes, (returnItems) => {
|
||||||
$externalHooks().run('nodeCreateList.filteredNodeTypesComputed', {
|
externalHooks.run('nodeCreateList.filteredNodeTypesComputed', {
|
||||||
nodeFilter: nodeCreatorStore.itemsFilter,
|
nodeFilter: nodeCreatorStore.itemsFilter,
|
||||||
result: returnItems,
|
result: returnItems,
|
||||||
selectedType: nodeCreatorStore.selectedView,
|
selectedType: nodeCreatorStore.selectedView,
|
||||||
|
@ -569,7 +569,7 @@ watch(
|
||||||
// Reset the index whenver the filter-value changes
|
// Reset the index whenver the filter-value changes
|
||||||
state.activeIndex = 0;
|
state.activeIndex = 0;
|
||||||
state.activeSubcategoryIndex = 0;
|
state.activeSubcategoryIndex = 0;
|
||||||
$externalHooks().run('nodeCreateList.nodeFilterChanged', {
|
externalHooks.run('nodeCreateList.nodeFilterChanged', {
|
||||||
oldValue,
|
oldValue,
|
||||||
newValue,
|
newValue,
|
||||||
selectedType: nodeCreatorStore.selectedView,
|
selectedType: nodeCreatorStore.selectedView,
|
||||||
|
|
|
@ -105,12 +105,12 @@ import {
|
||||||
import CategorizedItems from './CategorizedItems.vue';
|
import CategorizedItems from './CategorizedItems.vue';
|
||||||
import { useNodeCreatorStore } from '@/stores/nodeCreator';
|
import { useNodeCreatorStore } from '@/stores/nodeCreator';
|
||||||
import { getCategoriesWithNodes, getCategorizedList } from '@/utils';
|
import { getCategoriesWithNodes, getCategorizedList } from '@/utils';
|
||||||
import { externalHooks } from '@/mixins/externalHooks';
|
|
||||||
import { useNodeTypesStore } from '@/stores/nodeTypes';
|
import { useNodeTypesStore } from '@/stores/nodeTypes';
|
||||||
import { BaseTextKey } from '@/plugins/i18n';
|
import { BaseTextKey } from '@/plugins/i18n';
|
||||||
import NoResults from './NoResults.vue';
|
import NoResults from './NoResults.vue';
|
||||||
import { useRootStore } from '@/stores/n8nRootStore';
|
import { useRootStore } from '@/stores/n8nRootStore';
|
||||||
import useMainPanelView from './useMainPanelView';
|
import useMainPanelView from './useMainPanelView';
|
||||||
|
import { useExternalHooks } from '@/composables';
|
||||||
|
|
||||||
const instance = getCurrentInstance();
|
const instance = getCurrentInstance();
|
||||||
|
|
||||||
|
@ -124,7 +124,8 @@ const state = reactive({
|
||||||
activeNodeActions: null as INodeTypeDescription | null,
|
activeNodeActions: null as INodeTypeDescription | null,
|
||||||
});
|
});
|
||||||
const { baseUrl } = useRootStore();
|
const { baseUrl } = useRootStore();
|
||||||
const { $externalHooks } = new externalHooks();
|
const externalHooks = useExternalHooks();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
mergedAppNodes,
|
mergedAppNodes,
|
||||||
getActionData,
|
getActionData,
|
||||||
|
@ -324,7 +325,7 @@ function addHttpNode(isAction: boolean) {
|
||||||
setAddedNodeActionParameters(updateData, telemetry, false);
|
setAddedNodeActionParameters(updateData, telemetry, false);
|
||||||
|
|
||||||
const app_identifier = state.activeNodeActions?.name;
|
const app_identifier = state.activeNodeActions?.name;
|
||||||
$externalHooks().run('nodeCreateList.onActionsCustmAPIClicked', { app_identifier });
|
externalHooks.run('nodeCreateList.onActionsCustmAPIClicked', { app_identifier });
|
||||||
telemetry?.trackNodesPanel('nodeCreateList.onActionsCustmAPIClicked', { app_identifier });
|
telemetry?.trackNodesPanel('nodeCreateList.onActionsCustmAPIClicked', { app_identifier });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -362,7 +363,7 @@ function trackActionsView() {
|
||||||
trigger_action_count,
|
trigger_action_count,
|
||||||
};
|
};
|
||||||
|
|
||||||
$externalHooks().run('nodeCreateList.onViewActions', trackingPayload);
|
externalHooks.run('nodeCreateList.onViewActions', trackingPayload);
|
||||||
telemetry?.trackNodesPanel('nodeCreateList.onViewActions', trackingPayload);
|
telemetry?.trackNodesPanel('nodeCreateList.onViewActions', trackingPayload);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,8 +25,8 @@
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, reactive, toRefs, onBeforeUnmount } from 'vue';
|
import { onMounted, reactive, toRefs, onBeforeUnmount } from 'vue';
|
||||||
import { externalHooks } from '@/mixins/externalHooks';
|
|
||||||
import { EventBus } from '@/event-bus';
|
import { EventBus } from '@/event-bus';
|
||||||
|
import { useExternalHooks } from '@/composables';
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
placeholder: string;
|
placeholder: string;
|
||||||
|
@ -43,7 +43,7 @@ const emit = defineEmits<{
|
||||||
(event: 'input', value: string): void;
|
(event: 'input', value: string): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const { $externalHooks } = new externalHooks();
|
const externalHooks = useExternalHooks();
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
inputRef: null as HTMLInputElement | null,
|
inputRef: null as HTMLInputElement | null,
|
||||||
|
@ -63,7 +63,7 @@ function clear() {
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
$externalHooks().run('nodeCreator_searchBar.mount', { inputRef: state.inputRef });
|
externalHooks.run('nodeCreator_searchBar.mount', { inputRef: state.inputRef });
|
||||||
setTimeout(focus, 0);
|
setTimeout(focus, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ import { IVersionNode } from '@/Interface';
|
||||||
import { useRootStore } from '@/stores/n8nRootStore';
|
import { useRootStore } from '@/stores/n8nRootStore';
|
||||||
import { INodeTypeDescription } from 'n8n-workflow';
|
import { INodeTypeDescription } from 'n8n-workflow';
|
||||||
import { mapStores } from 'pinia';
|
import { mapStores } from 'pinia';
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
interface NodeIconSource {
|
interface NodeIconSource {
|
||||||
path?: string;
|
path?: string;
|
||||||
|
@ -26,7 +26,7 @@ interface NodeIconSource {
|
||||||
icon?: string;
|
icon?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'NodeIcon',
|
name: 'NodeIcon',
|
||||||
props: {
|
props: {
|
||||||
nodeType: {},
|
nodeType: {},
|
||||||
|
|
|
@ -40,9 +40,9 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'NodeTitle',
|
name: 'NodeTitle',
|
||||||
props: {
|
props: {
|
||||||
value: {
|
value: {
|
||||||
|
|
|
@ -9,9 +9,9 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'PageContentWrapper',
|
name: 'PageContentWrapper',
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -42,10 +42,10 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import Draggable from './Draggable.vue';
|
import Draggable from './Draggable.vue';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
Draggable,
|
Draggable,
|
||||||
},
|
},
|
||||||
|
|
|
@ -58,7 +58,8 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { IUpdateInformation } from '@/Interface';
|
import { IUpdateInformation } from '@/Interface';
|
||||||
import ParameterOptions from './ParameterOptions.vue';
|
import ParameterOptions from './ParameterOptions.vue';
|
||||||
import Vue, { PropType } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
import type { PropType } from 'vue';
|
||||||
import ParameterInputWrapper from './ParameterInputWrapper.vue';
|
import ParameterInputWrapper from './ParameterInputWrapper.vue';
|
||||||
import { isValueExpression } from '@/utils';
|
import { isValueExpression } from '@/utils';
|
||||||
import { INodeParameterResourceLocator, INodeProperties, IParameterLabel } from 'n8n-workflow';
|
import { INodeParameterResourceLocator, INodeProperties, IParameterLabel } from 'n8n-workflow';
|
||||||
|
@ -67,7 +68,7 @@ import { useWorkflowsStore } from '@/stores/workflows';
|
||||||
|
|
||||||
type ParamRef = InstanceType<typeof ParameterInputWrapper>;
|
type ParamRef = InstanceType<typeof ParameterInputWrapper>;
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'parameter-input-expanded',
|
name: 'parameter-input-expanded',
|
||||||
components: {
|
components: {
|
||||||
ParameterOptions,
|
ParameterOptions,
|
||||||
|
|
|
@ -17,9 +17,9 @@
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { sanitizeHtml } from '@/utils';
|
import { sanitizeHtml } from '@/utils';
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'InputHint',
|
name: 'InputHint',
|
||||||
props: {
|
props: {
|
||||||
hint: {
|
hint: {
|
||||||
|
|
|
@ -10,10 +10,10 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import TitledList from '@/components/TitledList.vue';
|
import TitledList from '@/components/TitledList.vue';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'ParameterIssues',
|
name: 'ParameterIssues',
|
||||||
components: {
|
components: {
|
||||||
TitledList,
|
TitledList,
|
||||||
|
|
|
@ -25,11 +25,12 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { NodeParameterValueType } from 'n8n-workflow';
|
import type { NodeParameterValueType } from 'n8n-workflow';
|
||||||
import Vue, { PropType } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
import type { PropType } from 'vue';
|
||||||
import { isValueExpression, isResourceLocatorValue } from '@/utils';
|
import { isValueExpression, isResourceLocatorValue } from '@/utils';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'parameter-options',
|
name: 'parameter-options',
|
||||||
props: {
|
props: {
|
||||||
parameter: {
|
parameter: {
|
||||||
|
|
|
@ -18,9 +18,9 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { useRootStore } from '@/stores/n8nRootStore';
|
import { useRootStore } from '@/stores/n8nRootStore';
|
||||||
import { mapStores } from 'pinia';
|
import { mapStores } from 'pinia';
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'PushConnectionTracker',
|
name: 'PushConnectionTracker',
|
||||||
computed: {
|
computed: {
|
||||||
...mapStores(useRootStore),
|
...mapStores(useRootStore),
|
||||||
|
|
|
@ -79,12 +79,13 @@
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { IResourceLocatorResultExpanded } from '@/Interface';
|
import { IResourceLocatorResultExpanded } from '@/Interface';
|
||||||
import Vue, { PropType } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
import type { PropType } from 'vue';
|
||||||
|
|
||||||
const SEARCH_BAR_HEIGHT_PX = 40;
|
const SEARCH_BAR_HEIGHT_PX = 40;
|
||||||
const SCROLL_MARGIN_PX = 10;
|
const SCROLL_MARGIN_PX = 10;
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'resource-locator-dropdown',
|
name: 'resource-locator-dropdown',
|
||||||
props: {
|
props: {
|
||||||
value: {
|
value: {
|
||||||
|
|
|
@ -6,10 +6,9 @@ import RunDataSchemaItem from '@/components/RunDataSchemaItem.vue';
|
||||||
import Draggable from '@/components/Draggable.vue';
|
import Draggable from '@/components/Draggable.vue';
|
||||||
import { useNDVStore } from '@/stores/ndv';
|
import { useNDVStore } from '@/stores/ndv';
|
||||||
import { useWebhooksStore } from '@/stores/webhooks';
|
import { useWebhooksStore } from '@/stores/webhooks';
|
||||||
import { runExternalHook } from '@/mixins/externalHooks';
|
|
||||||
import { telemetry } from '@/plugins/telemetry';
|
import { telemetry } from '@/plugins/telemetry';
|
||||||
import { IDataObject } from 'n8n-workflow';
|
import { IDataObject } from 'n8n-workflow';
|
||||||
import { getSchema, isEmpty } from '@/utils';
|
import { getSchema, isEmpty, runExternalHook } from '@/utils';
|
||||||
import { i18n } from '@/plugins/i18n';
|
import { i18n } from '@/plugins/i18n';
|
||||||
import MappingPill from './MappingPill.vue';
|
import MappingPill from './MappingPill.vue';
|
||||||
|
|
||||||
|
|
|
@ -14,10 +14,10 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { ITaskData } from 'n8n-workflow';
|
import type { ITaskData } from 'n8n-workflow';
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
props: {
|
props: {
|
||||||
taskData: {}, // ITaskData
|
taskData: {}, // ITaskData
|
||||||
},
|
},
|
||||||
|
|
|
@ -14,9 +14,9 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'SaveButton',
|
name: 'SaveButton',
|
||||||
props: {
|
props: {
|
||||||
saved: {
|
saved: {
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { useCredentialsStore } from '@/stores/credentials';
|
import { useCredentialsStore } from '@/stores/credentials';
|
||||||
import { mapStores } from 'pinia';
|
import { mapStores } from 'pinia';
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'ScopesNotice',
|
name: 'ScopesNotice',
|
||||||
props: ['activeCredentialType', 'scopes'],
|
props: ['activeCredentialType', 'scopes'],
|
||||||
computed: {
|
computed: {
|
||||||
|
|
|
@ -5,13 +5,13 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { shorten } from '@/utils';
|
import { shorten } from '@/utils';
|
||||||
|
|
||||||
const DEFAULT_WORKFLOW_NAME_LIMIT = 25;
|
const DEFAULT_WORKFLOW_NAME_LIMIT = 25;
|
||||||
const WORKFLOW_NAME_END_COUNT_TO_KEEP = 4;
|
const WORKFLOW_NAME_END_COUNT_TO_KEEP = 4;
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'ShortenName',
|
name: 'ShortenName',
|
||||||
props: ['name', 'limit', 'testId'],
|
props: ['name', 'limit', 'testId'],
|
||||||
computed: {
|
computed: {
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import Vue, { defineComponent } from 'vue';
|
||||||
|
|
||||||
import { ITag } from '@/Interface';
|
import { ITag } from '@/Interface';
|
||||||
import IntersectionObserver from './IntersectionObserver.vue';
|
import IntersectionObserver from './IntersectionObserver.vue';
|
||||||
|
@ -56,7 +56,7 @@ interface TagEl extends ITag {
|
||||||
isCount?: boolean;
|
isCount?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
components: { IntersectionObserver, IntersectionObserved },
|
components: { IntersectionObserver, IntersectionObserved },
|
||||||
name: 'TagsContainer',
|
name: 'TagsContainer',
|
||||||
props: ['tagIds', 'limit', 'clickable', 'responsive', 'hoverable'],
|
props: ['tagIds', 'limit', 'clickable', 'responsive', 'hoverable'],
|
||||||
|
|
|
@ -16,9 +16,9 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'NoTagsView',
|
name: 'NoTagsView',
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -110,7 +110,7 @@
|
||||||
import { Table as ElTable } from 'element-ui';
|
import { Table as ElTable } from 'element-ui';
|
||||||
import { MAX_TAG_NAME_LENGTH } from '@/constants';
|
import { MAX_TAG_NAME_LENGTH } from '@/constants';
|
||||||
import { ITagRow } from '@/Interface';
|
import { ITagRow } from '@/Interface';
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { N8nInput } from 'n8n-design-system';
|
import { N8nInput } from 'n8n-design-system';
|
||||||
|
|
||||||
type TableRef = InstanceType<typeof ElTable>;
|
type TableRef = InstanceType<typeof ElTable>;
|
||||||
|
@ -119,7 +119,7 @@ type N8nInputRef = InstanceType<typeof N8nInput>;
|
||||||
const INPUT_TRANSITION_TIMEOUT = 350;
|
const INPUT_TRANSITION_TIMEOUT = 350;
|
||||||
const DELETE_TRANSITION_TIMEOUT = 100;
|
const DELETE_TRANSITION_TIMEOUT = 100;
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'TagsTable',
|
name: 'TagsTable',
|
||||||
props: ['rows', 'isLoading', 'newName', 'isSaving'],
|
props: ['rows', 'isLoading', 'newName', 'isSaving'],
|
||||||
data() {
|
data() {
|
||||||
|
|
|
@ -29,9 +29,9 @@
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { MAX_TAG_NAME_LENGTH } from '@/constants';
|
import { MAX_TAG_NAME_LENGTH } from '@/constants';
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
props: {
|
props: {
|
||||||
disabled: {
|
disabled: {
|
||||||
default: false,
|
default: false,
|
||||||
|
|
|
@ -23,9 +23,9 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
import { ITag, ITagRow } from '@/Interface';
|
import type { ITag, ITagRow } from '@/Interface';
|
||||||
import TagsTableHeader from '@/components/TagsManager/TagsView/TagsTableHeader.vue';
|
import TagsTableHeader from '@/components/TagsManager/TagsView/TagsTableHeader.vue';
|
||||||
import TagsTable from '@/components/TagsManager/TagsView/TagsTable.vue';
|
import TagsTable from '@/components/TagsManager/TagsView/TagsTable.vue';
|
||||||
import { mapStores } from 'pinia';
|
import { mapStores } from 'pinia';
|
||||||
|
@ -34,7 +34,7 @@ import { useUsersStore } from '@/stores/users';
|
||||||
const matches = (name: string, filter: string) =>
|
const matches = (name: string, filter: string) =>
|
||||||
name.toLowerCase().trim().includes(filter.toLowerCase().trim());
|
name.toLowerCase().trim().includes(filter.toLowerCase().trim());
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
components: { TagsTableHeader, TagsTable },
|
components: { TagsTableHeader, TagsTable },
|
||||||
name: 'TagsView',
|
name: 'TagsView',
|
||||||
props: ['tags', 'isLoading'],
|
props: ['tags', 'isLoading'],
|
||||||
|
|
|
@ -47,14 +47,16 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue, { PropType } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
import type { PropType } from 'vue';
|
||||||
import TemplateDetailsBlock from '@/components/TemplateDetailsBlock.vue';
|
import TemplateDetailsBlock from '@/components/TemplateDetailsBlock.vue';
|
||||||
import NodeIcon from '@/components/NodeIcon.vue';
|
import NodeIcon from '@/components/NodeIcon.vue';
|
||||||
import { abbreviateNumber, filterTemplateNodes } from '@/utils';
|
import { abbreviateNumber, filterTemplateNodes } from '@/utils';
|
||||||
import { ITemplatesNode, ITemplatesWorkflow, ITemplatesWorkflowFull } from '@/Interface';
|
import { ITemplatesNode, ITemplatesWorkflow, ITemplatesWorkflowFull } from '@/Interface';
|
||||||
import { mapStores } from 'pinia';
|
import { mapStores } from 'pinia';
|
||||||
import { useTemplatesStore } from '@/stores/templates';
|
import { useTemplatesStore } from '@/stores/templates';
|
||||||
export default Vue.extend({
|
|
||||||
|
export default defineComponent({
|
||||||
name: 'TemplateDetails',
|
name: 'TemplateDetails',
|
||||||
props: {
|
props: {
|
||||||
blockTitle: {
|
blockTitle: {
|
||||||
|
|
|
@ -10,9 +10,9 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'TemplateDetailsBlock',
|
name: 'TemplateDetailsBlock',
|
||||||
props: {
|
props: {
|
||||||
title: {
|
title: {
|
||||||
|
|
|
@ -30,9 +30,9 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import { nextTick, defineComponent } from 'vue';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'TextEdit',
|
name: 'TextEdit',
|
||||||
props: ['dialogVisible', 'parameter', 'path', 'value', 'isReadOnly'],
|
props: ['dialogVisible', 'parameter', 'path', 'value', 'isReadOnly'],
|
||||||
data() {
|
data() {
|
||||||
|
@ -65,7 +65,7 @@ export default Vue.extend({
|
||||||
watch: {
|
watch: {
|
||||||
dialogVisible() {
|
dialogVisible() {
|
||||||
if (this.dialogVisible === true) {
|
if (this.dialogVisible === true) {
|
||||||
Vue.nextTick(() => {
|
nextTick(() => {
|
||||||
(this.$refs.inputField as HTMLInputElement).focus();
|
(this.$refs.inputField as HTMLInputElement).focus();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,11 +7,11 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { format, LocaleFunc, register } from 'timeago.js';
|
import { format, LocaleFunc, register } from 'timeago.js';
|
||||||
import { convertToHumanReadableDate } from '@/utils';
|
import { convertToHumanReadableDate } from '@/utils';
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { mapStores } from 'pinia';
|
import { mapStores } from 'pinia';
|
||||||
import { useRootStore } from '@/stores/n8nRootStore';
|
import { useRootStore } from '@/stores/n8nRootStore';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'TimeAgo',
|
name: 'TimeAgo',
|
||||||
props: {
|
props: {
|
||||||
date: {
|
date: {
|
||||||
|
|
|
@ -8,9 +8,9 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'TitledList',
|
name: 'TitledList',
|
||||||
props: {
|
props: {
|
||||||
title: {
|
title: {
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
import ModalDrawer from './ModalDrawer.vue';
|
import ModalDrawer from './ModalDrawer.vue';
|
||||||
import TimeAgo from './TimeAgo.vue';
|
import TimeAgo from './TimeAgo.vue';
|
||||||
|
@ -53,7 +53,7 @@ import { mapStores } from 'pinia';
|
||||||
import { useVersionsStore } from '@/stores/versions';
|
import { useVersionsStore } from '@/stores/versions';
|
||||||
import { IVersion } from '@/Interface';
|
import { IVersion } from '@/Interface';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'UpdatesPanel',
|
name: 'UpdatesPanel',
|
||||||
components: {
|
components: {
|
||||||
ModalDrawer,
|
ModalDrawer,
|
||||||
|
|
|
@ -55,7 +55,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import Vue, { defineComponent } from 'vue';
|
||||||
import NodeIcon from './NodeIcon.vue';
|
import NodeIcon from './NodeIcon.vue';
|
||||||
import TimeAgo from './TimeAgo.vue';
|
import TimeAgo from './TimeAgo.vue';
|
||||||
import Badge from './Badge.vue';
|
import Badge from './Badge.vue';
|
||||||
|
@ -67,7 +67,7 @@ Vue.component('TimeAgo', TimeAgo);
|
||||||
Vue.component('Badge', Badge);
|
Vue.component('Badge', Badge);
|
||||||
Vue.component('WarningTooltip', WarningTooltip);
|
Vue.component('WarningTooltip', WarningTooltip);
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
components: { NodeIcon, TimeAgo, Badge, WarningTooltip },
|
components: { NodeIcon, TimeAgo, Badge, WarningTooltip },
|
||||||
name: 'VersionCard',
|
name: 'VersionCard',
|
||||||
props: ['version'],
|
props: ['version'],
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { vi, describe, it, expect } from 'vitest';
|
import { vi, describe, it, expect } from 'vitest';
|
||||||
import Vue from 'vue';
|
import Vue, { defineComponent } from 'vue';
|
||||||
import { PiniaVuePlugin } from 'pinia';
|
import { PiniaVuePlugin } from 'pinia';
|
||||||
import { createTestingPinia } from '@pinia/testing';
|
import { createTestingPinia } from '@pinia/testing';
|
||||||
import { render } from '@testing-library/vue';
|
import { render } from '@testing-library/vue';
|
||||||
|
@ -47,7 +47,7 @@ const executionsData = Array.from({ length: 2 }, () => ({
|
||||||
|
|
||||||
let getPastExecutionsSpy = vi.fn().mockResolvedValue({ count: 0, results: [], estimated: false });
|
let getPastExecutionsSpy = vi.fn().mockResolvedValue({ count: 0, results: [], estimated: false });
|
||||||
|
|
||||||
const mockRestApiMixin = Vue.extend({
|
const mockRestApiMixin = defineComponent({
|
||||||
methods: {
|
methods: {
|
||||||
restApi() {
|
restApi() {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,20 +1,23 @@
|
||||||
import VariablesRow from '../VariablesRow.vue';
|
import VariablesRow from '../VariablesRow.vue';
|
||||||
import { EnvironmentVariable } from '@/Interface';
|
import { EnvironmentVariable } from '@/Interface';
|
||||||
import { fireEvent, render } from '@testing-library/vue';
|
import { fireEvent } from '@testing-library/vue';
|
||||||
import { createPinia, setActivePinia } from 'pinia';
|
import { createPinia, setActivePinia } from 'pinia';
|
||||||
import { setupServer } from '@/__tests__/server';
|
import { setupServer } from '@/__tests__/server';
|
||||||
import { afterAll, beforeAll } from 'vitest';
|
import { afterAll, beforeAll } from 'vitest';
|
||||||
import { useSettingsStore, useUsersStore } from '@/stores';
|
import { useSettingsStore, useUsersStore } from '@/stores';
|
||||||
|
import { renderComponent } from '@/__tests__/utils';
|
||||||
|
|
||||||
describe('VariablesRow', () => {
|
describe('VariablesRow', () => {
|
||||||
let server: ReturnType<typeof setupServer>;
|
let server: ReturnType<typeof setupServer>;
|
||||||
|
let pinia: ReturnType<typeof createPinia>;
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
server = setupServer();
|
server = setupServer();
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
setActivePinia(createPinia());
|
pinia = createPinia();
|
||||||
|
setActivePinia(pinia);
|
||||||
|
|
||||||
await useSettingsStore().getSettings();
|
await useSettingsStore().getSettings();
|
||||||
await useUsersStore().loginWithCookie();
|
await useUsersStore().loginWithCookie();
|
||||||
|
@ -33,11 +36,12 @@ describe('VariablesRow', () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
it('should render correctly', () => {
|
it('should render correctly', () => {
|
||||||
const wrapper = render(VariablesRow, {
|
const wrapper = renderComponent(VariablesRow, {
|
||||||
props: {
|
props: {
|
||||||
data: environmentVariable,
|
data: environmentVariable,
|
||||||
},
|
},
|
||||||
stubs,
|
stubs,
|
||||||
|
pinia,
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(wrapper.html()).toMatchSnapshot();
|
expect(wrapper.html()).toMatchSnapshot();
|
||||||
|
@ -45,11 +49,12 @@ describe('VariablesRow', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should show edit and delete buttons on hover', async () => {
|
it('should show edit and delete buttons on hover', async () => {
|
||||||
const wrapper = render(VariablesRow, {
|
const wrapper = renderComponent(VariablesRow, {
|
||||||
props: {
|
props: {
|
||||||
data: environmentVariable,
|
data: environmentVariable,
|
||||||
},
|
},
|
||||||
stubs,
|
stubs,
|
||||||
|
pinia,
|
||||||
});
|
});
|
||||||
|
|
||||||
await fireEvent.mouseEnter(wrapper.container);
|
await fireEvent.mouseEnter(wrapper.container);
|
||||||
|
@ -59,12 +64,13 @@ describe('VariablesRow', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should show key and value inputs in edit mode', async () => {
|
it('should show key and value inputs in edit mode', async () => {
|
||||||
const wrapper = render(VariablesRow, {
|
const wrapper = renderComponent(VariablesRow, {
|
||||||
props: {
|
props: {
|
||||||
data: environmentVariable,
|
data: environmentVariable,
|
||||||
editing: true,
|
editing: true,
|
||||||
},
|
},
|
||||||
stubs,
|
stubs,
|
||||||
|
pinia,
|
||||||
});
|
});
|
||||||
|
|
||||||
await fireEvent.mouseEnter(wrapper.container);
|
await fireEvent.mouseEnter(wrapper.container);
|
||||||
|
@ -82,12 +88,13 @@ describe('VariablesRow', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should show cancel and save buttons in edit mode', async () => {
|
it('should show cancel and save buttons in edit mode', async () => {
|
||||||
const wrapper = render(VariablesRow, {
|
const wrapper = renderComponent(VariablesRow, {
|
||||||
props: {
|
props: {
|
||||||
data: environmentVariable,
|
data: environmentVariable,
|
||||||
editing: true,
|
editing: true,
|
||||||
},
|
},
|
||||||
stubs,
|
stubs,
|
||||||
|
pinia,
|
||||||
});
|
});
|
||||||
|
|
||||||
await fireEvent.mouseEnter(wrapper.container);
|
await fireEvent.mouseEnter(wrapper.container);
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import * as monaco from 'monaco-editor';
|
import * as monaco from 'monaco-editor';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
props: {
|
props: {
|
||||||
type: {
|
type: {
|
||||||
type: String,
|
type: String,
|
||||||
|
|
|
@ -63,15 +63,16 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue, { PropType } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { EnterpriseEditionFeature } from '@/constants';
|
import { EnterpriseEditionFeature } from '@/constants';
|
||||||
import { IUser } from '@/Interface';
|
|
||||||
import { mapStores } from 'pinia';
|
import { mapStores } from 'pinia';
|
||||||
import { useUsersStore } from '@/stores/users';
|
import { useUsersStore } from '@/stores/users';
|
||||||
|
import type { PropType } from 'vue';
|
||||||
|
import type { IUser } from '@/Interface';
|
||||||
|
|
||||||
export type IResourceFiltersType = Record<string, boolean | string | string[]>;
|
export type IResourceFiltersType = Record<string, boolean | string | string[]>;
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
props: {
|
props: {
|
||||||
value: {
|
value: {
|
||||||
type: Object as PropType<IResourceFiltersType>,
|
type: Object as PropType<IResourceFiltersType>,
|
||||||
|
|
|
@ -8,10 +8,10 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { IMenuItem } from 'n8n-design-system';
|
import { IMenuItem } from 'n8n-design-system';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
props: {
|
props: {
|
||||||
value: {
|
value: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
|
|
|
@ -14,9 +14,9 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { useUIStore } from '@/stores/ui';
|
import { useUIStore } from '@/stores/ui';
|
||||||
import { mapStores } from 'pinia';
|
import { mapStores } from 'pinia';
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'PageViewLayout',
|
name: 'PageViewLayout',
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'SlideTransition',
|
name: 'SlideTransition',
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import { IExternalHooks } from '@/Interface';
|
import type { IExternalHooks } from '@/Interface';
|
||||||
import { IDataObject } from 'n8n-workflow';
|
import type { IDataObject } from 'n8n-workflow';
|
||||||
import { useWebhooksStore } from '@/stores';
|
import { useWebhooksStore } from '@/stores';
|
||||||
import { runExternalHook } from '@/mixins/externalHooks';
|
import { runExternalHook } from '@/utils';
|
||||||
|
|
||||||
export function useExternalHooks(): IExternalHooks {
|
export function useExternalHooks(): IExternalHooks {
|
||||||
return {
|
return {
|
||||||
async run(eventName: string, metadata?: IDataObject): Promise<void> {
|
async run(eventName: string, metadata?: IDataObject): Promise<void> {
|
||||||
return await runExternalHook.call(this, eventName, useWebhooksStore(), metadata);
|
return await runExternalHook(eventName, useWebhooksStore(), metadata);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,16 +19,14 @@ import '@fontsource/open-sans/latin-700.css';
|
||||||
import App from '@/App.vue';
|
import App from '@/App.vue';
|
||||||
import router from './router';
|
import router from './router';
|
||||||
|
|
||||||
import { runExternalHook } from '@/mixins/externalHooks';
|
import { runExternalHook } from '@/utils';
|
||||||
import { TelemetryPlugin } from './plugins/telemetry';
|
import { TelemetryPlugin } from './plugins/telemetry';
|
||||||
import { I18nPlugin, i18nInstance } from './plugins/i18n';
|
import { I18nPlugin, i18nInstance } from './plugins/i18n';
|
||||||
|
|
||||||
import { createPinia, PiniaVuePlugin } from 'pinia';
|
import { createPinia, PiniaVuePlugin } from 'pinia';
|
||||||
|
|
||||||
import { useWebhooksStore } from './stores/webhooks';
|
import { useWebhooksStore, useUsersStore } from '@/stores';
|
||||||
import { useUsersStore } from './stores/users';
|
|
||||||
import { VIEWS } from '@/constants';
|
import { VIEWS } from '@/constants';
|
||||||
import { useUIStore } from './stores/ui';
|
|
||||||
|
|
||||||
Vue.config.productionTip = false;
|
Vue.config.productionTip = false;
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
* Captures any pasted data and sends it to method "receivedCopyPasteData" which has to be
|
* Captures any pasted data and sends it to method "receivedCopyPasteData" which has to be
|
||||||
* defined on the component which uses this mixin
|
* defined on the component which uses this mixin
|
||||||
*/
|
*/
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { debounce } from 'lodash-es';
|
import { debounce } from 'lodash-es';
|
||||||
|
|
||||||
export const copyPaste = Vue.extend({
|
export const copyPaste = defineComponent({
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
copyPasteElementsGotCreated: false,
|
copyPasteElementsGotCreated: false,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { debounce } from 'lodash-es';
|
import { debounce } from 'lodash-es';
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
export const debounceHelper = Vue.extend({
|
export const debounceHelper = defineComponent({
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
debouncedFunctions: [] as any[],
|
debouncedFunctions: [] as any[],
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
export const deviceSupportHelpers = Vue.extend({
|
export const deviceSupportHelpers = defineComponent({
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
// @ts-ignore msMaxTouchPoints is deprecated but must fix tablet bugs before fixing this.. otherwise breaks touchscreen computers
|
// @ts-ignore msMaxTouchPoints is deprecated but must fix tablet bugs before fixing this.. otherwise breaks touchscreen computers
|
||||||
|
|
|
@ -1,35 +1,10 @@
|
||||||
import { IExternalHooks } from '@/Interface';
|
import type { IExternalHooks } from '@/Interface';
|
||||||
|
import type { IDataObject } from 'n8n-workflow';
|
||||||
import { useWebhooksStore } from '@/stores/webhooks';
|
import { useWebhooksStore } from '@/stores/webhooks';
|
||||||
import { IDataObject } from 'n8n-workflow';
|
import { defineComponent } from 'vue';
|
||||||
import { Store } from 'pinia';
|
import { runExternalHook } from '@/utils';
|
||||||
import Vue from 'vue';
|
|
||||||
|
|
||||||
declare global {
|
export const externalHooks = defineComponent({
|
||||||
interface Window {
|
|
||||||
n8nExternalHooks?: Record<
|
|
||||||
string,
|
|
||||||
Record<string, Array<(store: Store, metadata?: IDataObject) => Promise<void>>>
|
|
||||||
>;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function runExternalHook(eventName: string, store: Store, metadata?: IDataObject) {
|
|
||||||
if (!window.n8nExternalHooks) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const [resource, operator] = eventName.split('.');
|
|
||||||
|
|
||||||
if (window.n8nExternalHooks[resource]?.[operator]) {
|
|
||||||
const hookMethods = window.n8nExternalHooks[resource][operator];
|
|
||||||
|
|
||||||
for (const hookMethod of hookMethods) {
|
|
||||||
await hookMethod(store, metadata);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const externalHooks = Vue.extend({
|
|
||||||
methods: {
|
methods: {
|
||||||
$externalHooks(): IExternalHooks {
|
$externalHooks(): IExternalHooks {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { parse } from 'flatted';
|
import { parse } from 'flatted';
|
||||||
|
|
||||||
import { Method } from 'axios';
|
import { Method } from 'axios';
|
||||||
|
@ -55,7 +55,7 @@ function unflattenExecutionData(fullExecutionData: IExecutionFlattedResponse): I
|
||||||
return returnData;
|
return returnData;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const restApi = Vue.extend({
|
export const restApi = defineComponent({
|
||||||
computed: {
|
computed: {
|
||||||
...mapStores(useRootStore),
|
...mapStores(useRootStore),
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { IPermissions, IUser } from '@/Interface';
|
import type { IPermissions } from '@/Interface';
|
||||||
import { isAuthorized } from '@/utils';
|
import { isAuthorized } from '@/utils';
|
||||||
import { useUsersStore } from '@/stores/users';
|
import { useUsersStore } from '@/stores/users';
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { Route } from 'vue-router';
|
import type { Route } from 'vue-router';
|
||||||
|
|
||||||
export const userHelpers = Vue.extend({
|
export const userHelpers = defineComponent({
|
||||||
methods: {
|
methods: {
|
||||||
canUserAccessRouteByName(name: string): boolean {
|
canUserAccessRouteByName(name: string): boolean {
|
||||||
const { route } = this.$router.resolve({ name });
|
const { route } = this.$router.resolve({ name });
|
||||||
|
|
6
packages/editor-ui/src/shims.d.ts
vendored
6
packages/editor-ui/src/shims.d.ts
vendored
|
@ -1,4 +1,6 @@
|
||||||
import Vue, { VNode } from 'vue';
|
import Vue, { VNode } from 'vue';
|
||||||
|
import type { Store } from 'pinia';
|
||||||
|
import type { IDataObject } from 'n8n-workflow';
|
||||||
|
|
||||||
declare module 'markdown-it-link-attributes';
|
declare module 'markdown-it-link-attributes';
|
||||||
declare module 'markdown-it-emoji';
|
declare module 'markdown-it-emoji';
|
||||||
|
@ -17,6 +19,10 @@ declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
BASE_PATH: string;
|
BASE_PATH: string;
|
||||||
REST_ENDPOINT: string;
|
REST_ENDPOINT: string;
|
||||||
|
n8nExternalHooks?: Record<
|
||||||
|
string,
|
||||||
|
Record<string, Array<(store: Store, metadata?: IDataObject) => Promise<void>>>
|
||||||
|
>;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace JSX {
|
namespace JSX {
|
||||||
|
|
|
@ -20,11 +20,12 @@ import {
|
||||||
} from '@/constants';
|
} from '@/constants';
|
||||||
import { useNodeTypesStore } from '@/stores/nodeTypes';
|
import { useNodeTypesStore } from '@/stores/nodeTypes';
|
||||||
import { useWorkflowsStore } from './workflows';
|
import { useWorkflowsStore } from './workflows';
|
||||||
import { CUSTOM_API_CALL_KEY, ALL_NODE_FILTER } from '@/constants';
|
import { CUSTOM_API_CALL_KEY } from '@/constants';
|
||||||
import { INodeCreatorState, INodeFilterType, IUpdateInformation } from '@/Interface';
|
import { INodeCreatorState, INodeFilterType, IUpdateInformation } from '@/Interface';
|
||||||
import { BaseTextKey, i18n } from '@/plugins/i18n';
|
import { i18n } from '@/plugins/i18n';
|
||||||
import { externalHooks } from '@/mixins/externalHooks';
|
|
||||||
import { Telemetry } from '@/plugins/telemetry';
|
import { Telemetry } from '@/plugins/telemetry';
|
||||||
|
import { runExternalHook } from '@/utils';
|
||||||
|
import { useWebhooksStore } from '@/stores/webhooks';
|
||||||
|
|
||||||
const PLACEHOLDER_RECOMMENDED_ACTION_KEY = 'placeholder_recommended';
|
const PLACEHOLDER_RECOMMENDED_ACTION_KEY = 'placeholder_recommended';
|
||||||
|
|
||||||
|
@ -286,14 +287,12 @@ export const useNodeCreatorStore = defineStore(STORES.NODE_CREATOR, {
|
||||||
return storeWatcher;
|
return storeWatcher;
|
||||||
},
|
},
|
||||||
trackActionSelected(action: IUpdateInformation, telemetry?: Telemetry) {
|
trackActionSelected(action: IUpdateInformation, telemetry?: Telemetry) {
|
||||||
const { $externalHooks } = new externalHooks();
|
|
||||||
|
|
||||||
const payload = {
|
const payload = {
|
||||||
node_type: action.key,
|
node_type: action.key,
|
||||||
action: action.name,
|
action: action.name,
|
||||||
resource: (action.value as INodeParameters).resource || '',
|
resource: (action.value as INodeParameters).resource || '',
|
||||||
};
|
};
|
||||||
$externalHooks().run('nodeCreateList.addAction', payload);
|
runExternalHook('nodeCreateList.addAction', useWebhooksStore(), payload);
|
||||||
telemetry?.trackNodesPanel('nodeCreateList.addAction', payload);
|
telemetry?.trackNodesPanel('nodeCreateList.addAction', payload);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
18
packages/editor-ui/src/utils/externalHooks.ts
Normal file
18
packages/editor-ui/src/utils/externalHooks.ts
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import type { IDataObject } from 'n8n-workflow';
|
||||||
|
import type { Store } from 'pinia';
|
||||||
|
|
||||||
|
export async function runExternalHook(eventName: string, store: Store, metadata?: IDataObject) {
|
||||||
|
if (!window.n8nExternalHooks) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const [resource, operator] = eventName.split('.');
|
||||||
|
|
||||||
|
if (window.n8nExternalHooks[resource]?.[operator]) {
|
||||||
|
const hookMethods = window.n8nExternalHooks[resource][operator];
|
||||||
|
|
||||||
|
for (const hookMethod of hookMethods) {
|
||||||
|
await hookMethod(store, metadata);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
export * from './apiUtils';
|
export * from './apiUtils';
|
||||||
export * from './canvasUtils';
|
export * from './canvasUtils';
|
||||||
|
export * from './externalHooks';
|
||||||
export * from './htmlUtils';
|
export * from './htmlUtils';
|
||||||
export * from './nodeTypesUtils';
|
export * from './nodeTypesUtils';
|
||||||
export * from './sortUtils';
|
export * from './sortUtils';
|
||||||
|
|
|
@ -22,12 +22,12 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
import Logo from '@/components/Logo.vue';
|
import Logo from '@/components/Logo.vue';
|
||||||
import SSOLogin from '@/components/SSOLogin.vue';
|
import SSOLogin from '@/components/SSOLogin.vue';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'AuthView',
|
name: 'AuthView',
|
||||||
components: {
|
components: {
|
||||||
Logo,
|
Logo,
|
||||||
|
|
|
@ -18,9 +18,9 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'ErrorView',
|
name: 'ErrorView',
|
||||||
props: {
|
props: {
|
||||||
messageKey: {
|
messageKey: {
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import ExecutionsList from '@/components/ExecutionsList.vue';
|
import ExecutionsList from '@/components/ExecutionsList.vue';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'ExecutionsView',
|
name: 'ExecutionsView',
|
||||||
components: {
|
components: {
|
||||||
ExecutionsList,
|
ExecutionsList,
|
||||||
|
|
|
@ -4,12 +4,12 @@
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { IFakeDoor } from '@/Interface';
|
import { IFakeDoor } from '@/Interface';
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import FeatureComingSoon from '@/components/FeatureComingSoon.vue';
|
import FeatureComingSoon from '@/components/FeatureComingSoon.vue';
|
||||||
import { mapStores } from 'pinia';
|
import { mapStores } from 'pinia';
|
||||||
import { useUIStore } from '@/stores/ui';
|
import { useUIStore } from '@/stores/ui';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'SettingsFakeDoorView',
|
name: 'SettingsFakeDoorView',
|
||||||
components: {
|
components: {
|
||||||
FeatureComingSoon,
|
FeatureComingSoon,
|
||||||
|
|
|
@ -15,10 +15,10 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import GoBackButton from '@/components/GoBackButton.vue';
|
import GoBackButton from '@/components/GoBackButton.vue';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default defineComponent({
|
||||||
name: 'TemplatesView',
|
name: 'TemplatesView',
|
||||||
components: {
|
components: {
|
||||||
GoBackButton,
|
GoBackButton,
|
||||||
|
|
|
@ -4,16 +4,19 @@ import { setupServer } from '@/__tests__/server';
|
||||||
import { render } from '@testing-library/vue';
|
import { render } from '@testing-library/vue';
|
||||||
import VariablesView from '@/views/VariablesView.vue';
|
import VariablesView from '@/views/VariablesView.vue';
|
||||||
import { useSettingsStore, useUsersStore } from '@/stores';
|
import { useSettingsStore, useUsersStore } from '@/stores';
|
||||||
|
import { renderComponent } from '@/__tests__/utils';
|
||||||
|
|
||||||
describe('store', () => {
|
describe('store', () => {
|
||||||
let server: ReturnType<typeof setupServer>;
|
let server: ReturnType<typeof setupServer>;
|
||||||
|
let pinia: ReturnType<typeof createPinia>;
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
server = setupServer();
|
server = setupServer();
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
setActivePinia(createPinia());
|
pinia = createPinia();
|
||||||
|
setActivePinia(pinia);
|
||||||
|
|
||||||
await useSettingsStore().getSettings();
|
await useSettingsStore().getSettings();
|
||||||
await useUsersStore().fetchUsers();
|
await useUsersStore().fetchUsers();
|
||||||
|
@ -25,13 +28,13 @@ describe('store', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render loading state', () => {
|
it('should render loading state', () => {
|
||||||
const wrapper = render(VariablesView);
|
const wrapper = renderComponent(VariablesView, { pinia });
|
||||||
|
|
||||||
expect(wrapper.container.querySelectorAll('.n8n-loading')).toHaveLength(3);
|
expect(wrapper.container.querySelectorAll('.n8n-loading')).toHaveLength(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render empty state', async () => {
|
it('should render empty state', async () => {
|
||||||
const wrapper = render(VariablesView);
|
const wrapper = renderComponent(VariablesView, { pinia });
|
||||||
|
|
||||||
await wrapper.findByTestId('empty-resources-list');
|
await wrapper.findByTestId('empty-resources-list');
|
||||||
expect(wrapper.getByTestId('empty-resources-list')).toBeVisible();
|
expect(wrapper.getByTestId('empty-resources-list')).toBeVisible();
|
||||||
|
@ -40,7 +43,7 @@ describe('store', () => {
|
||||||
it('should render variable entries', async () => {
|
it('should render variable entries', async () => {
|
||||||
server.createList('variable', 3);
|
server.createList('variable', 3);
|
||||||
|
|
||||||
const wrapper = render(VariablesView);
|
const wrapper = renderComponent(VariablesView, { pinia });
|
||||||
|
|
||||||
await wrapper.findByTestId('resources-table');
|
await wrapper.findByTestId('resources-table');
|
||||||
expect(wrapper.getByTestId('resources-table')).toBeVisible();
|
expect(wrapper.getByTestId('resources-table')).toBeVisible();
|
||||||
|
|
Loading…
Reference in a new issue