Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 30 additions & 1 deletion packages/app/src/components/showcase/showcaseConfig.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
showcaseItems,
filterShowcaseItems,
countByCategory,
templateShowcaseLink,
} from './showcaseConfig';

describe('showcaseConfig', () => {
Expand Down Expand Up @@ -31,12 +32,40 @@ describe('showcaseConfig', () => {
it('every item links to a live portal surface', () => {
const allowed = ['/self-service', '/catalog', '/api-docs', '/search', '/docs', '/catalog-graph'];
showcaseItems.forEach(item => {
expect(allowed).toContain(item.link);
const isTemplateLink = item.link.startsWith('/self-service/templates/default/');
expect(allowed.includes(item.link) || isTemplateLink).toBe(true);
expect(item.linkLabel.length).toBeGreaterThan(0);
expect(item.description.length).toBeGreaterThan(20);
});
});

it('deep-links every template card to its real template entity', () => {
// Entity names from examples/templates/*/template.yaml (metadata.name)
const realTemplateNames = [
'ai-hub-service',
'answer-engine-worker',
'mcp-server',
'github-blank-repo',
'github-pull-request-docs',
'docs-blank-repo',
'docs-template-gitlab-merge-request',
];
const templates = showcaseItems.filter(i => i.category === 'templates');
templates.forEach(item => {
expect(item.link.startsWith('/self-service/templates/default/')).toBe(true);
const templateName = item.link.replace('/self-service/templates/default/', '');
expect(realTemplateNames).toContain(templateName);
});
expect(templates.map(t => t.link).sort()).toEqual(
realTemplateNames.map(name => templateShowcaseLink(name)).sort(),
);
const workerCard = showcaseItems.find(i => i.id === 'answer-engine-worker-card');
expect(workerCard?.link).toBe(templateShowcaseLink('answer-engine-worker'));
expect(templateShowcaseLink('ai-hub-service')).toBe(
'/self-service/templates/default/ai-hub-service',
);
});

it('filters by category', () => {
const github = filterShowcaseItems(showcaseItems, 'github', '');
expect(github.every(i => i.category === 'github')).toBe(true);
Expand Down
20 changes: 12 additions & 8 deletions packages/app/src/components/showcase/showcaseConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,18 @@ export const showcaseCategoryColors: Record<ShowcaseCategory, string> = {
platform: '#1a7f37',
};

export function templateShowcaseLink(templateName: string): string {
return `/self-service/templates/default/${templateName}`;
}

export const showcaseItems: ShowcaseItem[] = [
{
id: 'template-ai-hub-service',
name: 'AI Hub Service',
description:
'Scaffold a provider-agnostic gateway in front of your organisation LLM providers, with auth, rate limiting, cost tracking and audit logging.',
category: 'templates',
link: '/self-service',
link: templateShowcaseLink('ai-hub-service'),
linkLabel: 'Use template',
tags: ['recommended', 'ai', 'llm', 'github'],
isRecommended: true,
Expand All @@ -47,7 +51,7 @@ export const showcaseItems: ShowcaseItem[] = [
description:
'Scaffold a queue consumer that retrieves context from a document index and produces cited answers, with an indexer and query API.',
category: 'templates',
link: '/self-service',
link: templateShowcaseLink('answer-engine-worker'),
linkLabel: 'Use template',
tags: ['recommended', 'ai', 'rag', 'github'],
isRecommended: true,
Expand All @@ -58,7 +62,7 @@ export const showcaseItems: ShowcaseItem[] = [
description:
'Scaffold a Model Context Protocol server that AI assistants connect to for domain-specific tools and context.',
category: 'templates',
link: '/self-service',
link: templateShowcaseLink('mcp-server'),
linkLabel: 'Use template',
tags: ['recommended', 'ai', 'mcp', 'github'],
isRecommended: true,
Expand All @@ -69,7 +73,7 @@ export const showcaseItems: ShowcaseItem[] = [
description:
'Create a new blank repository in GitHub from a local skeleton and register it in the catalog.',
category: 'templates',
link: '/self-service',
link: templateShowcaseLink('github-blank-repo'),
linkLabel: 'Use template',
tags: ['recommended', 'github', 'repo'],
isRecommended: true,
Expand All @@ -80,7 +84,7 @@ export const showcaseItems: ShowcaseItem[] = [
description:
'Create a documentation site in a GitHub repository and open it as a pull request for review.',
category: 'templates',
link: '/self-service',
link: templateShowcaseLink('github-pull-request-docs'),
linkLabel: 'Use template',
tags: ['recommended', 'github', 'techdocs'],
isRecommended: true,
Expand All @@ -91,7 +95,7 @@ export const showcaseItems: ShowcaseItem[] = [
description:
'Create a new blank repository in GitLab from a local skeleton and register it in the catalog.',
category: 'templates',
link: '/self-service',
link: templateShowcaseLink('docs-blank-repo'),
linkLabel: 'Use template',
tags: ['recommended', 'gitlab', 'repo'],
isRecommended: true,
Expand All @@ -102,7 +106,7 @@ export const showcaseItems: ShowcaseItem[] = [
description:
'Create a documentation site in a GitLab repository and open it as a merge request for review.',
category: 'templates',
link: '/self-service',
link: templateShowcaseLink('docs-template-gitlab-merge-request'),
linkLabel: 'Use template',
tags: ['recommended', 'gitlab', 'techdocs'],
isRecommended: true,
Expand Down Expand Up @@ -154,7 +158,7 @@ export const showcaseItems: ShowcaseItem[] = [
description:
'Start your own answer engine worker with retrieval, citation handling and catalog registration built in.',
category: 'answer-engine',
link: '/self-service',
link: templateShowcaseLink('answer-engine-worker'),
linkLabel: 'Use template',
tags: ['ai', 'rag', 'template'],
isRecommended: true,
Expand Down
Loading