From 37e26da070d163b87ab3e3d77e3500bdd50d733d Mon Sep 17 00:00:00 2001 From: Dean Sheather Date: Tue, 5 Sep 2023 01:47:36 +0000 Subject: [PATCH 01/15] feat: add user quiet hours settings page --- codersdk/deployment.go | 1 + enterprise/coderd/coderd.go | 2 +- scripts/develop.sh | 2 +- site/src/AppRouter.tsx | 4 + site/src/api/api.ts | 15 +++ .../src/components/SettingsLayout/Sidebar.tsx | 12 +++ .../SchedulePage/SchedulePage.test.tsx | 96 +++++++++++++++++++ .../SchedulePage/SchedulePage.tsx | 59 ++++++++++++ 8 files changed, 189 insertions(+), 2 deletions(-) create mode 100644 site/src/pages/UserSettingsPage/SchedulePage/SchedulePage.test.tsx create mode 100644 site/src/pages/UserSettingsPage/SchedulePage/SchedulePage.tsx diff --git a/codersdk/deployment.go b/codersdk/deployment.go index 70fa7bbfc483a..8ee505f50e3fc 100644 --- a/codersdk/deployment.go +++ b/codersdk/deployment.go @@ -63,6 +63,7 @@ var FeatureNames = []FeatureName{ FeatureExternalProvisionerDaemons, FeatureAppearance, FeatureAdvancedTemplateScheduling, + FeatureTemplateAutostopRequirement, FeatureWorkspaceProxy, FeatureUserRoleManagement, FeatureWorkspaceBatchActions, diff --git a/enterprise/coderd/coderd.go b/enterprise/coderd/coderd.go index 7943c701dee33..44fd2ca5ec8fe 100644 --- a/enterprise/coderd/coderd.go +++ b/enterprise/coderd/coderd.go @@ -434,7 +434,7 @@ func (api *API) updateEntitlements(ctx context.Context) error { codersdk.FeatureAdvancedTemplateScheduling: true, // FeatureTemplateAutostopRequirement depends on // FeatureAdvancedTemplateScheduling. - codersdk.FeatureTemplateAutostopRequirement: api.DefaultQuietHoursSchedule != "", + codersdk.FeatureTemplateAutostopRequirement: api.AGPL.Experiments.Enabled(codersdk.ExperimentTemplateAutostopRequirement) && api.DefaultQuietHoursSchedule != "", codersdk.FeatureWorkspaceProxy: true, codersdk.FeatureUserRoleManagement: true, }) diff --git a/scripts/develop.sh b/scripts/develop.sh index 39f81c2951bc4..8a2356922bb14 100755 --- a/scripts/develop.sh +++ b/scripts/develop.sh @@ -136,7 +136,7 @@ fatal() { trap 'fatal "Script encountered an error"' ERR cdroot - start_cmd API "" "${CODER_DEV_SHIM}" server --http-address 0.0.0.0:3000 --swagger-enable --access-url "${CODER_DEV_ACCESS_URL}" --dangerous-allow-cors-requests=true "$@" + start_cmd API "" "${CODER_DEV_SHIM}" server --http-address 0.0.0.0:3000 --swagger-enable --access-url "${CODER_DEV_ACCESS_URL}" --dangerous-allow-cors-requests=true "$@" --experiments template_autostop_requirement --default-quiet-hours-schedule "CRON_TZ=Australia/Sydney 0 0 * * *" echo '== Waiting for Coder to become ready' # Start the timeout in the background so interrupting this script diff --git a/site/src/AppRouter.tsx b/site/src/AppRouter.tsx index 785048fe7298d..2747cf2c6c13b 100644 --- a/site/src/AppRouter.tsx +++ b/site/src/AppRouter.tsx @@ -29,6 +29,9 @@ const CliAuthenticationPage = lazy( const AccountPage = lazy( () => import("./pages/UserSettingsPage/AccountPage/AccountPage"), ) +const SchedulePage = lazy( + () => import("./pages/UserSettingsPage/SchedulePage/SchedulePage"), +) const SecurityPage = lazy( () => import("./pages/UserSettingsPage/SecurityPage/SecurityPage"), ) @@ -289,6 +292,7 @@ export const AppRouter: FC = () => { }> } /> + } /> } /> } /> diff --git a/site/src/api/api.ts b/site/src/api/api.ts index 3567e4f977332..6c893aa3552e2 100644 --- a/site/src/api/api.ts +++ b/site/src/api/api.ts @@ -667,6 +667,21 @@ export const updateProfile = async ( return response.data } +export const getUserQuietHoursSchedule = async ( + userId: TypesGen.User["id"], +): Promise => { + const response = await axios.get(`/api/v2/users/${userId}/quiet-hours`) + return response.data +} + +export const updateUserQuietHoursSchedule = async ( + userId: TypesGen.User["id"], + data: TypesGen.UpdateUserQuietHoursScheduleRequest, +): Promise => { + const response = await axios.put(`/api/v2/users/${userId}/quiet-hours`, data) + return response.data +} + export const activateUser = async ( userId: TypesGen.User["id"], ): Promise => { diff --git a/site/src/components/SettingsLayout/Sidebar.tsx b/site/src/components/SettingsLayout/Sidebar.tsx index e67c229f9e11f..c3e3afe1a44b7 100644 --- a/site/src/components/SettingsLayout/Sidebar.tsx +++ b/site/src/components/SettingsLayout/Sidebar.tsx @@ -8,7 +8,9 @@ import { FC, ElementType, PropsWithChildren, ReactNode } from "react" import { NavLink } from "react-router-dom" import { combineClasses } from "utils/combineClasses" import AccountIcon from "@mui/icons-material/Person" +import ScheduleIcon from "@mui/icons-material/EditCalendarOutlined" import SecurityIcon from "@mui/icons-material/LockOutlined" +import { useDashboard } from "components/Dashboard/DashboardProvider" const SidebarNavItem: FC< PropsWithChildren<{ href: string; icon: ReactNode }> @@ -41,6 +43,8 @@ const SidebarNavItemIcon: React.FC<{ icon: ElementType }> = ({ export const Sidebar: React.FC<{ user: User }> = ({ user }) => { const styles = useStyles() + const { entitlements } = useDashboard() + const allowAutostopRequirement = entitlements.features.template_autostop_requirement.enabled return (