fix(site): disable auto fields when they are disabled in the template settings (#10022)

- Disable form inputs 
- Add disable badge + tooltip with more info

<img width="1679" alt="Screen Shot 2023-10-03 at 14 20 26" src="https://github.com/coder/coder/assets/3165839/7555eb77-19d9-4a13-965e-6d40c3b852dd">

Fix https://github.com/coder/coder/issues/9820
This commit is contained in:
Bruno Quaresma
2023-10-04 15:00:09 -03:00
committed by GitHub
parent 46551e619d
commit 516b88dc25
5 changed files with 112 additions and 59 deletions
+65 -55
View File
@@ -1,4 +1,4 @@
import { type FC, type ReactNode, useMemo } from "react";
import { type FC, type ReactNode, useMemo, forwardRef } from "react";
import { css, type Interpolation, type Theme, useTheme } from "@emotion/react";
import { colors } from "theme/colors";
@@ -44,61 +44,71 @@ const themeStyles =
};
};
export const Pill: FC<PillProps> = (props) => {
const { lightBorder, icon, text = null, type = "neutral", ...attrs } = props;
const theme = useTheme();
export const Pill: FC<PillProps> = forwardRef<HTMLDivElement, PillProps>(
(props, ref) => {
const {
lightBorder,
icon,
text = null,
type = "neutral",
...attrs
} = props;
const theme = useTheme();
const typeStyles = useMemo(() => {
if (type in themeOverrides) {
return themeOverrides[type as keyof typeof themeOverrides](lightBorder);
}
return themeStyles(type, lightBorder);
}, [type, lightBorder]);
const typeStyles = useMemo(() => {
if (type in themeOverrides) {
return themeOverrides[type as keyof typeof themeOverrides](lightBorder);
}
return themeStyles(type, lightBorder);
}, [type, lightBorder]);
return (
<div
css={[
{
display: "inline-flex",
alignItems: "center",
borderWidth: 1,
borderStyle: "solid",
borderRadius: 99999,
fontSize: 12,
color: "#FFF",
height: theme.spacing(3),
paddingLeft: icon ? theme.spacing(0.75) : theme.spacing(1.5),
paddingRight: theme.spacing(1.5),
whiteSpace: "nowrap",
fontWeight: 400,
},
typeStyles,
]}
role="status"
{...attrs}
>
{icon && (
<div
css={css`
margin-right: ${theme.spacing(0.5)};
width: ${theme.spacing(1.75)};
height: ${theme.spacing(1.75)};
line-height: 0;
display: flex;
align-items: center;
justify-content: center;
& > img,
& > svg {
return (
<div
ref={ref}
css={[
{
cursor: "default",
display: "inline-flex",
alignItems: "center",
borderWidth: 1,
borderStyle: "solid",
borderRadius: 99999,
fontSize: 12,
color: "#FFF",
height: theme.spacing(3),
paddingLeft: icon ? theme.spacing(0.75) : theme.spacing(1.5),
paddingRight: theme.spacing(1.5),
whiteSpace: "nowrap",
fontWeight: 400,
},
typeStyles,
]}
role="status"
{...attrs}
>
{icon && (
<div
css={css`
margin-right: ${theme.spacing(0.5)};
width: ${theme.spacing(1.75)};
height: ${theme.spacing(1.75)};
}
`}
>
{icon}
</div>
)}
{text}
</div>
);
};
line-height: 0;
display: flex;
align-items: center;
justify-content: center;
& > img,
& > svg {
width: ${theme.spacing(1.75)};
height: ${theme.spacing(1.75)};
}
`}
>
{icon}
</div>
)}
{text}
</div>
);
},
);
@@ -18,6 +18,10 @@ dayjs.extend(timezone);
const meta: Meta<typeof WorkspaceScheduleForm> = {
title: "components/WorkspaceScheduleForm",
component: WorkspaceScheduleForm,
args: {
enableAutoStart: true,
enableAutoStop: true,
},
};
export default meta;
@@ -38,6 +42,8 @@ export const AllDisabled: Story = {
autostopEnabled: false,
ttl: emptyTTL,
},
enableAutoStart: false,
enableAutoStop: false,
},
};
@@ -49,6 +55,7 @@ export const Autostart: Story = {
autostopEnabled: false,
ttl: emptyTTL,
},
enableAutoStop: false,
},
};
@@ -30,6 +30,8 @@ import { ChangeEvent, FC } from "react";
import * as Yup from "yup";
import { getFormHelpers } from "utils/formUtils";
import { timeZones } from "utils/timeZones";
import { Pill } from "components/Pill/Pill";
import Tooltip from "@mui/material/Tooltip";
// REMARK: some plugins depend on utc, so it's listed first. Otherwise they're
// sorted alphabetically.
@@ -76,6 +78,8 @@ export interface WorkspaceScheduleFormProps {
submitScheduleError?: unknown;
initialValues: WorkspaceScheduleFormValues;
isLoading: boolean;
enableAutoStop: boolean;
enableAutoStart: boolean;
onCancel: () => void;
onSubmit: (values: WorkspaceScheduleFormValues) => void;
// for storybook
@@ -193,6 +197,8 @@ export const WorkspaceScheduleForm: FC<
onSubmit,
initialTouched,
defaultTTL,
enableAutoStop,
enableAutoStart,
}) => {
const styles = useStyles();
@@ -284,12 +290,25 @@ export const WorkspaceScheduleForm: FC<
<HorizontalForm onSubmit={form.handleSubmit}>
<FormSection
title="Autostart"
description="Select the time and days of week on which you want the workspace starting automatically."
description={
<>
<div css={{ marginBottom: 16 }}>
Select the time and days of week on which you want the workspace
starting automatically.
</div>
{!enableAutoStart && (
<Tooltip title="This option can be enabled in the template settings">
<Pill text="Disabled" />
</Tooltip>
)}
</>
}
>
<FormFields>
<FormControlLabel
control={
<Switch
disabled={!enableAutoStart}
name="autostartEnabled"
checked={form.values.autostartEnabled}
onChange={handleToggleAutostart}
@@ -352,7 +371,21 @@ export const WorkspaceScheduleForm: FC<
<FormSection
title="Autostop"
description="Set how many hours should elapse after a workspace is started before it automatically shuts down. If workspace connection activity is detected, the autostop timer will be bumped by this value."
description={
<>
<div css={{ marginBottom: 16 }}>
Set how many hours should elapse after a workspace is started
before it automatically shuts down. If workspace connection
activity is detected, the autostop timer will be bumped by this
value.
</div>
{!enableAutoStop && (
<Tooltip title="This option can be enabled in the template settings">
<Pill text="Disabled" />
</Tooltip>
)}
</>
}
>
<FormFields>
<FormControlLabel
@@ -361,6 +394,7 @@ export const WorkspaceScheduleForm: FC<
name="autostopEnabled"
checked={form.values.autostopEnabled}
onChange={handleToggleAutostop}
disabled={!enableAutoStop}
/>
}
label={Language.stopSwitch}
@@ -83,6 +83,8 @@ export const WorkspaceSchedulePage: FC = () => {
(scheduleState.matches("presentForm") ||
scheduleState.matches("submittingSchedule")) && (
<WorkspaceScheduleForm
enableAutoStart={template.allow_user_autostart}
enableAutoStop={template.allow_user_autostop}
submitScheduleError={submitScheduleError}
initialValues={{
...getAutostart(workspace),
+2 -2
View File
@@ -450,8 +450,8 @@ export const MockTemplate: TypesGen.Template = {
failure_ttl_ms: 0,
time_til_dormant_ms: 0,
time_til_dormant_autodelete_ms: 0,
allow_user_autostart: false,
allow_user_autostop: false,
allow_user_autostart: true,
allow_user_autostop: true,
};
export const MockTemplateVersionFiles: TemplateVersionFiles = {