Skip to content

Commit

Permalink
fix: algolia records should index endpoint body shape (#1103)
Browse files Browse the repository at this point in the history
Co-authored-by: dsinghvi <[email protected]>
  • Loading branch information
abvthecity and dsinghvi authored Jul 2, 2024
1 parent d336f77 commit c7efecf
Show file tree
Hide file tree
Showing 8 changed files with 429 additions and 74 deletions.
71 changes: 40 additions & 31 deletions packages/commons/search-utils/src/SearchConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export const REGISTRY_SERVICE = new FdrClient({
const FEATURE_FLAGS = ["inkeep-enabled" as const];

export type InkeepSharedSettings = DeepReadonly<{
replaceSearch: boolean;
baseSettings: InkeepWidgetBaseSettings;
aiChatSettings?: Partial<InkeepAIChatSettings>;
searchSettings?: Partial<InkeepSearchSettings>;
Expand All @@ -39,48 +40,35 @@ export declare namespace SearchConfig {
}

interface Inkeep extends InkeepSharedSettings {
isAvailable: true;
type: "inkeep";
replaceSearch: boolean;
}

interface Algolia {
isAvailable: true;
type: "algolia";
appId: string;
searchApiKey: Unversioned | Versioned;
index: string;
}

interface Available {
isAvailable: true;
inkeep?: Inkeep;
algolia: Algolia;
}

interface Unavailable {
isAvailable: false;
}
}

export type SearchConfig = SearchConfig.Inkeep | SearchConfig.Algolia | SearchConfig.Unavailable;
export type SearchConfig = SearchConfig.Available | SearchConfig.Unavailable;

export interface SearchRequest {
searchInfo: Algolia.SearchInfo | undefined;
}

export async function getSearchConfig(domain: string, { searchInfo }: SearchRequest): Promise<SearchConfig> {
try {
const config = await getAll<EdgeConfigResponse>(FEATURE_FLAGS);
const maybeInkeep = config["inkeep-enabled"]?.[domain];

if (maybeInkeep?.baseSettings.integrationId != null) {
return {
isAvailable: true,
type: "inkeep",
...maybeInkeep,
};
}
} catch (e) {
// eslint-disable-next-line no-console
console.error("Error fetching edge config", e);
}

async function getAlgoliaSearchConfig({ searchInfo }: SearchRequest): Promise<SearchConfig.Algolia | undefined> {
if (typeof searchInfo !== "object" || searchInfo.type === "legacyMultiAlgoliaIndex") {
return { isAvailable: false };
return undefined;
}

const algoliaAppId = process.env.NEXT_PUBLIC_ALGOLIA_APP_ID;
Expand All @@ -95,12 +83,10 @@ export async function getSearchConfig(domain: string, { searchInfo }: SearchRequ
});

if (!resp.ok) {
return { isAvailable: false };
return undefined;
}

return {
isAvailable: true,
type: "algolia",
appId: algoliaAppId,
searchApiKey: {
type: "unversioned",
Expand All @@ -117,19 +103,17 @@ export async function getSearchConfig(domain: string, { searchInfo }: SearchRequ
});

if (!resp.ok) {
return { isAvailable: false };
return undefined;
}

values[versionId] = resp.body.searchApiKey;
}

if (Object.keys(values).length === 0) {
return { isAvailable: false };
return undefined;
}

return {
isAvailable: true,
type: "algolia",
appId: algoliaAppId,
searchApiKey: {
type: "versioned",
Expand All @@ -139,5 +123,30 @@ export async function getSearchConfig(domain: string, { searchInfo }: SearchRequ
};
}

return { isAvailable: false };
return undefined;
}

export async function getSearchConfig(domain: string, searchRequest: SearchRequest): Promise<SearchConfig> {
const algolia = await getAlgoliaSearchConfig(searchRequest);
if (algolia == null) {
return { isAvailable: false };
}

try {
const config = await getAll<EdgeConfigResponse>(FEATURE_FLAGS);
const maybeInkeep = config["inkeep-enabled"]?.[domain];

if (maybeInkeep?.baseSettings.integrationId != null) {
return {
isAvailable: true,
algolia,
inkeep: maybeInkeep,
};
}
} catch (e) {
// eslint-disable-next-line no-console
console.error("Error fetching edge config", e);
}

return { isAvailable: true, algolia };
}
18 changes: 9 additions & 9 deletions packages/ui/app/src/search/SearchDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,20 @@ export const SearchDialog: React.FC<SearchDialog.Props> = ({ fromHeader }) => {
return null;
}

if (config.type === "algolia") {
if (config.inkeep == null) {
return <AlgoliaSearchDialog fromHeader={fromHeader} />;
}

if (config.type === "inkeep") {
} else {
return (
<>
<InkeepCustomTrigger />
{config.inkeep.replaceSearch ? (
<InkeepCustomTrigger />
) : (
<AlgoliaSearchDialog fromHeader={fromHeader} />
)}
<InkeepChatButton />
</>
);
}

return null;
};

export declare namespace SearchSidebar {
Expand All @@ -69,7 +69,7 @@ export const SearchSidebar: React.FC<PropsWithChildren<SearchSidebar.Props>> = (
return <>{children}</>;
}

if (searchConfig.type === "algolia" && algoliaSearchClient != null) {
if (searchConfig.inkeep?.replaceSearch !== true && algoliaSearchClient != null) {
const [searchClient, indexName] = algoliaSearchClient;

return (
Expand All @@ -80,7 +80,7 @@ export const SearchSidebar: React.FC<PropsWithChildren<SearchSidebar.Props>> = (
);
}

if (searchConfig.type === "inkeep") {
if (searchConfig.inkeep != null) {
return (
<>
<div className="p-4 pb-0">
Expand Down
15 changes: 9 additions & 6 deletions packages/ui/app/src/search/algolia/useAlgoliaSearchClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,28 @@ export function useAlgoliaSearchClient(): [SearchClient, index: string] | undefi
const [searchConfig] = useSearchConfig();

return useMemo(() => {
if (!searchConfig.isAvailable || searchConfig.type !== "algolia") {
if (!searchConfig.isAvailable) {
return;
}

if (searchConfig.searchApiKey.type === "unversioned") {
return [algolia(searchConfig.appId, searchConfig.searchApiKey.value), searchConfig.index];
if (searchConfig.algolia.searchApiKey.type === "unversioned") {
return [
algolia(searchConfig.algolia.appId, searchConfig.algolia.searchApiKey.value),
searchConfig.algolia.index,
];
}

if (searchConfig.searchApiKey.type === "versioned") {
if (searchConfig.algolia.searchApiKey.type === "versioned") {
assertNonNullish(
currentVersionId,
"Inconsistent State: Received search info is versioned but docs are unversioned.",
);
const searchApiKey = searchConfig.searchApiKey.values[currentVersionId];
const searchApiKey = searchConfig.algolia.searchApiKey.values[currentVersionId];
assertNonNullish(
searchApiKey,
`Inconsistent State: Did not receive index segment for version "${currentVersionId}". This may indicate a backend bug.`,
);
return [algolia(searchConfig.appId, searchApiKey), searchConfig.index];
return [algolia(searchConfig.algolia.appId, searchApiKey), searchConfig.algolia.index];
}
return;
}, [currentVersionId, searchConfig]);
Expand Down
10 changes: 3 additions & 7 deletions packages/ui/app/src/search/inkeep/InkeepCustomTrigger.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,22 @@
import { useEventCallback } from "@fern-ui/react-commons";
import { atom, useAtom } from "jotai";
import { useAtom } from "jotai";
import dynamic from "next/dynamic";
import { ReactElement } from "react";
import { useSearchTrigger } from "../useSearchTrigger";
import { SEARCH_DIALOG_OPEN_ATOM } from "../../atoms/sidebar";
import useInkeepSettings from "./useInkeepSettings";

const CustomTrigger = dynamic(() => import("@inkeep/widgets").then((mod) => mod.InkeepCustomTrigger), {
ssr: false,
});

export const INKEEP_TRIGGER = atom(false);

export function InkeepCustomTrigger(): ReactElement | null {
const settings = useInkeepSettings();
const [isOpen, setIsOpen] = useAtom(INKEEP_TRIGGER);
const [isOpen, setIsOpen] = useAtom(SEARCH_DIALOG_OPEN_ATOM);

const handleClose = useEventCallback(() => {
setIsOpen(false);
});

useSearchTrigger(setIsOpen);

if (settings == null) {
return null;
}
Expand Down
10 changes: 5 additions & 5 deletions packages/ui/app/src/search/inkeep/useInkeepSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const useInkeepSettings = ():
const { resolvedTheme: theme } = useTheme();
const [searchConfig] = useSearchConfig();

if (!searchConfig.isAvailable || searchConfig.type !== "inkeep") {
if (!searchConfig.isAvailable || searchConfig.inkeep == null) {
return;
}

Expand All @@ -37,15 +37,15 @@ const useInkeepSettings = ():
},
},
},
...searchConfig.baseSettings,
...searchConfig.inkeep.baseSettings,
};

return {
// cast readonly -> mutable types, since inkeep widget expects mutable types
baseSettings: baseSettings as InkeepWidgetBaseSettings,
aiChatSettings: searchConfig.aiChatSettings as InkeepAIChatSettings | undefined,
searchSettings: searchConfig.searchSettings as InkeepSearchSettings | undefined,
modalSettings: searchConfig.modalSettings as InkeepModalSettings | undefined,
aiChatSettings: searchConfig.inkeep.aiChatSettings as InkeepAIChatSettings | undefined,
searchSettings: searchConfig.inkeep.searchSettings as InkeepSearchSettings | undefined,
modalSettings: searchConfig.inkeep.modalSettings as InkeepModalSettings | undefined,
};
};

Expand Down
14 changes: 1 addition & 13 deletions packages/ui/app/src/sidebar/SidebarSearchBar.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import { useEventCallback } from "@fern-ui/react-commons";
import { MagnifyingGlassIcon } from "@radix-ui/react-icons";
import cn from "clsx";
import { useSetAtom } from "jotai";
import { memo } from "react";
import { useOpenSearchDialog } from "../atoms/sidebar";
import { INKEEP_TRIGGER } from "../search/inkeep/InkeepCustomTrigger";
import { useSearchConfig } from "../services/useSearchService";

export declare namespace SidebarSearchBar {
Expand All @@ -19,20 +16,11 @@ export const SidebarSearchBar: React.FC<SidebarSearchBar.Props> = memo(function
hideKeyboardShortcutHint,
}) {
const openSearchDialog = useOpenSearchDialog();
const openInkeepCustomTrigger = useSetAtom(INKEEP_TRIGGER);
const [searchService] = useSearchConfig();

const handleClick = useEventCallback(() => {
if (searchService.isAvailable && searchService.type === "inkeep") {
openInkeepCustomTrigger(true);
} else {
openSearchDialog();
}
});

return (
<button
onClick={handleClick}
onClick={openSearchDialog}
className={cn("fern-search-bar", className)}
disabled={!searchService.isAvailable}
>
Expand Down
Loading

0 comments on commit c7efecf

Please sign in to comment.