Skip to content

Commit

Permalink
fix(editor): Update Usage page for Community+ edition (#11074)
Browse files Browse the repository at this point in the history
  • Loading branch information
cstuncsik authored Oct 3, 2024
1 parent dbd2ae1 commit 3974981
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 4 deletions.
1 change: 1 addition & 0 deletions packages/editor-ui/src/plugins/i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1797,6 +1797,7 @@
"settings.usageAndPlan.license.activation.error.title": "Activation failed",
"settings.usageAndPlan.license.activation.success.title": "License activated",
"settings.usageAndPlan.license.activation.success.message": "Your {name} {type} has been successfully activated.",
"settings.usageAndPlan.license.communityRegistered.tooltip": "You have registered your email to unlock additional features on your community plan",
"settings.externalSecrets.title": "External Secrets",
"settings.externalSecrets.info": "Connect external secrets tools for centralized credentials management across environments, and to enhance system security.",
"settings.externalSecrets.info.link": "More info",
Expand Down
51 changes: 51 additions & 0 deletions packages/editor-ui/src/views/SettingsUsageAndPlan.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { createTestingPinia } from '@pinia/testing';
import { createComponentRenderer } from '@/__tests__/render';
import { mockedStore } from '@/__tests__/utils';
import { useUsageStore } from '@/stores/usage.store';
import SettingsUsageAndPlan from '@/views/SettingsUsageAndPlan.vue';

vi.mock('vue-router', () => {
return {
useRoute: () => ({
query: {},
}),
useRouter: () => ({
replace: vi.fn(),
}),
RouterLink: {
template: '<a><slot /></a>',
},
};
});

let usageStore: ReturnType<typeof mockedStore<typeof useUsageStore>>;

const renderComponent = createComponentRenderer(SettingsUsageAndPlan);

describe('SettingsUsageAndPlan', () => {
beforeEach(() => {
createTestingPinia();
usageStore = mockedStore(useUsageStore);
});

it('should not throw errors when rendering', async () => {
expect(() => renderComponent()).not.toThrow();
});

it('should render the title only while loading', async () => {
const { getByRole } = renderComponent();
expect(getByRole('heading', { level: 2 })).toBeInTheDocument();
expect(getByRole('heading').nextElementSibling).toBeNull();
});

it('should show community registered badge', async () => {
usageStore.isLoading = false;
usageStore.viewPlansUrl = 'https://subscription.n8n.io';
usageStore.managePlanUrl = 'https://subscription.n8n.io';
usageStore.planName = 'Community registered';
const { getByRole, container } = renderComponent();
expect(getByRole('heading', { level: 3 })).toHaveTextContent('Community Edition');
expect(getByRole('heading', { level: 3 })).toContain(container.querySelector('.n8n-badge'));
expect(container.querySelector('.n8n-badge')).toHaveTextContent('registered');
});
});
43 changes: 39 additions & 4 deletions packages/editor-ui/src/views/SettingsUsageAndPlan.vue
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,18 @@ const canUserActivateLicense = computed(() =>
hasPermission(['rbac'], { rbac: { scope: 'license:manage' } }),
);
const badgedPlanName = computed(() => {
const [name, badge] = usageStore.planName.split(' ');
return {
name,
badge,
};
});
const isCommunityEditionRegistered = computed(
() => usageStore.planName.toLowerCase() === 'community registered',
);
const showActivationSuccess = () => {
toast.showMessage({
type: 'success',
Expand Down Expand Up @@ -125,18 +137,34 @@ const onDialogOpened = () => {

<template>
<div class="settings-usage-and-plan">
<n8n-heading size="2xlarge">{{ locale.baseText('settings.usageAndPlan.title') }}</n8n-heading>
<n8n-heading tag="h2" size="2xlarge">{{
locale.baseText('settings.usageAndPlan.title')
}}</n8n-heading>
<div v-if="!usageStore.isLoading">
<n8n-heading :class="$style.title" size="large">
<n8n-heading tag="h3" :class="$style.title" size="large">
<i18n-t keypath="settings.usageAndPlan.description" tag="span">
<template #name>{{ usageStore.planName }}</template>
<template #name>{{
badgedPlanName.badge ? badgedPlanName.name : usageStore.planName
}}</template>
<template #type>
<span v-if="usageStore.planId">{{
locale.baseText('settings.usageAndPlan.plan')
}}</span>
<span v-else>{{ locale.baseText('settings.usageAndPlan.edition') }}</span>
</template>
</i18n-t>
<span :class="$style.titleTooltip">
<N8nTooltip v-if="badgedPlanName.badge" placement="top">
<template #content>
<i18n-t
v-if="isCommunityEditionRegistered"
keypath="settings.usageAndPlan.license.communityRegistered.tooltip"
>
</i18n-t>
</template>
<N8nBadge>{{ badgedPlanName.badge }}</N8nBadge>
</N8nTooltip>
</span>
</n8n-heading>

<div :class="$style.quota">
Expand Down Expand Up @@ -239,7 +267,8 @@ const onDialogOpened = () => {
}
.title {
display: block;
display: flex;
align-items: center;
padding: var(--spacing-2xl) 0 var(--spacing-m);
}
Expand Down Expand Up @@ -309,6 +338,12 @@ div[class*='info'] > span > span:last-child {
line-height: 1.4;
padding: 0 0 0 var(--spacing-4xs);
}
.titleTooltip {
display: flex;
align-items: center;
margin: 0 0 0 var(--spacing-2xs);
}
</style>

<style lang="scss" scoped>
Expand Down

0 comments on commit 3974981

Please sign in to comment.