Skip to content

Commit

Permalink
feat(catalog): add support for displaying public labels
Browse files Browse the repository at this point in the history
  • Loading branch information
andrewwylde committed Nov 29, 2024
1 parent 0865993 commit ebaf3c3
Show file tree
Hide file tree
Showing 14 changed files with 192 additions and 46 deletions.
103 changes: 102 additions & 1 deletion cypress/e2e/specs/catalog.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ProductCatalogIndexSourceLatestVersion, SearchResults, SearchResultsDataInner } from '@kong/sdk-portal-js'
import { generateProducts } from '../support/utils/generateProducts'
import { FeatureFlags } from '@/constants/feature-flags'

const mockProductSearchQuery = (searchQuery: string) => {
const searchResults: SearchResultsDataInner[] = ([
Expand All @@ -25,7 +26,8 @@ const mockProductSearchQuery = (searchQuery: string) => {
latest_version: {
name: versions[0],
id: crypto.randomUUID()
}
},
public_labels: {}
}
}))

Expand Down Expand Up @@ -197,6 +199,105 @@ describe('Catalog', () => {
cy.get('.k-table tbody td:nth-of-type(4) a').should('exist').should('contain', 'Documentation')
})
})

describe('Catalog Item Public Labels (feature flag enabled)', () => {
beforeEach(() => {
cy.mockPublicPortal()
cy.mockLaunchDarklyFlags([
{ name: FeatureFlags.publicLabelsUI, value: true }
])
cy.visit('/')
// click view toggle to table mode
cy.get('[data-testid="view-switcher"]:not(:disabled)').click()
})

it('renders public labels correctly', () => {
const productWithLabels = {
id: 'test-product',
title: 'Test Product',
description: 'A test product with public labels',
public_labels: {
category: 'test',
version: '1.0'
},
showSpecLink: true,
documentCount: 1,
latestVersion: { name: 'v1' }
}

cy.mockProductsCatalog(1, [productWithLabels])

cy.visit('/')

cy.get('.catalog-item').eq(0).within(() => {
// Check if the public labels section exists
cy.contains('Labels:').should('exist')

// Check if all public labels are rendered
cy.get('.product-public-label').should('have.length', 2)

// Check the content of each label
cy.get('.product-public-label').eq(0).should('contain', 'category: test')
cy.get('.product-public-label').eq(1).should('contain', 'version: 1.0')
})
})

it('does not render public labels section when product has no labels', () => {
const productWithoutLabels = {
id: 'test-product-no-labels',
title: 'Test Product Without Labels',
description: 'A test product without public labels',
public_labels: {},
showSpecLink: true,
documentCount: 1,
latestVersion: { name: 'v1' }
}

cy.mockProductsCatalog(1, [productWithoutLabels])

cy.visit('/')

cy.get('.catalog-item').eq(0).within(() => {
// Check that the public labels section does not exist
cy.contains('Labels:').should('not.exist')
cy.get('.product-public-label').should('not.exist')
})
})
})
describe('Catalog Item Public Labels (feature flag disabled)', () => {
beforeEach(() => {
cy.mockPublicPortal()
cy.mockLaunchDarklyFlags([
{ name: FeatureFlags.publicLabelsUI, value: false }
])
cy.visit('/')
})

it('renders no labels ', () => {
const productWithLabels = {
id: 'test-product',
title: 'Test Product',
description: 'A test product with public labels',
public_labels: {
category: 'test',
version: '1.0'
},
showSpecLink: true,
documentCount: 1,
latestVersion: { name: 'v1' }
}

cy.mockProductsCatalog(1, [productWithLabels])

cy.visit('/')

cy.get('.catalog-item').within(() => {
// Check if the public labels section exists
cy.contains('Labels:').should('not.exist')
cy.get('.product-public-label').should('not.exist')
})
})
})
})

