diff --git a/site/src/components/Badge/Badge.tsx b/site/src/components/Badge/Badge.tsx
index 3b2a5d5897eb3..0d11c96d30433 100644
--- a/site/src/components/Badge/Badge.tsx
+++ b/site/src/components/Badge/Badge.tsx
@@ -22,6 +22,8 @@ const badgeVariants = cva(
"border border-solid border-border-warning bg-surface-orange text-content-warning shadow",
destructive:
"border border-solid border-border-destructive bg-surface-red text-highlight-red shadow",
+ green:
+ "border border-solid border-surface-green bg-surface-green text-highlight-green shadow",
},
size: {
xs: "text-2xs font-regular h-5 [&_svg]:hidden rounded px-1.5",
diff --git a/site/src/components/EphemeralParametersDialog/EphemeralParametersDialog.tsx b/site/src/components/EphemeralParametersDialog/EphemeralParametersDialog.tsx
new file mode 100644
index 0000000000000..d1713d920f4a9
--- /dev/null
+++ b/site/src/components/EphemeralParametersDialog/EphemeralParametersDialog.tsx
@@ -0,0 +1,86 @@
+import type { TemplateVersionParameter } from "api/typesGenerated";
+import { Button } from "components/Button/Button";
+import {
+ Dialog,
+ DialogContent,
+ DialogDescription,
+ DialogFooter,
+ DialogHeader,
+ DialogTitle,
+} from "components/Dialog/Dialog";
+import type { FC } from "react";
+import { useNavigate } from "react-router-dom";
+
+interface EphemeralParametersDialogProps {
+ open: boolean;
+ onClose: () => void;
+ onContinue: () => void;
+ ephemeralParameters: TemplateVersionParameter[];
+ workspaceOwner: string;
+ workspaceName: string;
+ templateVersionId: string;
+}
+
+export const EphemeralParametersDialog: FC = ({
+ open,
+ onClose,
+ onContinue,
+ ephemeralParameters,
+ workspaceOwner,
+ workspaceName,
+ templateVersionId,
+}) => {
+ const navigate = useNavigate();
+
+ const handleGoToParameters = () => {
+ onClose();
+ navigate(
+ `/@${workspaceOwner}/${workspaceName}/settings/parameters?templateVersionId=${templateVersionId}`,
+ );
+ };
+
+ return (
+
+ );
+};
diff --git a/site/src/modules/workspaces/DynamicParameter/DynamicParameter.stories.tsx b/site/src/modules/workspaces/DynamicParameter/DynamicParameter.stories.tsx
index 4d1e91d9bf3e3..db3fa2f404c53 100644
--- a/site/src/modules/workspaces/DynamicParameter/DynamicParameter.stories.tsx
+++ b/site/src/modules/workspaces/DynamicParameter/DynamicParameter.stories.tsx
@@ -211,6 +211,15 @@ export const Immutable: Story = {
},
};
+export const Ephemeral: Story = {
+ args: {
+ parameter: {
+ ...MockPreviewParameter,
+ ephemeral: true,
+ },
+ },
+};
+
export const AllBadges: Story = {
args: {
parameter: {
diff --git a/site/src/modules/workspaces/DynamicParameter/DynamicParameter.tsx b/site/src/modules/workspaces/DynamicParameter/DynamicParameter.tsx
index c3448ac7d7182..9f97d558c8f08 100644
--- a/site/src/modules/workspaces/DynamicParameter/DynamicParameter.tsx
+++ b/site/src/modules/workspaces/DynamicParameter/DynamicParameter.tsx
@@ -36,6 +36,7 @@ import { useDebouncedValue } from "hooks/debounce";
import { useEffectEvent } from "hooks/hookPolyfills";
import {
CircleAlert,
+ Hourglass,
Info,
LinkIcon,
Settings,
@@ -162,6 +163,23 @@ const ParameterLabel: FC = ({
)}
+ {parameter.ephemeral && (
+
+
+
+
+
+
+ Ephemeral
+
+
+
+
+ This parameter only applies for a single workspace start
+
+
+
+ )}
{isPreset && (
diff --git a/site/src/pages/WorkspacePage/WorkspaceActions/BuildParametersPopover.tsx b/site/src/pages/WorkspacePage/WorkspaceActions/BuildParametersPopover.tsx
index d594351d8dcae..76b100fc96745 100644
--- a/site/src/pages/WorkspacePage/WorkspaceActions/BuildParametersPopover.tsx
+++ b/site/src/pages/WorkspacePage/WorkspaceActions/BuildParametersPopover.tsx
@@ -1,5 +1,4 @@
import { useTheme } from "@emotion/react";
-import Button from "@mui/material/Button";
import visuallyHidden from "@mui/utils/visuallyHidden";
import { API } from "api/api";
import type {
@@ -7,6 +6,7 @@ import type {
Workspace,
WorkspaceBuildParameter,
} from "api/typesGenerated";
+import { Button } from "components/Button/Button";
import { FormFields } from "components/Form/Form";
import { TopbarButton } from "components/FullPageLayout/Topbar";
import {
@@ -27,6 +27,7 @@ import { useFormik } from "formik";
import { ChevronDownIcon } from "lucide-react";
import type { FC } from "react";
import { useQuery } from "react-query";
+import { useNavigate } from "react-router-dom";
import { docs } from "utils/docs";
import { getFormHelpers } from "utils/formUtils";
import {
@@ -72,6 +73,7 @@ export const BuildParametersPopover: FC = ({
css={{ ".MuiPaper-root": { width: 304 } }}
>
= ({
};
interface BuildParametersPopoverContentProps {
+ workspace: Workspace;
ephemeralParameters?: TemplateVersionParameter[];
buildParameters?: WorkspaceBuildParameter[];
onSubmit: (buildParameters: WorkspaceBuildParameter[]) => void;
}
const BuildParametersPopoverContent: FC = ({
+ workspace,
ephemeralParameters,
buildParameters,
onSubmit,
}) => {
const theme = useTheme();
const popover = usePopover();
+ const navigate = useNavigate();
+
+ if (
+ !workspace.template_use_classic_parameter_flow &&
+ ephemeralParameters &&
+ ephemeralParameters.length > 0
+ ) {
+ const handleGoToParameters = () => {
+ popover.setOpen(false);
+ navigate(
+ `/@${workspace.owner_name}/${workspace.name}/settings/parameters`,
+ );
+ };
+
+ return (
+
+
+ Ephemeral Parameters
+
+
+ This template has ephemeral parameters that must be configured on the
+ workspace parameters page
+
+
+
+
+
+
+ );
+ }
return (
<>
@@ -206,8 +257,6 @@ const Form: FC = ({
- {standardParameters.map((parameter, index) => {
+ {parameters.map((parameter, index) => {
const currentParameterValueIndex =
form.values.rich_parameter_values?.findIndex(
(p) => p.name === parameter.name,
@@ -260,41 +257,6 @@ export const WorkspaceParametersPageViewExperimental: FC<
)}
- {ephemeralParameters.length > 0 && (
-
-
- Ephemeral Parameters
-
- These parameters only apply for a single workspace start
-
-
-
-
- {ephemeralParameters.map((parameter, index) => {
- const actualIndex = standardParameters.length + index;
- const parameterField = `rich_parameter_values.${actualIndex}`;
- const isDisabled =
- disabled || parameter.styling?.disabled || isSubmitting;
-
- return (
-
- handleChange(parameter, parameterField, value)
- }
- autofill={false}
- disabled={isDisabled}
- value={
- form.values?.rich_parameter_values?.[index]?.value || ""
- }
- />
- );
- })}
-
-
- )}
-