diff --git a/i18n/en/code.json b/i18n/en/code.json index 7164d17..31e8f83 100644 --- a/i18n/en/code.json +++ b/i18n/en/code.json @@ -1147,6 +1147,10 @@ "message": "Released {v0}", "description": "发布于 {v0}" }, + "catalog.currentVersionReleasedAt": { + "message": "Current version released on {v0}", + "description": "当前版本发布于 {v0}" + }, "site.a2d8188544aa": { "message": "Release date not provided", "description": "发布日期未提供" diff --git a/src/features/catalog/components.tsx b/src/features/catalog/components.tsx index 69e9542..e29b639 100644 --- a/src/features/catalog/components.tsx +++ b/src/features/catalog/components.tsx @@ -419,6 +419,21 @@ export function RecipeCard({ )}
+

+ {r.variant.releaseDate ? ( + + ) : ( + translate({ id: 'site.020ef0cc6f35', message: '日期未提供' }) + )} +

Engine
diff --git a/src/features/catalog/styles.module.css b/src/features/catalog/styles.module.css index dd76d45..0d40077 100644 --- a/src/features/catalog/styles.module.css +++ b/src/features/catalog/styles.module.css @@ -581,6 +581,12 @@ padding: 0 15px 13px; margin-top: 14px; } +.releaseDate { + margin: 0 0 8px; + color: var(--color-text-muted); + font-size: 12px; + line-height: 1.6; +} .cardFooter dl { border-top: 1px solid var(--color-border-default); padding: 9px 0; diff --git a/tests/e2e/recipe-release-date.spec.ts b/tests/e2e/recipe-release-date.spec.ts new file mode 100644 index 0000000..46f5667 --- /dev/null +++ b/tests/e2e/recipe-release-date.spec.ts @@ -0,0 +1,46 @@ +import { test, expect } from '@playwright/test'; +import baseline from '../../content/catalog/baseline.json'; +import { parseCatalog } from '../../src/features/catalog/data'; + +for (const context of ['catalog', 'model'] as const) { + for (const missing of [false, true]) { + test(`${context} card renders ${missing ? 'missing date fallback' : 'release date'}`, async ({ + page, + }) => { + const source = parseCatalog(baseline); + const model = source.models.find((m) => m.name === 'glm5.3')!; + const variant = model.variants.find( + (v) => v.id === 'sglang-tp4-b300-optimized', + )!; + const date = variant.releaseDate!; + if (missing) delete variant.releaseDate; + await page.route( + 'https://modelsphere.github.io/model-catalog/**', + (route) => + route.request().url().endsWith('index-v2.json') + ? route.fulfill({ json: source }) + : route.abort(), + ); + await page.goto( + context === 'catalog' + ? '/models?q=glm5.3' + : '/models/detail?modelId=glm5.3', + ); + const card = page.locator( + `[data-recipe-id="${model.name}/${variant.id}"]`, + ); + const releaseDate = card.locator('[data-recipe-release-date]'); + await expect(releaseDate).toHaveText( + missing ? '日期未提供' : `当前版本发布于 ${date}`, + ); + if (missing) { + await expect(releaseDate.locator('time')).toHaveCount(0); + } else { + await expect(releaseDate.locator('time')).toHaveAttribute( + 'datetime', + date, + ); + } + }); + } +}