Skip to content

Commit 176f747

Browse files
committed
feat: add default workspace name to Template Embed form
1 parent 91780db commit 176f747

File tree

2 files changed

+41
-2
lines changed

2 files changed

+41
-2
lines changed

site/src/pages/TemplatePage/TemplateEmbedPage/TemplateEmbedPage.test.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { screen } from "@testing-library/react";
1+
import { screen, within } from "@testing-library/react";
22
import userEvent from "@testing-library/user-event";
33
import { API } from "api/api";
44
import { TemplateLayout } from "pages/TemplatePage/TemplateLayout";
@@ -30,6 +30,11 @@ test("Users can fill the parameters and copy the open in coder url", async () =>
3030
await waitForLoaderToBeRemoved();
3131

3232
const user = userEvent.setup();
33+
const workspaceName = within(
34+
screen.getByTestId("default-workspace-name"),
35+
).getByRole("textbox");
36+
await user.clear(workspaceName);
37+
await user.type(workspaceName, "my-first-workspace");
3338
const firstParameterField = screen.getByLabelText(
3439
parameter1.display_name ?? parameter1.name,
3540
{ exact: false },
@@ -47,6 +52,6 @@ test("Users can fill the parameters and copy the open in coder url", async () =>
4752
const copyButton = screen.getByRole("button", { name: /copy/i });
4853
await userEvent.click(copyButton);
4954
expect(window.navigator.clipboard.writeText).toBeCalledWith(
50-
`[![Open in Coder](http://localhost/open-in-coder.svg)](http://localhost/templates/${MockTemplate.organization_name}/${MockTemplate.name}/workspace?mode=manual&param.first_parameter=firstParameterValue&param.second_parameter=123456)`,
55+
`[![Open in Coder](http://localhost/open-in-coder.svg)](http://localhost/templates/${MockTemplate.organization_name}/${MockTemplate.name}/workspace?mode=manual&param.first_parameter=firstParameterValue&param.second_parameter=123456&name=my-first-workspace)`,
5156
);
5257
});

site/src/pages/TemplatePage/TemplateEmbedPage/TemplateEmbedPage.tsx

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import Button from "@mui/material/Button";
22
import FormControlLabel from "@mui/material/FormControlLabel";
33
import Radio from "@mui/material/Radio";
44
import RadioGroup from "@mui/material/RadioGroup";
5+
import TextField from "@mui/material/TextField";
56
import { API } from "api/api";
67
import type { Template, TemplateVersionParameter } from "api/typesGenerated";
78
import { FormSection, VerticalForm } from "components/Form/Form";
@@ -13,9 +14,11 @@ import { useTemplateLayoutContext } from "pages/TemplatePage/TemplateLayout";
1314
import { type FC, useEffect, useState } from "react";
1415
import { Helmet } from "react-helmet-async";
1516
import { useQuery } from "react-query";
17+
import { nameValidator } from "utils/formUtils";
1618
import { pageTitle } from "utils/page";
1719
import { getInitialRichParameterValues } from "utils/richParameters";
1820
import { paramsUsedToCreateWorkspace } from "utils/workspace";
21+
import { ValidationError } from "yup";
1922

2023
type ButtonValues = Record<string, string>;
2124

@@ -89,6 +92,17 @@ export const TemplateEmbedPageView: FC<TemplateEmbedPageViewProps> = ({
8992
}
9093
}, [buttonValues, templateParameters]);
9194

95+
const [workspaceNameError, setWorkspaceNameError] = useState("");
96+
const workspaceNameValidator = nameValidator("Workspace name");
97+
const validateWorkspaceName = (workspaceName: string) => {
98+
try {
99+
workspaceName && workspaceNameValidator.validateSync(workspaceName);
100+
setWorkspaceNameError("");
101+
} catch (e) {
102+
setWorkspaceNameError(e instanceof ValidationError ? e.message : "");
103+
}
104+
};
105+
92106
return (
93107
<>
94108
<Helmet>
@@ -126,6 +140,26 @@ export const TemplateEmbedPageView: FC<TemplateEmbedPageViewProps> = ({
126140
</RadioGroup>
127141
</FormSection>
128142

143+
<FormSection
144+
title="Workspace name"
145+
description="Default name for the new workspace"
146+
>
147+
<TextField
148+
data-testid="default-workspace-name"
149+
defaultValue={buttonValues.name}
150+
fullWidth
151+
onChange={(event) => {
152+
validateWorkspaceName(event.target.value);
153+
setButtonValues((buttonValues) => ({
154+
...buttonValues,
155+
name: event.target.value,
156+
}));
157+
}}
158+
error={workspaceNameError !== ""}
159+
helperText={workspaceNameError}
160+
/>
161+
</FormSection>
162+
129163
{templateParameters.length > 0 && (
130164
<div
131165
css={{ display: "flex", flexDirection: "column", gap: 36 }}

0 commit comments

Comments
 (0)