fix(timeline): skip empty-title events in the cluster lookup
A titleless or whitespace-only event stored `''` in the lookup, so its letters still clustered and rendered a label-less `✉` mystery card. The lookup now skips events whose trimmed title is empty — those letters stay loose. Fixes review finding #8. Refs #850 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -59,6 +59,22 @@ describe('eventClustering — buildEventLookup', () => {
|
|||||||
expect(lookup.has(EV_A)).toBe(false);
|
expect(lookup.has(EV_A)).toBe(false);
|
||||||
expect(lookup.size).toBe(0);
|
expect(lookup.size).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('skips an event with an empty or whitespace title — no bare ✉ card (#8)', () => {
|
||||||
|
const timeline: TimelineDTO = {
|
||||||
|
years: [
|
||||||
|
{
|
||||||
|
year: 1916,
|
||||||
|
entries: [
|
||||||
|
makeEvent({ eventId: EV_A, title: '' }),
|
||||||
|
makeEvent({ eventId: EV_B, title: ' ' })
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
undated: []
|
||||||
|
};
|
||||||
|
expect(buildEventLookup(timeline).size).toBe(0);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('eventClustering — splitYearLetters', () => {
|
describe('eventClustering — splitYearLetters', () => {
|
||||||
|
|||||||
@@ -33,13 +33,17 @@ export interface SplitLetters {
|
|||||||
* Only year-band events are collected: an undated event renders as a plain pill in the undated
|
* Only year-band events are collected: an undated event renders as a plain pill in the undated
|
||||||
* bucket (out of clustering scope), so including it would scatter its dated letters into orphaned
|
* bucket (out of clustering scope), so including it would scatter its dated letters into orphaned
|
||||||
* cross-year cards detached from that pill (#7).
|
* cross-year cards detached from that pill (#7).
|
||||||
|
*
|
||||||
|
* An event with an empty/whitespace title is skipped too — clustering under it would render a
|
||||||
|
* label-less `✉` mystery card; its letters stay loose instead (#8).
|
||||||
*/
|
*/
|
||||||
export function buildEventLookup(timeline: TimelineDTO): Map<string, string> {
|
export function buildEventLookup(timeline: TimelineDTO): Map<string, string> {
|
||||||
const lookup = new Map<string, string>();
|
const lookup = new Map<string, string>();
|
||||||
const collect = (entries: TimelineEntryDTO[]) => {
|
const collect = (entries: TimelineEntryDTO[]) => {
|
||||||
for (const entry of entries) {
|
for (const entry of entries) {
|
||||||
if (entry.kind === 'EVENT' && entry.eventId && entry.type !== 'HISTORICAL') {
|
const title = entry.title?.trim();
|
||||||
lookup.set(entry.eventId, entry.title ?? '');
|
if (entry.kind === 'EVENT' && entry.eventId && entry.type !== 'HISTORICAL' && title) {
|
||||||
|
lookup.set(entry.eventId, title);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user