diff --git a/site/src/pages/CreateWorkspacePage/CreateWorkspaceExperimentRouter.tsx b/site/src/pages/CreateWorkspacePage/CreateWorkspaceExperimentRouter.tsx index 36cd921e28000..377424ca2f9a5 100644 --- a/site/src/pages/CreateWorkspacePage/CreateWorkspaceExperimentRouter.tsx +++ b/site/src/pages/CreateWorkspacePage/CreateWorkspaceExperimentRouter.tsx @@ -1,18 +1,76 @@ +import { templateByName } from "api/queries/templates"; +import { ErrorAlert } from "components/Alert/ErrorAlert"; +import { Loader } from "components/Loader/Loader"; import { useDashboard } from "modules/dashboard/useDashboard"; -import type { FC } from "react"; +import { type FC, createContext } from "react"; +import { useQuery } from "react-query"; +import { useParams } from "react-router-dom"; import CreateWorkspacePage from "./CreateWorkspacePage"; import CreateWorkspacePageExperimental from "./CreateWorkspacePageExperimental"; const CreateWorkspaceExperimentRouter: FC = () => { const { experiments } = useDashboard(); - const dynamicParametersEnabled = experiments.includes("dynamic-parameters"); + const { organization: organizationName = "default", template: templateName } = + useParams() as { organization?: string; template: string }; + const templateQuery = useQuery( + dynamicParametersEnabled + ? templateByName(organizationName, templateName) + : { enabled: false }, + ); + + const optOutQuery = useQuery( + templateQuery.data + ? { + queryKey: [ + organizationName, + "template", + templateQuery.data.id, + "optOut", + ], + queryFn: () => ({ + templateId: templateQuery.data.id, + optedOut: + localStorage.getItem(optOutKey(templateQuery.data.id)) === "true", + }), + } + : { enabled: false }, + ); + if (dynamicParametersEnabled) { - return ; + if (optOutQuery.isLoading) { + return ; + } + if (!optOutQuery.data) { + return ; + } + + const toggleOptedOut = () => { + const key = optOutKey(optOutQuery.data.templateId); + const current = localStorage.getItem(key) === "true"; + localStorage.setItem(key, (!current).toString()); + optOutQuery.refetch(); + }; + + return ( + + {optOutQuery.data.optedOut ? ( + + ) : ( + + )} + + ); } return ; }; export default CreateWorkspaceExperimentRouter; + +const optOutKey = (id: string) => `parameters.${id}.optOut`; + +export const ExperimentalFormContext = createContext< + { toggleOptedOut: () => void } | undefined +>(undefined); diff --git a/site/src/pages/CreateWorkspacePage/CreateWorkspacePageExperimental.tsx b/site/src/pages/CreateWorkspacePage/CreateWorkspacePageExperimental.tsx index 5711517855ebd..0c513a1733ec9 100644 --- a/site/src/pages/CreateWorkspacePage/CreateWorkspacePageExperimental.tsx +++ b/site/src/pages/CreateWorkspacePage/CreateWorkspacePageExperimental.tsx @@ -69,10 +69,11 @@ const CreateWorkspacePageExperimental: FC = () => { const templateQuery = useQuery( templateByName(organizationName, templateName), ); - const templateVersionPresetsQuery = useQuery({ - ...templateVersionPresets(templateQuery.data?.active_version_id ?? ""), - enabled: templateQuery.data !== undefined, - }); + const templateVersionPresetsQuery = useQuery( + templateQuery.data + ? templateVersionPresets(templateQuery.data.active_version_id) + : { enabled: false }, + ); const permissionsQuery = useQuery( templateQuery.data ? checkAuthorization({ diff --git a/site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.tsx b/site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.tsx index 66d0033ea6a74..8f284f7338688 100644 --- a/site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.tsx +++ b/site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.tsx @@ -1,5 +1,4 @@ import type { Interpolation, Theme } from "@emotion/react"; -import FormControlLabel from "@mui/material/FormControlLabel"; import FormHelperText from "@mui/material/FormHelperText"; import TextField from "@mui/material/TextField"; import type * as TypesGen from "api/typesGenerated"; @@ -29,7 +28,14 @@ import { Switch } from "components/Switch/Switch"; import { UserAutocomplete } from "components/UserAutocomplete/UserAutocomplete"; import { type FormikContextType, useFormik } from "formik"; import { generateWorkspaceName } from "modules/workspaces/generateWorkspaceName"; -import { type FC, useCallback, useEffect, useMemo, useState } from "react"; +import { + type FC, + useCallback, + useContext, + useEffect, + useMemo, + useState, +} from "react"; import { getFormHelpers, nameValidator, @@ -41,12 +47,14 @@ import { useValidationSchemaForRichParameters, } from "utils/richParameters"; import * as Yup from "yup"; +import { ExperimentalFormContext } from "./CreateWorkspaceExperimentRouter"; import type { CreateWorkspaceMode, ExternalAuthPollingState, } from "./CreateWorkspacePage"; import { ExternalAuthButton } from "./ExternalAuthButton"; import type { CreateWorkspacePermissions } from "./permissions"; + export const Language = { duplicationWarning: "Duplicating a workspace only copies its parameters. No state from the old workspace is copied over.", @@ -98,6 +106,7 @@ export const CreateWorkspacePageView: FC = ({ onSubmit, onCancel, }) => { + const experimentalFormContext = useContext(ExperimentalFormContext); const [owner, setOwner] = useState(defaultOwner); const [suggestedName, setSuggestedName] = useState(() => generateWorkspaceName(), @@ -211,9 +220,20 @@ export const CreateWorkspacePageView: FC = ({ - Cancel - + <> + {experimentalFormContext && ( + + )} + + } > diff --git a/site/src/pages/CreateWorkspacePage/CreateWorkspacePageViewExperimental.tsx b/site/src/pages/CreateWorkspacePage/CreateWorkspacePageViewExperimental.tsx index 0b33c27d57434..342eea1a1b396 100644 --- a/site/src/pages/CreateWorkspacePage/CreateWorkspacePageViewExperimental.tsx +++ b/site/src/pages/CreateWorkspacePage/CreateWorkspacePageViewExperimental.tsx @@ -22,10 +22,18 @@ import { useValidationSchemaForDynamicParameters, } from "modules/workspaces/DynamicParameter/DynamicParameter"; import { generateWorkspaceName } from "modules/workspaces/generateWorkspaceName"; -import { type FC, useCallback, useEffect, useId, useState } from "react"; +import { + type FC, + useCallback, + useContext, + useEffect, + useId, + useState, +} from "react"; import { getFormHelpers, nameValidator } from "utils/formUtils"; import type { AutofillBuildParameter } from "utils/richParameters"; import * as Yup from "yup"; +import { ExperimentalFormContext } from "./CreateWorkspaceExperimentRouter"; import type { CreateWorkspaceMode, ExternalAuthPollingState, @@ -89,6 +97,7 @@ export const CreateWorkspacePageViewExperimental: FC< owner, setOwner, }) => { + const experimentalFormContext = useContext(ExperimentalFormContext); const [suggestedName, setSuggestedName] = useState(() => generateWorkspaceName(), ); @@ -251,7 +260,7 @@ export const CreateWorkspacePageViewExperimental: FC<
-
+
New workspace {template.deprecated && Deprecated} + + {experimentalFormContext && ( + + )}