diff --git a/package-lock.json b/package-lock.json index 9d91054773b..cea607d263f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -65003,7 +65003,7 @@ }, "packages/common": { "name": "@esri/hub-common", - "version": "15.38.1", + "version": "15.41.0", "license": "Apache-2.0", "dependencies": { "@terraformer/arcgis": "^2.1.2", diff --git a/packages/common/src/search/types/IHubCatalog.ts b/packages/common/src/search/types/IHubCatalog.ts index a9d63260a09..6666c604074 100644 --- a/packages/common/src/search/types/IHubCatalog.ts +++ b/packages/common/src/search/types/IHubCatalog.ts @@ -103,17 +103,6 @@ export const targetEntities = [ ] as const; export type EntityType = (typeof targetEntities)[number]; -/** - * @private - * - * This interface wraps IHubCollection and provides additional fields - * for collection configuration. It is the actual interface used when - * when storing an entity's catalog collections. - */ -export interface IHubCollectionPersistance extends IHubCollection { - hidden?: boolean; -} - /** * IQuery is the fundamental unit used to execute a search. By composing * `Filter`'s and `IPredicate`s, we can express very complex queries diff --git a/packages/common/src/sites/_internal/applyDefaultCollectionMigration.ts b/packages/common/src/sites/_internal/applyDefaultCollectionMigration.ts index 39faa7d5845..eb4b6242a01 100644 --- a/packages/common/src/sites/_internal/applyDefaultCollectionMigration.ts +++ b/packages/common/src/sites/_internal/applyDefaultCollectionMigration.ts @@ -1,5 +1,5 @@ import { getWithDefault } from "../../objects"; -import { IHubCollectionPersistance } from "../../search/types/IHubCatalog"; +import { IHubCollection } from "../../search/types/IHubCatalog"; import { WellKnownCollection } from "../../search/wellKnownCatalog"; import { IModel } from "../../hub-types"; import { SearchCategories } from "./types"; @@ -21,7 +21,7 @@ import { defaultSiteCollectionKeys } from "../defaultSiteCollectionKeys"; * NOTE: The changes made in this migration will not be persisted to AGO at this time * * @param model site model to migrate - * @returns a migrated model with default `IHubCollectionPersistance` objects added + * @returns a migrated model with default `IHubCollection` objects added * to the catalog */ export function applyDefaultCollectionMigration(model: IModel): IModel { @@ -44,9 +44,12 @@ export function applyDefaultCollectionMigration(model: IModel): IModel { collection: key, filters: [], }, + displayConfig: { + hidden: false, + }, }; return map; - }, {} as Record); + }, {} as Record); const searchCategoryToCollection: Partial< Record > = { @@ -86,7 +89,7 @@ export function applyDefaultCollectionMigration(model: IModel): IModel { searchCategoryToCollection[searchCategory.key as SearchCategories]; const collection = baseCollectionMap[collectionKey]; collection.label = searchCategory.overrideText || null; - collection.hidden = searchCategory.hidden; + collection.displayConfig.hidden = !!searchCategory.hidden; return collection; }); diff --git a/packages/common/src/sites/_internal/reflectCollectionsToSearchCategories.ts b/packages/common/src/sites/_internal/reflectCollectionsToSearchCategories.ts index 42807cd3a37..734adc9115e 100644 --- a/packages/common/src/sites/_internal/reflectCollectionsToSearchCategories.ts +++ b/packages/common/src/sites/_internal/reflectCollectionsToSearchCategories.ts @@ -1,5 +1,5 @@ import { WellKnownCollection } from "../../search"; -import { IHubCollectionPersistance } from "../../search/types/IHubCatalog"; +import { IHubCollection } from "../../search/types/IHubCatalog"; import { IModel } from "../../hub-types"; import { cloneObject } from "../../util"; import { SearchCategories } from "./types"; @@ -35,8 +35,7 @@ export function reflectCollectionsToSearchCategories(model: IModel) { [SearchCategories.APPS_AND_MAPS]: "App,Map", [SearchCategories.DOCUMENTS]: "Document", }; - const collections: IHubCollectionPersistance[] = - clone.data.catalog.collections; + const collections: IHubCollection[] = clone.data.catalog.collections; const updatedSearchCategories = collections // We don't want to persist any non-standard collection as a search category, @@ -46,7 +45,7 @@ export function reflectCollectionsToSearchCategories(model: IModel) { const searchCategoryKey = collectionToSearchCategory[c.key as WellKnownCollection]; const updated: any = { - hidden: c.hidden, + hidden: !!c.displayConfig?.hidden, key: searchCategoryKey, queryParams: { collection: searchCategoryToQueryParam[searchCategoryKey], diff --git a/packages/common/test/sites/HubSites.test.ts b/packages/common/test/sites/HubSites.test.ts index dcd048bfc98..8fd62e33c2a 100644 --- a/packages/common/test/sites/HubSites.test.ts +++ b/packages/common/test/sites/HubSites.test.ts @@ -11,7 +11,7 @@ import { cloneObject, enrichSiteSearchResult, fetchSite, - IHubCollectionPersistance, + IHubCollection, IHubRequestOptions, } from "../../src"; import * as slugUtils from "../../src/items/slugs"; @@ -477,13 +477,15 @@ describe("HubSites:", () => { label: "My Datasets", key: "dataset", targetEntity: "item", - hidden: true, scope: { targetEntity: "item", collection: "dataset", filters: [], }, - } as IHubCollectionPersistance, + displayConfig: { + hidden: true, + }, + } as IHubCollection, ]; const chk = await commonModule.updateSite(updatedSite, MOCK_HUB_REQOPTS); diff --git a/packages/common/test/sites/_internal/applyDefaultCollectionMigration.test.ts b/packages/common/test/sites/_internal/applyDefaultCollectionMigration.test.ts index 78d64211007..1368fab7ae0 100644 --- a/packages/common/test/sites/_internal/applyDefaultCollectionMigration.test.ts +++ b/packages/common/test/sites/_internal/applyDefaultCollectionMigration.test.ts @@ -1,4 +1,4 @@ -import { IHubCollectionPersistance } from "../../../src/search/types/IHubCatalog"; +import { IHubCollection } from "../../../src/search/types/IHubCatalog"; import { applyDefaultCollectionMigration } from "../../../src/sites/_internal/applyDefaultCollectionMigration"; import { SearchCategories } from "../../../src/sites/_internal/types"; import { IModel } from "../../../src/hub-types"; @@ -31,7 +31,7 @@ describe("applyDefaultCollectionMigration", () => { it("Adds untouched default collections when no search categories are configured", () => { const result = applyDefaultCollectionMigration(site); const collectionKeys = result.data.catalog.collections.map( - (c: IHubCollectionPersistance) => c.key + (c: IHubCollection) => c.key ); expect(collectionKeys).toEqual([ "all", @@ -41,19 +41,13 @@ describe("applyDefaultCollectionMigration", () => { "appAndMap", ]); const collectionLabels = result.data.catalog.collections.map( - (c: IHubCollectionPersistance) => c.label + (c: IHubCollection) => c.label ); expect(collectionLabels).toEqual([null, null, null, null, null]); const hiddenStatuses = result.data.catalog.collections.map( - (c: IHubCollectionPersistance) => c.hidden + (c: IHubCollection) => c.displayConfig?.hidden ); - expect(hiddenStatuses).toEqual([ - undefined, - true, - undefined, - undefined, - undefined, - ]); + expect(hiddenStatuses).toEqual([false, true, false, false, false]); }); it("Reorders, re-labels, and hides default collections when search categories are configured", () => { @@ -78,7 +72,7 @@ describe("applyDefaultCollectionMigration", () => { ]; const result = applyDefaultCollectionMigration(site); const collectionKeys = result.data.catalog.collections.map( - (c: IHubCollectionPersistance) => c.key + (c: IHubCollection) => c.key ); // Note: 'all' collection is always prepended expect(collectionKeys).toEqual([ @@ -90,14 +84,14 @@ describe("applyDefaultCollectionMigration", () => { ]); const collectionLabels = result.data.catalog.collections.map( - (c: IHubCollectionPersistance) => c.label + (c: IHubCollection) => c.label ); expect(collectionLabels).toEqual([null, null, null, "My Sites", "My Data"]); const hiddenStatuses = result.data.catalog.collections.map( - (c: IHubCollectionPersistance) => c.hidden + (c: IHubCollection) => c.displayConfig.hidden ); - expect(hiddenStatuses).toEqual([undefined, undefined, true, false, false]); + expect(hiddenStatuses).toEqual([false, false, true, false, false]); }); it("Handles when a site has the 'initiatives' search category saved", () => { @@ -110,20 +104,20 @@ describe("applyDefaultCollectionMigration", () => { ]; const result = applyDefaultCollectionMigration(site); const collectionKeys = result.data.catalog.collections.map( - (c: IHubCollectionPersistance) => c.key + (c: IHubCollection) => c.key ); // Note: 'all' collection is always prepended expect(collectionKeys).toEqual(["all", "site"]); const collectionLabels = result.data.catalog.collections.map( - (c: IHubCollectionPersistance) => c.label + (c: IHubCollection) => c.label ); expect(collectionLabels).toEqual([null, "My Initiatives"]); const hiddenStatuses = result.data.catalog.collections.map( - (c: IHubCollectionPersistance) => c.hidden + (c: IHubCollection) => c.displayConfig.hidden ); - expect(hiddenStatuses).toEqual([undefined, true]); + expect(hiddenStatuses).toEqual([false, true]); }); it("Omits unsupported search categories, like an explicit 'all' or events", () => { @@ -139,19 +133,19 @@ describe("applyDefaultCollectionMigration", () => { ]; const result = applyDefaultCollectionMigration(site); const collectionKeys = result.data.catalog.collections.map( - (c: IHubCollectionPersistance) => c.key + (c: IHubCollection) => c.key ); // Note: 'all' collection can never be relabeled, hidden, or reordered expect(collectionKeys).toEqual(["all"]); const collectionLabels = result.data.catalog.collections.map( - (c: IHubCollectionPersistance) => c.label + (c: IHubCollection) => c.label ); expect(collectionLabels).toEqual([null]); const hiddenStatuses = result.data.catalog.collections.map( - (c: IHubCollectionPersistance) => c.hidden + (c: IHubCollection) => c.displayConfig.hidden ); - expect(hiddenStatuses).toEqual([undefined]); + expect(hiddenStatuses).toEqual([false]); }); }); diff --git a/packages/common/test/sites/_internal/reflectCollectionsToSearchCategories.test.ts b/packages/common/test/sites/_internal/reflectCollectionsToSearchCategories.test.ts index 97c867bf385..989d586855b 100644 --- a/packages/common/test/sites/_internal/reflectCollectionsToSearchCategories.test.ts +++ b/packages/common/test/sites/_internal/reflectCollectionsToSearchCategories.test.ts @@ -1,4 +1,4 @@ -import { IHubCollectionPersistance } from "../../../src/search/types/IHubCatalog"; +import { IHubCollection } from "../../../src/search/types/IHubCatalog"; import { WellKnownCollection } from "../../../src/search/wellKnownCatalog"; import { reflectCollectionsToSearchCategories } from "../../../src/sites/_internal/reflectCollectionsToSearchCategories"; import { SearchCategories } from "../../../src/sites/_internal/types"; @@ -33,24 +33,39 @@ describe("reflectCollectionsToSearchCategories", () => { label: null, key: "dataset", targetEntity: "item", - hidden: true, scope: { targetEntity: "item", collection: "dataset", filters: [], }, - } as IHubCollectionPersistance, + displayConfig: { + hidden: true, + }, + } as IHubCollection, { label: null, key: "document", targetEntity: "item", - hidden: false, + displayConfig: { + hidden: false, + }, scope: { targetEntity: "item", collection: "document", filters: [], }, - } as IHubCollectionPersistance, + } as IHubCollection, + { + label: null, + key: "appAndMap", + targetEntity: "item", + // intentionally leaving out displayConfig.hidden for branch coverage + scope: { + targetEntity: "item", + collection: "appAndMap", + filters: [], + }, + } as IHubCollection, ]; const result = reflectCollectionsToSearchCategories(site); @@ -69,6 +84,13 @@ describe("reflectCollectionsToSearchCategories", () => { collection: "Document", }, }, + { + key: SearchCategories.APPS_AND_MAPS, + hidden: false, + queryParams: { + collection: "App,Map", + }, + }, ]); }); it("handles re-labeled collections", () => { @@ -77,24 +99,28 @@ describe("reflectCollectionsToSearchCategories", () => { label: "My Cool Sites!", key: "site", targetEntity: "item", - hidden: false, + displayConfig: { + hidden: false, + }, scope: { targetEntity: "item", collection: "site", filters: [], }, - } as IHubCollectionPersistance, + } as IHubCollection, { label: "Apps & Maps", key: "appAndMap", targetEntity: "item", - hidden: false, + displayConfig: { + hidden: false, + }, scope: { targetEntity: "item", collection: "appAndMap", filters: [], }, - } as IHubCollectionPersistance, + } as IHubCollection, ]; const result = reflectCollectionsToSearchCategories(site); @@ -124,36 +150,42 @@ describe("reflectCollectionsToSearchCategories", () => { label: null, key: "dataset", targetEntity: "item", - hidden: false, + displayConfig: { + hidden: false, + }, scope: { targetEntity: "item", collection: "dataset", filters: [], }, - } as IHubCollectionPersistance, + } as IHubCollection, // 'all' _can_ be converted to a search category, but we explicitly do not persist it { label: null, key: "all", targetEntity: "item", - hidden: false, + displayConfig: { + hidden: false, + }, scope: { targetEntity: "item", collection: "all" as WellKnownCollection, filters: [], }, - } as IHubCollectionPersistance, + } as IHubCollection, // Customer-defined collection, cannot be converted to search category { label: "My Custom Collection", key: "custom-collection", targetEntity: "event", - hidden: false, + displayConfig: { + hidden: false, + }, scope: { targetEntity: "event", filters: [], }, - } as IHubCollectionPersistance, + } as IHubCollection, ]; const result = reflectCollectionsToSearchCategories(site); diff --git a/packages/common/test/sites/get-catalog-from-site-model.ts b/packages/common/test/sites/get-catalog-from-site-model.test.ts similarity index 80% rename from packages/common/test/sites/get-catalog-from-site-model.ts rename to packages/common/test/sites/get-catalog-from-site-model.test.ts index 640dc2cc44d..a6e64315815 100644 --- a/packages/common/test/sites/get-catalog-from-site-model.ts +++ b/packages/common/test/sites/get-catalog-from-site-model.test.ts @@ -15,19 +15,19 @@ describe("getCatalogFromSiteModel", () => { expect(chk.title).toBe("Default Site Catalog"); expect(chk.scopes).toBeDefined(); - expect(chk.scopes?.item?.filters.length).toBe(1); - expect(chk.scopes?.item?.filters[0].predicates[0].group).toEqual([ + expect(chk.scopes.item.filters.length).toBe(1); + expect(chk.scopes.item.filters[0].predicates[0].group).toEqual([ "00c", "00d", ]); - expect(chk.scopes?.event?.filters.length).toBe(1); - expect(chk.scopes?.event?.filters[0].predicates[0].group).toEqual([ + expect(chk.scopes.event.filters.length).toBe(1); + expect(chk.scopes.event.filters[0].predicates[0].group).toEqual([ "00c", "00d", ]); // check for collections - expect(chk.collections?.map((c) => c.key)).toEqual([ + expect(chk.collections.map((c) => c.key)).toEqual([ "all", "site", "dataset",