refactor(editor): Rename CollectionCard and CollectionCardCarousel (#7994)

## Summary
As part of the plan to reuse current `CollectionCarousel` component,
this PR makes it, and the cards it uses, more generic by renaming them
and adds a new property to card component which can be used to hide the
item count.

#### How to test the change:
Until the component that will use this is implmeneted, this can be
tested manually:
1. Run n8n
2. Set `showItemCount` property for workflow collection cards to `false`
3. Check if workflow count is showing (it shouldn't) and if everything
rendering correctly

## Issues fixed
Fixes ADO-1567

## Review / Merge checklist
- [ ] PR title and summary are descriptive. **Remember, the title
automatically goes into the changelog. Use `(no-changelog)` otherwise.**
([conventions](https://github.com/n8n-io/n8n/blob/master/.github/pull_request_title_conventions.md))
- [ ] [Docs updated](https://github.com/n8n-io/n8n-docs) or follow-up
ticket created.
- [ ] Tests included.
> A bug is not considered fixed, unless a test is added to prevent it
from happening again. A feature is not complete without tests.
  >
> *(internal)* You can use Slack commands to trigger [e2e
tests](https://www.notion.so/n8n/How-to-use-Test-Instances-d65f49dfc51f441ea44367fb6f67eb0a?pvs=4#a39f9e5ba64a48b58a71d81c837e8227)
or [deploy test
instance](https://www.notion.so/n8n/How-to-use-Test-Instances-d65f49dfc51f441ea44367fb6f67eb0a?pvs=4#f6a177d32bde4b57ae2da0b8e454bfce)
or [deploy early access version on
Cloud](https://www.notion.so/n8n/Cloudbot-3dbe779836004972b7057bc989526998?pvs=4#fef2d36ab02247e1a0f65a74f6fb534e).
This commit is contained in:
Milorad FIlipović 2023-12-11 17:37:26 +01:00 committed by GitHub
parent 435392cbfe
commit 240d259260
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 95 additions and 12 deletions

View file

@ -1,10 +1,12 @@
<template> <template>
<Card :loading="loading" :title="collection.name"> <Card :loading="loading" :title="collection.name">
<template #footer> <template #footer>
<n8n-text size="small" color="text-light"> <span>
{{ collection.workflows.length }} <n8n-text v-show="showItemCount" size="small" color="text-light">
{{ $locale.baseText('templates.workflows') }} {{ collection.workflows.length }}
</n8n-text> {{ $locale.baseText('templates.workflows') }}
</n8n-text>
</span>
<NodeList :nodes="collection.nodes" :showMore="false" /> <NodeList :nodes="collection.nodes" :showMore="false" />
</template> </template>
</Card> </Card>
@ -17,7 +19,7 @@ import Card from '@/components/CollectionWorkflowCard.vue';
import NodeList from '@/components/NodeList.vue'; import NodeList from '@/components/NodeList.vue';
export default defineComponent({ export default defineComponent({
name: 'CollectionCard', name: 'TemplatesInfoCard',
mixins: [genericHelpers], mixins: [genericHelpers],
props: { props: {
loading: { loading: {
@ -26,6 +28,10 @@ export default defineComponent({
collection: { collection: {
type: Object, type: Object,
}, },
showItemCount: {
type: Boolean,
default: true,
},
}, },
components: { components: {
Card, Card,

View file

@ -9,7 +9,7 @@
@after-change="updateCarouselScroll" @after-change="updateCarouselScroll"
> >
<Card v-for="n in loading ? 4 : 0" :key="`loading-${n}`" :loading="loading" /> <Card v-for="n in loading ? 4 : 0" :key="`loading-${n}`" :loading="loading" />
<CollectionCard <TemplatesInfoCard
v-for="collection in loading ? [] : collections" v-for="collection in loading ? [] : collections"
:key="collection.id" :key="collection.id"
:collection="collection" :collection="collection"
@ -30,7 +30,7 @@ import { defineComponent } from 'vue';
import type { PropType } from 'vue'; import type { PropType } from 'vue';
import type { ITemplatesCollection } from '@/Interface'; import type { ITemplatesCollection } from '@/Interface';
import Card from '@/components/CollectionWorkflowCard.vue'; import Card from '@/components/CollectionWorkflowCard.vue';
import CollectionCard from '@/components/CollectionCard.vue'; import TemplatesInfoCard from '@/components/TemplatesInfoCard.vue';
import { VueAgile } from 'vue-agile'; import { VueAgile } from 'vue-agile';
import { genericHelpers } from '@/mixins/genericHelpers'; import { genericHelpers } from '@/mixins/genericHelpers';
@ -38,7 +38,7 @@ import { genericHelpers } from '@/mixins/genericHelpers';
type SliderRef = InstanceType<typeof VueAgile>; type SliderRef = InstanceType<typeof VueAgile>;
export default defineComponent({ export default defineComponent({
name: 'CollectionsCarousel', name: 'TemplatesInfoCarousel',
mixins: [genericHelpers], mixins: [genericHelpers],
props: { props: {
collections: { collections: {
@ -62,7 +62,7 @@ export default defineComponent({
}, },
components: { components: {
Card, Card,
CollectionCard, TemplatesInfoCard,
agile: VueAgile, agile: VueAgile,
}, },
data() { data() {

View file

@ -0,0 +1,77 @@
import { createComponentRenderer } from '@/__tests__/render';
import { createPinia, setActivePinia } from 'pinia';
import TemplatesInfoCard from '@/components/TemplatesInfoCard.vue';
let pinia: ReturnType<typeof createPinia>;
const renderComponent = createComponentRenderer(TemplatesInfoCard);
const TEST_COLLECTION = {
id: 8,
rank: 1,
name: 'Advanced AI',
totalViews: null,
createdAt: '2023-10-03T17:04:44.645Z',
workflows: [{ id: 1951 }, { id: 1953 }, { id: 1954 }, { id: 1955 }],
nodes: [
{
id: 1119,
icon: 'fa:robot',
name: '@n8n/n8n-nodes-langchain.agent',
iconData: {
icon: 'robot',
type: 'icon',
},
displayName: 'Agent',
},
{
id: 1121,
icon: 'fa:link',
name: '@n8n/n8n-nodes-langchain.chainSummarization',
iconData: {
icon: 'link',
type: 'icon',
},
displayName: 'Summarization Chain',
},
{
id: 1123,
icon: 'fa:link',
name: '@n8n/n8n-nodes-langchain.chainLlm',
iconData: {
icon: 'link',
type: 'icon',
},
displayName: 'Basic LLM Chain',
},
],
};
describe('TemplatesInfoCard', () => {
beforeEach(() => {
pinia = createPinia();
setActivePinia(pinia);
});
it('should render component properly', () => {
const { getByText, container, debug } = renderComponent({
pinia,
props: {
collection: TEST_COLLECTION,
},
});
expect(getByText(TEST_COLLECTION.name)).toBeInTheDocument();
expect(getByText(`${TEST_COLLECTION.workflows.length} Workflows`)).toBeVisible();
expect(container.querySelectorAll('.n8n-node-icon').length).toBe(TEST_COLLECTION.nodes.length);
});
it('should not render item count if configured so', () => {
const { getByText } = renderComponent({
pinia,
props: {
collection: TEST_COLLECTION,
showItemCount: false,
},
});
expect(getByText(`${TEST_COLLECTION.workflows.length} Workflows`)).not.toBeVisible();
});
});

View file

@ -51,7 +51,7 @@
<span v-if="!loadingCollections" v-text="`(${collections.length})`" /> <span v-if="!loadingCollections" v-text="`(${collections.length})`" />
</n8n-heading> </n8n-heading>
</div> </div>
<CollectionsCarousel <TemplatesInfoCarousel
:collections="collections" :collections="collections"
:loading="loadingCollections" :loading="loadingCollections"
@openCollection="onOpenCollection" @openCollection="onOpenCollection"
@ -79,7 +79,7 @@
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import { mapStores } from 'pinia'; import { mapStores } from 'pinia';
import CollectionsCarousel from '@/components/CollectionsCarousel.vue'; import TemplatesInfoCarousel from '@/components/TemplatesInfoCarousel.vue';
import TemplateFilters from '@/components/TemplateFilters.vue'; import TemplateFilters from '@/components/TemplateFilters.vue';
import TemplateList from '@/components/TemplateList.vue'; import TemplateList from '@/components/TemplateList.vue';
import TemplatesView from '@/views/TemplatesView.vue'; import TemplatesView from '@/views/TemplatesView.vue';
@ -114,7 +114,7 @@ export default defineComponent({
name: 'TemplatesSearchView', name: 'TemplatesSearchView',
mixins: [genericHelpers, debounceHelper], mixins: [genericHelpers, debounceHelper],
components: { components: {
CollectionsCarousel, TemplatesInfoCarousel,
TemplateFilters, TemplateFilters,
TemplateList, TemplateList,
TemplatesView, TemplatesView,