mirror of
https://github.com/PeWu/topola-viewer.git
synced 2026-07-28 06:31:49 +00:00
Add configurable place display and shortening (#294)
* Add configurable place display and shortening * Fix prettier formatting stuff * Move place shortening logic to Chart
This commit is contained in:
50
src/util/place_util.spec.ts
Normal file
50
src/util/place_util.spec.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
import {describe, expect, it} from '@jest/globals';
|
||||
import {PlaceDisplay, shortenPlace} from './place_util';
|
||||
|
||||
const LONG = 'Cyclone, Keating Township, McKean, Pennsylvania, United States';
|
||||
|
||||
describe('shortenPlace', () => {
|
||||
it('returns full place unchanged in FULL mode', () => {
|
||||
expect(shortenPlace(LONG, PlaceDisplay.FULL)).toBe(LONG);
|
||||
});
|
||||
|
||||
it('returns undefined in HIDE mode', () => {
|
||||
expect(shortenPlace(LONG, PlaceDisplay.HIDE)).toBeUndefined();
|
||||
});
|
||||
|
||||
it('defaults to 2 components in SHORT mode', () => {
|
||||
expect(shortenPlace(LONG, PlaceDisplay.SHORT)).toBe(
|
||||
'Cyclone, Keating Township',
|
||||
);
|
||||
});
|
||||
|
||||
it('keeps first N components when count is specified', () => {
|
||||
expect(shortenPlace(LONG, PlaceDisplay.SHORT, 1)).toBe('Cyclone');
|
||||
expect(shortenPlace(LONG, PlaceDisplay.SHORT, 3)).toBe(
|
||||
'Cyclone, Keating Township, McKean',
|
||||
);
|
||||
});
|
||||
|
||||
it('leaves place unchanged when it has fewer parts than count', () => {
|
||||
expect(shortenPlace('Berlin, Germany', PlaceDisplay.SHORT, 3)).toBe(
|
||||
'Berlin, Germany',
|
||||
);
|
||||
});
|
||||
|
||||
it('leaves single-component place unchanged in SHORT mode', () => {
|
||||
expect(shortenPlace('Germany', PlaceDisplay.SHORT)).toBe('Germany');
|
||||
});
|
||||
|
||||
it('handles undefined place', () => {
|
||||
expect(shortenPlace(undefined, PlaceDisplay.SHORT)).toBeUndefined();
|
||||
});
|
||||
|
||||
it('handles empty string', () => {
|
||||
expect(shortenPlace('', PlaceDisplay.SHORT)).toBe('');
|
||||
});
|
||||
|
||||
it('is idempotent — applying SHORT twice with same count gives same result', () => {
|
||||
const once = shortenPlace(LONG, PlaceDisplay.SHORT, 2);
|
||||
expect(shortenPlace(once, PlaceDisplay.SHORT, 2)).toBe(once);
|
||||
});
|
||||
});
|
||||
36
src/util/place_util.ts
Normal file
36
src/util/place_util.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
export enum PlaceDisplay {
|
||||
FULL,
|
||||
SHORT,
|
||||
HIDE,
|
||||
}
|
||||
|
||||
export const DEFAULT_PLACE_DISPLAY_COUNT = 2;
|
||||
|
||||
/**
|
||||
* Shortens a GEDCOM place string for display in chart nodes.
|
||||
*
|
||||
* GEDCOM places are comma-separated from most-specific to least-specific,
|
||||
* e.g. "Cyclone, McKean, Pennsylvania, United States".
|
||||
* SHORT keeps the first `count` components (most-specific).
|
||||
* HIDE removes the place entirely.
|
||||
*/
|
||||
export function shortenPlace(
|
||||
place: string | undefined,
|
||||
mode: PlaceDisplay,
|
||||
count: number = DEFAULT_PLACE_DISPLAY_COUNT,
|
||||
): string | undefined {
|
||||
if (!place || mode === PlaceDisplay.FULL) {
|
||||
return place;
|
||||
}
|
||||
if (mode === PlaceDisplay.HIDE) {
|
||||
return undefined;
|
||||
}
|
||||
const parts = place
|
||||
.split(',')
|
||||
.map((p) => p.trim())
|
||||
.filter(Boolean);
|
||||
if (parts.length <= count) {
|
||||
return place;
|
||||
}
|
||||
return parts.slice(0, count).join(', ');
|
||||
}
|
||||
Reference in New Issue
Block a user