Skip to content

Commit 32c4839

Browse files
densumeshskeptrunedev
authored andcommitted
feature: added ability to easily switch to dev mode in settings
1 parent b750378 commit 32c4839

File tree

8 files changed

+308
-127
lines changed

8 files changed

+308
-127
lines changed

clients/search-component/example/src/routes/inline.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,9 @@ export default function Inline() {
4747
return (
4848
<>
4949
<div
50-
className={`p-12 flex flex-col items-center justify-center w-screen h-screen relative ${theme === "dark" ? "bg-zinc-900 text-zinc-50" : ""
51-
}`}
50+
className={`p-12 flex flex-col items-center justify-center w-screen h-screen relative ${
51+
theme === "dark" ? "bg-zinc-900 text-zinc-50" : ""
52+
}`}
5253
>
5354
<div className="absolute top-6 right-6">
5455
<ul>

clients/search-component/src/vanilla/index.tsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,14 @@ export function renderToDiv(element: HTMLElement, props: ModalProps) {
1313
case "none": {
1414
break;
1515
}
16+
case "local": {
17+
const link = document.createElement("link");
18+
link.rel = "stylesheet";
19+
link.href = "http://localhost:8000/dist/index.css";
20+
document.head.appendChild(link);
21+
console.log("local css");
22+
break;
23+
}
1624
case "stable": {
1725
const link = document.createElement("link");
1826
link.rel = "stylesheet";
@@ -47,6 +55,13 @@ export function renderRecommendationsToDiv(
4755
case "none": {
4856
break;
4957
}
58+
case "local": {
59+
const link = document.createElement("link");
60+
link.rel = "stylesheet";
61+
link.href = "http://localhost:8000/dist/recommendations.css";
62+
document.head.appendChild(link);
63+
break;
64+
}
5065
case "stable": {
5166
const link = document.createElement("link");
5267
link.rel = "stylesheet";

clients/trieve-shopify-extension/app/components/DatasetSettings.tsx

Lines changed: 109 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import { useSubmit } from "@remix-run/react";
22
import { useAppBridge } from "@shopify/app-bridge-react";
33
import {
4+
Badge,
45
BlockStack,
6+
Box,
57
Button,
68
Card,
79
FormLayout,
@@ -10,9 +12,12 @@ import {
1012
Select,
1113
Text,
1214
TextField,
15+
useBreakpoints,
1316
} from "@shopify/polaris";
14-
import { CheckCircleIcon } from "@shopify/polaris-icons";
15-
import { useEffect, useState } from "react";
17+
import { CheckCircleIcon, InfoIcon } from "@shopify/polaris-icons";
18+
import { useClientAdminApi } from "app/loaders/clientLoader";
19+
import { setAppMetafields } from "app/queries/metafield";
20+
import { useCallback, useEffect, useState } from "react";
1621
import { CrawlOptions, Dataset, DatasetConfigurationDTO } from "trieve-ts-sdk";
1722

1823
export type ExtendedCrawlOptions = Omit<CrawlOptions, "webhook_metadata"> & {
@@ -68,13 +73,18 @@ export const defaultServerEnvsConfiguration: DatasetConfig = {
6873
BM25_AVG_LEN: 256,
6974
};
7075

76+
export interface ShopifyDatasetSettings {
77+
webPixelInstalled: boolean;
78+
devMode: boolean;
79+
}
80+
7181
export const DatasetSettings = ({
7282
initalCrawlOptions,
73-
webPixelInstalled,
83+
shopifyDatasetSettings,
7484
shopDataset,
7585
}: {
7686
initalCrawlOptions: ExtendedCrawlOptions;
77-
webPixelInstalled: boolean;
87+
shopifyDatasetSettings: ShopifyDatasetSettings;
7888
shopDataset: Dataset;
7989
}) => {
8090
const [unsavedCrawlOptions, setUnsavedCrawlOptions] =
@@ -85,6 +95,30 @@ export const DatasetSettings = ({
8595
shopDataset.server_configuration ?? ({} as DatasetConfig),
8696
);
8797

98+
const adminApi = useClientAdminApi();
99+
100+
101+
const [devModeEnabled, setDevModeEnabled] = useState(
102+
shopifyDatasetSettings.devMode ?? false,
103+
);
104+
105+
106+
const handleToggle = useCallback(
107+
() =>{
108+
setDevModeEnabled((enabled) => {
109+
setAppMetafields(adminApi, [
110+
{
111+
key: "dev_mode",
112+
value: (!enabled).toString(),
113+
type: "boolean",
114+
},
115+
]);
116+
return !enabled
117+
})
118+
},
119+
[devModeEnabled],
120+
)
121+
88122
useEffect(() => {
89123
// Quickly set the nonnegotiable options for shopify to work
90124
setUnsavedCrawlOptions({
@@ -206,7 +240,7 @@ export const DatasetSettings = ({
206240
<FormLayout>
207241
<BlockStack gap="200">
208242
<div className="max-w-fit">
209-
{webPixelInstalled ? (
243+
{shopifyDatasetSettings.webPixelInstalled ? (
210244
<Button
211245
disabled
212246
fullWidth={false}
@@ -311,6 +345,76 @@ export const DatasetSettings = ({
311345
</InlineStack>
312346
</BlockStack>
313347
</Card>
348+
<Card>
349+
<BlockStack gap="200">
350+
<Text variant="headingLg" as="h1">
351+
Advanced Settings
352+
</Text>
353+
354+
<FormLayout>
355+
<BlockStack>
356+
<Box width="100%">
357+
<BlockStack>
358+
<Box width="100%">
359+
<InlineStack
360+
gap="1200"
361+
align="space-between"
362+
blockAlign="start"
363+
wrap={false}
364+
>
365+
<InlineStack gap="200" wrap={false}>
366+
<InlineStack
367+
gap="200"
368+
align="start"
369+
blockAlign="baseline"
370+
>
371+
<label>
372+
<Text variant="headingMd" as="h6">
373+
Dev Mode
374+
</Text>
375+
</label>
376+
<InlineStack
377+
gap="200"
378+
align="center"
379+
blockAlign="center"
380+
>
381+
<Badge
382+
tone={devModeEnabled ? "success" : undefined}
383+
toneAndProgressLabelOverride={`Setting is ${devModeEnabled ? "success" : undefined}`}
384+
>
385+
{devModeEnabled ? "On" : "Off"}
386+
</Badge>
387+
</InlineStack>
388+
</InlineStack>
389+
</InlineStack>
390+
<Box minWidth="fit-content">
391+
<InlineStack align="end">
392+
<Button
393+
role="switch"
394+
ariaChecked={devModeEnabled ? "true" : "false"}
395+
onClick={handleToggle}
396+
size="slim"
397+
>
398+
{devModeEnabled ? "Turn off" : "Turn on"}
399+
</Button>
400+
</InlineStack>
401+
</Box>
402+
</InlineStack>
403+
</Box>
404+
<BlockStack gap="400">
405+
<Text variant="bodyMd" as="p" tone="subdued">
406+
Enables dev mode for the shop embeds. This points the
407+
extension at the local dev server instead of the
408+
production server. This is useful for testing and
409+
debugging.{" "}
410+
</Text>
411+
</BlockStack>
412+
</BlockStack>
413+
</Box>
414+
</BlockStack>
415+
</FormLayout>
416+
</BlockStack>
417+
</Card>
314418
</BlockStack>
315419
);
316420
};
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
import { AdminApiCaller } from "app/loaders";
2+
import { AppInstallData } from "app/routes/app.setup";
3+
4+
export const setAppMetafields = async (
5+
adminApi: AdminApiCaller,
6+
valuesToSet: {
7+
key: string;
8+
value: string;
9+
type: 'boolean' | 'color' | 'date' | 'date_time' | 'dimension' | 'id' | 'json' |
10+
'link' | 'money' | 'multi_line_text_field' | 'number_decimal' | 'number_integer' |
11+
'rating' | 'rich_text_field' | 'single_line_text_field' | 'url' | 'volume' | 'weight';
12+
}[],
13+
) => {
14+
const response = await adminApi<AppInstallData>(`
15+
#graphql
16+
query {
17+
currentAppInstallation {
18+
id
19+
}
20+
}
21+
`);
22+
23+
if (response.error) {
24+
throw response.error;
25+
}
26+
27+
const appId = response.data;
28+
29+
let response_create = await adminApi(
30+
`#graphql
31+
mutation CreateAppDataMetafield($metafieldsSetInput: [MetafieldsSetInput!]!) {
32+
metafieldsSet(metafields: $metafieldsSetInput) {
33+
metafields {
34+
id
35+
namespace
36+
key
37+
}
38+
userErrors {
39+
field
40+
message
41+
}
42+
}
43+
}
44+
`,
45+
{
46+
variables: {
47+
metafieldsSetInput: valuesToSet.map((value) => ({
48+
namespace: "trieve",
49+
key: value.key,
50+
value: value.value,
51+
type: value.type,
52+
ownerId: appId.currentAppInstallation.id,
53+
})),
54+
},
55+
},
56+
);
57+
58+
if (response_create.error) {
59+
throw response_create.error;
60+
}
61+
62+
if ((response_create.data as any).metafieldsSet.userErrors.length > 0) {
63+
throw new Error((response_create.data as any).metafieldsSet.userErrors[0].message);
64+
}
65+
};
66+
67+
export type Metafields = {
68+
currentAppInstallation: {
69+
metafields: {
70+
nodes: {
71+
id: string;
72+
namespace: string;
73+
key: string;
74+
value: string;
75+
}[];
76+
};
77+
};
78+
};
79+
80+
export const getAppMetafields = async <T>(adminApi: AdminApiCaller, field: string): Promise<T> => {
81+
const response = await adminApi<Metafields>(`
82+
#graphql
83+
query {
84+
currentAppInstallation {
85+
metafields(first: 100) {
86+
nodes {
87+
id
88+
namespace
89+
key
90+
value
91+
}
92+
}
93+
}
94+
}
95+
`);
96+
97+
if (response.error) {
98+
throw response.error;
99+
}
100+
101+
const metafield = response.data.currentAppInstallation.metafields.nodes.find(
102+
(metafield) => metafield.key === field
103+
);
104+
105+
if (!metafield) {
106+
throw new Error(`Metafield ${field} not found`);
107+
}
108+
109+
try {
110+
return JSON.parse(metafield.value) as T;
111+
} catch {
112+
return metafield.value as T;
113+
}
114+
};

0 commit comments

Comments
 (0)