Skip to content

Commit 20f8742

Browse files
committed
Accept pre defined template
1 parent 4af315b commit 20f8742

File tree

4 files changed

+55
-13
lines changed

4 files changed

+55
-13
lines changed

site/src/pages/CreateWorkspacePage/CreateWorkspacePage.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { useActor, useMachine } from "@xstate/react"
22
import React, { useContext } from "react"
3-
import { useNavigate } from "react-router-dom"
3+
import { useNavigate, useSearchParams } from "react-router-dom"
44
import { Template } from "../../api/typesGenerated"
55
import { createWorkspaceMachine } from "../../xServices/createWorkspace/createWorkspaceXService"
66
import { XServiceContext } from "../../xServices/StateContext"
@@ -20,9 +20,11 @@ const useOrganizationId = () => {
2020

2121
const CreateWorkspacePage: React.FC = () => {
2222
const organizationId = useOrganizationId()
23+
const [searchParams] = useSearchParams()
24+
const preSelectedTemplateName = searchParams.get("template")
2325
const navigate = useNavigate()
2426
const [createWorkspaceState, send] = useMachine(createWorkspaceMachine, {
25-
context: { organizationId },
27+
context: { organizationId, preSelectedTemplateName },
2628
actions: {
2729
onCreateWorkspace: (_, event) => {
2830
navigate("/workspaces/" + event.data.id)

site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.tsx

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,9 @@ export const CreateWorkspacePageView: React.FC<CreateWorkspacePageViewProps> = (
5050
const form: FormikContextType<TypesGen.CreateWorkspaceRequest> = useFormik<TypesGen.CreateWorkspaceRequest>({
5151
initialValues: {
5252
name: "",
53-
template_id: "",
53+
template_id: props.selectedTemplate ? props.selectedTemplate.id : "",
5454
},
55+
enableReinitialize: true,
5556
validationSchema,
5657
onSubmit: (request) => {
5758
if (!props.templateSchema) {
@@ -84,9 +85,13 @@ export const CreateWorkspacePageView: React.FC<CreateWorkspacePageViewProps> = (
8485
throw new Error("Templates are not loaded")
8586
}
8687

87-
// The TextField + MenuItem returns the index of the selected option
88-
const templateIndex = Number(event.currentTarget.value)
89-
const selectedTemplate = props.templates[templateIndex]
88+
const templateId = event.target.value
89+
const selectedTemplate = props.templates.find((template) => template.id === templateId)
90+
91+
if (!selectedTemplate) {
92+
throw new Error(`Template ${templateId} not found`)
93+
}
94+
9095
form.setFieldValue("template_id", selectedTemplate.id)
9196
props.onSelectTemplate(selectedTemplate)
9297
}

site/src/pages/TemplatesPage/TemplatesPageView.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,11 @@ export const TemplatesPageView: React.FC<TemplatesPageViewProps> = (props) => {
8383
<Avatar variant="square" className={styles.templateAvatar}>
8484
{firstLetter(template.name)}
8585
</Avatar>
86-
<Link component={RouterLink} to={`/templates/${template.name}/new`} className={styles.templateLink}>
86+
<Link
87+
component={RouterLink}
88+
to={`/workspaces/new?template=${template.name}`}
89+
className={styles.templateLink}
90+
>
8791
<b>{template.name}</b>
8892
<span>{template.description}</span>
8993
</Link>

site/src/xServices/createWorkspace/createWorkspaceXService.ts

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ type CreateWorkspaceContext = {
99
templateSchema?: ParameterSchema[]
1010
createWorkspaceRequest?: CreateWorkspaceRequest
1111
createdWorkspace?: Workspace
12+
// This is useful when the user wants to create a workspace from the template
13+
// page having it pre selected. It is string or null because of the
14+
// useSearchQuery
15+
preSelectedTemplateName: string | null
1216
}
1317

1418
type CreateWorkspaceEvent =
@@ -45,10 +49,17 @@ export const createWorkspaceMachine = createMachine(
4549
gettingTemplates: {
4650
invoke: {
4751
src: "getTemplates",
48-
onDone: {
49-
actions: ["assignTemplates"],
50-
target: "selectingTemplate",
51-
},
52+
onDone: [
53+
{
54+
actions: ["assignTemplates", "assignPreSelectedTemplate"],
55+
target: "gettingTemplateSchema",
56+
cond: "hasValidPreSelectedTemplate",
57+
},
58+
{
59+
actions: ["assignTemplates"],
60+
target: "selectingTemplate",
61+
},
62+
],
5263
onError: {
5364
target: "error",
5465
},
@@ -67,14 +78,14 @@ export const createWorkspaceMachine = createMachine(
6778
src: "getTemplateSchema",
6879
onDone: {
6980
actions: ["assignTemplateSchema"],
70-
target: "fillingForm",
81+
target: "fillingParams",
7182
},
7283
onError: {
7384
target: "error",
7485
},
7586
},
7687
},
77-
fillingForm: {
88+
fillingParams: {
7889
on: {
7990
CREATE_WORKSPACE: {
8091
actions: ["assignCreateWorkspaceRequest"],
@@ -122,6 +133,15 @@ export const createWorkspaceMachine = createMachine(
122133
return createWorkspace(organizationId, createWorkspaceRequest)
123134
},
124135
},
136+
guards: {
137+
hasValidPreSelectedTemplate: (ctx, event) => {
138+
if (!ctx.preSelectedTemplateName) {
139+
return false
140+
}
141+
const template = event.data.find((template) => template.name === ctx.preSelectedTemplateName)
142+
return !!template
143+
},
144+
},
125145
actions: {
126146
assignTemplates: assign({
127147
templates: (_, event) => event.data,
@@ -135,6 +155,17 @@ export const createWorkspaceMachine = createMachine(
135155
assignCreateWorkspaceRequest: assign({
136156
createWorkspaceRequest: (_, event) => event.request,
137157
}),
158+
assignPreSelectedTemplate: assign({
159+
selectedTemplate: (ctx, event) => {
160+
const selectedTemplate = event.data.find((template) => template.name === ctx.preSelectedTemplateName)
161+
// The proper validation happens on hasValidPreSelectedTemplate
162+
if (!selectedTemplate) {
163+
throw new Error("Invalid template selected")
164+
}
165+
166+
return selectedTemplate
167+
},
168+
}),
138169
},
139170
},
140171
)

0 commit comments

Comments
 (0)