-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(hub-common): add support for searching for Events3 events from h… (
- Loading branch information
1 parent
5d3da09
commit 4afe9a4
Showing
27 changed files
with
1,123 additions
and
14 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { IHubEntityLinks } from "../../core/types"; | ||
import { getRelativeWorkspaceUrl } from "../../core/getRelativeWorkspaceUrl"; | ||
import { getHubRelativeUrl } from "../../content/_internal/internalContentUtils"; | ||
import { IEvent } from "../api/orval/api/orval-events"; | ||
import { getEventSlug } from "./getEventSlug"; | ||
|
||
/** | ||
* Compute the links that get appended to a Hub Event | ||
* search result and entity | ||
* | ||
* @param item | ||
* @param requestOptions | ||
*/ | ||
export function computeLinks(event: IEvent): IHubEntityLinks { | ||
const siteRelative = getHubRelativeUrl("event", getEventSlug(event)); | ||
return { | ||
self: siteRelative, | ||
siteRelative, | ||
workspaceRelative: getRelativeWorkspaceUrl("Event", event.id), | ||
// TODO | ||
// thumbnail: "", | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { slugify } from "../../utils/slugify"; | ||
import { IEvent } from "../api/orval/api/orval-events"; | ||
|
||
/** | ||
* Builds a slug for the given IEvent record. | ||
* @param event An IEvent record | ||
* @returns the slug for the given IEvent record | ||
*/ | ||
export function getEventSlug(event: IEvent): string { | ||
return ( | ||
[slugify(event.title), event.id] | ||
.join("-") | ||
// remove double hyphens | ||
.split("-") | ||
.filter(Boolean) | ||
.join("-") | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
20 changes: 20 additions & 0 deletions
20
packages/common/src/search/_internal/commonHelpers/shouldUseEventsApi.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { EntityType } from "../../types/IHubCatalog"; | ||
import { IHubSearchOptions } from "../../types/IHubSearchOptions"; | ||
|
||
/** | ||
* @private | ||
* Determines if the Events API can be targeted with the given | ||
* search parameters | ||
* @param targetEntity | ||
* @param options | ||
* @returns boolean | ||
*/ | ||
export function shouldUseEventsApi( | ||
targetEntity: EntityType, | ||
options: IHubSearchOptions | ||
): boolean { | ||
const { | ||
requestOptions: { isPortal }, | ||
} = options; | ||
return targetEntity === "event" && !isPortal; | ||
} |
42 changes: 42 additions & 0 deletions
42
packages/common/src/search/_internal/hubEventsHelpers/eventToSearchResult.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import { getUser } from "@esri/arcgis-rest-portal"; | ||
import { IHubSearchOptions } from "../../types/IHubSearchOptions"; | ||
import { IHubSearchResult } from "../../types/IHubSearchResult"; | ||
import { IEvent } from "../../../events/api/orval/api/orval-events"; | ||
import { AccessLevel } from "../../../core/types/types"; | ||
import { HubFamily } from "../../../types"; | ||
import { computeLinks } from "../../../events/_internal/computeLinks"; | ||
|
||
/** | ||
* Resolves an IHubSearchResult for the given IEvent record | ||
* @param event An IEvent record | ||
* @param options An IHubSearchOptions object | ||
* @returns a IHubSearchResult for the given IEvent record | ||
*/ | ||
export async function eventToSearchResult( | ||
event: IEvent, | ||
options: IHubSearchOptions | ||
): Promise<IHubSearchResult> { | ||
const ownerUser = await getUser({ | ||
username: event.creator.username, | ||
...options.requestOptions, | ||
}); | ||
const result = { | ||
access: event.access.toLowerCase() as AccessLevel, | ||
id: event.id, | ||
type: "Event", | ||
name: event.title, | ||
owner: event.creator.username, | ||
ownerUser, | ||
summary: event.summary || event.description, | ||
createdDate: new Date(event.createdAt), | ||
createdDateSource: "event.createdAt", | ||
updatedDate: new Date(event.updatedAt), | ||
updatedDateSource: "event.updatedAt", | ||
family: "event" as HubFamily, | ||
links: computeLinks(event), | ||
tags: event.tags, | ||
categories: event.categories, | ||
rawResult: event, | ||
}; | ||
return result; | ||
} |
83 changes: 83 additions & 0 deletions
83
packages/common/src/search/_internal/hubEventsHelpers/processFilters.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import { IFilter, IPredicate } from "../../types/IHubCatalog"; | ||
import { | ||
EventStatus, | ||
GetEventsParams, | ||
} from "../../../events/api/orval/api/orval-events"; | ||
import { unique } from "../../../util"; | ||
|
||
const getPredicateValuesByKey = ( | ||
filters: IFilter[], | ||
predicateKey: string | ||
): any[] => { | ||
const toPredicateValuesByKey = (a1: any[], filter: IFilter): any[] => | ||
filter.predicates.reduce<any[]>( | ||
(a2, predicate) => | ||
Object.entries(predicate).reduce( | ||
(a3, [key, val]) => (key === predicateKey ? [...a3, val] : a3), | ||
a2 | ||
), | ||
a1 | ||
); | ||
return filters.reduce(toPredicateValuesByKey, []); | ||
}; | ||
|
||
const getOptionalPredicateStringsByKey = ( | ||
filters: IFilter[], | ||
predicateKey: string | ||
): string => { | ||
const predicateValues = getPredicateValuesByKey(filters, predicateKey); | ||
const str = predicateValues.filter(unique).join(","); | ||
if (str) { | ||
return str; | ||
} | ||
}; | ||
|
||
/** | ||
* Builds a Partial<GetEventsParams> given an Array of IFilter objects | ||
* @param filters An Array of IFilter | ||
* @returns a Partial<GetEventsParams> for the given Array of IFilter objects | ||
*/ | ||
export function processFilters(filters: IFilter[]): Partial<GetEventsParams> { | ||
const processedFilters: Partial<GetEventsParams> = {}; | ||
const access = getOptionalPredicateStringsByKey(filters, "access"); | ||
if (access?.length) { | ||
// TODO: remove ts-ignore once GetEventsParams supports filtering by access | ||
// @ts-ignore | ||
processedFilters.access = access; | ||
} | ||
const term = getPredicateValuesByKey(filters, "term"); | ||
if (term.length) { | ||
processedFilters.title = term[0]; | ||
} | ||
const categories = getOptionalPredicateStringsByKey(filters, "categories"); | ||
if (categories?.length) { | ||
processedFilters.categories = categories; | ||
} | ||
const tags = getOptionalPredicateStringsByKey(filters, "tags"); | ||
if (tags?.length) { | ||
processedFilters.tags = tags; | ||
} | ||
const attendanceType = getOptionalPredicateStringsByKey( | ||
filters, | ||
"attendanceType" | ||
); | ||
if (attendanceType?.length) { | ||
processedFilters.attendanceTypes = attendanceType; | ||
} | ||
const status = getOptionalPredicateStringsByKey(filters, "status"); | ||
processedFilters.status = status?.length | ||
? status | ||
: [EventStatus.PLANNED, EventStatus.CANCELED] | ||
.map((val) => val.toLowerCase()) | ||
.join(","); | ||
const startDateRange = getPredicateValuesByKey(filters, "startDateRange"); | ||
if (startDateRange.length) { | ||
processedFilters.startDateTimeBefore = new Date( | ||
startDateRange[0].to | ||
).toISOString(); | ||
processedFilters.startDateTimeAfter = new Date( | ||
startDateRange[0].from | ||
).toISOString(); | ||
} | ||
return processedFilters; | ||
} |
33 changes: 33 additions & 0 deletions
33
packages/common/src/search/_internal/hubEventsHelpers/processOptions.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { IHubSearchOptions } from "../../types/IHubSearchOptions"; | ||
import { | ||
EventSort, | ||
GetEventsParams, | ||
SortOrder, | ||
} from "../../../events/api/orval/api/orval-events"; | ||
|
||
/** | ||
* Builds a Partial<GetEventsParams> for the given IHubSearchOptions | ||
* @param options An IHubSearchOptions object | ||
* @returns a Partial<GetEventsParams> for the given IHubSearchOptions | ||
*/ | ||
export function processOptions( | ||
options: IHubSearchOptions | ||
): Partial<GetEventsParams> { | ||
const processedOptions: Partial<GetEventsParams> = {}; | ||
if (options.num > 0) { | ||
processedOptions.num = options.num.toString(); | ||
} | ||
if (options.start > 1) { | ||
processedOptions.start = options.start.toString(); | ||
} | ||
if (options.sortField === "modified") { | ||
processedOptions.sortBy = EventSort.updatedAt; | ||
} else if (options.sortField === "created") { | ||
processedOptions.sortBy = EventSort.createdAt; | ||
} else if (options.sortField === "title") { | ||
processedOptions.sortBy = EventSort.title; | ||
} | ||
processedOptions.sortOrder = | ||
options.sortOrder === "desc" ? SortOrder.desc : SortOrder.asc; | ||
return processedOptions; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import { IQuery } from "../types/IHubCatalog"; | ||
import { IHubSearchOptions } from "../types/IHubSearchOptions"; | ||
import { IHubSearchResponse } from "../types/IHubSearchResponse"; | ||
import { IHubSearchResult } from "../types/IHubSearchResult"; | ||
import { getEvents } from "../../events/api/events"; | ||
import { GetEventsParams } from "../../events/api/orval/api/orval-events"; | ||
import { eventToSearchResult } from "./hubEventsHelpers/eventToSearchResult"; | ||
import { processOptions } from "./hubEventsHelpers/processOptions"; | ||
import { processFilters } from "./hubEventsHelpers/processFilters"; | ||
|
||
/** | ||
* Searches for events against the Events 3 API using the given `query` and `options` | ||
* @param query An IQuery object | ||
* @param options An IHubSearchOptions object | ||
* @returns a promise that resolves a <IHubSearchResponse<IHubSearchResult> object | ||
*/ | ||
export async function hubSearchEvents( | ||
query: IQuery, | ||
options: IHubSearchOptions | ||
): Promise<IHubSearchResponse<IHubSearchResult>> { | ||
const processedFilters = processFilters(query.filters); | ||
const processedOptions = processOptions(options); | ||
const data: GetEventsParams = { | ||
...processedFilters, | ||
...processedOptions, | ||
include: "creator,registrations", | ||
}; | ||
const { items, nextStart, total } = await getEvents({ | ||
...options.requestOptions, | ||
data, | ||
}); | ||
const results = await Promise.all( | ||
items.map((event) => eventToSearchResult(event, options)) | ||
); | ||
const hasNext = nextStart > -1; | ||
return { | ||
total, | ||
results, | ||
hasNext, | ||
next: () => { | ||
if (!hasNext) { | ||
throw new Error("No more hub events for the given query and options"); | ||
} | ||
return hubSearchEvents(query, { | ||
...options, | ||
start: nextStart, | ||
}); | ||
}, | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.