refactor(glossaire): preserve editorial order for entry relations

This commit is contained in:
2026-03-25 15:20:39 +01:00
parent b255436958
commit b2b4ec35c0

View File

@@ -128,17 +128,35 @@ export function uniqueGlossaryEntries(
return out;
}
export function resolveGlossaryEntries(
export function resolveGlossaryEntriesInSourceOrder(
slugs: string[] = [],
allEntries: GlossaryEntry[] = [],
): GlossaryEntry[] {
const bySlug = buildGlossaryBySlug(allEntries);
const seen = new Set<string>();
const resolved: GlossaryEntry[] = [];
const resolved = slugs
.map((slug) => bySlug.get(normalizeGlossarySlug(slug)))
.filter(Boolean) as GlossaryEntry[];
for (const rawSlug of slugs) {
const slug = normalizeGlossarySlug(rawSlug);
if (!slug || seen.has(slug)) continue;
return sortGlossaryEntries(uniqueGlossaryEntries(resolved));
const entry = bySlug.get(slug);
if (!entry) continue;
seen.add(slug);
resolved.push(entry);
}
return resolved;
}
export function resolveGlossaryEntries(
slugs: string[] = [],
allEntries: GlossaryEntry[] = [],
): GlossaryEntry[] {
return sortGlossaryEntries(
resolveGlossaryEntriesInSourceOrder(slugs, allEntries),
);
}
export function rawFamilyOf(
@@ -268,31 +286,44 @@ export type GlossaryRelationBlock = {
};
export function getRelationBlocks(
entry: GlossaryEntry,
allEntries: GlossaryEntry[] = [],
): GlossaryRelationBlock[] {
const relatedEntries = resolveGlossaryEntries(entry.data.related ?? [], allEntries);
const opposedEntries = resolveGlossaryEntries(entry.data.opposedTo ?? [], allEntries);
const seeAlsoEntries = resolveGlossaryEntries(entry.data.seeAlso ?? [], allEntries);
return [
{
title: "Concepts liés",
items: relatedEntries,
className: "is-related",
},
{
title: "En tension avec",
items: opposedEntries,
className: "is-opposed",
},
{
title: "Voir aussi",
items: seeAlsoEntries,
className: "is-see-also",
},
].filter((block) => block.items.length > 0);
}
entry: GlossaryEntry,
allEntries: GlossaryEntry[] = [],
): GlossaryRelationBlock[] {
const currentSlug = slugOfGlossaryEntry(entry);
const relatedEntries = resolveGlossaryEntriesInSourceOrder(
entry.data.related ?? [],
allEntries,
).filter((item) => slugOfGlossaryEntry(item) !== currentSlug);
const opposedEntries = resolveGlossaryEntriesInSourceOrder(
entry.data.opposedTo ?? [],
allEntries,
).filter((item) => slugOfGlossaryEntry(item) !== currentSlug);
const seeAlsoEntries = resolveGlossaryEntriesInSourceOrder(
entry.data.seeAlso ?? [],
allEntries,
).filter((item) => slugOfGlossaryEntry(item) !== currentSlug);
return [
{
title: "Concepts liés",
items: relatedEntries,
className: "is-related",
},
{
title: "En tension avec",
items: opposedEntries,
className: "is-opposed",
},
{
title: "Voir aussi",
items: seeAlsoEntries,
className: "is-see-also",
},
].filter((block) => block.items.length > 0);
}
export function getRelationSections(
entry: GlossaryEntry,