Skip to content
/ qp-n8n Public
forked from n8n-io/n8n

Commit

Permalink
feat(editor): Version control paywall (WIP) (n8n-io#6030)
Browse files Browse the repository at this point in the history
* feat(editor): Version control paywall (WIP)

* fix(editor): remove version control docs link
  • Loading branch information
cstuncsik authored and sunilrr committed Apr 24, 2023
1 parent 8bdb3d7 commit f4f7de8
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 1 deletion.
3 changes: 3 additions & 0 deletions packages/editor-ui/src/plugins/i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1293,6 +1293,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",
Expand Down
16 changes: 16 additions & 0 deletions packages/editor-ui/src/stores/versionControl.ts
Original file line number Diff line number Diff line change
@@ -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,
};
});
31 changes: 30 additions & 1 deletion packages/editor-ui/src/views/SettingsVersionControl.vue
Original file line number Diff line number Diff line change
@@ -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>
Original file line number Diff line number Diff line change
@@ -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();
});
});

0 comments on commit f4f7de8

Please sign in to comment.