diff --git a/__tests__/lib/import/ingesters/met/collectionsIngester.test.ts b/__tests__/lib/import/ingesters/met/collectionsIngester.test.ts
new file mode 100644
index 0000000..6b0c4d9
--- /dev/null
+++ b/__tests__/lib/import/ingesters/met/collectionsIngester.test.ts
@@ -0,0 +1,80 @@
+import { ingester } from '@/lib/import/ingesters/met/collectionsIngester';
+import { ArtworkDocument } from '@/types/document';
+
+const mockMetDocument = {
+ 'Object Number': '04.1a–c',
+ 'Is Highlight': true,
+ 'Is Timeline Work': true,
+ 'Is Public Domain': false,
+ 'Object ID': 35,
+ 'Gallery Number': 706,
+ Department: 'The American Wing',
+ AccessionYear: 1904,
+ 'Object Name': 'Vase',
+ Title: 'The Adams Vase',
+ Culture: 'American',
+ Period: null,
+ Dynasty: null,
+ Reign: null,
+ Portfolio: null,
+ 'Constituent ID': 108316253,
+ 'Artist Role': 'Designer|Manufacturer',
+ 'Artist Prefix': 'Designed by|Manufactured by',
+ 'Artist Display Name': 'Paulding Farnham|Tiffany & Co.',
+ 'Artist Display Bio': '1859–1927|1837–present',
+ 'Artist Suffix': ' | ',
+ 'Artist Alpha Sort': 'Farnham, Paulding|Tiffany & Co.',
+ 'Artist Nationality': 'American| ',
+ 'Artist Begin Date': '1859 |1837 ',
+ 'Artist End Date': '1927 |9999 ',
+ 'Artist Gender': '|',
+ 'Artist ULAN URL':
+ 'http://vocab.getty.edu/page/ulan/500336597|http://vocab.getty.edu/page/ulan/500330306',
+ 'Artist Wikidata URL':
+ 'https://www.wikidata.org/wiki/Q13476260|https://www.wikidata.org/wiki/Q1066858',
+ 'Object Date': '1893–95',
+ 'Object Begin Date': 1893,
+ 'Object End Date': 1895,
+ Medium:
+ 'Gold, amethysts, spessartites, tourmalines, fresh water pearls, quartzes, rock crystal, and enamel',
+ Dimensions:
+ 'Overall: 19 7/16 x 13 x 9 1/4 in. (49.4 x 33 x 23.5 cm); 352 oz. 18 dwt. (10977 g) Body: H. 18 7/8 in. (47.9 cm) Cover: 4 1/4 x 4 13/16 in. (10.8 x 12.2 cm); 19 oz. 6 dwt. (600.1 g)',
+ 'Credit Line': 'Gift of Edward D. Adams, 1904',
+ 'Geography Type': 'Made in',
+ City: 'New York',
+ State: null,
+ County: null,
+ Country: 'United States',
+ Region: null,
+ Subregion: null,
+ Locale: null,
+ Locus: null,
+ Excavation: null,
+ River: null,
+ Classification: null,
+ 'Rights and Reproduction': null,
+ 'Link Resource': 'http://www.metmuseum.org/art/collection/search/35',
+ 'Object Wikidata URL': 'https://www.wikidata.org/wiki/Q83545838',
+ 'Metadata Date': null,
+ Repository: 'Metropolitan Museum of Art, New York, NY',
+ Tags: 'Animals|Garlands|Birds|Men',
+ 'Tags AAT URL':
+ 'http://vocab.getty.edu/page/aat/300249525|http://vocab.getty.edu/page/aat/300167386|http://vocab.getty.edu/page/aat/300266506|http://vocab.getty.edu/page/aat/300025928',
+ 'Tags Wikidata URL':
+ 'https://www.wikidata.org/wiki/Q729|https://www.wikidata.org/wiki/Q756600|https://www.wikidata.org/wiki/Q5113|https://www.wikidata.org/wiki/Q8441',
+};
+
+describe('transformDoc', () => {
+ it('should transform MetDocument into ArtworkDocument', async () => {
+ const esDoc = await ingester.transform(mockMetDocument) as ArtworkDocument;
+
+ expect(esDoc.source).toBe('The Met');
+ expect(esDoc.id).toBe('35');
+ expect(esDoc.title).toBe('The Adams Vase');
+ expect(esDoc.dimensions).toContain('19 7/16 x 13 x 9 1/4 in.');
+ expect(esDoc.highlight).toBe(true);
+ expect(esDoc.keywords).toBeDefined();
+ expect(esDoc.keywords?.length).toBe(4);
+ expect(esDoc.primaryConstituent?.name).toBe('Paulding Farnham');
+ });
+});
diff --git a/components/search/event-search-checkboxes.tsx b/components/search/event-search-checkboxes.tsx
index fc546cd..515658d 100644
--- a/components/search/event-search-checkboxes.tsx
+++ b/components/search/event-search-checkboxes.tsx
@@ -12,7 +12,6 @@ export function EventSearchCheckboxes({ params }: EventSearchCheckboxesProps) {
return (
- {/*
- */}
40 chars, truncate and add ellipsis:
const myTitle =
@@ -44,8 +33,9 @@ function getBarText(item: BaseDocument | EventDocument) {
return `${myTitle} - ${item.source}`;
}
-function getDomainMin(items: (BaseDocument | EventDocument)[]) {
- const min = Math.min(
+function getDomainMin(items: EventDocument[]) {
+ if (!(items?.length > 0)) return new Date().getTime();
+ const min = Math.max(
...items
.filter((item) => item.date)
.map((item) => new Date(item.date || '').getTime())
@@ -54,31 +44,41 @@ function getDomainMin(items: (BaseDocument | EventDocument)[]) {
}
function getDomainMax(items: (BaseDocument | EventDocument)[]) {
+ const maxDate = new Date(new Date().setMonth(new Date().getMonth() + 6))
+ .toISOString()
+ .split('T')[0];
+ if (!(items?.length > 0)) return new Date().getTime();
const max = Math.max(
...items
- .filter((item): item is EventDocument => 'endDate' in item && item.endDate !== undefined)
+ .filter(
+ (item): item is EventDocument =>
+ 'endDate' in item && item.endDate !== undefined
+ )
.map((item) => {
- // if item.endDate is greater than 5 years into future, don't use it:
- const endDate = new Date(item.endDate || '').getTime();
- return endDate >
- new Date(
- new Date().setFullYear(new Date().getFullYear() + 5)
- ).getTime()
- ? new Date(maxDate).getTime()
- : endDate;
+ // if item.endDate is greater than 3 years into future, don't use it:
+ try {
+ const endDate = new Date(item.endDate || '').getTime();
+ return endDate >
+ new Date(
+ new Date().setFullYear(new Date().getFullYear() + 20)
+ ).getTime()
+ ? new Date(maxDate).getTime()
+ : endDate;
+ } catch (e) {
+ return 0;
+ }
})
);
return max;
}
-interface TimelineProps {
- items: (BaseDocument | EventDocument)[];
-}
-
-export function Timeline({ items }: TimelineProps) {
- const dict = getDictionary();
- // create a new array of items, sorted by location:
- const sortedItems = items.sort((a, b) => {
+/**
+ * Sort items by location and sourceId
+ * @param items Array of items to sort
+ * @returns Sorted array of items
+ */
+function getSortedItems(items: (BaseDocument | EventDocument)[]) {
+ return [...items].sort((a, b) => {
if (a.sourceId && b.sourceId) {
const locationA = a.sourceId && sources[a.sourceId]?.location;
const locationB = b.sourceId && sources[b.sourceId]?.location;
@@ -94,35 +94,44 @@ export function Timeline({ items }: TimelineProps) {
}
return 0;
});
+}
- // for each item, if endDate > maxTime, set endDate to maxTime
- const maxTime = getDomainMax(sortedItems);
- const maxDate = format(new Date(maxTime), 'yyyy-MM-dd');
+function getMinTimeWithinDomain(item: EventDocument, minTime: number) {
+ if (item.date) return new Date(item.date).getTime();
+ return minTime;
+}
+
+function getMaxTimeWithinDomain(item: EventDocument, maxTime: number) {
+ if (item.endDate && new Date(item.endDate).getTime() < maxTime) {
+ return new Date(item.endDate).getTime();
+ }
+ return maxTime;
+}
+
+const chartMargin = { top: 40, right: 10, bottom: 10, left: 10 };
+const chartWidth = 1200;
+const chartHeight = 600;
+
+interface TimelineProps {
+ items: (BaseDocument | EventDocument)[];
+}
+
+export function Timeline({ items }: TimelineProps) {
+ const dict = getDictionary();
+ const sortedItems = getSortedItems(items);
const minTime = getDomainMin(sortedItems);
- const minDate = format(new Date(minTime), 'yyyy-MM-dd');
- sortedItems.forEach((item: EventDocument) => {
- // if item.endDate is greater than 5 years into future, don't use it:
- if (item.endDate) {
- const endDate = new Date(item.endDate).getTime();
- if (
- endDate >
- new Date(new Date().setFullYear(new Date().getFullYear() + 5)).getTime()
- ) {
- item.endDate = format(new Date(maxTime), 'yyyy-MM-dd');
- }
- }
- });
+ const maxTime = getDomainMax(sortedItems);
const timeScale = scaleLinear({
- domain: [getDomainMin(sortedItems), getDomainMax(sortedItems)],
- range: [margin.left, width - margin.right], // Now for horizontal
+ domain: [minTime, maxTime],
+ range: [chartMargin.left, chartWidth - chartMargin.right], // Now for horizontal
});
const itemScale = scaleBand({
domain: sortedItems
.filter((item) => item.title)
.map((item) => item.title) as string[],
- range: [height - margin.bottom, margin.top],
+ range: [chartHeight - chartMargin.bottom, chartMargin.top],
padding: 0.1,
});
@@ -141,12 +150,12 @@ export function Timeline({ items }: TimelineProps) {
return (
<>
-