From bb03df8148e5aad75f8f0650e0a02aed2554192d Mon Sep 17 00:00:00 2001 From: Joe Previte Date: Thu, 5 Jan 2023 14:16:54 -0700 Subject: [PATCH] feat: add storybook for /deployment/appearance page (#5582) * wip * wip: move appearancesettingspage * refactor: separate page and view ApperanceSettings * refactor: create storybook from AppearanceSettingsView * fixup: formatting and types --- site/src/AppRouter.tsx | 5 +- .../AppearanceSettingsPage.tsx | 62 +++++++++++++ .../AppearanceSettingsPageView.stories.tsx | 35 +++++++ .../AppearanceSettingsPageView.tsx} | 93 ++++++------------- 4 files changed, 129 insertions(+), 66 deletions(-) create mode 100644 site/src/pages/DeploySettingsPage/AppearanceSettingsPage/AppearanceSettingsPage.tsx create mode 100644 site/src/pages/DeploySettingsPage/AppearanceSettingsPage/AppearanceSettingsPageView.stories.tsx rename site/src/pages/DeploySettingsPage/{AppearanceSettingsPage.tsx => AppearanceSettingsPage/AppearanceSettingsPageView.tsx} (83%) diff --git a/site/src/AppRouter.tsx b/site/src/AppRouter.tsx index 58d3262364..715beaea3a 100644 --- a/site/src/AppRouter.tsx +++ b/site/src/AppRouter.tsx @@ -77,7 +77,10 @@ const SecuritySettingsPage = lazy( () => import("./pages/DeploySettingsPage/SecuritySettingsPage"), ) const AppearanceSettingsPage = lazy( - () => import("./pages/DeploySettingsPage/AppearanceSettingsPage"), + () => + import( + "./pages/DeploySettingsPage/AppearanceSettingsPage/AppearanceSettingsPage" + ), ) const UserAuthSettingsPage = lazy( () => import("./pages/DeploySettingsPage/UserAuthSettingsPage"), diff --git a/site/src/pages/DeploySettingsPage/AppearanceSettingsPage/AppearanceSettingsPage.tsx b/site/src/pages/DeploySettingsPage/AppearanceSettingsPage/AppearanceSettingsPage.tsx new file mode 100644 index 0000000000..81bcfe2c15 --- /dev/null +++ b/site/src/pages/DeploySettingsPage/AppearanceSettingsPage/AppearanceSettingsPage.tsx @@ -0,0 +1,62 @@ +import { useActor } from "@xstate/react" +import { FeatureNames } from "api/types" +import { AppearanceConfig } from "api/typesGenerated" +import React, { useContext } from "react" +import { Helmet } from "react-helmet-async" +import { pageTitle } from "util/page" +import { XServiceContext } from "xServices/StateContext" +import { AppearanceSettingsPageView } from "./AppearanceSettingsPageView" + +// ServiceBanner is unlike the other Deployment Settings pages because it +// implements a form, whereas the others are read-only. We make this +// exception because the Service Banner is visual, and configuring it from +// the command line would be a significantly worse user experience. +const AppearanceSettingsPage: React.FC = () => { + const xServices = useContext(XServiceContext) + const [appearanceXService, appearanceSend] = useActor( + xServices.appearanceXService, + ) + const [entitlementsState] = useActor(xServices.entitlementsXService) + const appearance = appearanceXService.context.appearance + + const isEntitled = + entitlementsState.context.entitlements.features[FeatureNames.Appearance] + .entitlement !== "not_entitled" + + const updateAppearance = ( + newConfig: Partial, + preview: boolean, + ) => { + const newAppearance = { + ...appearance, + ...newConfig, + } + if (preview) { + appearanceSend({ + type: "SET_PREVIEW_APPEARANCE", + appearance: newAppearance, + }) + return + } + appearanceSend({ + type: "SET_APPEARANCE", + appearance: newAppearance, + }) + } + + return ( + <> + + {pageTitle("Appearance Settings")} + + + + + ) +} + +export default AppearanceSettingsPage diff --git a/site/src/pages/DeploySettingsPage/AppearanceSettingsPage/AppearanceSettingsPageView.stories.tsx b/site/src/pages/DeploySettingsPage/AppearanceSettingsPage/AppearanceSettingsPageView.stories.tsx new file mode 100644 index 0000000000..0bad75deda --- /dev/null +++ b/site/src/pages/DeploySettingsPage/AppearanceSettingsPage/AppearanceSettingsPageView.stories.tsx @@ -0,0 +1,35 @@ +import { ComponentMeta, Story } from "@storybook/react" +import { + AppearanceSettingsPageView, + AppearanceSettingsPageViewProps, +} from "./AppearanceSettingsPageView" + +export default { + title: "pages/AppearanceSettingsPageView", + component: AppearanceSettingsPageView, + argTypes: { + appearance: { + defaultValue: { + logo_url: "https://github.com/coder.png", + service_banner: { + enabled: true, + message: "hello world", + background_color: "white", + }, + }, + }, + isEntitled: { + defaultValue: false, + }, + updateAppearance: { + defaultValue: () => { + return undefined + }, + }, + }, +} as ComponentMeta + +const Template: Story = (args) => ( + +) +export const Page = Template.bind({}) diff --git a/site/src/pages/DeploySettingsPage/AppearanceSettingsPage.tsx b/site/src/pages/DeploySettingsPage/AppearanceSettingsPage/AppearanceSettingsPageView.tsx similarity index 83% rename from site/src/pages/DeploySettingsPage/AppearanceSettingsPage.tsx rename to site/src/pages/DeploySettingsPage/AppearanceSettingsPage/AppearanceSettingsPageView.tsx index 5689e433b8..14b4bad082 100644 --- a/site/src/pages/DeploySettingsPage/AppearanceSettingsPage.tsx +++ b/site/src/pages/DeploySettingsPage/AppearanceSettingsPage/AppearanceSettingsPageView.tsx @@ -1,70 +1,43 @@ -import Button from "@material-ui/core/Button" -import FormControlLabel from "@material-ui/core/FormControlLabel" -import FormHelperText from "@material-ui/core/FormHelperText" -import InputAdornment from "@material-ui/core/InputAdornment" -import { useTheme } from "@material-ui/core/styles" -import makeStyles from "@material-ui/core/styles/makeStyles" -import Switch from "@material-ui/core/Switch" -import TextField from "@material-ui/core/TextField" -import { useActor } from "@xstate/react" -import { FeatureNames } from "api/types" -import { AppearanceConfig } from "api/typesGenerated" +import { useState } from "react" +import { Header } from "components/DeploySettingsLayout/Header" import { Badges, DisabledBadge, EnterpriseBadge, EntitledBadge, } from "components/DeploySettingsLayout/Badges" +import InputAdornment from "@material-ui/core/InputAdornment" import { Fieldset } from "components/DeploySettingsLayout/Fieldset" -import { Header } from "components/DeploySettingsLayout/Header" +import { getFormHelpers } from "util/formUtils" +import Button from "@material-ui/core/Button" +import FormControlLabel from "@material-ui/core/FormControlLabel" +import FormHelperText from "@material-ui/core/FormHelperText" +import { BlockPicker } from "react-color" +import { useTranslation } from "react-i18next" +import makeStyles from "@material-ui/core/styles/makeStyles" +import Switch from "@material-ui/core/Switch" +import TextField from "@material-ui/core/TextField" +import { AppearanceConfig } from "api/typesGenerated" import { Stack } from "components/Stack/Stack" import { useFormik } from "formik" -import React, { useContext, useState } from "react" -import { BlockPicker } from "react-color" -import { Helmet } from "react-helmet-async" -import { useTranslation } from "react-i18next" -import { getFormHelpers } from "util/formUtils" -import { pageTitle } from "util/page" -import { XServiceContext } from "xServices/StateContext" +import { useTheme } from "@material-ui/core/styles" -// ServiceBanner is unlike the other Deployment Settings pages because it -// implements a form, whereas the others are read-only. We make this -// exception because the Service Banner is visual, and configuring it from -// the command line would be a significantly worse user experience. -const AppearanceSettingsPage: React.FC = () => { - const xServices = useContext(XServiceContext) - const [appearanceXService, appearanceSend] = useActor( - xServices.appearanceXService, - ) - const [entitlementsState] = useActor(xServices.entitlementsXService) - const appearance = appearanceXService.context.appearance - const styles = useStyles() - - const isEntitled = - entitlementsState.context.entitlements.features[FeatureNames.Appearance] - .entitlement !== "not_entitled" - - const updateAppearance = ( +export type AppearanceSettingsPageViewProps = { + appearance: AppearanceConfig + isEntitled: boolean + updateAppearance: ( newConfig: Partial, preview: boolean, - ) => { - const newAppearance = { - ...appearance, - ...newConfig, - } - if (preview) { - appearanceSend({ - type: "SET_PREVIEW_APPEARANCE", - appearance: newAppearance, - }) - return - } - appearanceSend({ - type: "SET_APPEARANCE", - appearance: newAppearance, - }) - } - + ) => void +} +export const AppearanceSettingsPageView = ({ + appearance, + isEntitled, + updateAppearance, +}: AppearanceSettingsPageViewProps): JSX.Element => { + const styles = useStyles() + const theme = useTheme() + const [t] = useTranslation("appearanceSettings") const logoForm = useFormik<{ logo_url: string }>({ @@ -93,16 +66,8 @@ const AppearanceSettingsPage: React.FC = () => { const [backgroundColor, setBackgroundColor] = useState( serviceBannerForm.values.background_color, ) - - const theme = useTheme() - const [t] = useTranslation("appearanceSettings") - return ( <> - - {pageTitle("Appearance Settings")} - -
({ }, }, })) - -export default AppearanceSettingsPage