diff --git a/clients/search-component/README.md b/clients/search-component/README.md index dfc028b1b..bb439ada1 100644 --- a/clients/search-component/README.md +++ b/clients/search-component/README.md @@ -73,31 +73,33 @@ declare module "solid-js" { #### Props -| Name | Type | Default | -| -------------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------------ | -| datasetId | string | '' | -| apiKey | string | '' | -| baseUrl | string | "https://api.trieve.ai" | -| type | "docs" | "ecommerce" | "docs" | -| useGroupSearch | boolean | false | -| chat | boolean | true | -| analytics | boolean | true | -| placeholder | string | "Search..." | -| onResultClick | () => void | () => {} | -| theme | "light" or "dark" | "light" | -| searchOptions | [AutocompleteReqPayload](https://ts-sdk.trieve.ai/types/types_gen.AutocompleteReqPayload.html) | `{ search_type: "fulltext" }` | -| openKeyCombination | { key?: string; label?: string; ctrl?: boolean }[] | [{ ctrl: true }, { key: "k", label: "K" }] | -| tags | { tag: string; label?: string; selected? boolean; iconClassName?: string }[] | [{tag: "docs", label: "dev docs", iconClassName: "fa-solid fa-info"}] | -| ButtonEl | JSX.ElementType | null | -| suggestedQueries | boolean | true | -| defaultSearchQueries | string[] | [] | -| defaultAiQuestions | string[] | [] | -| brandLogoImgSrcUrl | string | null | -| brandName | string | null | -| brandColor | string | #CB53EB | -| brandFontFamily | string | Maven Pro | -| problemLink | string (example: "mailto:help@trieve.ai?subject=") | null | -| responsive | boolean | false | +| Name | Type | Default | +| ---------------------- | ---------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- | +| datasetId | string | '' | +| apiKey | string | '' | +| baseUrl | string | "https://api.trieve.ai" | +| type | "docs" | "ecommerce" | "docs" | +| useGroupSearch | boolean | false | +| chat | boolean | true | +| analytics | boolean | true | +| placeholder | string | "Search..." | +| onResultClick | () => void | () => {} | +| theme | "light" or "dark" | "light" | +| searchOptions | [AutocompleteReqPayload](https://ts-sdk.trieve.ai/types/types_gen.AutocompleteReqPayload.html) | `{ search_type: "fulltext" }` | +| openKeyCombination | { key?: string; label?: string; ctrl?: boolean }[] | [{ ctrl: true }, { key: "k", label: "K" }] | +| tags | { tag: string; label?: string; selected? boolean; iconClassName?: string }[] | [{tag: "docs", label: "dev docs", iconClassName: "fa-solid fa-info"}] | +| ButtonEl | JSX.ElementType | null | +| suggestedQueries | boolean | true | +| defaultSearchQueries | string[] | [] | +| defaultAiQuestions | string[] | [] | +| brandLogoImgSrcUrl | string | null | +| brandName | string | null | +| brandColor | string | #CB53EB | +| brandFontFamily | string | Maven Pro | +| problemLink | string (example: "mailto:help@trieve.ai?subject=") | null | +| responsive | boolean | false | +| floatingButtonPosition | "top-left", "top-right", "bottom-left", or "bottom-right" | "bottom-right" | +| showFloatingButton | boolean | false | ### Search Results @@ -155,4 +157,4 @@ Run the example application $clients/search-component cd example/ $clients/search-component yarn $clients/search-component yarn dev -``` +``` \ No newline at end of file diff --git a/clients/search-component/example/.env.dist b/clients/search-component/example/.env.dist index 5ed2c3b97..bc9109821 100644 --- a/clients/search-component/example/.env.dist +++ b/clients/search-component/example/.env.dist @@ -4,4 +4,6 @@ VITE_API_KEY="tr-zpPVGUq18FxOCmXgLfqGbmDOY4UMW00r" VITE_BRAND_LOGO_SRC_URL="https://cdn.trieve.ai/trieve-logo.png" VITE_BRAND_NAME="Trieve" VITE_BRAND_COLOR="#CB53EB" -VITE_PROBLEM_LINK="mailto:help@trieve.ai?subject=" \ No newline at end of file +VITE_PROBLEM_LINK="mailto:help@trieve.ai?subject=" +VITE_SHOW_FLOATING_BTN="true" +VITE_FLOATING_BTN_POSITION="bottom-right" \ No newline at end of file diff --git a/clients/search-component/example/src/routes/__root.tsx b/clients/search-component/example/src/routes/__root.tsx index 26681ca55..594d44c23 100644 --- a/clients/search-component/example/src/routes/__root.tsx +++ b/clients/search-component/example/src/routes/__root.tsx @@ -5,7 +5,7 @@ export const Route = createRootRoute({ component: () => ( <>
- Hi, I'm a random root div that is outside the Hiearchy + Hi, I'm a random root div that is outside the hierarchy
diff --git a/clients/search-component/example/src/routes/ecommerce.tsx b/clients/search-component/example/src/routes/ecommerce.tsx index 88851531b..241fe66ba 100644 --- a/clients/search-component/example/src/routes/ecommerce.tsx +++ b/clients/search-component/example/src/routes/ecommerce.tsx @@ -17,11 +17,14 @@ export default function ECommerce() { const brandColor = import.meta.env.VITE_ACCENT_COLOR; const problemLink = import.meta.env.VITE_PROBLEM_LINK; const useGroupSearch = import.meta.env.VITE_USE_GROUP_SEARCH == "true"; + const showFloatingButton = import.meta.env.VITE_SHOW_FLOATING_BTN == "true"; + const floatingButtonPosition = import.meta.env.VITE_FLOATING_BTN_POSITION; + const defaultSearchQueries: string[] = ( import.meta.env.VITE_DEFAULT_SEARCH_QUERIES ?? "" ).split(","); const defaultTags: any[] = JSON.parse( - import.meta.env.VITE_DEFAULT_TAGS ?? "[]" + import.meta.env.VITE_DEFAULT_TAGS ?? "[]", ); const [theme, setTheme] = useState<"light" | "dark">("light"); @@ -80,6 +83,8 @@ export default function ECommerce() { }} defaultSearchQueries={defaultSearchQueries} tags={defaultTags} + floatingButtonPosition={floatingButtonPosition} + showFloatingButton={showFloatingButton} /> ) : ( diff --git a/clients/search-component/package.json b/clients/search-component/package.json index 386bfc2c7..aa457ee1c 100644 --- a/clients/search-component/package.json +++ b/clients/search-component/package.json @@ -19,7 +19,7 @@ "import": "./dist/vanilla/index.js" } }, - "version": "0.2.25", + "version": "0.2.26", "license": "MIT", "homepage": "https://github.com/devflowinc/trieve/tree/main/clients/search-component", "scripts": { diff --git a/clients/search-component/src/TrieveModal/FloatingActionButton.tsx b/clients/search-component/src/TrieveModal/FloatingActionButton.tsx new file mode 100644 index 000000000..ec1d12fb0 --- /dev/null +++ b/clients/search-component/src/TrieveModal/FloatingActionButton.tsx @@ -0,0 +1,43 @@ +import React, { startTransition } from "react"; +import { useModalState } from "../utils/hooks/modal-context"; + +export const FloatingActionButton = () => { + const { props, setOpen, setMode } = useModalState(); + + const setButtonPosition = (position: string) => { + switch (position) { + case "top-left": + return { top: "20px", left: "20px" }; + case "top-right": + return { top: "20px", right: "20px" }; + case "bottom-left": + return { bottom: "20px", left: "20px" }; + case "bottom-right": + return { bottom: "20px", right: "20px" }; + default: + return { bottom: "20px", right: "20px" }; + } + }; + + return ( + + ); +}; diff --git a/clients/search-component/src/TrieveModal/index.css b/clients/search-component/src/TrieveModal/index.css index a9c3fb907..c30e1c21b 100644 --- a/clients/search-component/src/TrieveModal/index.css +++ b/clients/search-component/src/TrieveModal/index.css @@ -1137,4 +1137,10 @@ body { } } } + + .floating-action-button { + @apply fixed flex flex-row w-24 h-10 gap-3 justify-center items-center text-sm cursor-pointer text-white rounded-xl; + background-color: var(--tv-prop-brand-color); + font-family: var(--tv-prop-brand-font-family); + } } diff --git a/clients/search-component/src/TrieveModal/index.tsx b/clients/search-component/src/TrieveModal/index.tsx index f74e80f74..70ce614cb 100644 --- a/clients/search-component/src/TrieveModal/index.tsx +++ b/clients/search-component/src/TrieveModal/index.tsx @@ -14,6 +14,7 @@ import { ChatProvider, useChatState } from "../utils/hooks/chat-context"; import r2wc from "@r2wc/react-to-web-component"; import { setClickTriggers } from "../utils/hooks/setClickTriggers"; import { ChunkGroup } from "trieve-ts-sdk"; +import { FloatingActionButton } from "./FloatingActionButton"; const Modal = () => { useKeyboardNavigation(); @@ -121,6 +122,7 @@ const Modal = () => { )} + ); }; diff --git a/clients/search-component/src/utils/hooks/modal-context.tsx b/clients/search-component/src/utils/hooks/modal-context.tsx index ea07d0405..70190a108 100644 --- a/clients/search-component/src/utils/hooks/modal-context.tsx +++ b/clients/search-component/src/utils/hooks/modal-context.tsx @@ -80,6 +80,8 @@ export type ModalProps = { selector: string; mode: SearchModes; }[]; + showFloatingButton?: boolean; + floatingButtonPosition?: "top-left" | "top-right" | "bottom-left" | "bottom-right"; }; const defaultProps = { @@ -109,6 +111,12 @@ const defaultProps = { currencyPosition: "before" as currencyPosition, responsive: false, debounceMs: 0, + show: true, + position: "bottom-right" as + | "top-left" + | "top-right" + | "bottom-left" + | "bottom-right", }; const ModalContext = createContext<{ diff --git a/clients/ts-sdk/openapi.json b/clients/ts-sdk/openapi.json index 26245dcf1..a36154652 100644 --- a/clients/ts-sdk/openapi.json +++ b/clients/ts-sdk/openapi.json @@ -12324,6 +12324,10 @@ }, "nullable": true }, + "floatingButtonPosition": { + "type": "string", + "nullable": true + }, "forBrandName": { "type": "string", "nullable": true @@ -12376,6 +12380,10 @@ ], "nullable": true }, + "showFloatingButton": { + "type": "boolean", + "nullable": true + }, "singleProductOptions": { "allOf": [ { diff --git a/clients/ts-sdk/src/types.gen.ts b/clients/ts-sdk/src/types.gen.ts index ddd8a8dd0..ff317c2ec 100644 --- a/clients/ts-sdk/src/types.gen.ts +++ b/clients/ts-sdk/src/types.gen.ts @@ -2055,6 +2055,7 @@ export type PublicPageParameters = { defaultCurrency?: (string) | null; defaultSearchMode?: (string) | null; defaultSearchQueries?: Array<(string)> | null; + floatingButtonPosition?: (string) | null; forBrandName?: (string) | null; headingPrefix?: (string) | null; heroPattern?: ((HeroPattern) | null); @@ -2065,6 +2066,7 @@ export type PublicPageParameters = { problemLink?: (string) | null; responsive?: (boolean) | null; searchOptions?: ((PublicPageSearchOptions) | null); + showFloatingButton?: (boolean) | null; singleProductOptions?: ((SingleProductOptions) | null); suggestedQueries?: (boolean) | null; tabMessages?: Array | null; diff --git a/frontends/dashboard/src/pages/dataset/PublicPageSettings.tsx b/frontends/dashboard/src/pages/dataset/PublicPageSettings.tsx index 45314834c..5466a8b36 100644 --- a/frontends/dashboard/src/pages/dataset/PublicPageSettings.tsx +++ b/frontends/dashboard/src/pages/dataset/PublicPageSettings.tsx @@ -755,6 +755,56 @@ const PublicPageControls = () => { +
+
+
+ + + } + /> +
+ { + setExtraParams( + "showFloatingButton", + e.currentTarget.checked, + ); + }} + class="block w-4 rounded border border-neutral-300 px-3 py-1.5 shadow-sm placeholder:text-neutral-400 focus:outline-magenta-500 sm:text-sm sm:leading-6" + /> +
+
+
+ + + } + /> +
+ { + setExtraParams( + "floatingButtonPosition", + e.currentTarget.value, + ); + }} + class="block w-full rounded border border-neutral-300 px-3 py-1.5 shadow-sm placeholder:text-neutral-400 focus:outline-magenta-500 sm:text-sm sm:leading-6" + /> +
+
+
diff --git a/server/src/data/models.rs b/server/src/data/models.rs index 87f2b841d..5a1880530 100644 --- a/server/src/data/models.rs +++ b/server/src/data/models.rs @@ -3147,6 +3147,12 @@ impl DatasetConfigurationDTO { currency_position: page_parameters_self .currency_position .or(page_parameters_curr.currency_position), + floating_button_position: page_parameters_self + .floating_button_position + .or(page_parameters_curr.floating_button_position), + show_floating_button: page_parameters_self + .show_floating_button + .or(page_parameters_curr.show_floating_button), debounce_ms: page_parameters_self .debounce_ms .or(page_parameters_curr.debounce_ms), diff --git a/server/src/handlers/page_handler.rs b/server/src/handlers/page_handler.rs index 2646cc846..e9d750e8f 100644 --- a/server/src/handlers/page_handler.rs +++ b/server/src/handlers/page_handler.rs @@ -213,6 +213,10 @@ pub struct PublicPageParameters { #[serde(skip_serializing_if = "Option::is_none")] pub currency_position: Option, #[serde(skip_serializing_if = "Option::is_none")] + pub floating_button_position: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub show_floating_button: Option, + #[serde(skip_serializing_if = "Option::is_none")] pub debounce_ms: Option, #[serde(skip_serializing_if = "Option::is_none")] pub hero_pattern: Option, diff --git a/server/src/public/page.html b/server/src/public/page.html index ef27ff38f..ec6e706a2 100644 --- a/server/src/public/page.html +++ b/server/src/public/page.html @@ -4,7 +4,7 @@