diff --git a/site/src/pages/StarterTemplatePage/StarterTemplatePage.tsx b/site/src/pages/StarterTemplatePage/StarterTemplatePage.tsx
index 289f7f0bb359d..3dddb37b1f432 100644
--- a/site/src/pages/StarterTemplatePage/StarterTemplatePage.tsx
+++ b/site/src/pages/StarterTemplatePage/StarterTemplatePage.tsx
@@ -1,31 +1,30 @@
-import { useMachine } from "@xstate/react";
import { useOrganizationId } from "hooks/useOrganizationId";
import { FC } from "react";
import { Helmet } from "react-helmet-async";
import { useParams } from "react-router-dom";
import { pageTitle } from "utils/page";
-import { starterTemplateMachine } from "xServices/starterTemplates/starterTemplateXService";
import { StarterTemplatePageView } from "./StarterTemplatePageView";
+import { useQuery } from "@tanstack/react-query";
+import { templateExamples } from "api/queries/templates";
const StarterTemplatePage: FC = () => {
const { exampleId } = useParams() as { exampleId: string };
const organizationId = useOrganizationId();
- const [state] = useMachine(starterTemplateMachine, {
- context: {
- organizationId,
- exampleId,
- },
- });
+ const templateExamplesQuery = useQuery(templateExamples(organizationId));
+ const starterTemplate = templateExamplesQuery.data?.find(
+ (example) => example.id === exampleId,
+ );
return (
<>
-
- {pageTitle(state.context.starterTemplate?.name ?? exampleId)}
-
+ {pageTitle(starterTemplate?.name ?? exampleId)}
-
+
>
);
};
diff --git a/site/src/pages/StarterTemplatePage/StarterTemplatePageView.stories.tsx b/site/src/pages/StarterTemplatePage/StarterTemplatePageView.stories.tsx
index 4434ab57e6df2..c2d753b3ea793 100644
--- a/site/src/pages/StarterTemplatePage/StarterTemplatePageView.stories.tsx
+++ b/site/src/pages/StarterTemplatePage/StarterTemplatePageView.stories.tsx
@@ -1,8 +1,4 @@
-import {
- mockApiError,
- MockOrganization,
- MockTemplateExample,
-} from "testHelpers/entities";
+import { mockApiError, MockTemplateExample } from "testHelpers/entities";
import { StarterTemplatePageView } from "./StarterTemplatePageView";
import type { Meta, StoryObj } from "@storybook/react";
@@ -17,23 +13,15 @@ type Story = StoryObj;
export const Default: Story = {
args: {
- context: {
- exampleId: MockTemplateExample.id,
- organizationId: MockOrganization.id,
- error: undefined,
- starterTemplate: MockTemplateExample,
- },
+ error: undefined,
+ starterTemplate: MockTemplateExample,
},
};
export const Error: Story = {
args: {
- context: {
- exampleId: MockTemplateExample.id,
- organizationId: MockOrganization.id,
- error: mockApiError({
- message: `Example ${MockTemplateExample.id} not found.`,
- }),
- starterTemplate: undefined,
- },
+ error: mockApiError({
+ message: `Example ${MockTemplateExample.id} not found.`,
+ }),
+ starterTemplate: undefined,
},
};
diff --git a/site/src/pages/StarterTemplatePage/StarterTemplatePageView.tsx b/site/src/pages/StarterTemplatePage/StarterTemplatePageView.tsx
index d1abe96270ad5..0264ce0eef4b4 100644
--- a/site/src/pages/StarterTemplatePage/StarterTemplatePageView.tsx
+++ b/site/src/pages/StarterTemplatePage/StarterTemplatePageView.tsx
@@ -9,27 +9,28 @@ import {
PageHeaderTitle,
} from "components/PageHeader/PageHeader";
import { FC } from "react";
-import { StarterTemplateContext } from "xServices/starterTemplates/starterTemplateXService";
import ViewCodeIcon from "@mui/icons-material/OpenInNewOutlined";
import PlusIcon from "@mui/icons-material/AddOutlined";
import { Stack } from "components/Stack/Stack";
import { Link } from "react-router-dom";
import { ErrorAlert } from "components/Alert/ErrorAlert";
+import { TemplateExample } from "api/typesGenerated";
export interface StarterTemplatePageViewProps {
- context: StarterTemplateContext;
+ starterTemplate?: TemplateExample;
+ error?: unknown;
}
export const StarterTemplatePageView: FC = ({
- context,
+ starterTemplate,
+ error,
}) => {
const styles = useStyles();
- const { starterTemplate } = context;
- if (context.error) {
+ if (error) {
return (
-
+
);
}
diff --git a/site/src/pages/StarterTemplatesPage/StarterTemplatesPage.tsx b/site/src/pages/StarterTemplatesPage/StarterTemplatesPage.tsx
index 997d2610bbc53..c83e5f73db404 100644
--- a/site/src/pages/StarterTemplatesPage/StarterTemplatesPage.tsx
+++ b/site/src/pages/StarterTemplatesPage/StarterTemplatesPage.tsx
@@ -1,16 +1,18 @@
-import { useMachine } from "@xstate/react";
import { useOrganizationId } from "hooks/useOrganizationId";
import { FC } from "react";
import { Helmet } from "react-helmet-async";
import { pageTitle } from "utils/page";
-import { starterTemplatesMachine } from "xServices/starterTemplates/starterTemplatesXService";
import { StarterTemplatesPageView } from "./StarterTemplatesPageView";
+import { useQuery } from "@tanstack/react-query";
+import { templateExamples } from "api/queries/templates";
+import { getTemplatesByTag } from "utils/starterTemplates";
const StarterTemplatesPage: FC = () => {
const organizationId = useOrganizationId();
- const [state] = useMachine(starterTemplatesMachine, {
- context: { organizationId },
- });
+ const templateExamplesQuery = useQuery(templateExamples(organizationId));
+ const starterTemplatesByTag = templateExamplesQuery.data
+ ? getTemplatesByTag(templateExamplesQuery.data)
+ : undefined;
return (
<>
@@ -18,7 +20,10 @@ const StarterTemplatesPage: FC = () => {
{pageTitle("Starter Templates")}
-
+
>
);
};
diff --git a/site/src/pages/StarterTemplatesPage/StarterTemplatesPageView.stories.tsx b/site/src/pages/StarterTemplatesPage/StarterTemplatesPageView.stories.tsx
index e5c67ca2f5bbd..81cea380541d0 100644
--- a/site/src/pages/StarterTemplatesPage/StarterTemplatesPageView.stories.tsx
+++ b/site/src/pages/StarterTemplatesPage/StarterTemplatesPageView.stories.tsx
@@ -1,6 +1,5 @@
import {
mockApiError,
- MockOrganization,
MockTemplateExample,
MockTemplateExample2,
} from "testHelpers/entities";
@@ -18,25 +17,19 @@ type Story = StoryObj;
export const Default: Story = {
args: {
- context: {
- organizationId: MockOrganization.id,
- error: undefined,
- starterTemplatesByTag: getTemplatesByTag([
- MockTemplateExample,
- MockTemplateExample2,
- ]),
- },
+ error: undefined,
+ starterTemplatesByTag: getTemplatesByTag([
+ MockTemplateExample,
+ MockTemplateExample2,
+ ]),
},
};
export const Error: Story = {
args: {
- context: {
- organizationId: MockOrganization.id,
- error: mockApiError({
- message: "Error on loading the template examples",
- }),
- starterTemplatesByTag: undefined,
- },
+ error: mockApiError({
+ message: "Error on loading the template examples",
+ }),
+ starterTemplatesByTag: undefined,
},
};
diff --git a/site/src/pages/StarterTemplatesPage/StarterTemplatesPageView.tsx b/site/src/pages/StarterTemplatesPage/StarterTemplatesPageView.tsx
index 82c0a962405c8..0fd768acaa60e 100644
--- a/site/src/pages/StarterTemplatesPage/StarterTemplatesPageView.tsx
+++ b/site/src/pages/StarterTemplatesPage/StarterTemplatesPageView.tsx
@@ -13,7 +13,7 @@ import { TemplateExampleCard } from "components/TemplateExampleCard/TemplateExam
import { FC } from "react";
import { Link, useSearchParams } from "react-router-dom";
import { combineClasses } from "utils/combineClasses";
-import { StarterTemplatesContext } from "xServices/starterTemplates/starterTemplatesXService";
+import { StarterTemplatesByTag } from "utils/starterTemplates";
const getTagLabel = (tag: string) => {
const labelByTag: Record = {
@@ -26,22 +26,25 @@ const getTagLabel = (tag: string) => {
return labelByTag[tag] ?? tag;
};
-const selectTags = ({ starterTemplatesByTag }: StarterTemplatesContext) => {
+const selectTags = (starterTemplatesByTag: StarterTemplatesByTag) => {
return starterTemplatesByTag
? Object.keys(starterTemplatesByTag).sort((a, b) => a.localeCompare(b))
: undefined;
};
export interface StarterTemplatesPageViewProps {
- context: StarterTemplatesContext;
+ starterTemplatesByTag?: StarterTemplatesByTag;
+ error?: unknown;
}
export const StarterTemplatesPageView: FC = ({
- context,
+ starterTemplatesByTag,
+ error,
}) => {
const [urlParams] = useSearchParams();
const styles = useStyles();
- const { starterTemplatesByTag } = context;
- const tags = selectTags(context);
+ const tags = starterTemplatesByTag
+ ? selectTags(starterTemplatesByTag)
+ : undefined;
const activeTag = urlParams.get("tag") ?? "all";
const visibleTemplates = starterTemplatesByTag
? starterTemplatesByTag[activeTag]
@@ -56,8 +59,8 @@ export const StarterTemplatesPageView: FC = ({
-
-
+
+
diff --git a/site/src/xServices/starterTemplates/starterTemplateXService.ts b/site/src/xServices/starterTemplates/starterTemplateXService.ts
deleted file mode 100644
index 5104b9729b8b7..0000000000000
--- a/site/src/xServices/starterTemplates/starterTemplateXService.ts
+++ /dev/null
@@ -1,71 +0,0 @@
-import { getTemplateExamples } from "api/api";
-import { TemplateExample } from "api/typesGenerated";
-import { assign, createMachine } from "xstate";
-
-export interface StarterTemplateContext {
- organizationId: string;
- exampleId: string;
- starterTemplate?: TemplateExample;
- error?: unknown;
-}
-
-export const starterTemplateMachine = createMachine(
- {
- id: "starterTemplate",
- predictableActionArguments: true,
- schema: {
- context: {} as StarterTemplateContext,
- services: {} as {
- loadStarterTemplate: {
- data: TemplateExample;
- };
- },
- },
- tsTypes: {} as import("./starterTemplateXService.typegen").Typegen0,
- initial: "loading",
- states: {
- loading: {
- invoke: {
- src: "loadStarterTemplate",
- onDone: {
- actions: ["assignStarterTemplate"],
- target: "idle.ok",
- },
- onError: {
- actions: ["assignError"],
- target: "idle.error",
- },
- },
- },
- idle: {
- initial: "ok",
- states: {
- ok: { type: "final" },
- error: { type: "final" },
- },
- },
- },
- },
- {
- services: {
- loadStarterTemplate: async ({ organizationId, exampleId }) => {
- const examples = await getTemplateExamples(organizationId);
- const starterTemplate = examples.find(
- (example) => example.id === exampleId,
- );
- if (!starterTemplate) {
- throw new Error(`Example ${exampleId} not found.`);
- }
- return starterTemplate;
- },
- },
- actions: {
- assignError: assign({
- error: (_, { data }) => data,
- }),
- assignStarterTemplate: assign({
- starterTemplate: (_, { data }) => data,
- }),
- },
- },
-);
diff --git a/site/src/xServices/starterTemplates/starterTemplatesXService.ts b/site/src/xServices/starterTemplates/starterTemplatesXService.ts
deleted file mode 100644
index 7771b4538a7c1..0000000000000
--- a/site/src/xServices/starterTemplates/starterTemplatesXService.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-import { getTemplateExamples } from "api/api";
-import { TemplateExample } from "api/typesGenerated";
-import {
- getTemplatesByTag,
- StarterTemplatesByTag,
-} from "utils/starterTemplates";
-import { assign, createMachine } from "xstate";
-
-export interface StarterTemplatesContext {
- organizationId: string;
- starterTemplatesByTag?: StarterTemplatesByTag;
- error?: unknown;
-}
-
-export const starterTemplatesMachine = createMachine(
- {
- id: "starterTemplates",
- predictableActionArguments: true,
- schema: {
- context: {} as StarterTemplatesContext,
- services: {} as {
- loadStarterTemplates: {
- data: TemplateExample[];
- };
- },
- },
- tsTypes: {} as import("./starterTemplatesXService.typegen").Typegen0,
- initial: "loading",
- states: {
- loading: {
- invoke: {
- src: "loadStarterTemplates",
- onDone: {
- actions: ["assignStarterTemplates"],
- target: "idle.ok",
- },
- onError: {
- actions: ["assignError"],
- target: "idle.error",
- },
- },
- },
- idle: {
- initial: "ok",
- states: {
- ok: { type: "final" },
- error: { type: "final" },
- },
- },
- },
- },
- {
- services: {
- loadStarterTemplates: ({ organizationId }) =>
- getTemplateExamples(organizationId),
- },
- actions: {
- assignError: assign({
- error: (_, { data }) => data,
- }),
- assignStarterTemplates: assign({
- starterTemplatesByTag: (_, { data }) => getTemplatesByTag(data),
- }),
- },
- },
-);