fix(mira): [pageName] h1 顯示 entity 名 + listing dedupe by entity

兩個 leo 反饋的 UI bug:

1. wiki/[pageName] 對 index-entry 渲染時,h1 用 block.content(整篇 markdown)
   會把整個內容塞進 h1。改:wiki-page 用 content 當 entity 名;其他類型
   (index-entry/schema/log)用 page_name 剝 `wiki-` / `index-` prefix。

2. listing「Wiki Pages (21)」累積式設計造成同 entity 多版顯示為多張卡,雜亂。
   改:用 useMemo dedupe by entity(content)— 每 entity 一張卡顯示最新版,
   標題顯示「N 版累積」當 N>1。原始 21 筆 → 現在約 6-7 個 unique entity。
This commit is contained in:
2026-05-16 09:03:45 +08:00
parent 64193f2aa5
commit 3689f30409
2 changed files with 36 additions and 11 deletions
+5 -1
View File
@@ -141,8 +141,12 @@ export default function WikiPagePage({
return Array.from(groups.entries()).map(([facet, paragraphs]) => ({ facet, paragraphs }));
}, [paragraphs, triplets]);
const entity = block?.content?.trim() || decodedName.replace(/^wiki-/, '');
const isWikiPage = block?.type === 'wiki-page';
// 標題:wiki-page 用 contententity 名稱),其他(index-entry/schema/log/...)用 page_name 剝 prefix
// 修 bug:原本一律用 block.content,但 index-entry 的 content 是整篇 markdown,會把整個 content render 成 h1
const entity = isWikiPage
? (block?.content?.trim() || decodedName.replace(/^wiki-/, ''))
: decodedName.replace(/^(wiki|index)-/, '');
function toggleCollapse(key: string) {
setCollapsed((c) => ({ ...c, [key]: !c[key] }));
+31 -10
View File
@@ -6,7 +6,7 @@
// 階段 7-A 已建:mira-wiki-schema、mira-wiki-index(+4 children)、mira-wiki-log(+1 child)
// 此頁列出這些 infra block 與既有 wiki-page,方便 leo 在瀏覽器確認 schema 寫得對不對
import { useEffect, useState } from 'react';
import { useEffect, useMemo, useState } from 'react';
import Link from 'next/link';
import '../mira.css';
@@ -124,6 +124,27 @@ export default function WikiIndexPage() {
};
}, []);
// Dedupe wiki-pages by entitycontent)— 累積式設計每個 raw 各建一個 wiki-page
// 同 entity 多版只在 listing 顯示最新一張卡 + 版本數提示
const dedupedWikiPages = useMemo(() => {
const groups = new Map<string, { entity: string; latest: Block; versionCount: number }>();
for (const p of otherWikiPages) {
const entity = (p.content || '').trim() || p.page_name || '?';
const existing = groups.get(entity);
if (!existing) {
groups.set(entity, { entity, latest: p, versionCount: 1 });
} else {
existing.versionCount++;
if ((p.created_at ?? 0) > (existing.latest.created_at ?? 0)) {
existing.latest = p;
}
}
}
return Array.from(groups.values()).sort(
(a, b) => (b.latest.created_at ?? 0) - (a.latest.created_at ?? 0),
);
}, [otherWikiPages]);
return (
<main className="mira-app">
<div className="mira-content">
@@ -220,18 +241,18 @@ export default function WikiIndexPage() {
)}
</Section>
<Section title={`📖 Wiki Pages${otherWikiPages.length}`}>
{otherWikiPages.length > 0 ? (
<Section title={`📖 Wiki Pages${dedupedWikiPages.length},原 ${otherWikiPages.length} 筆累積版本`}>
{dedupedWikiPages.length > 0 ? (
<div style={{ display: 'grid', gap: 8 }}>
{otherWikiPages.map((p) => (
{dedupedWikiPages.map((g) => (
<WikiCardLink
key={p.id}
page_name={p.page_name}
title={(p.content || '').trim() || p.page_name}
key={g.latest.id}
page_name={g.latest.page_name}
title={g.entity}
excerpt={
p.created_at
? `建立 ${new Date(p.created_at * 1000).toLocaleString('zh-TW')}`
: p.page_name
g.versionCount > 1
? `${g.versionCount} 版累積 ・ 最新 ${new Date((g.latest.created_at ?? 0) * 1000).toLocaleString('zh-TW')}`
: `建立 ${new Date((g.latest.created_at ?? 0) * 1000).toLocaleString('zh-TW')}`
}
/>
))}