Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 86350be

Browse files
committed
Display starter templates
1 parent b00a3b9 commit 86350be

File tree

7 files changed

+158
-0
lines changed

7 files changed

+158
-0
lines changed

site/src/AppRouter.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ const GitAuthPage = lazy(() => import("./pages/GitAuthPage/GitAuthPage"))
9292
const TemplateVersionPage = lazy(
9393
() => import("./pages/TemplateVersionPage/TemplateVersionPage"),
9494
)
95+
const StarterTemplatesPage = lazy(
96+
() => import("./pages/StarterTemplatesPage/StarterTemplatesPage"),
97+
)
9598

9699
export const AppRouter: FC = () => {
97100
const xServices = useContext(XServiceContext)
@@ -141,6 +144,17 @@ export const AppRouter: FC = () => {
141144
}
142145
/>
143146

147+
<Route path="starter-templates">
148+
<Route
149+
index
150+
element={
151+
<AuthAndFrame>
152+
<StarterTemplatesPage />
153+
</AuthAndFrame>
154+
}
155+
/>
156+
</Route>
157+
144158
<Route path="templates">
145159
<Route
146160
index

site/src/api/api.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -675,3 +675,12 @@ export const setServiceBanner = async (
675675
const response = await axios.put(`/api/v2/service-banner`, b)
676676
return response.data
677677
}
678+
679+
export const getTemplateExamples = async (
680+
organizationId: string,
681+
): Promise<TypesGen.TemplateExample[]> => {
682+
const response = await axios.get(
683+
`/api/v2/organizations/${organizationId}/templates/examples`,
684+
)
685+
return response.data
686+
}

site/src/i18n/en/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import templateVersionPage from "./templateVersionPage.json"
1212
import loginPage from "./loginPage.json"
1313
import workspaceChangeVersionPage from "./workspaceChangeVersionPage.json"
1414
import serviceBannerSettings from "./serviceBannerSettings.json"
15+
import starterTemplatesPage from "./starterTemplatesPage.json"
1516

1617
export const en = {
1718
common,
@@ -28,4 +29,5 @@ export const en = {
2829
loginPage,
2930
workspaceChangeVersionPage,
3031
serviceBannerSettings,
32+
starterTemplatesPage,
3133
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"title": "Starter Templates",
3+
"subtitle": "Pick one of the built-in templates to start using Coder"
4+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { useMachine } from "@xstate/react"
2+
import { useOrganizationId } from "hooks/useOrganizationId"
3+
import { FC } from "react"
4+
import { Helmet } from "react-helmet-async"
5+
import { useTranslation } from "react-i18next"
6+
import { pageTitle } from "util/page"
7+
import { starterTemplatesMachine } from "xServices/starterTemplates/starterTemplatesXService"
8+
import { StarterTemplatesPageView } from "./StarterTemplatesPageView"
9+
10+
const StarterTemplatesPage: FC = () => {
11+
const { t } = useTranslation("starterTemplatesPage")
12+
const organizationId = useOrganizationId()
13+
const [state] = useMachine(starterTemplatesMachine, {
14+
context: { organizationId },
15+
})
16+
17+
return (
18+
<>
19+
<Helmet>
20+
<title>{pageTitle(t("title"))}</title>
21+
</Helmet>
22+
23+
<StarterTemplatesPageView context={state.context} />
24+
</>
25+
)
26+
}
27+
28+
export default StarterTemplatesPage
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { AlertBanner } from "components/AlertBanner/AlertBanner"
2+
import { Maybe } from "components/Conditionals/Maybe"
3+
import { Margins } from "components/Margins/Margins"
4+
import {
5+
PageHeader,
6+
PageHeaderSubtitle,
7+
PageHeaderTitle,
8+
} from "components/PageHeader/PageHeader"
9+
import { FC } from "react"
10+
import { useTranslation } from "react-i18next"
11+
import { StarterTemplatesContext } from "xServices/starterTemplates/starterTemplatesXService"
12+
13+
export interface StarterTemplatesPageViewProps {
14+
context: StarterTemplatesContext
15+
}
16+
17+
export const StarterTemplatesPageView: FC<StarterTemplatesPageViewProps> = ({
18+
context,
19+
}) => {
20+
const { t } = useTranslation("starterTemplatesPage")
21+
22+
return (
23+
<Margins>
24+
<PageHeader>
25+
<PageHeaderTitle>{t("title")}</PageHeaderTitle>
26+
<PageHeaderSubtitle>{t("subtitle")}</PageHeaderSubtitle>
27+
</PageHeader>
28+
29+
<Maybe condition={Boolean(context.error)}>
30+
<AlertBanner error={context.error} severity="error" />
31+
</Maybe>
32+
33+
{context.starterTemplates &&
34+
context.starterTemplates.map((example) => (
35+
<div key={example.id}>{example.name}</div>
36+
))}
37+
</Margins>
38+
)
39+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { getTemplateExamples } from "api/api"
2+
import { TemplateExample } from "api/typesGenerated"
3+
import { assign, createMachine } from "xstate"
4+
5+
export interface StarterTemplatesContext {
6+
organizationId: string
7+
starterTemplates?: TemplateExample[]
8+
error?: unknown
9+
}
10+
11+
export const starterTemplatesMachine = createMachine(
12+
{
13+
id: "starterTemplates",
14+
predictableActionArguments: true,
15+
schema: {
16+
context: {} as StarterTemplatesContext,
17+
services: {} as {
18+
loadStarterTemplates: {
19+
data: TemplateExample[]
20+
}
21+
},
22+
},
23+
tsTypes: {} as import("./starterTemplatesXService.typegen").Typegen0,
24+
initial: "loading",
25+
states: {
26+
loading: {
27+
invoke: {
28+
src: "loadStarterTemplates",
29+
onDone: {
30+
actions: ["assignStarterTemplates"],
31+
target: "idle.ok",
32+
},
33+
onError: {
34+
actions: ["assignError"],
35+
target: "idle.error",
36+
},
37+
},
38+
},
39+
idle: {
40+
initial: "ok",
41+
states: {
42+
ok: { type: "final" },
43+
error: { type: "final" },
44+
},
45+
},
46+
},
47+
},
48+
{
49+
services: {
50+
loadStarterTemplates: ({ organizationId }) =>
51+
getTemplateExamples(organizationId),
52+
},
53+
actions: {
54+
assignError: assign({
55+
error: (_, { data }) => data,
56+
}),
57+
assignStarterTemplates: assign({
58+
starterTemplates: (_, { data }) => data,
59+
}),
60+
},
61+
},
62+
)

0 commit comments

Comments
 (0)