diff --git a/docs/templates/open-in-coder.md b/docs/templates/open-in-coder.md index cec46537acaba..494eaaf482f49 100644 --- a/docs/templates/open-in-coder.md +++ b/docs/templates/open-in-coder.md @@ -106,6 +106,13 @@ approach for "Open in Coder" flows. ![Pre-filled parameters](../images/templates/pre-filled-parameters.png) +1. Optional: disable specific parameter fields by including their names as + specified in your template in the `disable_params` search params list + + ```md + [![Open in Coder](https://YOUR_ACCESS_URL/open-in-coder.svg)](https://YOUR_ACCESS_URL/templates/YOUR_TEMPLATE/workspace?disable_params=first_parameter,second_parameter) + ``` + ## Example: Kubernetes For a full example of the Open in Coder flow in Kubernetes, check out diff --git a/site/e2e/tests/createWorkspace.spec.ts b/site/e2e/tests/createWorkspace.spec.ts index c2b1e7cad72d3..d7cec29a90aa3 100644 --- a/site/e2e/tests/createWorkspace.spec.ts +++ b/site/e2e/tests/createWorkspace.spec.ts @@ -1,4 +1,4 @@ -import { test } from "@playwright/test"; +import { test, expect } from "@playwright/test"; import { createTemplate, createWorkspace, @@ -119,3 +119,25 @@ test("create workspace and overwrite default parameters", async ({ page }) => { ); await verifyParameters(page, workspaceName, richParameters, buildParameters); }); + +test("create workspace with disable_param search params", async ({ page }) => { + const richParameters: RichParameter[] = [ + firstParameter, // mutable + secondParameter, //immutable + ]; + + const templateName = await createTemplate( + page, + echoResponsesWithParameters(richParameters), + ); + + await page.goto( + `/templates/${templateName}/workspace?disable_params=first_parameter,second_parameter`, + { + waitUntil: "domcontentloaded", + }, + ); + + await expect(page.getByLabel(/First parameter/i)).toBeDisabled(); + await expect(page.getByLabel(/Second parameter/i)).toBeDisabled(); +}); diff --git a/site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.tsx b/site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.tsx index c473d12ef52e5..2883f28bf53ae 100644 --- a/site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.tsx +++ b/site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.tsx @@ -31,6 +31,7 @@ import { ExternalAuth } from "./ExternalAuth"; import { ErrorAlert } from "components/Alert/ErrorAlert"; import { Stack } from "components/Stack/Stack"; import { type ExternalAuthPollingState } from "./CreateWorkspacePage"; +import { useSearchParams } from "react-router-dom"; export interface CreateWorkspacePageViewProps { error: unknown; @@ -72,6 +73,9 @@ export const CreateWorkspacePageView: FC = ({ const [owner, setOwner] = useState(defaultOwner); const { verifyExternalAuth, externalAuthErrors } = useExternalAuthVerification(externalAuth); + const [searchParams] = useSearchParams(); + const disabledParamsList = searchParams?.get("disable_params")?.split(","); + const form: FormikContextType = useFormik({ initialValues: { @@ -198,7 +202,10 @@ export const CreateWorkspacePageView: FC = ({ value: value, }); }, - disabled: form.isSubmitting, + disabled: + disabledParamsList?.includes( + parameter.name.toLowerCase().replace(/ /g, "_"), + ) || form.isSubmitting, }; }} /> @@ -216,7 +223,10 @@ export const CreateWorkspacePageView: FC = ({ value: value, }); }, - disabled: form.isSubmitting, + disabled: + disabledParamsList?.includes( + parameter.name.toLowerCase().replace(/ /g, "_"), + ) || form.isSubmitting, }; }} />