Skip to content

Commit

Permalink
feat(hub-common): introduces types and function modifications for dis…
Browse files Browse the repository at this point in the history
…cussion post search (#1425)
  • Loading branch information
drspacemanphd authored Mar 7, 2024
1 parent 57b993f commit b0080ff
Show file tree
Hide file tree
Showing 15 changed files with 343 additions and 31 deletions.
48 changes: 30 additions & 18 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export function getApi(
} else if (shouldUseDiscussionsApi(targetEntity, options)) {
result = getDiscussionsApiDefinition();
} else if (shouldUseOgcApi(targetEntity, options)) {
result = getOgcApiDefinition(options);
result = getOgcApiDefinition(targetEntity, options);
} else {
result = { type: "arcgis", url: portal };
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { EntityType } from "../../types";
import { IHubSearchOptions } from "../../types/IHubSearchOptions";
import { IApiDefinition } from "../../types/types";

Expand All @@ -9,11 +10,17 @@ import { IApiDefinition } from "../../types/types";
* @returns an IApiDefinition with needed info to target the OGC API
*/
export function getOgcApiDefinition(
targetEntity: EntityType,
options: IHubSearchOptions
): IApiDefinition {
const umbrellaDomain = new URL(options.requestOptions.hubApiUrl).hostname;
return {
type: "arcgis-hub",
url: `https://${umbrellaDomain}/api/search/v1`,
};
return targetEntity === "discussionPost"
? {
type: "arcgis-hub",
url: `https://${umbrellaDomain}/api/search/v2`,
}
: {
type: "arcgis-hub",
url: `https://${umbrellaDomain}/api/search/v1`,
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,7 @@ export function shouldUseOgcApi(
site,
requestOptions: { isPortal },
} = options;
return targetEntity === "item" && !!site && !isPortal;
if (isPortal) return false;
if (targetEntity === "discussionPost") return true;
return targetEntity === "item" && !!site;
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,55 @@
import { IQuery } from "../../types/IHubCatalog";
import { IHubSearchOptions } from "../../types/IHubSearchOptions";
import { IHubSearchResponse } from "../../types/IHubSearchResponse";
import { IHubSearchResult } from "../../types/IHubSearchResult";
import { getNextOgcCallback } from "./getNextOgcCallback";
import { IOgcItemsResponse } from "./interfaces";
import { ogcItemToSearchResult } from "./ogcItemToSearchResult";
import { ogcItemToDiscussionPostResult } from "./ogcItemToDiscussionPostResult";
import { IHubSearchResult } from "../../types";

export async function formatOgcItemsResponse(
response: IOgcItemsResponse,
originalQuery: IQuery,
originalOptions: IHubSearchOptions
): Promise<IHubSearchResponse<IHubSearchResult>> {
if (originalQuery.targetEntity === "discussionPost") {
return formatDiscussionPostTargetEntityResponse(
response,
originalQuery,
originalOptions
);
}

return formatItemTargetEntityResponse(
response,
originalQuery,
originalOptions
);
}

async function formatDiscussionPostTargetEntityResponse(
response: IOgcItemsResponse,
originalQuery: IQuery,
originalOptions: IHubSearchOptions
): Promise<IHubSearchResponse<IHubSearchResult>> {
const formattedResults = await Promise.all(
response.features.map((f) => ogcItemToDiscussionPostResult(f))
);
const next = getNextOgcCallback(response, originalQuery, originalOptions);
const nextLink = response.links.find((l) => l.rel === "next");

return {
total: response.numberMatched,
results: formattedResults,
hasNext: !!nextLink,
next,
};
}

async function formatItemTargetEntityResponse(
response: IOgcItemsResponse,
originalQuery: IQuery,
originalOptions: IHubSearchOptions
): Promise<IHubSearchResponse<IHubSearchResult>> {
const formattedResults = await Promise.all(
response.features.map((f) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ import { IApiDefinition } from "../../types/types";
*/
export function getOgcCollectionUrl(query: IQuery, options: IHubSearchOptions) {
const apiDefinition = options.api as IApiDefinition;
// Discussion posts as a target entity will be searchable with one collection,
// so simply use that for the URL
if (query.targetEntity === "discussionPost") {
return `${apiDefinition.url}/collections/discussion-post`;
}
const collectionId = query.collection || "all";
return `${apiDefinition.url}/collections/${collectionId}`;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { IOgcItem } from "./interfaces";
import { IPost } from "../../../discussions";
import { IHubSearchResult } from "../../types";

/**
* This method is responsible for converting an OGC item whose properties
* represent an IPost into an IHubSearchResult. Although some fields do not
* apply, this is being done such that result of a discussion post search
* can automatically be used in a gallery.
* @param ogcItem
* @returns IHubSearchResult
*/
export async function ogcItemToDiscussionPostResult(
ogcItem: IOgcItem
): Promise<IHubSearchResult> {
return {
id: ogcItem.id,
name: ogcItem.properties.title,
summary: ogcItem.properties.body,
createdDate: new Date(ogcItem.properties.createdAt),
createdDateSource: "properties.createdAt",
updatedDate: new Date(ogcItem.properties.updatedAt),
updatedDateSource: "properties.updatedAt",
type: ogcItem.properties.postType,
owner: ogcItem.properties.creator,
location: ogcItem.properties.geometry,
created: new Date(ogcItem.properties.createdAt),
modified: new Date(ogcItem.properties.updatedAt),
title: ogcItem.properties.title,
rawResult: ogcItem.properties,
access: null,
family: null,
} as IHubSearchResult;
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import { IItem } from "@esri/arcgis-rest-types";
import {
IHubGeography,
IHubRequestOptions,
IPolygonProperties,
} from "../../../types";
import { IHubRequestOptions } from "../../../types";
import { IHubSearchResult } from "../../types/IHubSearchResult";
import { itemToSearchResult } from "../portalSearchItems";
import { IOgcItem } from "./interfaces";
Expand Down
1 change: 1 addition & 0 deletions packages/common/src/search/hubSearch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ export async function hubSearch(
"arcgis-hub": {
item: hubSearchItems,
channel: hubSearchChannels,
discussionPost: hubSearchItems,
},
};

Expand Down
3 changes: 2 additions & 1 deletion packages/common/src/search/types/IHubCatalog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ export type EntityType =
| "communityUser"
| "groupMember"
| "event"
| "channel";
| "channel"
| "discussionPost";
/**
* @private
*
Expand Down
13 changes: 13 additions & 0 deletions packages/common/test/search/_internal/getApi.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,17 @@ describe("getApi", () => {
url: portal,
});
});
it("otherwise returns reference to OGC API V2 API if targetEntity is discussionPost", () => {
const options = {
site,
requestOptions: {
hubApiUrl,
isPortal: false,
},
} as unknown as IHubSearchOptions;
expect(getApi("discussionPost", options)).toEqual({
type: "arcgis-hub",
url: `${hubApiUrl}/api/search/v2`,
});
});
});
Loading

0 comments on commit b0080ff

Please sign in to comment.