* feat(askai): Allow Agent Studio specific search params
* Simplify DocSearchProps types definitions
* Revert "Simplify DocSearchProps types definitions"
This reverts commit b53bc97688.
* fix: types
292 lines
9.1 KiB
TypeScript
292 lines
9.1 KiB
TypeScript
import type { AutocompleteOptions, AutocompleteState } from '@algolia/autocomplete-core';
|
|
import { DocSearch as DocSearchProvider, useDocSearch } from '@docsearch/core';
|
|
import type { DocSearchModalShortcuts, DocSearchRef, InitialAskAiMessage } from '@docsearch/core';
|
|
import type { LiteClient, SearchParamsObject } from 'algoliasearch/lite';
|
|
import React, { type JSX } from 'react';
|
|
import { createPortal } from 'react-dom';
|
|
|
|
import { DocSearchButton } from './DocSearchButton';
|
|
import { DocSearchModal } from './DocSearchModal';
|
|
import type { DocSearchHit, DocSearchTheme, InternalDocSearchHit, StoredDocSearchHit } from './types';
|
|
|
|
import type { ButtonTranslations, ModalTranslations } from '.';
|
|
|
|
export type { DocSearchRef } from '@docsearch/core';
|
|
|
|
export type DocSearchTranslations = Partial<{
|
|
button: ButtonTranslations;
|
|
modal: ModalTranslations;
|
|
}>;
|
|
|
|
// The interface that describes the minimal implementation required for the algoliasearch client, when using the [`transformSearchClient`](https://docsearch.algolia.com/docs/api/#transformsearchclient) option.
|
|
export type DocSearchTransformClient = {
|
|
search: LiteClient['search'];
|
|
addAlgoliaAgent: LiteClient['addAlgoliaAgent'];
|
|
transporter: Pick<LiteClient['transporter'], 'algoliaAgent'>;
|
|
};
|
|
|
|
// Define the specific search parameters allowed for Ask AI
|
|
export type AskAiSearchParameters = {
|
|
facetFilters?: string[];
|
|
filters?: string;
|
|
attributesToRetrieve?: string[];
|
|
restrictSearchableAttributes?: string[];
|
|
distinct?: boolean | number | string;
|
|
};
|
|
|
|
export type AgentStudioSearchParameters = Record<string, Omit<AskAiSearchParameters, 'facetFilters'>>;
|
|
|
|
export type DocSearchAskAi = {
|
|
/**
|
|
* The index name to use for the ask AI feature. Your assistant will search this index for relevant documents.
|
|
* If not provided, the index name will be used.
|
|
*/
|
|
indexName?: string;
|
|
/**
|
|
* The API key to use for the ask AI feature. Your assistant will use this API key to search the index.
|
|
* If not provided, the API key will be used.
|
|
*/
|
|
apiKey?: string;
|
|
/**
|
|
* The app ID to use for the ask AI feature. Your assistant will use this app ID to search the index.
|
|
* If not provided, the app ID will be used.
|
|
*/
|
|
appId?: string;
|
|
/**
|
|
* The assistant ID to use for the ask AI feature.
|
|
*/
|
|
assistantId: string;
|
|
/**
|
|
* Enables displaying suggested questions on Ask AI's new conversation screen.
|
|
*
|
|
* @default false
|
|
*/
|
|
suggestedQuestions?: boolean;
|
|
// HACK: This is a hack for testing staging, remove before releasing
|
|
useStagingEnv?: boolean;
|
|
} & (
|
|
| {
|
|
/**
|
|
* **Experimental:** Whether to use Agent Studio as the chat backend.
|
|
*
|
|
* This is an experimental feature and its API may change without notice in future releases.
|
|
* Use with caution in production environments.
|
|
*
|
|
* @default false
|
|
*/
|
|
agentStudio?: never;
|
|
/**
|
|
* The search parameters to use for the ask AI feature.
|
|
*
|
|
* **NOTE**: If using `agentStudio = true`, the `searchParameters` object is
|
|
* keyed by the index name.
|
|
*/
|
|
searchParameters?: AskAiSearchParameters;
|
|
}
|
|
| {
|
|
agentStudio: false;
|
|
searchParameters?: AskAiSearchParameters;
|
|
}
|
|
| {
|
|
agentStudio: true;
|
|
/**
|
|
* The search parameters to use for the ask AI feature.
|
|
* Keyed by the index name.
|
|
*
|
|
* @example
|
|
* {
|
|
* "INDEX_NAME": { distinct: false }
|
|
* }
|
|
*/
|
|
searchParameters?: AgentStudioSearchParameters;
|
|
}
|
|
);
|
|
|
|
export interface DocSearchIndex {
|
|
name: string;
|
|
searchParameters?: SearchParamsObject;
|
|
}
|
|
|
|
export interface DocSearchProps {
|
|
/**
|
|
* Algolia application id used by the search client.
|
|
*/
|
|
appId: string;
|
|
/**
|
|
* Public api key with search permissions for the index.
|
|
*/
|
|
apiKey: string;
|
|
/**
|
|
* Name of the algolia index to query.
|
|
*
|
|
* @deprecated `indexName` will be removed in a future version. Please use `indices` property going forward.
|
|
*/
|
|
indexName?: string;
|
|
/**
|
|
* List of indices and _optional_ searchParameters to be used for search.
|
|
*
|
|
* @see {@link https://docsearch.algolia.com/docs/api#indices}
|
|
*/
|
|
indices?: Array<DocSearchIndex | string>;
|
|
/**
|
|
* Configuration or assistant id to enable ask ai mode. Pass a string assistant id or a full config object.
|
|
*/
|
|
askAi?: DocSearchAskAi | string;
|
|
/**
|
|
* Intercept Ask AI requests (e.g. Submitting a prompt or selecting a suggested question).
|
|
*
|
|
* Return `true` to prevent the default modal Ask AI flow (no toggle, no sendMessage).
|
|
* Useful to route Ask AI into a different UI (e.g. `@docsearch/sidepanel-js`) without flicker.
|
|
*/
|
|
interceptAskAiEvent?: (initialMessage: InitialAskAiMessage) => boolean | void;
|
|
/**
|
|
* Theme overrides applied to the modal and related components.
|
|
*/
|
|
theme?: DocSearchTheme;
|
|
/**
|
|
* Placeholder text for the search input.
|
|
*/
|
|
placeholder?: string;
|
|
/**
|
|
* Additional algolia search parameters to merge into each query.
|
|
*
|
|
* @deprecated `searchParameters` will be removed in a future version. Please use `indices` property going forward.
|
|
*/
|
|
searchParameters?: SearchParamsObject;
|
|
/**
|
|
* Maximum number of hits to display per source/group.
|
|
*/
|
|
maxResultsPerGroup?: number;
|
|
/**
|
|
* Hook to post-process hits before rendering.
|
|
*/
|
|
transformItems?: (items: DocSearchHit[]) => DocSearchHit[];
|
|
/**
|
|
* Custom component to render an individual hit.
|
|
* Supports template patterns:
|
|
* - HTML strings with html helper: (props, { html }) => html`<div>...</div>`
|
|
* - JSX templates: (props) => <div>...</div>
|
|
* - Function-based templates: (props) => string | JSX.Element | Function.
|
|
*/
|
|
hitComponent?: (
|
|
props: {
|
|
hit: InternalDocSearchHit | StoredDocSearchHit;
|
|
children: React.ReactNode;
|
|
},
|
|
helpers?: {
|
|
html: (template: TemplateStringsArray, ...values: any[]) => any;
|
|
},
|
|
) => JSX.Element;
|
|
/**
|
|
* Custom component rendered at the bottom of the results panel.
|
|
* Supports template patterns:
|
|
* - HTML strings with html helper: (props, { html }) => html`<div>...</div>`
|
|
* - JSX templates: (props) => <div>...</div>
|
|
* - Function-based templates: (props) => string | JSX.Element | Function.
|
|
*/
|
|
resultsFooterComponent?: (
|
|
props: {
|
|
state: AutocompleteState<InternalDocSearchHit>;
|
|
},
|
|
helpers?: {
|
|
html: (template: TemplateStringsArray, ...values: any[]) => any;
|
|
},
|
|
) => JSX.Element | null;
|
|
/**
|
|
* Hook to wrap or modify the algolia search client.
|
|
*/
|
|
transformSearchClient?: (searchClient: DocSearchTransformClient) => DocSearchTransformClient;
|
|
/**
|
|
* Disable storage and usage of recent and favorite searches.
|
|
*/
|
|
disableUserPersonalization?: boolean;
|
|
/**
|
|
* Query string to prefill when opening the modal.
|
|
*/
|
|
initialQuery?: string;
|
|
/**
|
|
* Custom navigator for controlling link navigation.
|
|
*/
|
|
navigator?: AutocompleteOptions<InternalDocSearchHit>['navigator'];
|
|
/**
|
|
* Localized strings for the button and modal ui.
|
|
*/
|
|
translations?: DocSearchTranslations;
|
|
/**
|
|
* Builds a url to report missing results for a given query.
|
|
*/
|
|
getMissingResultsUrl?: ({ query }: { query: string }) => string;
|
|
/**
|
|
* Insights client integration options to send analytics events.
|
|
*/
|
|
insights?: AutocompleteOptions<InternalDocSearchHit>['insights'];
|
|
/**
|
|
* The container element where the modal should be portaled to. Defaults to document.body.
|
|
*/
|
|
portalContainer?: DocumentFragment | Element;
|
|
/**
|
|
* Limit of how many recent searches should be saved/displayed..
|
|
*
|
|
* @default 7
|
|
*/
|
|
recentSearchesLimit?: number;
|
|
/**
|
|
* Limit of how many recent searches should be saved/displayed when there are favorited searches..
|
|
*
|
|
* @default 4
|
|
*/
|
|
recentSearchesWithFavoritesLimit?: number;
|
|
/**
|
|
* Configuration for keyboard shortcuts. Allows enabling/disabling specific shortcuts.
|
|
*
|
|
* @default `{ 'Ctrl/Cmd+K': true, '/': true }`
|
|
*/
|
|
keyboardShortcuts?: DocSearchModalShortcuts;
|
|
}
|
|
|
|
function DocSearchComponent(props: DocSearchProps, ref: React.ForwardedRef<DocSearchRef>): JSX.Element {
|
|
return (
|
|
<DocSearchProvider {...props} ref={ref}>
|
|
<DocSearchInner {...props} />
|
|
</DocSearchProvider>
|
|
);
|
|
}
|
|
|
|
export const DocSearch = React.forwardRef(DocSearchComponent);
|
|
|
|
export function DocSearchInner(props: DocSearchProps): JSX.Element {
|
|
const {
|
|
searchButtonRef,
|
|
keyboardShortcuts,
|
|
isModalActive,
|
|
isAskAiActive,
|
|
initialQuery,
|
|
onAskAiToggle,
|
|
openModal,
|
|
closeModal,
|
|
} = useDocSearch();
|
|
|
|
return (
|
|
<>
|
|
<DocSearchButton
|
|
keyboardShortcuts={keyboardShortcuts}
|
|
ref={searchButtonRef}
|
|
translations={props.translations?.button}
|
|
onClick={openModal}
|
|
/>
|
|
{isModalActive &&
|
|
createPortal(
|
|
<DocSearchModal
|
|
{...props}
|
|
initialScrollY={window.scrollY}
|
|
initialQuery={initialQuery}
|
|
translations={props?.translations?.modal}
|
|
isAskAiActive={isAskAiActive}
|
|
onAskAiToggle={onAskAiToggle}
|
|
onClose={closeModal}
|
|
/>,
|
|
props.portalContainer ?? document.body,
|
|
)}
|
|
</>
|
|
);
|
|
}
|