refactor(editor): Move editor-ui and design-system to frontend dir (no-changelog) (#13564)

This commit is contained in:
Alex Grozav
2025-02-28 14:28:30 +02:00
committed by GitHub
parent 684353436d
commit f5743176e5
1635 changed files with 805 additions and 1079 deletions

View File

@@ -0,0 +1,56 @@
import { createComponentRenderer } from '@/__tests__/render';
import SetupWorkflowCredentialsButton from '@/components/SetupWorkflowCredentialsButton/SetupWorkflowCredentialsButton.vue';
import { createTestingPinia } from '@pinia/testing';
import { mockedStore } from '@/__tests__/utils';
import { useWorkflowsStore } from '@/stores/workflows.store';
vi.mock('vue-router', async () => {
const actual = await vi.importActual('vue-router');
const params = {};
const location = {};
return {
...actual,
useRouter: () => ({
push: vi.fn(),
}),
useRoute: () => ({
params,
location,
}),
};
});
let workflowsStore: ReturnType<typeof mockedStore<typeof useWorkflowsStore>>;
const renderComponent = createComponentRenderer(SetupWorkflowCredentialsButton);
const EMPTY_WORKFLOW = {
id: '__EMPTY__',
createdAt: -1,
updatedAt: -1,
versionId: '1',
name: 'Email Summary Agent ',
active: false,
connections: {},
nodes: [],
usedCredentials: [],
meta: { templateId: '2722', templateCredsSetupCompleted: true },
};
describe('SetupWorkflowCredentialsButton', () => {
beforeEach(() => {
createTestingPinia();
workflowsStore = mockedStore(useWorkflowsStore);
});
it('renders', () => {
workflowsStore.workflow = EMPTY_WORKFLOW;
expect(() => renderComponent()).not.toThrow();
});
it('does not render the button if there are no nodes', () => {
workflowsStore.workflow = EMPTY_WORKFLOW;
const { queryByTestId } = renderComponent();
expect(queryByTestId('setup-credentials-button')).toBeNull();
});
});

View File

@@ -0,0 +1,73 @@
<script lang="ts" setup>
import { computed, onBeforeUnmount, watch } from 'vue';
import { useI18n } from '@/composables/useI18n';
import { SETUP_CREDENTIALS_MODAL_KEY, TEMPLATE_CREDENTIAL_SETUP_EXPERIMENT } from '@/constants';
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
import { usePostHog } from '@/stores/posthog.store';
import { useUIStore } from '@/stores/ui.store';
import { useWorkflowsStore } from '@/stores/workflows.store';
import { doesNodeHaveAllCredentialsFilled } from '@/utils/nodes/nodeTransforms';
const workflowsStore = useWorkflowsStore();
const nodeTypesStore = useNodeTypesStore();
const uiStore = useUIStore();
const posthogStore = usePostHog();
const i18n = useI18n();
const isTemplateSetupCompleted = computed(() => {
return !!workflowsStore.workflow?.meta?.templateCredsSetupCompleted;
});
const allCredentialsFilled = computed(() => {
if (isTemplateSetupCompleted.value) {
return true;
}
const nodes = workflowsStore.getNodes();
if (!nodes.length) {
return true;
}
return nodes.every((node) => doesNodeHaveAllCredentialsFilled(nodeTypesStore, node));
});
const showButton = computed(() => {
const isFeatureEnabled = posthogStore.isFeatureEnabled(TEMPLATE_CREDENTIAL_SETUP_EXPERIMENT);
const isCreatedFromTemplate = !!workflowsStore.workflow?.meta?.templateId;
if (!isFeatureEnabled || !isCreatedFromTemplate || isTemplateSetupCompleted.value) {
return false;
}
return !allCredentialsFilled.value;
});
const unsubscribe = watch(allCredentialsFilled, (newValue) => {
if (newValue) {
workflowsStore.addToWorkflowMetadata({
templateCredsSetupCompleted: true,
});
unsubscribe();
}
});
const handleClick = () => {
uiStore.openModal(SETUP_CREDENTIALS_MODAL_KEY);
};
onBeforeUnmount(() => {
uiStore.closeModal(SETUP_CREDENTIALS_MODAL_KEY);
});
</script>
<template>
<n8n-button
v-if="showButton"
:label="i18n.baseText('nodeView.setupTemplate')"
data-test-id="setup-credentials-button"
size="large"
icon="box-open"
type="secondary"
@click="handleClick()"
/>
</template>