From 8de54064c52da966dd6ad6293ba6e3b0ad5633ff Mon Sep 17 00:00:00 2001 From: Felix Perron-Brault Date: Tue, 17 Sep 2024 10:08:09 -0400 Subject: [PATCH] chore(headless, atomic, quantic)!: remove deprecated functions/properties (#4350) This PR removes deprecated functions and properties. It also removes some atomic-react properties and big changes in atomic-hosted-page. It includes changes to `atomic-category-facet` and the equivalent in quantic as the `parents` and `values` properties have been replaced with `valuesAsTrees` and `selectedValueAncestry` https://coveord.atlassian.net/browse/KIT-2379 --------- Co-authored-by: Alex Prudhomme <78121423+alexprudhomme@users.noreply.github.com> Co-authored-by: Frederic Beaudoin --- .../atomic-hosted-page/src/components.d.ts | 80 ------------ .../atomic-hosted-page/atomic-hosted-page.tsx | 71 ----------- .../atomic-hosted-page/hosted-pages.ts | 114 ------------------ .../atomic-simple-builder.tsx | 73 ----------- .../atomic-hosted-page/src/pages/index.html | 24 ---- .../src/pages/simple-builder.html | 24 ---- .../atomic-hosted-page/tests/smoke.spec.ts | 2 - .../recommendation/RecsInterfaceWrapper.tsx | 8 -- .../search/SearchInterfaceWrapper.tsx | 8 -- .../atomic-category-facet.tsx | 44 ++++--- packages/headless/src/app/logger.ts | 8 +- .../headless-core-category-facet.test.ts | 36 +----- .../headless-core-category-facet.ts | 13 -- .../headless-category-facet.test.ts | 33 +++-- .../quickview/headless-insight-quickview.ts | 14 --- .../ipx-actions-history-actions-loader.ts | 1 - .../features/analytics/search-action-cause.ts | 12 -- .../category-field-suggestions.test.ts | 2 +- .../src/integration-tests/search-app.test.ts | 4 +- packages/headless/src/utils/utils.ts | 2 +- .../quanticCategoryFacet.js | 18 ++- .../category-facet/category-facet.class.tsx | 11 +- .../category-facet/category-facet.fn.tsx | 8 +- 23 files changed, 78 insertions(+), 532 deletions(-) delete mode 100644 packages/atomic-hosted-page/src/components/atomic-hosted-page/atomic-hosted-page.tsx delete mode 100644 packages/atomic-hosted-page/src/components/atomic-hosted-page/hosted-pages.ts delete mode 100644 packages/atomic-hosted-page/src/components/atomic-simple-builder/atomic-simple-builder.tsx delete mode 100644 packages/atomic-hosted-page/src/pages/index.html delete mode 100644 packages/atomic-hosted-page/src/pages/simple-builder.html diff --git a/packages/atomic-hosted-page/src/components.d.ts b/packages/atomic-hosted-page/src/components.d.ts index 56cf23332aa..cd98cf326cf 100644 --- a/packages/atomic-hosted-page/src/components.d.ts +++ b/packages/atomic-hosted-page/src/components.d.ts @@ -8,20 +8,6 @@ import { HTMLStencilElement, JSXBase } from "@stencil/core/internal"; import { PlatformEnvironment } from "@coveo/headless"; export { PlatformEnvironment } from "@coveo/headless"; export namespace Components { - /** - * A Web Component used to inject a Coveo Hosted Search Page in the DOM. - * Pulls from the [Hosted Pages API](https://platform.cloud.coveo.com/docs?urls.primaryName=Search%20Interface%20Service#/Hosted%20Page) - * @deprecated Use `` instead {@link AtomicHostedUI }. - */ - interface AtomicHostedPage { - /** - * Returns the unique, organization-specific endpoint(s) - * @param organizationId - * @param env - */ - "getOrganizationEndpoints": (organizationId: string, env?: PlatformEnvironment) => Promise<{ platform: string; analytics: string; search: string; admin: string; }>; - "initialize": (options: AtomicHostedPageInitializationOptions) => Promise; - } /** * A Web Component used to inject a Coveo Hosted Search Page in the DOM. * Pulls from the [Search Interfaces API](https://platform.cloud.coveo.com/docs?urls.primaryName=Search%20Interface%20Service#/) @@ -39,33 +25,8 @@ export namespace Components { "hostedType": 'trial' | 'builder' | 'code'; "initialize": (options: AtomicHostedUIInitializationOptions) => Promise; } - /** - * A Web Component used to inject a [Coveo Search Interface made with the simple builder](https://docs.coveo.com/en/m7e92019/adobe/build-the-search-solution-using-a-coveo-ui-library-directly#search-interface-builder) in the DOM. - * Pulls from the [Search Interfaces API](https://platform.cloud.coveo.com/docs?urls.primaryName=Search%20Interface%20Service#/) - * @deprecated Use `` instead {@link AtomicHostedUI }. - */ - interface AtomicSimpleBuilder { - /** - * Returns the unique, organization-specific endpoint(s) - * @param organizationId - * @param env - */ - "getOrganizationEndpoints": (organizationId: string, env?: PlatformEnvironment) => Promise<{ platform: string; analytics: string; search: string; admin: string; }>; - "initialize": (options: AtomicSimpleBuilderInitializationOptions) => Promise; - } } declare global { - /** - * A Web Component used to inject a Coveo Hosted Search Page in the DOM. - * Pulls from the [Hosted Pages API](https://platform.cloud.coveo.com/docs?urls.primaryName=Search%20Interface%20Service#/Hosted%20Page) - * @deprecated Use `` instead {@link AtomicHostedUI }. - */ - interface HTMLAtomicHostedPageElement extends Components.AtomicHostedPage, HTMLStencilElement { - } - var HTMLAtomicHostedPageElement: { - prototype: HTMLAtomicHostedPageElement; - new (): HTMLAtomicHostedPageElement; - }; /** * A Web Component used to inject a Coveo Hosted Search Page in the DOM. * Pulls from the [Search Interfaces API](https://platform.cloud.coveo.com/docs?urls.primaryName=Search%20Interface%20Service#/) @@ -76,31 +37,11 @@ declare global { prototype: HTMLAtomicHostedUiElement; new (): HTMLAtomicHostedUiElement; }; - /** - * A Web Component used to inject a [Coveo Search Interface made with the simple builder](https://docs.coveo.com/en/m7e92019/adobe/build-the-search-solution-using-a-coveo-ui-library-directly#search-interface-builder) in the DOM. - * Pulls from the [Search Interfaces API](https://platform.cloud.coveo.com/docs?urls.primaryName=Search%20Interface%20Service#/) - * @deprecated Use `` instead {@link AtomicHostedUI }. - */ - interface HTMLAtomicSimpleBuilderElement extends Components.AtomicSimpleBuilder, HTMLStencilElement { - } - var HTMLAtomicSimpleBuilderElement: { - prototype: HTMLAtomicSimpleBuilderElement; - new (): HTMLAtomicSimpleBuilderElement; - }; interface HTMLElementTagNameMap { - "atomic-hosted-page": HTMLAtomicHostedPageElement; "atomic-hosted-ui": HTMLAtomicHostedUiElement; - "atomic-simple-builder": HTMLAtomicSimpleBuilderElement; } } declare namespace LocalJSX { - /** - * A Web Component used to inject a Coveo Hosted Search Page in the DOM. - * Pulls from the [Hosted Pages API](https://platform.cloud.coveo.com/docs?urls.primaryName=Search%20Interface%20Service#/Hosted%20Page) - * @deprecated Use `` instead {@link AtomicHostedUI }. - */ - interface AtomicHostedPage { - } /** * A Web Component used to inject a Coveo Hosted Search Page in the DOM. * Pulls from the [Search Interfaces API](https://platform.cloud.coveo.com/docs?urls.primaryName=Search%20Interface%20Service#/) @@ -111,40 +52,19 @@ declare namespace LocalJSX { */ "hostedType"?: 'trial' | 'builder' | 'code'; } - /** - * A Web Component used to inject a [Coveo Search Interface made with the simple builder](https://docs.coveo.com/en/m7e92019/adobe/build-the-search-solution-using-a-coveo-ui-library-directly#search-interface-builder) in the DOM. - * Pulls from the [Search Interfaces API](https://platform.cloud.coveo.com/docs?urls.primaryName=Search%20Interface%20Service#/) - * @deprecated Use `` instead {@link AtomicHostedUI }. - */ - interface AtomicSimpleBuilder { - } interface IntrinsicElements { - "atomic-hosted-page": AtomicHostedPage; "atomic-hosted-ui": AtomicHostedUi; - "atomic-simple-builder": AtomicSimpleBuilder; } } export { LocalJSX as JSX }; declare module "@stencil/core" { export namespace JSX { interface IntrinsicElements { - /** - * A Web Component used to inject a Coveo Hosted Search Page in the DOM. - * Pulls from the [Hosted Pages API](https://platform.cloud.coveo.com/docs?urls.primaryName=Search%20Interface%20Service#/Hosted%20Page) - * @deprecated Use `` instead {@link AtomicHostedUI }. - */ - "atomic-hosted-page": LocalJSX.AtomicHostedPage & JSXBase.HTMLAttributes; /** * A Web Component used to inject a Coveo Hosted Search Page in the DOM. * Pulls from the [Search Interfaces API](https://platform.cloud.coveo.com/docs?urls.primaryName=Search%20Interface%20Service#/) */ "atomic-hosted-ui": LocalJSX.AtomicHostedUi & JSXBase.HTMLAttributes; - /** - * A Web Component used to inject a [Coveo Search Interface made with the simple builder](https://docs.coveo.com/en/m7e92019/adobe/build-the-search-solution-using-a-coveo-ui-library-directly#search-interface-builder) in the DOM. - * Pulls from the [Search Interfaces API](https://platform.cloud.coveo.com/docs?urls.primaryName=Search%20Interface%20Service#/) - * @deprecated Use `` instead {@link AtomicHostedUI }. - */ - "atomic-simple-builder": LocalJSX.AtomicSimpleBuilder & JSXBase.HTMLAttributes; } } } diff --git a/packages/atomic-hosted-page/src/components/atomic-hosted-page/atomic-hosted-page.tsx b/packages/atomic-hosted-page/src/components/atomic-hosted-page/atomic-hosted-page.tsx deleted file mode 100644 index adacb926052..00000000000 --- a/packages/atomic-hosted-page/src/components/atomic-hosted-page/atomic-hosted-page.tsx +++ /dev/null @@ -1,71 +0,0 @@ -import {StringValue} from '@coveo/bueno'; -import { - PlatformEnvironment, - getOrganizationEndpoints as getOrganizationEndpointsHeadless, -} from '@coveo/headless'; -import {Component, ComponentInterface, Method, Element} from '@stencil/core'; -import { - InitializationOptions, - extractPlatformUrl, - validateOptions, -} from '../utils/options-utils'; -import {processHostedPage} from './hosted-pages'; - -interface AtomicHostedPageInitializationOptions extends InitializationOptions { - /** - * The unique identifier of the hosted page. - */ - pageId: string; -} - -/** - * A Web Component used to inject a Coveo Hosted Search Page in the DOM. - * Pulls from the [Hosted Pages API](https://platform.cloud.coveo.com/docs?urls.primaryName=Search%20Interface%20Service#/Hosted%20Page) - * @deprecated Use `` instead {@link AtomicHostedUI}. - */ -@Component({ - tag: 'atomic-hosted-page', - shadow: false, -}) -export class AtomicHostedPage implements ComponentInterface { - @Element() private element!: HTMLElement; - - private validateOptions(opts: AtomicHostedPageInitializationOptions) { - validateOptions(opts, { - pageId: new StringValue({required: true, emptyAllowed: false}), - }); - } - - @Method() public async initialize( - options: AtomicHostedPageInitializationOptions - ) { - this.validateOptions(options); - const platformUrl = extractPlatformUrl(options); - try { - const pageResponse = await fetch( - `${platformUrl}/rest/organizations/${options.organizationId}/hostedpages/${options.pageId}`, - { - headers: { - Authorization: `Bearer ${options.accessToken}`, - }, - } - ); - - processHostedPage(this.element, await pageResponse.json()); - } catch (e) { - console.error(e); - } - } - - /** - * Returns the unique, organization-specific endpoint(s) - * @param {string} organizationId - * @param {'prod'|'hipaa'|'staging'|'dev'} [env=Prod] - */ - @Method() public async getOrganizationEndpoints( - organizationId: string, - env: PlatformEnvironment = 'prod' - ) { - return getOrganizationEndpointsHeadless(organizationId, env); - } -} diff --git a/packages/atomic-hosted-page/src/components/atomic-hosted-page/hosted-pages.ts b/packages/atomic-hosted-page/src/components/atomic-hosted-page/hosted-pages.ts deleted file mode 100644 index 9058c6a9266..00000000000 --- a/packages/atomic-hosted-page/src/components/atomic-hosted-page/hosted-pages.ts +++ /dev/null @@ -1,114 +0,0 @@ -export interface HostedPage { - /** - * The unique identifier of the hosted page. - */ - id: string; - /** - * A short descriptive name to help manage hosted pages. - */ - name: string; - /** - * The HTML markup of the hosted page. - */ - html: string; - /** - * The JavaScript resources appended to the header of a specific hosted page in the target Coveo Cloud organization. - */ - javascript?: HostedPageJavascriptFile[]; - /** - * The CSS resources appended in the header, pertaining to a specific hosted page in the target Coveo Cloud organization. - */ - css?: HostedPageCSS[]; - /** - * The creation timestamp. (ISO 8601) - */ - created: string; - - /** - * The [principal](https://en.wikipedia.org/wiki/Principal_(computer_security)) that created the hosted search page. - */ - createdBy: string; - - /** - * The last update timestamp. (ISO 8601) - */ - updated: string; - - /** - * The principal that last updated the hosted search page. - */ - updatedBy: string; -} - -export type HostedPageCSS = HostedPageCssInlineFile | HostedPageCssUrlFile; - -export interface HostedPageCssUrlFile { - /** - * The URL of CSS stylesheet. - */ - url: string; -} - -export interface HostedPageCssInlineFile { - /** - * The content of the header `style` tag. - */ - inlineContent: string; -} - -export interface HostedPageJavascriptFile { - /** - * Whether the inline code should be treated as a JavaScript module. If this property is `true`, the `type` property will be set to `module` on the `script` tag. - */ - isModule: boolean; - /** - * The content of the header `script` tag. If this property is defined, the `url` property should not be specified. - */ - inlineContent?: string; - /** - * The URL of the JavaScript source file. If this property is defined, the `inlineContent` property should not be specified. - */ - url?: string; -} - -export function processHostedPage( - element: HTMLElement, - hostedPage: HostedPage -) { - element.innerHTML = hostedPage.html; - hostedPage.javascript?.forEach((file) => insertJS(file)); - hostedPage.css?.forEach((file) => - 'url' in file ? insertCSSUrl(file) : insertCSSInline(file) - ); -} - -function insertJS(file: HostedPageJavascriptFile) { - const script = document.createElement('script'); - if (file.isModule) { - script.type = 'module'; - } - - if (file.url) { - script.src = file.url; - } - - if (file.inlineContent) { - script.innerHTML = file.inlineContent; - } - - document.head.appendChild(script); -} - -function insertCSSInline(file: HostedPageCssInlineFile) { - const style = document.createElement('style'); - style.innerHTML = file.inlineContent!; - - document.head.appendChild(style); -} - -function insertCSSUrl(file: HostedPageCssUrlFile) { - const link = document.createElement('link'); - link.rel = 'stylesheet'; - link.href = file.url; - document.head.appendChild(link); -} diff --git a/packages/atomic-hosted-page/src/components/atomic-simple-builder/atomic-simple-builder.tsx b/packages/atomic-hosted-page/src/components/atomic-simple-builder/atomic-simple-builder.tsx deleted file mode 100644 index 2d9d109a59d..00000000000 --- a/packages/atomic-hosted-page/src/components/atomic-simple-builder/atomic-simple-builder.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import {StringValue} from '@coveo/bueno'; -import { - PlatformEnvironment, - getOrganizationEndpoints as getOrganizationEndpointsHeadless, -} from '@coveo/headless'; -import {Component, ComponentInterface, Method, Element} from '@stencil/core'; -import {processHostedPage} from '../atomic-hosted-page/hosted-pages'; -import { - InitializationOptions, - extractPlatformUrl, - validateOptions, -} from '../utils/options-utils'; - -interface AtomicSimpleBuilderInitializationOptions - extends InitializationOptions { - /** - * The unique identifier of the search interface. - */ - interfaceId: string; -} - -/** - * A Web Component used to inject a [Coveo Search Interface made with the simple builder](https://docs.coveo.com/en/m7e92019/adobe/build-the-search-solution-using-a-coveo-ui-library-directly#search-interface-builder) in the DOM. - * Pulls from the [Search Interfaces API](https://platform.cloud.coveo.com/docs?urls.primaryName=Search%20Interface%20Service#/) - * @deprecated Use `` instead {@link AtomicHostedUI}. - */ -@Component({ - tag: 'atomic-simple-builder', - shadow: false, -}) -export class AtomicSimpleBuilder implements ComponentInterface { - @Element() private element!: HTMLElement; - - private validateOptions(opts: AtomicSimpleBuilderInitializationOptions) { - validateOptions(opts, { - interfaceId: new StringValue({required: true, emptyAllowed: false}), - }); - } - - @Method() public async initialize( - options: AtomicSimpleBuilderInitializationOptions - ) { - this.validateOptions(options); - const platformUrl = extractPlatformUrl(options); - - try { - const pageResponse = await fetch( - `${platformUrl}/rest/organizations/${options.organizationId}/searchinterfaces/${options.interfaceId}/hostedpage/v1`, - { - headers: { - Authorization: `Bearer ${options.accessToken}`, - }, - } - ); - - processHostedPage(this.element, await pageResponse.json()); - } catch (e) { - console.error(e); - } - } - - /** - * Returns the unique, organization-specific endpoint(s) - * @param {string} organizationId - * @param {'prod'|'hipaa'|'staging'|'dev'} [env=Prod] - */ - @Method() public async getOrganizationEndpoints( - organizationId: string, - env: PlatformEnvironment = 'prod' - ) { - return getOrganizationEndpointsHeadless(organizationId, env); - } -} diff --git a/packages/atomic-hosted-page/src/pages/index.html b/packages/atomic-hosted-page/src/pages/index.html deleted file mode 100644 index 324d53b56cf..00000000000 --- a/packages/atomic-hosted-page/src/pages/index.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - Coveo Atomic Hosted Page - - - - - - - - diff --git a/packages/atomic-hosted-page/src/pages/simple-builder.html b/packages/atomic-hosted-page/src/pages/simple-builder.html deleted file mode 100644 index 9199a3d44f9..00000000000 --- a/packages/atomic-hosted-page/src/pages/simple-builder.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - Coveo Atomic Hosted Page - - - - - - - - diff --git a/packages/atomic-hosted-page/tests/smoke.spec.ts b/packages/atomic-hosted-page/tests/smoke.spec.ts index 4cd017d5712..e9c2e5c9519 100644 --- a/packages/atomic-hosted-page/tests/smoke.spec.ts +++ b/packages/atomic-hosted-page/tests/smoke.spec.ts @@ -1,8 +1,6 @@ import {test, expect} from '@playwright/test'; const urls = [ - 'http://localhost:3335/', - 'http://localhost:3335/simple-builder.html', 'http://localhost:3335/hosted-ui.html', 'http://localhost:3335/hosted-ui-trial.html', 'http://localhost:3335/hosted-ui-code.html', diff --git a/packages/atomic-react/src/components/recommendation/RecsInterfaceWrapper.tsx b/packages/atomic-react/src/components/recommendation/RecsInterfaceWrapper.tsx index f2c7c77852a..90978b630ee 100644 --- a/packages/atomic-react/src/components/recommendation/RecsInterfaceWrapper.tsx +++ b/packages/atomic-react/src/components/recommendation/RecsInterfaceWrapper.tsx @@ -25,14 +25,6 @@ interface WrapperProps * */ localization?: (i18n: i18n) => void; - /** - * @deprecated This option has no effect. Rather, set the pipeline through the `engine` `search` configuration. - */ - pipeline?: string; - /** - * @deprecated This option has no effect. Rather, set the search hub through the `engine` `search` configuration. - */ - searchHub?: string; } const DefaultProps: Required> = { diff --git a/packages/atomic-react/src/components/search/SearchInterfaceWrapper.tsx b/packages/atomic-react/src/components/search/SearchInterfaceWrapper.tsx index d14b8cdf30f..24be32f5e7a 100644 --- a/packages/atomic-react/src/components/search/SearchInterfaceWrapper.tsx +++ b/packages/atomic-react/src/components/search/SearchInterfaceWrapper.tsx @@ -28,14 +28,6 @@ interface WrapperProps * */ localization?: (i18n: i18n) => void; - /** - * @deprecated This option has no effect. Rather, set the pipeline through the `engine` `search` configuration. - */ - pipeline?: string; - /** - * @deprecated This option has no effect. Rather, set the search hub through the `engine` `search` configuration. - */ - searchHub?: string; } const DefaultProps: Required> = { diff --git a/packages/atomic/src/components/search/facets/atomic-category-facet/atomic-category-facet.tsx b/packages/atomic/src/components/search/facets/atomic-category-facet/atomic-category-facet.tsx index 6d8de127bc4..4956dc0fcda 100644 --- a/packages/atomic/src/components/search/facets/atomic-category-facet/atomic-category-facet.tsx +++ b/packages/atomic/src/components/search/facets/atomic-category-facet/atomic-category-facet.tsx @@ -305,7 +305,7 @@ export class AtomicCategoryFacet implements InitializableComponent { this.bindings.store.registerFacet('categoryFacets', facetInfo); initializePopover(this.host, { ...facetInfo, - hasValues: () => !!this.facet.state.values.length, + hasValues: () => !!this.facet.state.valuesAsTrees.length, numberOfActiveValues: () => (this.facetState.hasActiveValues ? 1 : 0), }); this.initializeDependenciesManager(); @@ -344,7 +344,8 @@ export class AtomicCategoryFacet implements InitializableComponent { return ( this.searchStatusState.hasError || !this.facet.state.enabled || - (!this.facet.state.values.length && !this.facet.state.parents.length) + (!this.facet.state.selectedValueAncestry.length && + !this.facet.state.valuesAsTrees.length) ); } @@ -381,7 +382,7 @@ export class AtomicCategoryFacet implements InitializableComponent { } private get hasParents() { - return !!this.facetState.parents.length; + return !!this.facetState.selectedValueAncestry.length; } private initializeDependenciesManager() { @@ -447,7 +448,10 @@ export class AtomicCategoryFacet implements InitializableComponent { ); } - private renderValuesTree(parents: CategoryFacetValue[], isRoot: boolean) { + private renderValuesTree( + valuesAsTrees: CategoryFacetValue[], + isRoot: boolean + ) { if (!this.hasParents) { return this.renderChildren(); } @@ -463,14 +467,14 @@ export class AtomicCategoryFacet implements InitializableComponent { }} /> - {this.renderValuesTree(parents, false)} + {this.renderValuesTree(valuesAsTrees, false)} ); } - if (parents.length > 1) { - const parentValue = parents[0]; + if (valuesAsTrees.length > 1) { + const parentValue = valuesAsTrees[0]; return ( @@ -484,13 +488,13 @@ export class AtomicCategoryFacet implements InitializableComponent { }} /> - {this.renderValuesTree(parents.slice(1), false)} + {this.renderValuesTree(valuesAsTrees.slice(1), false)} ); } - const activeParent = parents[0]; + const activeParent = valuesAsTrees[0]; const activeParentDisplayValue = getFieldValueCaption( this.field, activeParent.value, @@ -551,11 +555,22 @@ export class AtomicCategoryFacet implements InitializableComponent { } private renderChildren() { - if (!this.facetState.values.length) { + if (!this.facetState.valuesAsTrees.length) { return; } + if (this.facetState.selectedValueAncestry.length > 0) { + return this.facetState.selectedValueAncestry + .find((value) => value.state === 'selected') + ?.children.map((value, i) => + this.renderChild( + value, + i === 0, + i === this.resultIndexToFocusOnShowMore + ) + ); + } - return this.facetState.values.map((value, i) => + return this.facetState.valuesAsTrees.map((value, i) => this.renderChild(value, i === 0, i === this.resultIndexToFocusOnShowMore) ); } @@ -598,7 +613,8 @@ export class AtomicCategoryFacet implements InitializableComponent { label={this.label} i18n={this.bindings.i18n} onShowMore={() => { - this.resultIndexToFocusOnShowMore = this.facetState.values.length; + this.resultIndexToFocusOnShowMore = + this.facetState.valuesAsTrees[0].children.length; this.focusTargets.showMoreFocus.focusAfterSearch(); this.facet.showMoreValues(); }} @@ -627,7 +643,7 @@ export class AtomicCategoryFacet implements InitializableComponent { const { bindings: {i18n}, label, - facetState: {facetSearch, enabled, valuesAsTrees, parents}, + facetState: {facetSearch, enabled, valuesAsTrees, selectedValueAncestry}, searchStatusState: {hasError, firstSearchExecuted}, } = this; @@ -666,7 +682,7 @@ export class AtomicCategoryFacet implements InitializableComponent { isTopLevel={true} className="mt-3" > - {this.renderValuesTree(parents, true)} + {this.renderValuesTree(selectedValueAncestry, true)} ) : ( diff --git a/packages/headless/src/app/logger.ts b/packages/headless/src/app/logger.ts index ca669c560f7..2d99fbd3a6d 100644 --- a/packages/headless/src/app/logger.ts +++ b/packages/headless/src/app/logger.ts @@ -1,4 +1,4 @@ -import pino, {LevelWithSilent, LogEvent} from 'pino'; +import pino, {LevelWithSilent} from 'pino'; export type LogLevel = LevelWithSilent; @@ -12,12 +12,6 @@ export interface LoggerOptions { * All arguments passed to the log method, except the message, will be pass to this function. By default it does not change the shape of the log object. */ logFormatter?: (object: {}) => {}; - /** - * Function which will be called after writing the log message in the browser. - * - * @deprecated This option is deprecated and will be removed in a future version. - */ - browserPostLogHook?: (level: LogLevel, logEvent: LogEvent) => void; } export function buildLogger(options: LoggerOptions | undefined) { diff --git a/packages/headless/src/controllers/core/facets/category-facet/headless-core-category-facet.test.ts b/packages/headless/src/controllers/core/facets/category-facet/headless-core-category-facet.test.ts index a4e0a8d9133..5f845e135cd 100644 --- a/packages/headless/src/controllers/core/facets/category-facet/headless-core-category-facet.test.ts +++ b/packages/headless/src/controllers/core/facets/category-facet/headless-core-category-facet.test.ts @@ -152,16 +152,10 @@ describe('category facet', () => { }); describe('when the search response is empty', () => { - it('#state.values is an empty array', () => { - expect(state.search.response.facets).toEqual([]); - expect(categoryFacet.state.values).toEqual([]); + it('#state.selectedValueAncestry is an empty array', () => { + expect(categoryFacet.state.selectedValueAncestry).toEqual([]); }); - - it('#state.parents is an empty array', () => { - expect(categoryFacet.state.parents).toEqual([]); - }); - - it('#state.valuesAsTrees', () => { + it('#state.valuesAsTrees is an empty array', () => { expect(categoryFacet.state.valuesAsTrees).toEqual([]); }); }); @@ -174,10 +168,6 @@ describe('category facet', () => { state.search.response.facets = [response]; }); - it('#state.values contains the same values', () => { - expect(categoryFacet.state.values).toBe(values); - }); - it('#state.valuesAsTrees contains the same values', () => { expect(categoryFacet.state.valuesAsTrees).toBe(values); }); @@ -212,18 +202,6 @@ describe('category facet', () => { state.search.response.facets = [response]; }); - it('#state.parents contains the outer and middle values', () => { - expect(categoryFacet.state.parents).toEqual([outerValue, middleValue]); - }); - - it('#state.values contains the innermost values', () => { - expect(categoryFacet.state.values).toBe(innerValues); - }); - - it('#state.parents contains the outer and middle values', () => { - expect(categoryFacet.state.parents).toEqual([outerValue, middleValue]); - }); - it('#state.valueAsTree contains the outer value', () => { expect(categoryFacet.state.valuesAsTrees).toEqual([outerValue]); }); @@ -283,18 +261,14 @@ describe('category facet', () => { state.search.response.facets = [response]; }); - it('#state.parents contains the selected leaf value', () => { - expect(categoryFacet.state.parents).toEqual([selectedValue]); - }); - it('#state.selectedValueAncestry contains the selected leaf value', () => { expect(categoryFacet.state.selectedValueAncestry).toEqual([ selectedValue, ]); }); - it('#state.values is an empty array', () => { - expect(categoryFacet.state.values).toEqual([]); + it('#state.activeValue.children an empty array', () => { + expect(categoryFacet.state.activeValue?.children).toEqual([]); }); it('#state.activeValue is the selected leaf value', () => { diff --git a/packages/headless/src/controllers/core/facets/category-facet/headless-core-category-facet.ts b/packages/headless/src/controllers/core/facets/category-facet/headless-core-category-facet.ts index cedcf3b60ee..dd171b44584 100644 --- a/packages/headless/src/controllers/core/facets/category-facet/headless-core-category-facet.ts +++ b/packages/headless/src/controllers/core/facets/category-facet/headless-core-category-facet.ts @@ -164,19 +164,6 @@ export interface CoreCategoryFacetState { */ isHierarchical: boolean; - /** - * The facet's parent values. - * @deprecated uses `valuesAsTrees` instead. - * - */ - parents: CategoryFacetValue[]; - - /** - * The facet's values. - * @deprecated use `selectedValueAncestry` instead. - */ - values: CategoryFacetValue[]; - /** * The selected facet values ancestry. * The first element is the "root" of the selected value ancestry tree. diff --git a/packages/headless/src/controllers/facets/category-facet/headless-category-facet.test.ts b/packages/headless/src/controllers/facets/category-facet/headless-category-facet.test.ts index a53fdd027b0..6f9d272e279 100644 --- a/packages/headless/src/controllers/facets/category-facet/headless-category-facet.test.ts +++ b/packages/headless/src/controllers/facets/category-facet/headless-category-facet.test.ts @@ -119,13 +119,10 @@ describe('category facet', () => { }); describe('when the search response is empty', () => { - it('#state.values is an empty array', () => { + it('#state.valuesAsTrees and #state.selectedValueAncestry are empty arrays', () => { expect(state.search.response.facets).toEqual([]); - expect(categoryFacet.state.values).toEqual([]); - }); - - it('#state.parents is an empty array', () => { - expect(categoryFacet.state.parents).toEqual([]); + expect(categoryFacet.state.valuesAsTrees).toEqual([]); + expect(categoryFacet.state.selectedValueAncestry).toEqual([]); }); }); @@ -135,7 +132,7 @@ describe('category facet', () => { const response = buildMockCategoryFacetResponse({facetId, values}); state.search.response.facets = [response]; - expect(categoryFacet.state.values).toBe(values); + expect(categoryFacet.state.valuesAsTrees).toBe(values); }); describe('when the search response has a category facet with nested values', () => { @@ -160,16 +157,12 @@ describe('category facet', () => { state.search.response.facets = [response]; }); - it('#state.parents contains the outer and middle values', () => { - expect(categoryFacet.state.parents).toEqual([outerValue, middleValue]); - }); - - it('#state.values contains the innermost values', () => { - expect(categoryFacet.state.values).toBe(innerValues); + it('#state.valueAsTree contains the outer value', () => { + expect(categoryFacet.state.valuesAsTrees).toEqual([outerValue]); }); - it('#state.parents contains the outer and middle values', () => { - expect(categoryFacet.state.parents).toEqual([outerValue, middleValue]); + it('#state.isHierarchical should be true', () => { + expect(categoryFacet.state.isHierarchical).toBe(true); }); }); @@ -188,12 +181,14 @@ describe('category facet', () => { state.search.response.facets = [response]; }); - it('#state.parents contains the selected leaf value', () => { - expect(categoryFacet.state.parents).toEqual([selectedValue]); + it('#state.valuesAsTrees contains the selected leaf value', () => { + expect(categoryFacet.state.valuesAsTrees).toEqual([selectedValue]); }); - it('#state.values is an empty array', () => { - expect(categoryFacet.state.values).toEqual([]); + it('#state.selectedValueAncestry contains the selected leaf value', () => { + expect(categoryFacet.state.selectedValueAncestry).toEqual([ + selectedValue, + ]); }); }); diff --git a/packages/headless/src/controllers/insight/quickview/headless-insight-quickview.ts b/packages/headless/src/controllers/insight/quickview/headless-insight-quickview.ts index f8370b1bb35..4b8b1c77181 100644 --- a/packages/headless/src/controllers/insight/quickview/headless-insight-quickview.ts +++ b/packages/headless/src/controllers/insight/quickview/headless-insight-quickview.ts @@ -28,12 +28,6 @@ export interface QuickviewOptions { * The maximum preview size to retrieve, in bytes. By default, the full preview is retrieved. */ maximumPreviewSize?: number; - /** - * Whether to only update the `contentURL` attribute when using `fetchResultContent` rather than updating `content`. - * Use this if you are using an iframe with `state.contentURL` as the source url. - * @deprecated This option is always set to `true` ad the Insight Quickview only supports `contentURL` mode. - */ - onlyContentURL?: boolean; } export interface Quickview extends Controller { @@ -49,14 +43,6 @@ export interface Quickview extends Controller { } export interface QuickviewState { - /** - * The result preview HTML content. - * - * @default "" - * @deprecated This value will always be empty as the InsightQuickview only supports usage of the `contentURL`. - */ - content: string; - /** * `true` if the configured result has a preview, and `false` otherwise. */ diff --git a/packages/headless/src/features/actions-history/ipx-actions-history-actions-loader.ts b/packages/headless/src/features/actions-history/ipx-actions-history-actions-loader.ts index 2bafafeffcc..faee000659a 100644 --- a/packages/headless/src/features/actions-history/ipx-actions-history-actions-loader.ts +++ b/packages/headless/src/features/actions-history/ipx-actions-history-actions-loader.ts @@ -5,7 +5,6 @@ import {addPageViewEntryInActionsHistory} from './ipx-actions-history-actions'; /** * Internal and experimental actions loader for the IPX. * @internal - * @deprecated */ export interface IPXActionsHistoryActionCreators { addPageViewEntryInActionsHistory( diff --git a/packages/headless/src/features/analytics/search-action-cause.ts b/packages/headless/src/features/analytics/search-action-cause.ts index 6af3b3907eb..7c0960d2715 100644 --- a/packages/headless/src/features/analytics/search-action-cause.ts +++ b/packages/headless/src/features/analytics/search-action-cause.ts @@ -200,18 +200,6 @@ export enum SearchPageEvents { * Identifies the custom event that gets logged when a snippet suggestion for a related question is collapsed. */ collapseSmartSnippetSuggestion = 'collapseSmartSnippetSuggestion', - /** - * Identifies the custom event that gets logged when the user presses "show more" on a snippet suggestion for a related question. - * - * @deprecated - */ - showMoreSmartSnippetSuggestion = 'showMoreSmartSnippetSuggestion', - /** - * Identifies the custom event that gets logged when the user presses "show less" on a snippet suggestion for a related question. - * - * @deprecated - */ - showLessSmartSnippetSuggestion = 'showLessSmartSnippetSuggestion', /** * Identifies the custom event that gets logged when a user clicks on the source of an answer in a smart snippet. */ diff --git a/packages/headless/src/integration-tests/category-field-suggestions.test.ts b/packages/headless/src/integration-tests/category-field-suggestions.test.ts index be91938b1b6..e83cc472da1 100644 --- a/packages/headless/src/integration-tests/category-field-suggestions.test.ts +++ b/packages/headless/src/integration-tests/category-field-suggestions.test.ts @@ -28,7 +28,7 @@ describe('category field suggestions', () => { let categoryFieldSuggestions: CategoryFieldSuggestions; function getSelectedValue() { - return categoryFacet.state.parents.slice(-1)[0]; + return categoryFacet.state.selectedValueAncestry.slice(-1)[0]; } beforeEach(async () => { diff --git a/packages/headless/src/integration-tests/search-app.test.ts b/packages/headless/src/integration-tests/search-app.test.ts index 452c52e70fa..e68223f450e 100644 --- a/packages/headless/src/integration-tests/search-app.test.ts +++ b/packages/headless/src/integration-tests/search-app.test.ts @@ -78,7 +78,7 @@ describe('search app', () => { }); it('displays 5 values in the category facet', () => { - expect(categoryFacet.state.values.length).toBe(5); + expect(categoryFacet.state.valuesAsTrees.length).toBe(5); }); describe('SearchBox: submit query', () => { @@ -147,7 +147,7 @@ describe('search app', () => { initialFacetValues = facet.state.values; initialResults = resultList.state.results; - const [firstFacetValue] = categoryFacet.state.values; + const [firstFacetValue] = categoryFacet.state.valuesAsTrees; await waitForNextStateChange(facet, { action: () => categoryFacet.toggleSelect(firstFacetValue), diff --git a/packages/headless/src/utils/utils.ts b/packages/headless/src/utils/utils.ts index e0785d0b06c..92af128c4d1 100644 --- a/packages/headless/src/utils/utils.ts +++ b/packages/headless/src/utils/utils.ts @@ -47,7 +47,7 @@ const doNotTrackValues = new Set(['1', 1, 'yes', true]); /** * Logic copied from coveo.analytics. * - * @deprecated Starting with Event Protocol, Coveo will no longer respect the DNT standard. + * @deprecated V4 - Starting with Event Protocol, Coveo will no longer respect the DNT standard. * Instead, we will provide implementers with documentation on privacy best-practices, letting * them decide which standards to respect. * For more context behind the decision, see: https://coveord.atlassian.net/browse/LENS-1502 diff --git a/packages/quantic/force-app/main/default/lwc/quanticCategoryFacet/quanticCategoryFacet.js b/packages/quantic/force-app/main/default/lwc/quanticCategoryFacet/quanticCategoryFacet.js index e4b3184b371..51f9e27bb5b 100644 --- a/packages/quantic/force-app/main/default/lwc/quanticCategoryFacet/quanticCategoryFacet.js +++ b/packages/quantic/force-app/main/default/lwc/quanticCategoryFacet/quanticCategoryFacet.js @@ -286,15 +286,23 @@ export default class QuanticCategoryFacet extends LightningElement { } get values() { - return this.state?.values ?? []; + if (!this.state?.valuesAsTrees?.length) { + return []; + } + + if (this.state?.selectedValueAncestry?.length > 0) { + return this.state?.activeValue?.children ?? []; + } + + return this.state?.valuesAsTrees; } get nonActiveParents() { - return this.state?.parents?.slice(0, -1) ?? []; + return this.state?.selectedValueAncestry?.slice(0, -1) ?? []; } get activeParent() { - return this.state?.parents?.slice(-1)[0]; + return this.state?.selectedValueAncestry?.slice(-1)[0]; } get activeParentFormattedValue() { @@ -314,11 +322,11 @@ export default class QuanticCategoryFacet extends LightningElement { } get hasParents() { - return this.state?.parents?.length; + return this.state?.selectedValueAncestry?.length; } get hasValues() { - return this.state?.values?.length; + return this.state?.valuesAsTrees?.length; } get hasSearchResults() { diff --git a/packages/samples/headless-react/src/components/category-facet/category-facet.class.tsx b/packages/samples/headless-react/src/components/category-facet/category-facet.class.tsx index 2f726a0b8d2..a26f0057529 100644 --- a/packages/samples/headless-react/src/components/category-facet/category-facet.class.tsx +++ b/packages/samples/headless-react/src/components/category-facet/category-facet.class.tsx @@ -67,8 +67,8 @@ export class CategoryFacet extends Component< this.state.hasActiveValues && (
Filtering by: {this.renderClearButton()} - {this.state.parents.map((parentValue, i) => { - const isSelectedValue = i === this.state.parents.length - 1; + {this.state.valuesAsTrees.map((parentValue, i) => { + const isSelectedValue = i === this.state.valuesAsTrees.length - 1; return ( @@ -93,7 +93,7 @@ export class CategoryFacet extends Component< private renderActiveValues() { return (
    - {this.state.values.map((value) => ( + {this.state.selectedValueAncestry.map((value) => (