mirror of
https://github.com/n8n-io/n8n.git
synced 2024-12-25 20:54:07 -08:00
feat(editor): Version control paywall (WIP) (#6030)
* feat(editor): Version control paywall (WIP) * fix(editor): remove version control docs link
This commit is contained in:
parent
a74284bac3
commit
ef79b03f38
|
@ -1292,6 +1292,9 @@
|
||||||
"settings.usageAndPlan.desktop.title": "Upgrade to n8n Cloud for the full experience",
|
"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.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.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.cancel": "@:_reusableBaseText.cancel",
|
||||||
"showMessage.ok": "OK",
|
"showMessage.ok": "OK",
|
||||||
"showMessage.showDetails": "Show Details",
|
"showMessage.showDetails": "Show Details",
|
||||||
|
|
16
packages/editor-ui/src/stores/versionControl.ts
Normal file
16
packages/editor-ui/src/stores/versionControl.ts
Normal file
|
@ -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,
|
||||||
|
};
|
||||||
|
});
|
|
@ -1,11 +1,40 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { i18n as locale } from '@/plugins/i18n';
|
import { i18n as locale } from '@/plugins/i18n';
|
||||||
|
import { useVersionControlStore } from '@/stores/versionControl';
|
||||||
|
import { useUIStore } from '@/stores/ui';
|
||||||
|
|
||||||
|
const versionControlStore = useVersionControlStore();
|
||||||
|
const uiStore = useUIStore();
|
||||||
|
|
||||||
|
const goToUpgrade = () => {
|
||||||
|
uiStore.goToUpgrade('version-control', 'upgrade-version-control');
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<n8n-heading size="2xlarge">{{ locale.baseText('settings.versionControl.title') }}</n8n-heading>
|
<n8n-heading size="2xlarge">{{ locale.baseText('settings.versionControl.title') }}</n8n-heading>
|
||||||
|
<div
|
||||||
|
v-if="versionControlStore.isEnterpriseVersionControlEnabled"
|
||||||
|
data-test-id="version-control-content-licensed"
|
||||||
|
></div>
|
||||||
|
<n8n-action-box
|
||||||
|
v-else
|
||||||
|
data-test-id="version-control-content-unlicensed"
|
||||||
|
:class="$style.actionBox"
|
||||||
|
:description="locale.baseText('settings.versionControl.actionBox.description')"
|
||||||
|
:buttonText="locale.baseText('settings.versionControl.actionBox.buttonText')"
|
||||||
|
@click="goToUpgrade"
|
||||||
|
>
|
||||||
|
<template #heading>
|
||||||
|
<span>{{ locale.baseText('settings.versionControl.actionBox.title') }}</span>
|
||||||
|
</template>
|
||||||
|
</n8n-action-box>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss" module></style>
|
<style lang="scss" module>
|
||||||
|
.actionBox {
|
||||||
|
margin: var(--spacing-2xl) 0 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -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<typeof createTestingPinia>;
|
||||||
|
let versionControlStore: ReturnType<typeof useVersionControlStore>;
|
||||||
|
|
||||||
|
const renderComponent = (renderOptions: Parameters<typeof render>[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();
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in a new issue