describe('Catalog versions', () => {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"@kong/kong-auth-elements": "2.12.6",
"@kong/kongponents": "8.127.0",
"@kong/markdown": "1.7.8",
"@kong/sdk-portal-js": "2.15.4",
"@kong/sdk-portal-js": "2.16.0",
"@unhead/vue": "1.11.6",
"@xstate/vue": "2.0.0",
"axios": "1.6.7",
Expand Down
43 changes: 36 additions & 7 deletions src/components/CatalogItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@
</template>
<template #body>
<p class="description color-text_colors-secondary">
<template
v-if="loading"
>
<template v-if="loading">
<KSkeletonBox width="100" />
<KSkeletonBox width="50" />
<KSkeletonBox width="75" />
Expand All @@ -35,9 +33,7 @@
v-if="version"
class="my-2 color-text_colors-secondary"
>
<template
v-if="loading"
>
<template v-if="loading">
<KSkeletonBox width="2" />
</template>
<template v-else>
Expand All @@ -52,6 +48,33 @@
</template>
</span>
</li>
<li
v-if="publicLabelsUIEnabled"
class="details-item"
>
<span
v-if="product.publicLabels.length"
class="my-2 color-text_colors-secondary"
>
<template v-if="loading">
<KSkeletonBox width="2" />
</template>
<template v-else>
<span class="mr-2">{{ helpText.publicLabels }}</span>
<div>
<KBadge
v-for="label in product.publicLabels"
:key="label.key"
color="var(--text_colors-secondary)"
background-color="var(--section_colors-accent)"
class="product-public-label"
>
{{ label.key }}: {{ label.value }}
</KBadge>
</div>
</template>
</span>
</li>
<li class="docs-links">
<div
v-if="product.showSpecLink"
Expand Down Expand Up @@ -104,6 +127,8 @@
</template>

<script lang="ts">
import { FeatureFlags } from '@/constants/feature-flags'
import useLDFeatureFlag from '@/hooks/useLDFeatureFlag'
import { CatalogItemModel, useI18nStore } from '@/stores'
import { PropType } from 'vue'
Expand All @@ -122,8 +147,12 @@ export default {
data () {
const helpText = useI18nStore().state.helpText.catalogItem
// check for feature flag
const publicLabelsUIEnabled = useLDFeatureFlag(FeatureFlags.publicLabelsUI, false)
return {
helpText
helpText,
publicLabelsUIEnabled
}
},
computed: {
Expand Down
22 changes: 22 additions & 0 deletions src/components/CatalogTableList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,22 @@
<template #title="{ rowValue }">
{{ rowValue }}
</template>
<template #publicLabels="{ row }">
<div v-if="publicLabelsUIEnabled">
<div
v-for="label in row.publicLabels"
:key="label.key"
>
<KBadge
color="var(--text_colors-secondary)"
background-color="var(--section_colors-accent)"
class="product-version"
>
{{ label.key }}: {{ label.value }}
</KBadge>
</div>
</div>
</template>
<template #latestVersion="{ row }">
<div>
<KBadge
Expand Down Expand Up @@ -47,6 +63,8 @@
</template>

<script lang="ts">
import { FeatureFlags } from '@/constants/feature-flags'
import useLDFeatureFlag from '@/hooks/useLDFeatureFlag'
import { useI18nStore, CatalogItemModel } from '@/stores'
import { defineComponent, ref, computed, watch, PropType } from 'vue'
import { useRouter } from 'vue-router'
Expand Down Expand Up @@ -95,11 +113,15 @@ export default defineComponent({
}
},
data () {
const publicLabelsUIEnabled = useLDFeatureFlag(FeatureFlags.publicLabelsUI, false)
return {
publicLabelsUIEnabled,
tableHeaders: [
{ label: 'Title', key: 'title' },
{ label: 'Description', key: 'description' },
{ label: 'Latest Version', key: 'latestVersion' },
{ label: 'Labels', key: 'publicLabels' },
{ label: 'Details', key: 'links' }
]
}
Expand Down
1 change: 1 addition & 0 deletions src/constants/feature-flags.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export enum FeatureFlags {
newMarkdownRender = 'tdx-4186-new-markdown',
publicLabelsUI = 'tdx-4824-public-labels-ui'
}
3 changes: 2 additions & 1 deletion src/locales/ca_ES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,8 @@ export const ca_ES: I18nType = {
catalogItem: {
latestVersion: 'Última versió:',
specificationLink: 'Especificació',
documentationLink: 'Documentació'
documentationLink: 'Documentació',
publicLabels: translationNeeded(en.catalogItem.publicLabels)
},
catalogTable: {
specificationLink: 'Especificació',
Expand Down
3 changes: 2 additions & 1 deletion src/locales/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,8 @@ export const de: I18nType = {
catalogItem: {
latestVersion: 'Aktuelle Version:',
specificationLink: 'Spezifikation',
documentationLink: 'Dokumentation'
documentationLink: 'Dokumentation',
publicLabels: translationNeeded(en.catalogItem.publicLabels)
},
catalogTable: {
specificationLink: 'Spezifikation',
Expand Down
1 change: 1 addition & 0 deletions src/locales/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ export const en = {
},
catalogItem: {
latestVersion: 'Latest Version:',
publicLabels: 'Labels:',
specificationLink: 'Specification',
documentationLink: 'Documentation'
},
Expand Down
3 changes: 2 additions & 1 deletion src/locales/es_ES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,8 @@ export const es_ES: I18nType = {
catalogItem: {
latestVersion: 'Última versión: ',
specificationLink: 'Especificación',
documentationLink: 'Documentación'
documentationLink: 'Documentación',
publicLabels: translationNeeded(en.catalogItem.publicLabels)
},
catalogTable: {
specificationLink: 'Especificación',
Expand Down
3 changes: 2 additions & 1 deletion src/locales/fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,8 @@ export const fr: I18nType = {
catalogItem: {
latestVersion: 'Dernière version :',
specificationLink: 'Spécification',
documentationLink: 'Documentation'
documentationLink: 'Documentation',
publicLabels: translationNeeded(en.catalogItem.publicLabels)
},
catalogTable: {
specificationLink: 'Spécification',
Expand Down
1 change: 1 addition & 0 deletions src/locales/i18n-type.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ export interface I18nType {
};
catalogItem: {
latestVersion: string;
publicLabels: string;
specificationLink: string;
documentationLink: string;
};
Expand Down
1 change: 1 addition & 0 deletions src/stores/product.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export interface CatalogItemModel {
description: string;
documentCount: number;
versionCount: number;
publicLabels: Array<{key: string; value: string}>;
}

export type CustomOperation = Operation & {tag?: string}
Expand Down
13 changes: 12 additions & 1 deletion src/views/ProductCatalogWrapper.vue
Original file line number Diff line number Diff line change
Expand Up @@ -152,14 +152,25 @@ export default defineComponent({
})
}
// convert source public_labels from key/value to array
const publicLabels = source.public_labels
? Object.entries(source.public_labels).map(([key, value]) => {
return {
key,
value
}
})
: []
return {
id: source.id,
title: source.name,
latestVersion: source.latest_version,
showSpecLink,
description: source.description,
documentCount: source.document_count,
versionCount: source.version_count
versionCount: source.version_count,
publicLabels
}
}))
totalCount.value = meta.page.total
Expand Down
Loading

0 comments on commit ebaf3c3

Please sign in to comment.