mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 18:12:04 +00:00
fix(editor): Hide Evaluations setup wizard if protected instance (#18055)
This commit is contained in:
@@ -3295,6 +3295,7 @@
|
||||
"evaluation.executions.toast.addedTo.title": "Execution added to test ",
|
||||
"evaluation.executions.toast.closeTab": "Close this tab",
|
||||
"evaluation.executions.toast.removedFrom.title": "Execution removed from test ",
|
||||
"evaluations.readOnlyNotice": "Evaluations can't be built in read-only mode. Build your evaluation on your development environment.",
|
||||
"evaluations.paywall.title": "Register to enable evaluation",
|
||||
"evaluations.paywall.description": "Register your Community instance to unlock the evaluation feature",
|
||||
"evaluations.paywall.cta": "Register instance",
|
||||
|
||||
@@ -9,9 +9,10 @@ import { useToast } from '@/composables/useToast';
|
||||
import { useI18n } from '@n8n/i18n';
|
||||
import { useEvaluationStore } from '@/stores/evaluation.store.ee';
|
||||
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
|
||||
import { useSourceControlStore } from '@/stores/sourceControl.store';
|
||||
|
||||
import { computed, watch } from 'vue';
|
||||
import { N8nLink, N8nText } from '@n8n/design-system';
|
||||
import { N8nCallout, N8nLink, N8nText } from '@n8n/design-system';
|
||||
import EvaluationsPaywall from '@/components/Evaluations.ee/Paywall/EvaluationsPaywall.vue';
|
||||
import SetupWizard from '@/components/Evaluations.ee/SetupWizard/SetupWizard.vue';
|
||||
|
||||
@@ -26,6 +27,7 @@ const nodeTypesStore = useNodeTypesStore();
|
||||
const telemetry = useTelemetry();
|
||||
const toast = useToast();
|
||||
const locale = useI18n();
|
||||
const sourceControlStore = useSourceControlStore();
|
||||
|
||||
const { initializeWorkspace } = useCanvasOperations();
|
||||
|
||||
@@ -33,6 +35,10 @@ const evaluationsLicensed = computed(() => {
|
||||
return usageStore.workflowsWithEvaluationsLimit !== 0;
|
||||
});
|
||||
|
||||
const isProtectedEnvironment = computed(() => {
|
||||
return sourceControlStore.preferences.branchReadOnly;
|
||||
});
|
||||
|
||||
const runs = computed(() => {
|
||||
return Object.values(evaluationStore.testRunsById ?? {}).filter(
|
||||
({ workflowId }) => workflowId === props.name,
|
||||
@@ -142,7 +148,10 @@ watch(
|
||||
</N8nText>
|
||||
</div>
|
||||
|
||||
<div :class="$style.config">
|
||||
<N8nCallout v-if="isProtectedEnvironment" theme="info" icon="info">
|
||||
{{ locale.baseText('evaluations.readOnlyNotice') }}
|
||||
</N8nCallout>
|
||||
<div v-else :class="$style.config">
|
||||
<iframe
|
||||
style="min-width: 500px"
|
||||
width="500"
|
||||
|
||||
@@ -7,6 +7,7 @@ import EvaluationRootView from '../EvaluationsRootView.vue';
|
||||
import { useWorkflowsStore } from '@/stores/workflows.store';
|
||||
import { useEvaluationStore } from '@/stores/evaluation.store.ee';
|
||||
import { useUsageStore } from '@/stores/usage.store';
|
||||
import { useSourceControlStore } from '@/stores/sourceControl.store';
|
||||
import { mockedStore } from '@/__tests__/utils';
|
||||
import type { IWorkflowDb } from '@/Interface';
|
||||
import { waitFor } from '@testing-library/vue';
|
||||
@@ -15,6 +16,7 @@ import { PLACEHOLDER_EMPTY_WORKFLOW_ID } from '@/constants';
|
||||
import { useTelemetry } from '@/composables/useTelemetry';
|
||||
import { EVALUATION_NODE_TYPE, EVALUATION_TRIGGER_NODE_TYPE, NodeHelpers } from 'n8n-workflow';
|
||||
import { mockNodeTypeDescription } from '@/__tests__/mocks';
|
||||
import type { SourceControlPreferences } from '@/types/sourceControl.types';
|
||||
|
||||
vi.mock('@/composables/useTelemetry', () => {
|
||||
const track = vi.fn();
|
||||
@@ -32,6 +34,15 @@ vi.mock('@/stores/nodeTypes.store', () => ({
|
||||
})),
|
||||
}));
|
||||
|
||||
vi.mock('@n8n/i18n', async (importOriginal) => {
|
||||
return {
|
||||
...(await importOriginal()),
|
||||
useI18n: () => ({
|
||||
baseText: vi.fn((key: string) => `mocked-${key}`),
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
describe('EvaluationsRootView', () => {
|
||||
const renderComponent = createComponentRenderer(EvaluationRootView);
|
||||
|
||||
@@ -127,6 +138,21 @@ describe('EvaluationsRootView', () => {
|
||||
await waitFor(() => expect(container.querySelector('.setupContent')).toBeTruthy());
|
||||
});
|
||||
|
||||
it('should render read-only callout when in protected environment', async () => {
|
||||
const workflowsStore = mockedStore(useWorkflowsStore);
|
||||
const sourceControlStore = mockedStore(useSourceControlStore);
|
||||
workflowsStore.fetchWorkflow.mockResolvedValue(mockWorkflow);
|
||||
sourceControlStore.preferences = mock<SourceControlPreferences>({ branchReadOnly: true });
|
||||
|
||||
const { container } = renderComponent({ props: { name: mockWorkflow.id } });
|
||||
|
||||
await waitFor(() => {
|
||||
const callout = container.querySelector('[role="alert"]');
|
||||
expect(callout).toBeTruthy();
|
||||
expect(callout?.textContent).toContain('mocked-evaluations.readOnlyNotice');
|
||||
});
|
||||
});
|
||||
|
||||
describe('telemetry', () => {
|
||||
it('should send telemetry event on mount with setup view when no test runs exist', async () => {
|
||||
const workflowsStore = mockedStore(useWorkflowsStore);
|
||||
|
||||
Reference in New Issue
Block a user