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