mirror of
https://github.com/n8n-io/n8n.git
synced 2026-05-30 16:26:59 +02:00
refactor(editor): Extract communityNodes code into features (no-changelog) (#20747)
This commit is contained in:
parent
0fab5ea3d3
commit
eb805d2ba7
|
|
@ -4,8 +4,6 @@ import {
|
|||
ANNOTATION_TAGS_MANAGER_MODAL_KEY,
|
||||
CHANGE_PASSWORD_MODAL_KEY,
|
||||
CHAT_EMBED_MODAL_KEY,
|
||||
COMMUNITY_PACKAGE_CONFIRM_MODAL_KEY,
|
||||
COMMUNITY_PACKAGE_INSTALL_MODAL_KEY,
|
||||
CONTACT_PROMPT_MODAL_KEY,
|
||||
CREDENTIAL_EDIT_MODAL_KEY,
|
||||
CREDENTIAL_SELECT_MODAL_KEY,
|
||||
|
|
@ -52,6 +50,10 @@ import {
|
|||
SOURCE_CONTROL_PULL_MODAL_KEY,
|
||||
SOURCE_CONTROL_PUSH_MODAL_KEY,
|
||||
} from '@/features/sourceControl.ee/sourceControl.constants';
|
||||
import {
|
||||
COMMUNITY_PACKAGE_CONFIRM_MODAL_KEY,
|
||||
COMMUNITY_PACKAGE_INSTALL_MODAL_KEY,
|
||||
} from '@/features/communityNodes/communityNodes.constants';
|
||||
import { API_KEY_CREATE_OR_EDIT_MODAL_KEY } from '@/features/apiKeys/apiKeys.constants';
|
||||
import AboutModal from '@/components/AboutModal.vue';
|
||||
import ActivationModal from '@/components/ActivationModal.vue';
|
||||
|
|
@ -60,8 +62,8 @@ import NewAssistantSessionModal from '@/features/assistant/components/Chat/NewAs
|
|||
import ChangePasswordModal from '@/features/auth/components/ChangePasswordModal.vue';
|
||||
import ConfirmPasswordModal from '@/features/auth/components/ConfirmPasswordModal.vue';
|
||||
import ChatEmbedModal from '@/components/ChatEmbedModal.vue';
|
||||
import CommunityPackageInstallModal from '@/components/CommunityPackageInstallModal.vue';
|
||||
import CommunityPackageManageConfirmModal from '@/components/CommunityPackageManageConfirmModal.vue';
|
||||
import CommunityPackageInstallModal from '@/features/communityNodes/components/CommunityPackageInstallModal.vue';
|
||||
import CommunityPackageManageConfirmModal from '@/features/communityNodes/components/CommunityPackageManageConfirmModal.vue';
|
||||
import CommunityPlusEnrollmentModal from '@/features/communityPlus/components/CommunityPlusEnrollmentModal.vue';
|
||||
import ContactPromptModal from '@/components/ContactPromptModal.vue';
|
||||
import CredentialEdit from '@/components/CredentialEdit/CredentialEdit.vue';
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import { useI18n } from '@n8n/i18n';
|
||||
import CommunityNodeInstallHint from '../Panel/CommunityNodeInstallHint.vue';
|
||||
import CommunityNodeInstallHint from '@/features/communityNodes/components/nodeCreator/CommunityNodeInstallHint.vue';
|
||||
import { N8nButton } from '@n8n/design-system';
|
||||
export interface Props {
|
||||
isPreview: boolean;
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
<script setup lang="ts">
|
||||
import type { SimplifiedNodeType } from '@/Interface';
|
||||
import {
|
||||
COMMUNITY_NODES_INSTALLATION_DOCS_URL,
|
||||
CREDENTIAL_ONLY_NODE_PREFIX,
|
||||
DEFAULT_SUBCATEGORY,
|
||||
DRAG_EVENT_DATA_KEY,
|
||||
HITL_SUBCATEGORY,
|
||||
} from '@/constants';
|
||||
import { COMMUNITY_NODES_INSTALLATION_DOCS_URL } from '@/features/communityNodes/communityNodes.constants';
|
||||
import { computed, ref } from 'vue';
|
||||
|
||||
import NodeIcon from '@/components/NodeIcon.vue';
|
||||
|
|
|
|||
|
|
@ -31,8 +31,8 @@ import { useNodeCreatorStore } from '@/stores/nodeCreator.store';
|
|||
import OrderSwitcher from './../OrderSwitcher.vue';
|
||||
import { getActiveViewCallouts, isNodePreviewKey } from '../utils';
|
||||
|
||||
import CommunityNodeInfo from '../Panel/CommunityNodeInfo.vue';
|
||||
import CommunityNodeFooter from '../Panel/CommunityNodeFooter.vue';
|
||||
import CommunityNodeInfo from '@/features/communityNodes/components/nodeCreator/CommunityNodeInfo.vue';
|
||||
import CommunityNodeFooter from '@/features/communityNodes/components/nodeCreator/CommunityNodeFooter.vue';
|
||||
import { useCalloutHelpers } from '@/composables/useCalloutHelpers';
|
||||
|
||||
import { N8nCallout, N8nInfoTip } from '@n8n/design-system';
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import { useInstallNode } from '@/composables/useInstallNode';
|
||||
import { useInstallNode } from '@/features/communityNodes/composables/useInstallNode';
|
||||
import { useNodeCreatorStore } from '@/stores/nodeCreator.store';
|
||||
import { useUsersStore } from '@/features/users/users.store';
|
||||
import { getNodeIconSource } from '@/utils/nodeIcon';
|
||||
|
|
|
|||
|
|
@ -22,10 +22,10 @@ import { useI18n } from '@n8n/i18n';
|
|||
import { useDebounce } from '@/composables/useDebounce';
|
||||
import NodeIcon from '@/components/NodeIcon.vue';
|
||||
|
||||
import CommunityNodeDetails from './CommunityNodeDetails.vue';
|
||||
import CommunityNodeInfo from './CommunityNodeInfo.vue';
|
||||
import CommunityNodeDocsLink from './CommunityNodeDocsLink.vue';
|
||||
import CommunityNodeFooter from './CommunityNodeFooter.vue';
|
||||
import CommunityNodeDetails from '@/features/communityNodes/components/nodeCreator/CommunityNodeDetails.vue';
|
||||
import CommunityNodeInfo from '@/features/communityNodes/components/nodeCreator/CommunityNodeInfo.vue';
|
||||
import CommunityNodeDocsLink from '@/features/communityNodes/components/nodeCreator/CommunityNodeDocsLink.vue';
|
||||
import CommunityNodeFooter from '@/features/communityNodes/components/nodeCreator/CommunityNodeFooter.vue';
|
||||
import { useUsersStore } from '@/features/users/users.store';
|
||||
|
||||
import { N8nIcon, N8nNotice } from '@n8n/design-system';
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import ItemsRenderer from './ItemsRenderer.vue';
|
|||
import CategoryItem from '../ItemTypes/CategoryItem.vue';
|
||||
import { useNodeCreatorStore } from '@/stores/nodeCreator.store';
|
||||
|
||||
import CommunityNodeInstallHint from '../Panel/CommunityNodeInstallHint.vue';
|
||||
import CommunityNodeInstallHint from '@/features/communityNodes/components/nodeCreator/CommunityNodeInstallHint.vue';
|
||||
|
||||
export interface Props {
|
||||
elements: INodeCreateElement[];
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ import FreeAiCreditsCallout from '@/components/FreeAiCreditsCallout.vue';
|
|||
import NodeActionsList from '@/components/NodeActionsList.vue';
|
||||
import NodeSettingsInvalidNodeWarning from '@/components/NodeSettingsInvalidNodeWarning.vue';
|
||||
import { useExternalHooks } from '@/composables/useExternalHooks';
|
||||
import { useInstalledCommunityPackage } from '@/composables/useInstalledCommunityPackage';
|
||||
import { useInstalledCommunityPackage } from '@/features/communityNodes/composables/useInstalledCommunityPackage';
|
||||
import { useNodeCredentialOptions } from '@/composables/useNodeCredentialOptions';
|
||||
import { useNodeHelpers } from '@/composables/useNodeHelpers';
|
||||
import { useNodeSettingsParameters } from '@/composables/useNodeSettingsParameters';
|
||||
|
|
@ -56,8 +56,8 @@ import {
|
|||
import { useI18n } from '@n8n/i18n';
|
||||
import type { EventBus } from '@n8n/utils/event-bus';
|
||||
import { useResizeObserver } from '@vueuse/core';
|
||||
import CommunityNodeFooter from '@/components/Node/NodeCreator/Panel/CommunityNodeFooter.vue';
|
||||
import CommunityNodeUpdateInfo from '@/components/Node/NodeCreator/Panel/CommunityNodeUpdateInfo.vue';
|
||||
import CommunityNodeFooter from '@/features/communityNodes/components/nodeCreator/CommunityNodeFooter.vue';
|
||||
import CommunityNodeUpdateInfo from '@/features/communityNodes/components/nodeCreator/CommunityNodeUpdateInfo.vue';
|
||||
import NodeExecuteButton from './NodeExecuteButton.vue';
|
||||
|
||||
import { N8nBlockUi, N8nIcon, N8nNotice, N8nText } from '@n8n/design-system';
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { mockNode } from '@/__tests__/mocks';
|
||||
import { renderComponent } from '@/__tests__/render';
|
||||
import { mockedStore, type MockedStore } from '@/__tests__/utils';
|
||||
import { useInstallNode } from '@/composables/useInstallNode';
|
||||
import { useInstallNode } from '@/features/communityNodes/composables/useInstallNode';
|
||||
import { type NodeTypesByTypeNameAndVersion } from '@/Interface';
|
||||
import { useNDVStore } from '@/stores/ndv.store';
|
||||
import { useNodeCreatorStore } from '@/stores/nodeCreator.store';
|
||||
|
|
@ -16,7 +16,7 @@ import { vi, type MockedFunction } from 'vitest';
|
|||
import { ref } from 'vue';
|
||||
import NodeSettingsInvalidNodeWarning from './NodeSettingsInvalidNodeWarning.vue';
|
||||
|
||||
vi.mock('@/composables/useInstallNode');
|
||||
vi.mock('@/features/communityNodes/composables/useInstallNode');
|
||||
vi.mock('@/composables/useTelemetry', () => ({
|
||||
useTelemetry: () => ({
|
||||
track: vi.fn(),
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
<script setup lang="ts">
|
||||
import { useInstallNode } from '@/composables/useInstallNode';
|
||||
import { useInstallNode } from '@/features/communityNodes/composables/useInstallNode';
|
||||
import { useTelemetry } from '@/composables/useTelemetry';
|
||||
import { COMMUNITY_PACKAGE_INSTALL_MODAL_KEY, CUSTOM_NODES_DOCS_URL } from '@/constants';
|
||||
import { CUSTOM_NODES_DOCS_URL } from '@/constants';
|
||||
import { COMMUNITY_PACKAGE_INSTALL_MODAL_KEY } from '@/features/communityNodes/communityNodes.constants';
|
||||
import type { INodeUi } from '@/Interface';
|
||||
import { useNDVStore } from '@/stores/ndv.store';
|
||||
import { useNodeCreatorStore } from '@/stores/nodeCreator.store';
|
||||
|
|
@ -13,7 +14,7 @@ import { useI18n } from '@n8n/i18n';
|
|||
import { isCommunityPackageName } from 'n8n-workflow';
|
||||
import { computed, watch } from 'vue';
|
||||
import { I18nT } from 'vue-i18n';
|
||||
import ContactAdministratorToInstall from './ContactAdministratorToInstall.vue';
|
||||
import ContactAdministratorToInstall from '@/features/communityNodes/components/ContactAdministratorToInstall.vue';
|
||||
import { removePreviewToken } from './Node/NodeCreator/utils';
|
||||
|
||||
const { node, previewMode = false } = defineProps<{ node: INodeUi; previewMode?: boolean }>();
|
||||
|
|
|
|||
|
|
@ -4,12 +4,12 @@ import { createComponentRenderer } from '@/__tests__/render';
|
|||
import { createTestingPinia } from '@pinia/testing';
|
||||
import NodeSettingsTabs from '@/components/NodeSettingsTabs.vue';
|
||||
import { ref } from 'vue';
|
||||
import type { ExtendedPublicInstalledPackage } from '@/utils/communityNodeUtils';
|
||||
import { useInstalledCommunityPackage } from '@/composables/useInstalledCommunityPackage';
|
||||
import type { ExtendedPublicInstalledPackage } from '@/features/communityNodes/communityNodes.utils';
|
||||
import { useInstalledCommunityPackage } from '@/features/communityNodes/composables/useInstalledCommunityPackage';
|
||||
|
||||
const renderComponent = createComponentRenderer(NodeSettingsTabs);
|
||||
|
||||
vi.mock('@/composables/useInstalledCommunityPackage', () => ({
|
||||
vi.mock('@/features/communityNodes/composables/useInstalledCommunityPackage', () => ({
|
||||
useInstalledCommunityPackage: vi.fn(() => ({
|
||||
installedPackage: ref<ExtendedPublicInstalledPackage | undefined>(undefined),
|
||||
isCommunityNode: ref(false),
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import type { ITab } from '@/Interface';
|
||||
import { COMMUNITY_NODES_INSTALLATION_DOCS_URL } from '@/constants';
|
||||
import { COMMUNITY_NODES_INSTALLATION_DOCS_URL } from '@/features/communityNodes/communityNodes.constants';
|
||||
import { useNDVStore } from '@/stores/ndv.store';
|
||||
import { useWorkflowsStore } from '@/stores/workflows.store';
|
||||
import type { INodeTypeDescription } from 'n8n-workflow';
|
||||
|
|
@ -8,7 +8,7 @@ import { NodeConnectionTypes } from 'n8n-workflow';
|
|||
import { computed } from 'vue';
|
||||
|
||||
import { useExternalHooks } from '@/composables/useExternalHooks';
|
||||
import { useInstalledCommunityPackage } from '@/composables/useInstalledCommunityPackage';
|
||||
import { useInstalledCommunityPackage } from '@/features/communityNodes/composables/useInstalledCommunityPackage';
|
||||
import { useNodeDocsUrl } from '@/composables/useNodeDocsUrl';
|
||||
import { useTelemetry } from '@/composables/useTelemetry';
|
||||
import type { NodeSettingsTab } from '@/types/nodeSettings';
|
||||
|
|
|
|||
|
|
@ -64,8 +64,6 @@ export const CONTACT_PROMPT_MODAL_KEY = 'contactPrompt';
|
|||
export const NODE_PINNING_MODAL_KEY = 'nodePinning';
|
||||
export const NPS_SURVEY_MODAL_KEY = 'npsSurvey';
|
||||
export const WORKFLOW_ACTIVE_MODAL_KEY = 'activation';
|
||||
export const COMMUNITY_PACKAGE_INSTALL_MODAL_KEY = 'communityPackageInstall';
|
||||
export const COMMUNITY_PACKAGE_CONFIRM_MODAL_KEY = 'communityPackageManageConfirm';
|
||||
export const IMPORT_CURL_MODAL_KEY = 'importCurl';
|
||||
export const LOG_STREAM_MODAL_KEY = 'settingsLogStream';
|
||||
export const DEBUG_PAYWALL_MODAL_KEY = 'debugPaywall';
|
||||
|
|
@ -88,12 +86,6 @@ export const CHAT_HUB_SIDE_MENU_DRAWER_MODAL_KEY = 'chatHubSideMenuDrawer';
|
|||
export const EXPERIMENT_TEMPLATE_RECO_V2_KEY = 'templateRecoV2';
|
||||
export const EXPERIMENT_TEMPLATE_RECO_V3_KEY = 'templateRecoV3';
|
||||
|
||||
export const COMMUNITY_PACKAGE_MANAGE_ACTIONS = {
|
||||
UNINSTALL: 'uninstall',
|
||||
UPDATE: 'update',
|
||||
VIEW_DOCS: 'view-documentation',
|
||||
};
|
||||
|
||||
// breakpoints
|
||||
export const BREAKPOINT_SM = 768;
|
||||
export const BREAKPOINT_MD = 992;
|
||||
|
|
@ -108,12 +100,7 @@ export const DATA_EDITING_DOCS_URL = `https://${DOCS_DOMAIN}/data/data-editing/`
|
|||
export const SCHEMA_PREVIEW_DOCS_URL = `https://${DOCS_DOMAIN}/data/schema-preview/`;
|
||||
export const MFA_DOCS_URL = `https://${DOCS_DOMAIN}/user-management/two-factor-auth/`;
|
||||
export const NPM_PACKAGE_DOCS_BASE_URL = 'https://www.npmjs.com/package/';
|
||||
export const NPM_KEYWORD_SEARCH_URL =
|
||||
'https://www.npmjs.com/search?q=keywords%3An8n-community-node-package';
|
||||
export const N8N_QUEUE_MODE_DOCS_URL = `https://${DOCS_DOMAIN}/hosting/scaling/queue-mode/`;
|
||||
export const COMMUNITY_NODES_INSTALLATION_DOCS_URL = `https://${DOCS_DOMAIN}/integrations/community-nodes/installation/gui-install/`;
|
||||
export const COMMUNITY_NODES_RISKS_DOCS_URL = `https://${DOCS_DOMAIN}/integrations/community-nodes/risks/`;
|
||||
export const COMMUNITY_NODES_BLOCKLIST_DOCS_URL = `https://${DOCS_DOMAIN}/integrations/community-nodes/blocklist/`;
|
||||
export const CUSTOM_NODES_DOCS_URL = `https://${DOCS_DOMAIN}/integrations/creating-nodes/code/create-n8n-nodes-module/`;
|
||||
export const EXPRESSIONS_DOCS_URL = `https://${DOCS_DOMAIN}/code-examples/expressions/`;
|
||||
export const EVALUATIONS_DOCS_URL = `https://${DOCS_DOMAIN}/advanced-ai/evaluations/overview/`;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
import { DOCS_DOMAIN } from '@/constants';
|
||||
|
||||
export const COMMUNITY_PACKAGE_INSTALL_MODAL_KEY = 'communityPackageInstall';
|
||||
export const COMMUNITY_PACKAGE_CONFIRM_MODAL_KEY = 'communityPackageManageConfirm';
|
||||
|
||||
export const COMMUNITY_NODES_INSTALLATION_DOCS_URL = `https://${DOCS_DOMAIN}/integrations/community-nodes/installation/gui-install/`;
|
||||
export const COMMUNITY_NODES_RISKS_DOCS_URL = `https://${DOCS_DOMAIN}/integrations/community-nodes/risks/`;
|
||||
export const COMMUNITY_NODES_BLOCKLIST_DOCS_URL = `https://${DOCS_DOMAIN}/integrations/community-nodes/blocklist/`;
|
||||
export const NPM_KEYWORD_SEARCH_URL =
|
||||
'https://www.npmjs.com/search?q=keywords%3An8n-community-node-package';
|
||||
|
||||
export const COMMUNITY_PACKAGE_MANAGE_ACTIONS = {
|
||||
UNINSTALL: 'uninstall',
|
||||
UPDATE: 'update',
|
||||
VIEW_DOCS: 'view-documentation',
|
||||
};
|
||||
|
|
@ -5,7 +5,7 @@ import type { PublicInstalledPackage } from 'n8n-workflow';
|
|||
import { STORES } from '@n8n/stores';
|
||||
import { computed, ref } from 'vue';
|
||||
import { isAuthenticated } from '@/utils/rbac/checks';
|
||||
import type { CommunityPackageMap } from '@/Interface';
|
||||
import type { CommunityPackageMap } from './communityNodes.types';
|
||||
|
||||
const LOADER_DELAY = 300;
|
||||
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
import type { PublicInstalledPackage } from 'n8n-workflow';
|
||||
|
||||
export interface CommunityPackageMap {
|
||||
[name: string]: PublicInstalledPackage;
|
||||
}
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
import { describe, it, expect, vi } from 'vitest';
|
||||
import { fetchInstalledPackageInfo } from './communityNodeUtils';
|
||||
import { useCommunityNodesStore } from '@/stores/communityNodes.store';
|
||||
import { fetchInstalledPackageInfo } from './communityNodes.utils';
|
||||
import { useCommunityNodesStore } from './communityNodes.store';
|
||||
import { type NodeTypesStore, useNodeTypesStore } from '@/stores/nodeTypes.store';
|
||||
import type { PublicInstalledPackage } from 'n8n-workflow';
|
||||
import type { CommunityNodeType } from '@n8n/api-types';
|
||||
import { createTestingPinia } from '@pinia/testing';
|
||||
|
||||
vi.mock('@/stores/communityNodes.store', () => ({
|
||||
vi.mock('./communityNodes.store', () => ({
|
||||
useCommunityNodesStore: vi.fn(() => ({
|
||||
getInstalledPackage: vi.fn(),
|
||||
})),
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import { useCommunityNodesStore } from '@/stores/communityNodes.store';
|
||||
import { useCommunityNodesStore } from './communityNodes.store';
|
||||
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
|
||||
import { type PublicInstalledPackage } from 'n8n-workflow';
|
||||
import semver from 'semver';
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
<script lang="ts" setup>
|
||||
import { useUIStore } from '@/stores/ui.store';
|
||||
import type { IUser, PublicInstalledPackage } from 'n8n-workflow';
|
||||
import { NPM_PACKAGE_DOCS_BASE_URL, COMMUNITY_PACKAGE_MANAGE_ACTIONS } from '@/constants';
|
||||
import { COMMUNITY_PACKAGE_MANAGE_ACTIONS } from '../communityNodes.constants';
|
||||
import { NPM_PACKAGE_DOCS_BASE_URL } from '@/constants';
|
||||
import { useI18n } from '@n8n/i18n';
|
||||
import { useTelemetry } from '@/composables/useTelemetry';
|
||||
import { useSettingsStore } from '@/stores/settings.store';
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import { createComponentRenderer } from '@/__tests__/render';
|
||||
import { retry } from '@/__tests__/utils';
|
||||
import { useInstallNode } from '@/composables/useInstallNode';
|
||||
import { COMMUNITY_PACKAGE_INSTALL_MODAL_KEY } from '@/constants';
|
||||
import { useInstallNode } from '../composables/useInstallNode';
|
||||
import { COMMUNITY_PACKAGE_INSTALL_MODAL_KEY } from '../communityNodes.constants';
|
||||
import { STORES } from '@n8n/stores';
|
||||
import { createTestingPinia } from '@pinia/testing';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
|
|
@ -9,7 +9,7 @@ import { vi, type MockedFunction } from 'vitest';
|
|||
import { ref } from 'vue';
|
||||
import CommunityPackageInstallModal from './CommunityPackageInstallModal.vue';
|
||||
|
||||
vi.mock('@/composables/useInstallNode');
|
||||
vi.mock('../composables/useInstallNode');
|
||||
vi.mock('@/composables/useTelemetry', () => ({
|
||||
useTelemetry: () => ({
|
||||
track: vi.fn(),
|
||||
|
|
@ -1,13 +1,13 @@
|
|||
<script setup lang="ts">
|
||||
import Modal from '@/components/Modal.vue';
|
||||
import { useInstallNode } from '@/composables/useInstallNode';
|
||||
import { useInstallNode } from '../composables/useInstallNode';
|
||||
import { useTelemetry } from '@/composables/useTelemetry';
|
||||
import {
|
||||
COMMUNITY_PACKAGE_INSTALL_MODAL_KEY,
|
||||
COMMUNITY_NODES_INSTALLATION_DOCS_URL,
|
||||
COMMUNITY_NODES_RISKS_DOCS_URL,
|
||||
COMMUNITY_PACKAGE_INSTALL_MODAL_KEY,
|
||||
NPM_KEYWORD_SEARCH_URL,
|
||||
} from '@/constants';
|
||||
} from '../communityNodes.constants';
|
||||
import { useUIStore } from '@/stores/ui.store';
|
||||
import { useI18n } from '@n8n/i18n';
|
||||
import { createEventBus } from '@n8n/utils/event-bus';
|
||||
|
|
@ -7,7 +7,7 @@ import { defaultSettings } from '@/__tests__/defaults';
|
|||
import { mockNodeTypeDescription } from '@/__tests__/mocks';
|
||||
import { createTestingPinia } from '@pinia/testing';
|
||||
import { STORES } from '@n8n/stores';
|
||||
import { COMMUNITY_PACKAGE_CONFIRM_MODAL_KEY } from '@/constants';
|
||||
import { COMMUNITY_PACKAGE_CONFIRM_MODAL_KEY } from '../communityNodes.constants';
|
||||
|
||||
const fetchWorkflowsWithNodesIncluded = vi.fn();
|
||||
vi.mock('@/stores/workflows.store', () => ({
|
||||
|
|
@ -1,8 +1,11 @@
|
|||
<script setup lang="ts">
|
||||
import Modal from '@/components/Modal.vue';
|
||||
import { COMMUNITY_PACKAGE_CONFIRM_MODAL_KEY, COMMUNITY_PACKAGE_MANAGE_ACTIONS } from '@/constants';
|
||||
import {
|
||||
COMMUNITY_PACKAGE_CONFIRM_MODAL_KEY,
|
||||
COMMUNITY_PACKAGE_MANAGE_ACTIONS,
|
||||
} from '../communityNodes.constants';
|
||||
import { useToast } from '@/composables/useToast';
|
||||
import { useCommunityNodesStore } from '@/stores/communityNodes.store';
|
||||
import { useCommunityNodesStore } from '../communityNodes.store';
|
||||
import { createEventBus } from '@n8n/utils/event-bus';
|
||||
import { useI18n } from '@n8n/i18n';
|
||||
import { useTelemetry } from '@/composables/useTelemetry';
|
||||
|
|
@ -16,7 +19,7 @@ import { useWorkflowsStore } from '@/stores/workflows.store';
|
|||
import type { WorkflowResource } from '@/Interface';
|
||||
|
||||
import { N8nButton, N8nNotice, N8nText } from '@n8n/design-system';
|
||||
import NodesInWorkflowTable from '@/components/NodesInWorkflowTable.vue';
|
||||
import NodesInWorkflowTable from './NodesInWorkflowTable.vue';
|
||||
|
||||
export type CommunityPackageManageMode = 'uninstall' | 'update' | 'view-documentation';
|
||||
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import { createComponentRenderer } from '@/__tests__/render';
|
||||
import NodesInWorkflowTable from '@/components/NodesInWorkflowTable.vue';
|
||||
import NodesInWorkflowTable from './NodesInWorkflowTable.vue';
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { screen } from '@testing-library/vue';
|
||||
import { createTestingPinia } from '@pinia/testing';
|
||||
|
|
@ -61,7 +61,7 @@ vi.mock('@/stores/nodeTypes.store', () => ({
|
|||
})),
|
||||
}));
|
||||
|
||||
vi.mock('@/stores/communityNodes.store', () => ({
|
||||
vi.mock('../../communityNodes.store', () => ({
|
||||
useCommunityNodesStore: vi.fn(() => ({
|
||||
installPackage,
|
||||
})),
|
||||
|
|
@ -78,7 +78,7 @@ vi.mock('@/composables/useToast', () => ({
|
|||
})),
|
||||
}));
|
||||
|
||||
vi.mock('../composables/useViewStacks', () => ({
|
||||
vi.mock('@/components/Node/NodeCreator/composables/useViewStacks', () => ({
|
||||
useViewStacks: vi.fn(() => ({
|
||||
activeViewStack: {
|
||||
communityNodeDetails: {
|
||||
|
|
@ -0,0 +1,169 @@
|
|||
<script setup lang="ts">
|
||||
import { useInstallNode } from '@/features/communityNodes/composables/useInstallNode';
|
||||
import { useNodeCreatorStore } from '@/stores/nodeCreator.store';
|
||||
import { useUsersStore } from '@/features/users/users.store';
|
||||
import { getNodeIconSource } from '@/utils/nodeIcon';
|
||||
import { N8nButton, N8nIcon, N8nText, N8nTooltip } from '@n8n/design-system';
|
||||
import { i18n } from '@n8n/i18n';
|
||||
import OfficialIcon from 'virtual:icons/mdi/verified';
|
||||
import { computed } from 'vue';
|
||||
import { useViewStacks } from '@/components/Node/NodeCreator/composables/useViewStacks';
|
||||
import {
|
||||
prepareCommunityNodeDetailsViewStack,
|
||||
removePreviewToken,
|
||||
} from '@/components/Node/NodeCreator/utils';
|
||||
import NodeIcon from '@/components/NodeIcon.vue';
|
||||
|
||||
const {
|
||||
activeViewStack,
|
||||
pushViewStack,
|
||||
popViewStack,
|
||||
getAllNodeCreateElements,
|
||||
updateCurrentViewStack,
|
||||
} = useViewStacks();
|
||||
|
||||
const { communityNodeDetails } = activeViewStack;
|
||||
|
||||
const nodeCreatorStore = useNodeCreatorStore();
|
||||
const { installNode, loading } = useInstallNode();
|
||||
|
||||
const isOwner = computed(() => useUsersStore().isInstanceOwner);
|
||||
|
||||
const updateViewStack = (key: string) => {
|
||||
const installedNodeKey = removePreviewToken(key);
|
||||
const installedNode = getAllNodeCreateElements().find((node) => node.key === installedNodeKey);
|
||||
|
||||
if (installedNode) {
|
||||
const nodeActions = nodeCreatorStore.actions?.[installedNode.key] || [];
|
||||
|
||||
popViewStack();
|
||||
|
||||
updateCurrentViewStack({ searchItems: nodeCreatorStore.mergedNodes });
|
||||
|
||||
const viewStack = prepareCommunityNodeDetailsViewStack(
|
||||
installedNode,
|
||||
getNodeIconSource(installedNode.properties),
|
||||
activeViewStack.rootView,
|
||||
nodeActions,
|
||||
);
|
||||
|
||||
pushViewStack(viewStack, {
|
||||
transitionDirection: 'none',
|
||||
});
|
||||
} else {
|
||||
const viewStack = { ...activeViewStack };
|
||||
viewStack.communityNodeDetails!.installed = true;
|
||||
|
||||
pushViewStack(activeViewStack, { resetStacks: true });
|
||||
}
|
||||
};
|
||||
|
||||
const updateStoresAndViewStack = (key: string) => {
|
||||
updateViewStack(key);
|
||||
nodeCreatorStore.removeNodeFromMergedNodes(key);
|
||||
};
|
||||
|
||||
const onInstall = async () => {
|
||||
if (isOwner.value && activeViewStack.communityNodeDetails && !communityNodeDetails?.installed) {
|
||||
const { key, packageName } = activeViewStack.communityNodeDetails;
|
||||
const result = await installNode({ type: 'verified', packageName, nodeType: key });
|
||||
if (result.success) {
|
||||
updateStoresAndViewStack(key);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="communityNodeDetails" :class="$style.container">
|
||||
<div :class="$style.header">
|
||||
<div :class="$style.title">
|
||||
<NodeIcon
|
||||
v-if="communityNodeDetails.nodeIcon"
|
||||
:class="$style.nodeIcon"
|
||||
:icon-source="communityNodeDetails.nodeIcon"
|
||||
:circle="false"
|
||||
:show-tooltip="false"
|
||||
/>
|
||||
<span>{{ communityNodeDetails.title }}</span>
|
||||
<N8nTooltip v-if="communityNodeDetails.official" placement="bottom" :show-after="500">
|
||||
<template #content>
|
||||
{{
|
||||
i18n.baseText('generic.officialNode.tooltip', {
|
||||
interpolate: {
|
||||
author: communityNodeDetails.companyName ?? communityNodeDetails.title,
|
||||
},
|
||||
})
|
||||
}}
|
||||
</template>
|
||||
<OfficialIcon :class="$style.officialIcon" />
|
||||
</N8nTooltip>
|
||||
</div>
|
||||
<div>
|
||||
<div v-if="communityNodeDetails.installed" :class="$style.installed">
|
||||
<N8nIcon v-if="!communityNodeDetails.official" :class="$style.installedIcon" icon="box" />
|
||||
<N8nText color="text-light" size="small" bold>
|
||||
{{ i18n.baseText('communityNodeDetails.installed') }}
|
||||
</N8nText>
|
||||
</div>
|
||||
|
||||
<N8nButton
|
||||
v-if="isOwner && !communityNodeDetails.installed"
|
||||
:loading="loading"
|
||||
:disabled="loading"
|
||||
:label="i18n.baseText('communityNodeDetails.install')"
|
||||
size="small"
|
||||
data-test-id="install-community-node-button"
|
||||
@click="onInstall"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" module>
|
||||
.container {
|
||||
width: 100%;
|
||||
padding: var(--spacing--sm);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-bottom: var(--spacing--xs);
|
||||
}
|
||||
.header {
|
||||
display: flex;
|
||||
gap: var(--spacing--2xs);
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: var(--color-text);
|
||||
font-size: var(--font-size--xl);
|
||||
font-weight: var(--font-weight--bold);
|
||||
}
|
||||
.nodeIcon {
|
||||
--node--icon--size: 36px;
|
||||
margin-right: var(--spacing--sm);
|
||||
}
|
||||
|
||||
.installedIcon {
|
||||
margin-right: var(--spacing--3xs);
|
||||
color: var(--color--text);
|
||||
font-size: var(--font-size--2xs);
|
||||
}
|
||||
|
||||
.officialIcon {
|
||||
display: inline-flex;
|
||||
flex-shrink: 0;
|
||||
margin-left: var(--spacing--4xs);
|
||||
color: var(--color--text);
|
||||
width: 14px;
|
||||
}
|
||||
|
||||
.installed {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-right: var(--spacing--xs);
|
||||
}
|
||||
</style>
|
||||
|
|
@ -6,12 +6,12 @@ import CommunityNodeFooter from './CommunityNodeFooter.vue';
|
|||
import { createComponentRenderer } from '@/__tests__/render';
|
||||
import { vi } from 'vitest';
|
||||
import { ref } from 'vue';
|
||||
import type { ExtendedPublicInstalledPackage } from '@/utils/communityNodeUtils';
|
||||
import type { ExtendedPublicInstalledPackage } from '../../communityNodes.utils';
|
||||
|
||||
// Mock the useInstalledCommunityPackage composable
|
||||
const mockInstalledPackage = ref<ExtendedPublicInstalledPackage | undefined>(undefined);
|
||||
|
||||
vi.mock('@/composables/useInstalledCommunityPackage', () => ({
|
||||
vi.mock('../../composables/useInstalledCommunityPackage', () => ({
|
||||
useInstalledCommunityPackage: vi.fn(() => ({
|
||||
installedPackage: mockInstalledPackage,
|
||||
isUpdateCheckAvailable: ref(false),
|
||||
|
|
@ -4,7 +4,7 @@ import { captureException } from '@sentry/vue';
|
|||
import { onMounted, ref } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
import { useInstalledCommunityPackage } from '@/composables/useInstalledCommunityPackage';
|
||||
import { useInstalledCommunityPackage } from '../../composables/useInstalledCommunityPackage';
|
||||
import { i18n } from '@n8n/i18n';
|
||||
|
||||
import { N8nLink, N8nText } from '@n8n/design-system';
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
import { createComponentRenderer } from '@/__tests__/render';
|
||||
import { useInstalledCommunityPackage } from '@/composables/useInstalledCommunityPackage';
|
||||
import type { ExtendedPublicInstalledPackage } from '@/utils/communityNodeUtils';
|
||||
import { useInstalledCommunityPackage } from '../../composables/useInstalledCommunityPackage';
|
||||
import type { ExtendedPublicInstalledPackage } from '../../communityNodes.utils';
|
||||
import { type TestingPinia, createTestingPinia } from '@pinia/testing';
|
||||
import { waitFor } from '@testing-library/vue';
|
||||
import { setActivePinia } from 'pinia';
|
||||
import { type ComputedRef, ref } from 'vue';
|
||||
import type { CommunityNodeDetails } from '../composables/useViewStacks';
|
||||
import type { CommunityNodeDetails } from '@/components/Node/NodeCreator/composables/useViewStacks';
|
||||
import CommunityNodeInfo from './CommunityNodeInfo.vue';
|
||||
|
||||
vi.mock('./utils', () => ({
|
||||
|
|
@ -26,7 +26,7 @@ const defaultUseInstalledCommunityPackage = {
|
|||
initInstalledPackage: vi.fn(),
|
||||
} as unknown as ReturnType<typeof useInstalledCommunityPackage>;
|
||||
|
||||
vi.mock('@/composables/useInstalledCommunityPackage', () => ({
|
||||
vi.mock('../../composables/useInstalledCommunityPackage', () => ({
|
||||
useInstalledCommunityPackage: vi.fn(() => defaultUseInstalledCommunityPackage),
|
||||
}));
|
||||
|
||||
|
|
@ -44,7 +44,7 @@ vi.mock('@/features/users/users.store', () => ({
|
|||
})),
|
||||
}));
|
||||
|
||||
vi.mock('../composables/useViewStacks', () => ({
|
||||
vi.mock('@/components/Node/NodeCreator/composables/useViewStacks', () => ({
|
||||
useViewStacks: vi.fn(),
|
||||
}));
|
||||
|
||||
|
|
@ -94,7 +94,9 @@ describe('CommunityNodeInfo', () => {
|
|||
originalFetch = global.fetch;
|
||||
global.fetch = vi.fn();
|
||||
|
||||
const { useViewStacks } = await import('../composables/useViewStacks');
|
||||
const { useViewStacks } = await import(
|
||||
'@/components/Node/NodeCreator/composables/useViewStacks'
|
||||
);
|
||||
vi.mocked(useViewStacks).mockReturnValue({
|
||||
activeViewStack: defaultViewStack,
|
||||
} as ReturnType<typeof useViewStacks>);
|
||||
|
|
@ -135,7 +137,9 @@ describe('CommunityNodeInfo', () => {
|
|||
});
|
||||
|
||||
it('should display update notice, should show verified badge for older versions', async () => {
|
||||
const { useViewStacks } = await import('../composables/useViewStacks');
|
||||
const { useViewStacks } = await import(
|
||||
'@/components/Node/NodeCreator/composables/useViewStacks'
|
||||
);
|
||||
vi.mocked(useViewStacks).mockReturnValue({
|
||||
activeViewStack: {
|
||||
...defaultViewStack,
|
||||
|
|
@ -179,7 +183,9 @@ describe('CommunityNodeInfo', () => {
|
|||
});
|
||||
|
||||
it('should NOT display update notice for unverified update', async () => {
|
||||
const { useViewStacks } = await import('../composables/useViewStacks');
|
||||
const { useViewStacks } = await import(
|
||||
'@/components/Node/NodeCreator/composables/useViewStacks'
|
||||
);
|
||||
vi.mocked(useViewStacks).mockReturnValue({
|
||||
activeViewStack: {
|
||||
...defaultViewStack,
|
||||
|
|
@ -1,16 +1,16 @@
|
|||
<script setup lang="ts">
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
import { useViewStacks } from '../composables/useViewStacks';
|
||||
import { useViewStacks } from '@/components/Node/NodeCreator/composables/useViewStacks';
|
||||
import { useUsersStore } from '@/features/users/users.store';
|
||||
import { i18n } from '@n8n/i18n';
|
||||
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
|
||||
import { captureException } from '@sentry/vue';
|
||||
import ShieldIcon from 'virtual:icons/fa-solid/shield-alt';
|
||||
import ContactAdministratorToInstall from '@/components/ContactAdministratorToInstall.vue';
|
||||
import { useInstalledCommunityPackage } from '@/composables/useInstalledCommunityPackage';
|
||||
import ContactAdministratorToInstall from '../ContactAdministratorToInstall.vue';
|
||||
import { useInstalledCommunityPackage } from '../../composables/useInstalledCommunityPackage';
|
||||
|
||||
import { N8nIcon, N8nText, N8nTooltip } from '@n8n/design-system';
|
||||
import CommunityNodeUpdateInfo from '@/components/Node/NodeCreator/Panel/CommunityNodeUpdateInfo.vue';
|
||||
import CommunityNodeUpdateInfo from './CommunityNodeUpdateInfo.vue';
|
||||
|
||||
const { activeViewStack } = useViewStacks();
|
||||
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import { removePreviewToken } from '@/components/Node/NodeCreator/utils';
|
||||
import type { IWorkflowDb } from '@/Interface';
|
||||
import { useCommunityNodesStore } from '@/stores/communityNodes.store';
|
||||
import { useCommunityNodesStore } from '../communityNodes.store';
|
||||
import { useCredentialsStore } from '@/stores/credentials.store';
|
||||
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
|
||||
import { useUsersStore } from '@/features/users/users.store';
|
||||
|
|
@ -9,9 +9,9 @@ import type { CommunityNodeType } from '@n8n/api-types';
|
|||
import { createTestingPinia } from '@pinia/testing';
|
||||
import type { INode } from 'n8n-workflow';
|
||||
import { setActivePinia } from 'pinia';
|
||||
import { useCanvasOperations } from './useCanvasOperations';
|
||||
import { useCanvasOperations } from '@/composables/useCanvasOperations';
|
||||
import { useInstallNode } from './useInstallNode';
|
||||
import { useToast } from './useToast';
|
||||
import { useToast } from '@/composables/useToast';
|
||||
|
||||
vi.mock('@/composables/useCanvasOperations', () => ({
|
||||
useCanvasOperations: vi.fn().mockReturnValue({
|
||||
|
|
@ -19,7 +19,7 @@ vi.mock('@/composables/useCanvasOperations', () => ({
|
|||
}),
|
||||
}));
|
||||
|
||||
vi.mock('./useToast', () => ({
|
||||
vi.mock('@/composables/useToast', () => ({
|
||||
useToast: vi.fn().mockReturnValue({
|
||||
showError: vi.fn(),
|
||||
showMessage: vi.fn(),
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
import { useCommunityNodesStore } from '@/stores/communityNodes.store';
|
||||
import { useCommunityNodesStore } from '../communityNodes.store';
|
||||
import { useCredentialsStore } from '@/stores/credentials.store';
|
||||
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
|
||||
import { useUsersStore } from '@/features/users/users.store';
|
||||
import { computed, nextTick, ref } from 'vue';
|
||||
import { i18n } from '@n8n/i18n';
|
||||
import { useToast } from './useToast';
|
||||
import { useToast } from '@/composables/useToast';
|
||||
import { useWorkflowsStore } from '@/stores/workflows.store';
|
||||
import { useCanvasOperations } from './useCanvasOperations';
|
||||
import { useCanvasOperations } from '@/composables/useCanvasOperations';
|
||||
import { removePreviewToken } from '@/components/Node/NodeCreator/utils';
|
||||
|
||||
type InstallNodeProps = {
|
||||
|
|
@ -5,9 +5,9 @@ import { nextTick } from 'vue';
|
|||
import { mockedStore } from '@/__tests__/utils';
|
||||
|
||||
import { useInstalledCommunityPackage } from './useInstalledCommunityPackage';
|
||||
import { useCommunityNodesStore } from '@/stores/communityNodes.store';
|
||||
import { useCommunityNodesStore } from '../communityNodes.store';
|
||||
import { useUsersStore } from '@/features/users/users.store';
|
||||
import type { ExtendedPublicInstalledPackage } from '@/utils/communityNodeUtils';
|
||||
import type { ExtendedPublicInstalledPackage } from '../communityNodes.utils';
|
||||
import type * as n8nWorkflow from 'n8n-workflow';
|
||||
|
||||
vi.mock('n8n-workflow', async (importOriginal) => {
|
||||
|
|
@ -18,13 +18,13 @@ vi.mock('n8n-workflow', async (importOriginal) => {
|
|||
};
|
||||
});
|
||||
|
||||
vi.mock('@/utils/communityNodeUtils', () => ({
|
||||
vi.mock('../communityNodes.utils', () => ({
|
||||
fetchInstalledPackageInfo: vi.fn(),
|
||||
}));
|
||||
|
||||
// Import mocked functions
|
||||
import { isCommunityPackageName } from 'n8n-workflow';
|
||||
import { fetchInstalledPackageInfo } from '@/utils/communityNodeUtils';
|
||||
import { fetchInstalledPackageInfo } from '../communityNodes.utils';
|
||||
|
||||
const mockIsCommunityPackageName = vi.mocked(isCommunityPackageName);
|
||||
const mockFetchInstalledPackageInfo = vi.mocked(fetchInstalledPackageInfo);
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
import { useCommunityNodesStore } from '@/stores/communityNodes.store';
|
||||
import { useCommunityNodesStore } from '../communityNodes.store';
|
||||
import { useUsersStore } from '@/features/users/users.store';
|
||||
import { isCommunityPackageName } from 'n8n-workflow';
|
||||
import {
|
||||
type ExtendedPublicInstalledPackage,
|
||||
fetchInstalledPackageInfo,
|
||||
} from '@/utils/communityNodeUtils';
|
||||
} from '../communityNodes.utils';
|
||||
import { computed, type MaybeRefOrGetter, onMounted, ref, watch, toValue } from 'vue';
|
||||
|
||||
export function useInstalledCommunityPackage(nodeTypeName?: MaybeRefOrGetter<string | undefined>) {
|
||||
|
|
@ -2,13 +2,13 @@
|
|||
import {
|
||||
COMMUNITY_PACKAGE_INSTALL_MODAL_KEY,
|
||||
COMMUNITY_NODES_INSTALLATION_DOCS_URL,
|
||||
} from '@/constants';
|
||||
import CommunityPackageCard from '@/components/CommunityPackageCard.vue';
|
||||
} from '../communityNodes.constants';
|
||||
import CommunityPackageCard from '../components/CommunityPackageCard.vue';
|
||||
import { useToast } from '@/composables/useToast';
|
||||
import { useDocumentTitle } from '@/composables/useDocumentTitle';
|
||||
import type { PublicInstalledPackage } from 'n8n-workflow';
|
||||
|
||||
import { useCommunityNodesStore } from '@/stores/communityNodes.store';
|
||||
import { useCommunityNodesStore } from '../communityNodes.store';
|
||||
import { useUIStore } from '@/stores/ui.store';
|
||||
import { onBeforeUnmount, ref, computed, onBeforeMount, onMounted } from 'vue';
|
||||
import { useExternalHooks } from '@/composables/useExternalHooks';
|
||||
|
|
@ -44,7 +44,7 @@ const SettingsPersonalView = async () =>
|
|||
await import('@/features/auth/views/SettingsPersonalView.vue');
|
||||
const SettingsUsersView = async () => await import('@/features/users/views/SettingsUsersView.vue');
|
||||
const SettingsCommunityNodesView = async () =>
|
||||
await import('./views/SettingsCommunityNodesView.vue');
|
||||
await import('@/features/communityNodes/views/SettingsCommunityNodesView.vue');
|
||||
const SettingsApiView = async () => await import('@/features/apiKeys/views/SettingsApiView.vue');
|
||||
const SettingsLogStreamingView = async () =>
|
||||
await import('@/features/logStreaming.ee/views/SettingsLogStreamingView.vue');
|
||||
|
|
|
|||
|
|
@ -2,9 +2,6 @@ import {
|
|||
ABOUT_MODAL_KEY,
|
||||
CHAT_EMBED_MODAL_KEY,
|
||||
CHANGE_PASSWORD_MODAL_KEY,
|
||||
COMMUNITY_PACKAGE_CONFIRM_MODAL_KEY,
|
||||
COMMUNITY_PACKAGE_INSTALL_MODAL_KEY,
|
||||
COMMUNITY_PACKAGE_MANAGE_ACTIONS,
|
||||
CONTACT_PROMPT_MODAL_KEY,
|
||||
CREDENTIAL_EDIT_MODAL_KEY,
|
||||
CREDENTIAL_SELECT_MODAL_KEY,
|
||||
|
|
@ -55,6 +52,11 @@ import {
|
|||
SOURCE_CONTROL_PUSH_MODAL_KEY,
|
||||
SOURCE_CONTROL_PULL_MODAL_KEY,
|
||||
} from '@/features/sourceControl.ee/sourceControl.constants';
|
||||
import {
|
||||
COMMUNITY_PACKAGE_CONFIRM_MODAL_KEY,
|
||||
COMMUNITY_PACKAGE_INSTALL_MODAL_KEY,
|
||||
COMMUNITY_PACKAGE_MANAGE_ACTIONS,
|
||||
} from '@/features/communityNodes/communityNodes.constants';
|
||||
import { API_KEY_CREATE_OR_EDIT_MODAL_KEY } from '@/features/apiKeys/apiKeys.constants';
|
||||
import { STORES } from '@n8n/stores';
|
||||
import type {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user