Skip to content

Commit 9d2587d

Browse files
skeptrunedevdensumesh
authored andcommitted
feat: finish making the demo pages automated
1 parent fcab72d commit 9d2587d

5 files changed

Lines changed: 106 additions & 91 deletions

File tree

frontends/dashboard/src/pages/dataset/PublicPageSettings.tsx

Lines changed: 85 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,12 @@ import {
1818
import { createStore } from "solid-js/store";
1919
import {
2020
$OpenApiTs,
21+
ChunkMetadata,
2122
CrawlRequest,
2223
PriceToolCallOptions,
2324
PublicPageTabMessage,
2425
RelevanceToolCallOptions,
26+
SearchOverGroupsResponseBody,
2527
} from "trieve-ts-sdk";
2628
import FilterSidebarBuilder from "../../components/FilterSidebarBuilder";
2729
import { DatasetContext } from "../../contexts/DatasetContext";
@@ -254,6 +256,15 @@ const PublicPageControls = () => {
254256
};
255257
});
256258

259+
createEffect(() => {
260+
const singleProductOptions = extraParams.singleProductOptions;
261+
const hasKey =
262+
singleProductOptions &&
263+
Object.keys(singleProductOptions).length > 0 &&
264+
Object.values(singleProductOptions).some((option) => option);
265+
setExtraParams("inline", hasKey);
266+
});
267+
257268
return (
258269
<>
259270
<Show when={!isPublic()}>
@@ -1650,7 +1661,10 @@ const PublicPageControls = () => {
16501661
};
16511662

16521663
export const SingleProductOptions = () => {
1664+
const [loadingAutoFill, setLoadingAutoFill] = createSignal(false);
16531665
const { extraParams, setExtraParams } = usePublicPage();
1666+
const datasetContext = useContext(DatasetContext);
1667+
const trieve = useTrieve();
16541668

16551669
return (
16561670
<details class="my-4">
@@ -1690,17 +1704,63 @@ export const SingleProductOptions = () => {
16901704
</div>
16911705
<div class="grow">
16921706
<label class="block">Product Name</label>
1693-
<input
1694-
placeholder="Name of the product to display"
1695-
value={extraParams.singleProductOptions?.productName || ""}
1696-
onInput={(e) => {
1697-
setExtraParams("singleProductOptions", {
1698-
...extraParams.singleProductOptions,
1699-
productName: e.currentTarget.value,
1700-
});
1701-
}}
1702-
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"
1703-
/>
1707+
<div class="flex items-center gap-2">
1708+
<input
1709+
placeholder="Name of the product to display"
1710+
value={extraParams.singleProductOptions?.productName || ""}
1711+
onInput={(e) => {
1712+
setExtraParams("singleProductOptions", {
1713+
...extraParams.singleProductOptions,
1714+
productName: e.currentTarget.value,
1715+
});
1716+
}}
1717+
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"
1718+
/>
1719+
<button
1720+
onClick={() => {
1721+
setLoadingAutoFill(true);
1722+
void trieve
1723+
.fetch("/api/chunk_group/group_oriented_search", "post", {
1724+
data: {
1725+
query:
1726+
extraParams.singleProductOptions?.productName || "",
1727+
page_size: 10,
1728+
search_type: "fulltext",
1729+
},
1730+
datasetId: datasetContext.datasetId(),
1731+
})
1732+
.then((res) => {
1733+
const typedRes: SearchOverGroupsResponseBody =
1734+
res as SearchOverGroupsResponseBody;
1735+
const firstGroup = typedRes.results?.length
1736+
? typedRes.results[0]
1737+
: null;
1738+
const firstChunk = firstGroup?.chunks?.length
1739+
? firstGroup.chunks[0]
1740+
: null;
1741+
if (!firstGroup || !firstChunk) {
1742+
return;
1743+
}
1744+
setExtraParams("singleProductOptions", {
1745+
groupTrackingId: firstGroup.group.tracking_id,
1746+
productTrackingId: firstChunk.chunk.tracking_id,
1747+
productPrimaryImageUrl: firstChunk.chunk.image_urls
1748+
?.length
1749+
? firstChunk.chunk.image_urls[0]
1750+
: "",
1751+
productDescriptionHtml: (
1752+
firstChunk.chunk as ChunkMetadata
1753+
).chunk_html,
1754+
});
1755+
setLoadingAutoFill(false);
1756+
});
1757+
}}
1758+
disabled={loadingAutoFill()}
1759+
class="inline-flex justify-center rounded-md bg-magenta-500 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-magenta-700 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-magenta-900 disabled:animate-pulse min-w-[130px]"
1760+
>
1761+
{loadingAutoFill() ? "Loading..." : "Auto Fill"}
1762+
</button>
1763+
</div>
17041764
</div>
17051765
</div>
17061766
<div class="flex gap-4 pb-2 pt-2">
@@ -1733,7 +1793,6 @@ export const SingleProductOptions = () => {
17331793
value={extraParams.singleProductOptions?.productQuestions || []}
17341794
onChange={(e) => {
17351795
setExtraParams("singleProductOptions", {
1736-
...extraParams.singleProductOptions,
17371796
productQuestions: e,
17381797
});
17391798
}}
@@ -1745,35 +1804,35 @@ export const SingleProductOptions = () => {
17451804
</div>
17461805
<div class="flex gap-4 pb-2 pt-2">
17471806
<div class="grow">
1748-
<label class="block">Recommendation Search Query</label>
1749-
<input
1750-
placeholder="Search query to use for recommendations"
1751-
value={extraParams.singleProductOptions?.recSearchQuery || ""}
1807+
<label class="block">Product Description HTML</label>
1808+
<textarea
1809+
cols={2}
1810+
placeholder="Description of the page"
1811+
value={
1812+
extraParams.singleProductOptions?.productDescriptionHtml || ""
1813+
}
17521814
onInput={(e) => {
17531815
setExtraParams("singleProductOptions", {
17541816
...extraParams.singleProductOptions,
1755-
recSearchQuery: e.currentTarget.value,
1817+
productDescriptionHtml: e.currentTarget.value,
17561818
});
1819+
setExtraParams("inline", !!e.currentTarget.value);
17571820
}}
17581821
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"
17591822
/>
17601823
</div>
17611824
</div>
17621825
<div class="flex gap-4 pb-2 pt-2">
17631826
<div class="grow">
1764-
<label class="block">Product Description HTML</label>
1765-
<textarea
1766-
cols={2}
1767-
placeholder="Description of the page"
1768-
value={
1769-
extraParams.singleProductOptions?.productDescriptionHtml || ""
1770-
}
1827+
<label class="block">Recommendation Search Query</label>
1828+
<input
1829+
placeholder="Search query to use for recommendations"
1830+
value={extraParams.singleProductOptions?.recSearchQuery || ""}
17711831
onInput={(e) => {
17721832
setExtraParams("singleProductOptions", {
17731833
...extraParams.singleProductOptions,
1774-
productDescriptionHtml: e.currentTarget.value,
1834+
recSearchQuery: e.currentTarget.value,
17751835
});
1776-
setExtraParams("inline", !!e.currentTarget.value);
17771836
}}
17781837
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"
17791838
/>

frontends/shared/ui/MultiStringInput.tsx

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,6 @@ interface MultiStringInputProps {
1313
disabled?: boolean;
1414
}
1515

16-
type TEntry = {
17-
value: string;
18-
id: string;
19-
};
20-
2116
const addBlankStringIfEmpty = (value: string[]) => {
2217
if (value.length === 0) {
2318
return [""];
@@ -26,16 +21,13 @@ const addBlankStringIfEmpty = (value: string[]) => {
2621
};
2722

2823
export const MultiStringInput = (props: MultiStringInputProps) => {
29-
const [proxyStore, setProxyStore] = createStore<TEntry[]>([]);
30-
31-
createEffect(() => {
32-
setProxyStore(
33-
addBlankStringIfEmpty(props.value).map((value) => ({
34-
value,
35-
id: Math.random().toString(36).slice(2),
36-
})),
37-
);
38-
});
24+
const [proxyStore, setProxyStore] = createStore(
25+
// eslint-disable-next-line solid/reactivity
26+
addBlankStringIfEmpty(props.value).map((value) => ({
27+
value,
28+
id: Math.random().toString(36).slice(2),
29+
})),
30+
);
3931

4032
createEffect(() => {
4133
props.onChange(

server/src/public/page.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -564,7 +564,7 @@
564564
</div>
565565
{% endif %}
566566
</div>
567-
{% if params.searchPageProps.display %}
567+
{% if params.searchPageProps and params.searchPageProps.display %}
568568
<div id="inline-serp-root"></div>
569569
{% endif %}
570570
{% if params.videoLink and params.videoPosition == "static" %}

server/src/public/product.html

Lines changed: 13 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -36,34 +36,8 @@
3636
<div class="mt-2 text-gray-500 dark:text-gray-300 paragraph-text">
3737
{{ params.singleProductOptions.productDescriptionHtml|safe }}
3838
</div>
39-
{% endif %} {% if params.inline and params.singleProductOptions and
40-
params.singleProductOptions.productName %}
39+
{% endif %} {% if params.inline and params.singleProductOptions %}
4140
<div id="inline-root"></div>
42-
{% else %}
43-
<div class="mt-4 border-t border-gray-200">
44-
<h3 class="text-brand-color text-sm font-medium mt-4">
45-
<span class="text-brand-color"
46-
><i class="fa-solid fa-wand-magic-sparkles"></i
47-
></span>
48-
Ask AI
49-
</h3>
50-
<div class="starter-questions flex flex-wrap gap-1 mt-2">
51-
{% for question in params.singleProductOptions.productQuestions %}
52-
<button
53-
type="button"
54-
class="px-3 py-1.5 text-sm rounded-lg text-brand-color"
55-
>
56-
{{ question }}
57-
</button>
58-
{% endfor %}
59-
<button
60-
type="button"
61-
class="bg-brand-color px-3 py-1.5 text-sm rounded-lg text-white"
62-
>
63-
Ask something else
64-
</button>
65-
</div>
66-
</div>
6741
{% endif %}
6842
</div>
6943
</section>
@@ -143,7 +117,7 @@ <h4 class="text-sm text-gray-500 dark:text-gray-300 mt-2 w-fit">
143117

144118
const getGroupRecommendations = async (
145119
positiveGroupTrackingIds,
146-
negativeGroupTrackingIds
120+
negativeGroupTrackingIds,
147121
) => {
148122
const recommendations = await fetch(
149123
`${window.paramsData.baseUrl}/api/chunk_group/recommend`,
@@ -165,7 +139,7 @@ <h4 class="text-sm text-gray-500 dark:text-gray-300 mt-2 w-fit">
165139
negative_group_tracking_ids: negativeGroupTrackingIds,
166140
}),
167141
credentials: "omit",
168-
}
142+
},
169143
);
170144

171145
const recommendationsData = await recommendations.json();
@@ -212,16 +186,16 @@ <h4 class="text-sm text-gray-500 dark:text-gray-300 mt-2 w-fit">
212186
curWindowRecData[oppositeField] = curWindowRecData[
213187
oppositeField
214188
]?.filter(
215-
(id) => id !== recProduct.getAttribute("x-group-tracking-id")
189+
(id) => id !== recProduct.getAttribute("x-group-tracking-id"),
216190
);
217191

218192
if (isActive) {
219193
curWindowRecData[field] = curWindowRecData[field].filter(
220-
(id) => id !== recProduct.getAttribute("x-group-tracking-id")
194+
(id) => id !== recProduct.getAttribute("x-group-tracking-id"),
221195
);
222196
} else {
223197
curWindowRecData[field].push(
224-
recProduct.getAttribute("x-group-tracking-id")
198+
recProduct.getAttribute("x-group-tracking-id"),
225199
);
226200
}
227201
window.recData = curWindowRecData;
@@ -233,7 +207,7 @@ <h4 class="text-sm text-gray-500 dark:text-gray-300 mt-2 w-fit">
233207
]);
234208
getGroupRecommendations(
235209
window.recData.positiveGroupTrackingIds ?? [],
236-
window.recData.negativeGroupTrackingIds ?? []
210+
window.recData.negativeGroupTrackingIds ?? [],
237211
);
238212
});
239213
});
@@ -264,7 +238,7 @@ <h4 class="text-sm text-gray-500 dark:text-gray-300 mt-2 w-fit">
264238
const chunkHtmlElement = document.createElement("div");
265239
chunkHtmlElement.innerHTML = chunk.chunk_html;
266240
const firstHeading = chunkHtmlElement.querySelector(
267-
"h1, h2, h3, h4, h5, h6"
241+
"h1, h2, h3, h4, h5, h6",
268242
);
269243
if (firstHeading) {
270244
firstHeading.remove();
@@ -287,7 +261,7 @@ <h4 class="text-sm text-gray-500 dark:text-gray-300 mt-2 w-fit">
287261

288262
const chunkElement = document.createElement("div");
289263
chunkElement.classList.add(
290-
...["rec", "w-64", "flex-shrink-0", "flex", "flex-col"]
264+
...["rec", "w-64", "flex-shrink-0", "flex", "flex-col"],
291265
);
292266
chunkElement.setAttribute("x-group-tracking-id", groupTrackingId);
293267
chunkElement.innerHTML = `
@@ -348,7 +322,7 @@ <h6 class="rec-price mt-1 text-sm text-gray-700 dark:text-gray-300">${price}</h6
348322
page_size: 15,
349323
}),
350324
credentials: "omit",
351-
}
325+
},
352326
);
353327
const recommendationsData = await recommendations.json();
354328
replaceLoadingStateProducts(recommendationsData.results);
@@ -369,12 +343,12 @@ <h6 class="rec-price mt-1 text-sm text-gray-700 dark:text-gray-300">${price}</h6
369343
"TR-Dataset": window.paramsData.datasetId,
370344
},
371345
credentials: "omit",
372-
}
346+
},
373347
);
374348
const group = await getGroupByTrackingIdResp.json();
375349

376350
const starterQuestions = document.querySelectorAll(
377-
".starter-questions button"
351+
".starter-questions button",
378352
);
379353
starterQuestions.forEach((button) => {
380354
button.addEventListener("click", async () => {
@@ -392,7 +366,7 @@ <h6 class="rec-price mt-1 text-sm text-gray-700 dark:text-gray-300">${price}</h6
392366
betterGroupName,
393367
message,
394368
},
395-
})
369+
}),
396370
);
397371
});
398372
});

server/static/output.css

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -840,11 +840,6 @@ video {
840840
padding-right: 0.25rem;
841841
}
842842

843-
.px-3 {
844-
padding-left: 0.75rem;
845-
padding-right: 0.75rem;
846-
}
847-
848843
.px-4 {
849844
padding-left: 1rem;
850845
padding-right: 1rem;
@@ -855,11 +850,6 @@ video {
855850
padding-right: 2rem;
856851
}
857852

858-
.py-1\.5 {
859-
padding-top: 0.375rem;
860-
padding-bottom: 0.375rem;
861-
}
862-
863853
.py-16 {
864854
padding-top: 4rem;
865855
padding-bottom: 4rem;

0 commit comments

Comments
 (0)