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:
Csaba Tuncsik 2023-04-21 11:25:39 +02:00 committed by GitHub
parent a74284bac3
commit ef79b03f38
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 109 additions and 1 deletions

View file

@ -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 dont 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",

View 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,
};
});

View file

@ -1,11 +1,40 @@
<script lang="ts" setup>
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>
<template>
<div>
<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>
</template>
<style lang="scss" module></style>
<style lang="scss" module>
.actionBox {
margin: var(--spacing-2xl) 0 0;
}
</style>

View file

@ -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();
});
});