diff --git a/packages/editor-ui/src/plugins/i18n/locales/en.json b/packages/editor-ui/src/plugins/i18n/locales/en.json index e40f8fe35..0e7454c12 100644 --- a/packages/editor-ui/src/plugins/i18n/locales/en.json +++ b/packages/editor-ui/src/plugins/i18n/locales/en.json @@ -1292,6 +1292,9 @@ "settings.usageAndPlan.desktop.title": "Upgrade to n8n Cloud for the full experience", "settings.usageAndPlan.desktop.description": "Cloud plans allow you to collaborate with teammates. Plus you don’t need to leave this app open all the time for your workflows to run.", "settings.versionControl.title": "Version Control", + "settings.versionControl.actionBox.title": "Available on Enterprise plan", + "settings.versionControl.actionBox.description": "Use Version Control to connect your instance to an external Git repository to backup and track changes made to your workflows, variables, and credentials. With Version Control you can also sync instances across multiple environments (development, production...).", + "settings.versionControl.actionBox.buttonText": "See plans", "showMessage.cancel": "@:_reusableBaseText.cancel", "showMessage.ok": "OK", "showMessage.showDetails": "Show Details", diff --git a/packages/editor-ui/src/stores/versionControl.ts b/packages/editor-ui/src/stores/versionControl.ts new file mode 100644 index 000000000..315d20445 --- /dev/null +++ b/packages/editor-ui/src/stores/versionControl.ts @@ -0,0 +1,16 @@ +import { computed } from 'vue'; +import { defineStore } from 'pinia'; +import { EnterpriseEditionFeature } from '@/constants'; +import { useSettingsStore } from '@/stores/settings'; + +export const useVersionControlStore = defineStore('versionControl', () => { + const settingsStore = useSettingsStore(); + + const isEnterpriseVersionControlEnabled = computed(() => + settingsStore.isEnterpriseFeatureEnabled(EnterpriseEditionFeature.VersionControl), + ); + + return { + isEnterpriseVersionControlEnabled, + }; +}); diff --git a/packages/editor-ui/src/views/SettingsVersionControl.vue b/packages/editor-ui/src/views/SettingsVersionControl.vue index ca0a897e6..4c6906c6a 100644 --- a/packages/editor-ui/src/views/SettingsVersionControl.vue +++ b/packages/editor-ui/src/views/SettingsVersionControl.vue @@ -1,11 +1,40 @@ - + diff --git a/packages/editor-ui/src/views/__tests__/SettingsVersionControl.test.ts b/packages/editor-ui/src/views/__tests__/SettingsVersionControl.test.ts new file mode 100644 index 000000000..c3bec841c --- /dev/null +++ b/packages/editor-ui/src/views/__tests__/SettingsVersionControl.test.ts @@ -0,0 +1,60 @@ +import { PiniaVuePlugin } from 'pinia'; +import { render } from '@testing-library/vue'; +import { createTestingPinia } from '@pinia/testing'; +import { merge } from 'lodash-es'; +import { STORES } from '@/constants'; +import { SETTINGS_STORE_DEFAULT_STATE } from '@/__tests__/utils'; +import { i18n } from '@/plugins/i18n'; +import SettingsVersionControl from '@/views/SettingsVersionControl.vue'; +import { useVersionControlStore } from '@/stores/versionControl'; + +let pinia: ReturnType; +let versionControlStore: ReturnType; + +const renderComponent = (renderOptions: Parameters[1] = {}) => + render( + SettingsVersionControl, + merge( + { + pinia, + i18n, + }, + renderOptions, + ), + (vue) => { + vue.use(PiniaVuePlugin); + }, + ); + +describe('SettingsSso', () => { + beforeEach(() => { + pinia = createTestingPinia({ + initialState: { + [STORES.SETTINGS]: { + settings: merge({}, SETTINGS_STORE_DEFAULT_STATE.settings), + }, + }, + }); + versionControlStore = useVersionControlStore(pinia); + }); + + afterEach(() => { + vi.clearAllMocks(); + }); + + it('should render paywall state when there is no license', () => { + const { getByTestId, queryByTestId } = renderComponent(); + + expect(queryByTestId('version-control-content-licensed')).not.toBeInTheDocument(); + expect(getByTestId('version-control-content-unlicensed')).toBeInTheDocument(); + }); + + it('should render licensed content', () => { + vi.spyOn(versionControlStore, 'isEnterpriseVersionControlEnabled', 'get').mockReturnValue(true); + + const { getByTestId, queryByTestId } = renderComponent(); + + expect(getByTestId('version-control-content-licensed')).toBeInTheDocument(); + expect(queryByTestId('version-control-content-unlicensed')).not.toBeInTheDocument(); + }); +});