feat: Community nodes details footer update (#17158)

This commit is contained in:
Michael Kret
2025-07-17 14:13:21 +03:00
committed by GitHub
parent 0237d8b8ec
commit 81cd49014a
3 changed files with 81 additions and 13 deletions

View File

@@ -1,13 +1,22 @@
import { fireEvent } from '@testing-library/vue';
import { fireEvent, waitFor } from '@testing-library/vue';
import { VIEWS } from '@/constants';
import { createTestingPinia } from '@pinia/testing';
import { setActivePinia } from 'pinia';
import CommunityNodeFooter from './CommunityNodeFooter.vue';
import { createComponentRenderer } from '@/__tests__/render';
import { vi } from 'vitest';
import type { PublicInstalledPackage } from 'n8n-workflow';
const getInstalledPackage = vi.fn();
const push = vi.fn();
const communityNodesStore: {
getInstalledPackage: (packageName: string) => Promise<PublicInstalledPackage>;
} = {
getInstalledPackage,
};
vi.mock('vue-router', async (importOriginal) => {
const actual = await importOriginal();
return {
@@ -18,6 +27,10 @@ vi.mock('vue-router', async (importOriginal) => {
};
});
vi.mock('@/stores/communityNodes.store', () => ({
useCommunityNodesStore: vi.fn(() => communityNodesStore),
}));
describe('CommunityNodeInfo - links & bugs URL', () => {
beforeEach(() => {
setActivePinia(createTestingPinia());
@@ -55,4 +68,36 @@ describe('CommunityNodeInfo - links & bugs URL', () => {
expect(queryByText('Manage')).not.toBeInTheDocument();
});
it('displays "Legacy" when updateAvailable', async () => {
getInstalledPackage.mockResolvedValue({
installedVersion: '1.0.0',
updateAvailable: '1.0.1',
} as PublicInstalledPackage);
const { getByText } = createComponentRenderer(CommunityNodeFooter)({
props: {
packageName: 'n8n-nodes-test',
showManage: false,
},
});
await waitFor(() => expect(getInstalledPackage).toHaveBeenCalled());
expect(getByText('Package version 1.0.0 (Legacy)')).toBeInTheDocument();
});
it('displays "Latest" when not updateAvailable', async () => {
getInstalledPackage.mockResolvedValue({
installedVersion: '1.0.0',
} as PublicInstalledPackage);
const { getByText } = createComponentRenderer(CommunityNodeFooter)({
props: {
packageName: 'n8n-nodes-test',
showManage: false,
},
});
await waitFor(() => expect(getInstalledPackage).toHaveBeenCalled());
expect(getByText('Package version 1.0.0 (Latest)')).toBeInTheDocument();
});
});

View File

@@ -3,6 +3,8 @@ import { VIEWS } from '@/constants';
import { onMounted, ref } from 'vue';
import { useRouter } from 'vue-router';
import { captureException } from '@sentry/vue';
import { useCommunityNodesStore } from '@/stores/communityNodes.store';
import type { PublicInstalledPackage } from 'n8n-workflow';
import { N8nText, N8nLink } from '@n8n/design-system';
@@ -15,6 +17,7 @@ const props = defineProps<Props>();
const router = useRouter();
const bugsUrl = ref<string>(`https://registry.npmjs.org/${props.packageName}`);
const installedPackage = ref<PublicInstalledPackage | undefined>(undefined);
async function openSettingsPage() {
await router.push({ name: VIEWS.COMMUNITY_NODES });
@@ -49,30 +52,45 @@ async function getBugsUrl(packageName: string) {
onMounted(async () => {
if (props.packageName) {
await getBugsUrl(props.packageName);
installedPackage.value = await useCommunityNodesStore().getInstalledPackage(props.packageName);
}
});
</script>
<template>
<div>
<div :class="$style.separator"></div>
<div :class="$style.container">
<N8nText v-if="installedPackage" size="small" color="text-light" style="margin-right: auto">
Package version {{ installedPackage.installedVersion }} ({{
installedPackage.updateAvailable ? 'Legacy' : 'Latest'
}})
</N8nText>
<template v-if="props.showManage">
<N8nLink theme="text" @click="openSettingsPage">
<N8nText size="small" color="primary" bold> Manage </N8nText>
</N8nLink>
<N8nText size="small" color="primary" bold>|</N8nText>
<N8nText size="small" style="color: var(--color-foreground-base)" bold>|</N8nText>
</template>
<N8nLink theme="text" @click="openIssuesPage">
<N8nText size="small" color="primary" bold> Report issue </N8nText>
</N8nLink>
</div>
</div>
</template>
<style lang="scss" module>
.container {
display: flex;
justify-content: center;
justify-content: right;
align-items: center;
gap: var(--spacing-s);
padding-bottom: var(--spacing-s);
gap: var(--spacing-2xs);
padding: var(--spacing-s);
}
.separator {
height: var(--border-width-base);
background: var(--color-foreground-base);
margin-right: var(--spacing-s);
margin-left: var(--spacing-s);
}
</style>

View File

@@ -1039,6 +1039,11 @@ function handleWheelEvent(event: WheelEvent) {
@open-connection-node-creator="onOpenConnectionNodeCreator"
/>
<n8n-block-ui :show="blockUI" />
<CommunityNodeFooter
v-if="openPanel === 'settings' && isCommunityNode"
:package-name="packageName"
:show-manage="useUsersStore().isInstanceOwner"
/>
</div>
</template>