From b579a7c0a3d1f186f674816dd593d0c752795d1a Mon Sep 17 00:00:00 2001 From: Bruno Date: Wed, 6 Apr 2022 19:06:33 +0000 Subject: [PATCH 1/8] Add preferences page --- site/src/AppRouter.tsx | 51 ++++++++++++++++++- site/src/components/Panel/Panel.stories.tsx | 21 -------- site/src/components/Preferences/Layout.tsx | 20 ++++++++ .../components/Sidebar/Sidebar.stories.tsx | 20 -------- .../components/TabPanel/TabPanel.stories.tsx | 20 ++++++++ .../TabPanel/TabSidebar.stories.tsx | 19 +++++++ .../index.tsx => TabPanel/TabSidebar.tsx} | 40 +++++++-------- .../components/{Panel => TabPanel}/index.tsx | 12 ++--- site/src/pages/preferences/account.tsx | 17 +++++++ .../src/pages/preferences/linked-accounts.tsx | 17 +++++++ site/src/pages/preferences/security.tsx | 14 +++++ site/src/pages/preferences/ssh-keys.tsx | 17 +++++++ 12 files changed, 198 insertions(+), 70 deletions(-) delete mode 100644 site/src/components/Panel/Panel.stories.tsx create mode 100644 site/src/components/Preferences/Layout.tsx delete mode 100644 site/src/components/Sidebar/Sidebar.stories.tsx create mode 100644 site/src/components/TabPanel/TabPanel.stories.tsx create mode 100644 site/src/components/TabPanel/TabSidebar.stories.tsx rename site/src/components/{Sidebar/index.tsx => TabPanel/TabSidebar.tsx} (67%) rename site/src/components/{Panel => TabPanel}/index.tsx (84%) create mode 100644 site/src/pages/preferences/account.tsx create mode 100644 site/src/pages/preferences/linked-accounts.tsx create mode 100644 site/src/pages/preferences/security.tsx create mode 100644 site/src/pages/preferences/ssh-keys.tsx diff --git a/site/src/AppRouter.tsx b/site/src/AppRouter.tsx index e573ac5ecbf0f..5003a14a11966 100644 --- a/site/src/AppRouter.tsx +++ b/site/src/AppRouter.tsx @@ -1,14 +1,24 @@ import React from "react" -import { Route, Routes } from "react-router-dom" +import { Navigate, Route, Routes } from "react-router-dom" import { AuthAndNav, RequireAuth } from "./components" import { IndexPage } from "./pages" import { NotFoundPage } from "./pages/404" import { CliAuthenticationPage } from "./pages/cli-auth" import { HealthzPage } from "./pages/healthz" import { SignInPage } from "./pages/login" +<<<<<<< Updated upstream import { ProjectsPage } from "./pages/projects" import { ProjectPage } from "./pages/projects/[organization]/[project]" import { CreateWorkspacePage } from "./pages/projects/[organization]/[project]/create" +======= +import { PreferencesAccountPage } from "./pages/preferences/account" +import { PreferencesLinkedAccountsPage } from "./pages/preferences/linked-accounts" +import { PreferencesSecurityPage } from "./pages/preferences/security" +import { PreferencesSSHKeysPage } from "./pages/preferences/ssh-keys" +import { TemplatesPage } from "./pages/templates" +import { TemplatePage } from "./pages/templates/[organization]/[template]" +import { CreateWorkspacePage } from "./pages/templates/[organization]/[template]/create" +>>>>>>> Stashed changes import { WorkspacePage } from "./pages/workspaces/[workspace]" export const AppRouter: React.FC = () => ( @@ -67,6 +77,45 @@ export const AppRouter: React.FC = () => ( /> +<<<<<<< Updated upstream +======= + + } /> + + + + } + /> + + + + } + /> + + + + } + /> + + + + } + /> + + +>>>>>>> Stashed changes {/* Using path="*"" means "match anything", so this route acts like a catch-all for URLs that we don't have explicit routes for. */} diff --git a/site/src/components/Panel/Panel.stories.tsx b/site/src/components/Panel/Panel.stories.tsx deleted file mode 100644 index 9db07820d9dee..0000000000000 --- a/site/src/components/Panel/Panel.stories.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import { Story } from "@storybook/react" -import React from "react" -import { Panel, PanelProps } from "./" - -export default { - title: "Page/Panel", - component: Panel, -} - -const Template: Story = (args: PanelProps) => - -export const Example = Template.bind({}) -Example.args = { - title: "Panel title", - activeTab: "oauthSettings", - menuItems: [ - { label: "OAuth Settings", value: "oauthSettings" }, - { label: "Security", value: "oauthSettings", hasChanges: true }, - { label: "Hardware", value: "oauthSettings" }, - ], -} diff --git a/site/src/components/Preferences/Layout.tsx b/site/src/components/Preferences/Layout.tsx new file mode 100644 index 0000000000000..81bebc5bae2f9 --- /dev/null +++ b/site/src/components/Preferences/Layout.tsx @@ -0,0 +1,20 @@ +import Box from "@material-ui/core/Box" +import React from "react" +import { TabPanel } from "../TabPanel" + +const menuItems = [ + { label: "Account", path: "/preferences/account" }, + { label: "Security", path: "/preferences/security" }, + { label: "SSH Keys", path: "/preferences/ssh-keys" }, + { label: "Linked Accounts", path: "/preferences/linked-accounts" }, +] + +export const Layout: React.FC = ({ children }) => { + return ( + + + {children} + + + ) +} diff --git a/site/src/components/Sidebar/Sidebar.stories.tsx b/site/src/components/Sidebar/Sidebar.stories.tsx deleted file mode 100644 index 2dc682773d958..0000000000000 --- a/site/src/components/Sidebar/Sidebar.stories.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import { Story } from "@storybook/react" -import React from "react" -import { Sidebar, SidebarProps } from "./" - -export default { - title: "Page/Sidebar", - component: Sidebar, -} - -const Template: Story = (args: SidebarProps) => - -export const Example = Template.bind({}) -Example.args = { - activeItem: "oauthSettings", - menuItems: [ - { label: "OAuth Settings", value: "oauthSettings" }, - { label: "Security", value: "security", hasChanges: true }, - { label: "Hardware", value: "hardware" }, - ], -} diff --git a/site/src/components/TabPanel/TabPanel.stories.tsx b/site/src/components/TabPanel/TabPanel.stories.tsx new file mode 100644 index 0000000000000..9510f2e0946dd --- /dev/null +++ b/site/src/components/TabPanel/TabPanel.stories.tsx @@ -0,0 +1,20 @@ +import { Story } from "@storybook/react" +import React from "react" +import { TabPanel, TabPanelProps } from "." + +export default { + title: "Page/TabTabPanel", + component: TabPanel, +} + +const Template: Story = (args: TabPanelProps) => + +export const Example = Template.bind({}) +Example.args = { + title: "Title", + menuItems: [ + { label: "OAuth Settings", path: "oauthSettings" }, + { label: "Security", path: "oauthSettings", hasChanges: true }, + { label: "Hardware", path: "oauthSettings" }, + ], +} diff --git a/site/src/components/TabPanel/TabSidebar.stories.tsx b/site/src/components/TabPanel/TabSidebar.stories.tsx new file mode 100644 index 0000000000000..b3eeb7856db91 --- /dev/null +++ b/site/src/components/TabPanel/TabSidebar.stories.tsx @@ -0,0 +1,19 @@ +import { Story } from "@storybook/react" +import React from "react" +import { TabSidebar, TabSidebarProps } from "./TabSidebar" + +export default { + title: "Page/TabSidebar", + component: TabSidebar, +} + +const Template: Story = (args: TabSidebarProps) => + +export const Example = Template.bind({}) +Example.args = { + menuItems: [ + { label: "OAuth Settings", path: "oauthSettings" }, + { label: "Security", path: "security", hasChanges: true }, + { label: "Hardware", path: "hardware" }, + ], +} diff --git a/site/src/components/Sidebar/index.tsx b/site/src/components/TabPanel/TabSidebar.tsx similarity index 67% rename from site/src/components/Sidebar/index.tsx rename to site/src/components/TabPanel/TabSidebar.tsx index 2058621775d92..598aa69329c98 100644 --- a/site/src/components/Sidebar/index.tsx +++ b/site/src/components/TabPanel/TabSidebar.tsx @@ -2,41 +2,35 @@ import List from "@material-ui/core/List" import ListItem from "@material-ui/core/ListItem" import { makeStyles } from "@material-ui/core/styles" import React from "react" +import { NavLink } from "react-router-dom" import { combineClasses } from "../../util/combine-classes" -export interface SidebarItem { - value: string +export interface TabSidebarItem { + path: string label: string hasChanges?: boolean } -export interface SidebarProps { - menuItems: SidebarItem[] - activeItem?: string - onSelect?: (value: string) => void +export interface TabSidebarProps { + menuItems: TabSidebarItem[] } -export const Sidebar: React.FC = ({ menuItems, activeItem, onSelect }) => { +export const TabSidebar: React.FC = ({ menuItems }) => { const styles = useStyles() return ( {menuItems.map(({ hasChanges, ...tab }) => { - const isActive = activeItem === tab.value return ( - onSelect(tab.value) : undefined} - className={styles.menuItem} - disableRipple - focusRipple={false} - component="li" - > - - {hasChanges ? `${tab.label}*` : tab.label} - - + + {({ isActive }) => ( + + + {hasChanges ? `${tab.label}*` : tab.label} + + + )} + ) })} @@ -49,6 +43,10 @@ const useStyles = makeStyles((theme) => ({ marginTop: theme.spacing(5), }, + link: { + textDecoration: "none", + }, + menuItem: { letterSpacing: -theme.spacing(0.0375), padding: 0, diff --git a/site/src/components/Panel/index.tsx b/site/src/components/TabPanel/index.tsx similarity index 84% rename from site/src/components/Panel/index.tsx rename to site/src/components/TabPanel/index.tsx index d4294d82faa18..7ea9fe8281f59 100644 --- a/site/src/components/Panel/index.tsx +++ b/site/src/components/TabPanel/index.tsx @@ -1,18 +1,16 @@ import { makeStyles } from "@material-ui/core/styles" import { fade } from "@material-ui/core/styles/colorManipulator" import React from "react" -import { Sidebar, SidebarItem } from "../Sidebar" +import { TabSidebar, TabSidebarItem } from "./TabSidebar" export type AdminMenuItemCallback = (menuItem: string) => void -export interface PanelProps { +export interface TabPanelProps { title: string - menuItems: SidebarItem[] - activeTab: string - onSelect: AdminMenuItemCallback + menuItems: TabSidebarItem[] } -export const Panel: React.FC = ({ children, title, menuItems, activeTab, onSelect }) => { +export const TabPanel: React.FC = ({ children, title, menuItems }) => { const styles = useStyles() return ( @@ -20,7 +18,7 @@ export const Panel: React.FC = ({ children, title, menuItems, active
{title}
- +
{children}
diff --git a/site/src/pages/preferences/account.tsx b/site/src/pages/preferences/account.tsx new file mode 100644 index 0000000000000..014ec43a31d87 --- /dev/null +++ b/site/src/pages/preferences/account.tsx @@ -0,0 +1,17 @@ +import Box from "@material-ui/core/Box" +import React from "react" +import { Layout } from "../../components/Preferences/Layout" +import { Section } from "../../components/Section" + +export const PreferencesAccountPage: React.FC = () => { + return ( + + +
+ + + ) +} diff --git a/site/src/pages/preferences/linked-accounts.tsx b/site/src/pages/preferences/linked-accounts.tsx new file mode 100644 index 0000000000000..a28a914315515 --- /dev/null +++ b/site/src/pages/preferences/linked-accounts.tsx @@ -0,0 +1,17 @@ +import Box from "@material-ui/core/Box" +import React from "react" +import { Layout } from "../../components/Preferences/Layout" +import { Section } from "../../components/Section" + +export const PreferencesLinkedAccountsPage: React.FC = () => { + return ( + + +
+ + + ) +} diff --git a/site/src/pages/preferences/security.tsx b/site/src/pages/preferences/security.tsx new file mode 100644 index 0000000000000..7754de444c685 --- /dev/null +++ b/site/src/pages/preferences/security.tsx @@ -0,0 +1,14 @@ +import Box from "@material-ui/core/Box" +import React from "react" +import { Layout } from "../../components/Preferences/Layout" +import { Section } from "../../components/Section" + +export const PreferencesSecurityPage: React.FC = () => { + return ( + + +
+ + + ) +} diff --git a/site/src/pages/preferences/ssh-keys.tsx b/site/src/pages/preferences/ssh-keys.tsx new file mode 100644 index 0000000000000..925cbd256099b --- /dev/null +++ b/site/src/pages/preferences/ssh-keys.tsx @@ -0,0 +1,17 @@ +import Box from "@material-ui/core/Box" +import React from "react" +import { Layout } from "../../components/Preferences/Layout" +import { Section } from "../../components/Section" + +export const PreferencesSSHKeysPage: React.FC = () => { + return ( + + +
+ + + ) +} From 70a782cd292be4d4e41aa5c65f889e18f8247074 Mon Sep 17 00:00:00 2001 From: Bruno Date: Wed, 6 Apr 2022 19:08:53 +0000 Subject: [PATCH 2/8] Fix AppRouter --- site/src/AppRouter.tsx | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/site/src/AppRouter.tsx b/site/src/AppRouter.tsx index 5003a14a11966..4e58c697fabc5 100644 --- a/site/src/AppRouter.tsx +++ b/site/src/AppRouter.tsx @@ -6,19 +6,13 @@ import { NotFoundPage } from "./pages/404" import { CliAuthenticationPage } from "./pages/cli-auth" import { HealthzPage } from "./pages/healthz" import { SignInPage } from "./pages/login" -<<<<<<< Updated upstream -import { ProjectsPage } from "./pages/projects" -import { ProjectPage } from "./pages/projects/[organization]/[project]" -import { CreateWorkspacePage } from "./pages/projects/[organization]/[project]/create" -======= import { PreferencesAccountPage } from "./pages/preferences/account" import { PreferencesLinkedAccountsPage } from "./pages/preferences/linked-accounts" import { PreferencesSecurityPage } from "./pages/preferences/security" import { PreferencesSSHKeysPage } from "./pages/preferences/ssh-keys" -import { TemplatesPage } from "./pages/templates" -import { TemplatePage } from "./pages/templates/[organization]/[template]" -import { CreateWorkspacePage } from "./pages/templates/[organization]/[template]/create" ->>>>>>> Stashed changes +import { ProjectsPage } from "./pages/projects" +import { ProjectPage } from "./pages/projects/[organization]/[project]" +import { CreateWorkspacePage } from "./pages/projects/[organization]/[project]/create" import { WorkspacePage } from "./pages/workspaces/[workspace]" export const AppRouter: React.FC = () => ( @@ -77,8 +71,6 @@ export const AppRouter: React.FC = () => ( /> -<<<<<<< Updated upstream -======= } /> ( /> ->>>>>>> Stashed changes {/* Using path="*"" means "match anything", so this route acts like a catch-all for URLs that we don't have explicit routes for. */} From 32a5542b6573aa081865ce29aa82d252f20da6fd Mon Sep 17 00:00:00 2001 From: Bruno Date: Thu, 7 Apr 2022 13:10:18 +0000 Subject: [PATCH 3/8] refactor: use react-router-dom outlet --- site/src/AppRouter.tsx | 39 +++---------------- site/src/components/Preferences/Layout.tsx | 18 ++++++--- site/src/pages/preferences/account.tsx | 14 ++----- .../src/pages/preferences/linked-accounts.tsx | 14 ++----- site/src/pages/preferences/security.tsx | 10 +---- site/src/pages/preferences/ssh-keys.tsx | 14 ++----- 6 files changed, 31 insertions(+), 78 deletions(-) diff --git a/site/src/AppRouter.tsx b/site/src/AppRouter.tsx index 934092a82b8c5..bbcd2a7fd1376 100644 --- a/site/src/AppRouter.tsx +++ b/site/src/AppRouter.tsx @@ -1,6 +1,7 @@ import React from "react" import { Navigate, Route, Routes } from "react-router-dom" import { AuthAndNav, RequireAuth } from "./components" +import { PreferencesLayout } from "./components/Preferences/Layout" import { IndexPage } from "./pages" import { NotFoundPage } from "./pages/404" import { CliAuthenticationPage } from "./pages/cli-auth" @@ -71,40 +72,12 @@ export const AppRouter: React.FC = () => ( /> - + }> } /> - - - - } - /> - - - - } - /> - - - - } - /> - - - - } - /> + } /> + } /> + } /> + } /> {/* Using path="*"" means "match anything", so this route diff --git a/site/src/components/Preferences/Layout.tsx b/site/src/components/Preferences/Layout.tsx index 81bebc5bae2f9..30203452b59d2 100644 --- a/site/src/components/Preferences/Layout.tsx +++ b/site/src/components/Preferences/Layout.tsx @@ -1,5 +1,7 @@ import Box from "@material-ui/core/Box" import React from "react" +import { Outlet } from "react-router-dom" +import { AuthAndNav } from "../Page" import { TabPanel } from "../TabPanel" const menuItems = [ @@ -9,12 +11,16 @@ const menuItems = [ { label: "Linked Accounts", path: "/preferences/linked-accounts" }, ] -export const Layout: React.FC = ({ children }) => { +export const PreferencesLayout: React.FC = () => { return ( - - - {children} - - + + + + + + + + + ) } diff --git a/site/src/pages/preferences/account.tsx b/site/src/pages/preferences/account.tsx index 014ec43a31d87..90f587e170182 100644 --- a/site/src/pages/preferences/account.tsx +++ b/site/src/pages/preferences/account.tsx @@ -1,17 +1,11 @@ -import Box from "@material-ui/core/Box" import React from "react" -import { Layout } from "../../components/Preferences/Layout" import { Section } from "../../components/Section" export const PreferencesAccountPage: React.FC = () => { return ( - - -
- - +
) } diff --git a/site/src/pages/preferences/linked-accounts.tsx b/site/src/pages/preferences/linked-accounts.tsx index a28a914315515..0c582878ea28e 100644 --- a/site/src/pages/preferences/linked-accounts.tsx +++ b/site/src/pages/preferences/linked-accounts.tsx @@ -1,17 +1,11 @@ -import Box from "@material-ui/core/Box" import React from "react" -import { Layout } from "../../components/Preferences/Layout" import { Section } from "../../components/Section" export const PreferencesLinkedAccountsPage: React.FC = () => { return ( - - -
- - +
) } diff --git a/site/src/pages/preferences/security.tsx b/site/src/pages/preferences/security.tsx index 7754de444c685..1491d7fed7943 100644 --- a/site/src/pages/preferences/security.tsx +++ b/site/src/pages/preferences/security.tsx @@ -1,14 +1,6 @@ -import Box from "@material-ui/core/Box" import React from "react" -import { Layout } from "../../components/Preferences/Layout" import { Section } from "../../components/Section" export const PreferencesSecurityPage: React.FC = () => { - return ( - - -
- - - ) + return
} diff --git a/site/src/pages/preferences/ssh-keys.tsx b/site/src/pages/preferences/ssh-keys.tsx index 925cbd256099b..2335f3572ef0a 100644 --- a/site/src/pages/preferences/ssh-keys.tsx +++ b/site/src/pages/preferences/ssh-keys.tsx @@ -1,17 +1,11 @@ -import Box from "@material-ui/core/Box" import React from "react" -import { Layout } from "../../components/Preferences/Layout" import { Section } from "../../components/Section" export const PreferencesSSHKeysPage: React.FC = () => { return ( - - -
- - +
) } From 20ddc3ff5d124929f394526c3a1d57f2b9ee4501 Mon Sep 17 00:00:00 2001 From: Bruno Date: Thu, 7 Apr 2022 13:13:04 +0000 Subject: [PATCH 4/8] refactor: use Language object --- site/src/components/Preferences/Layout.tsx | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/site/src/components/Preferences/Layout.tsx b/site/src/components/Preferences/Layout.tsx index 30203452b59d2..fad3dbefe60fb 100644 --- a/site/src/components/Preferences/Layout.tsx +++ b/site/src/components/Preferences/Layout.tsx @@ -4,11 +4,19 @@ import { Outlet } from "react-router-dom" import { AuthAndNav } from "../Page" import { TabPanel } from "../TabPanel" +export const Language = { + accountLabel: "Account", + securityLabel: "Security", + sshKeysLabel: "SSH Keys", + linkedAccountsLabel: "Linked Accounts", + preferencesLabel: "Preferences", +} + const menuItems = [ - { label: "Account", path: "/preferences/account" }, - { label: "Security", path: "/preferences/security" }, - { label: "SSH Keys", path: "/preferences/ssh-keys" }, - { label: "Linked Accounts", path: "/preferences/linked-accounts" }, + { label: Language.accountLabel, path: "/preferences/account" }, + { label: Language.securityLabel, path: "/preferences/security" }, + { label: Language.sshKeysLabel, path: "/preferences/ssh-keys" }, + { label: Language.linkedAccountsLabel, path: "/preferences/linked-accounts" }, ] export const PreferencesLayout: React.FC = () => { @@ -16,7 +24,7 @@ export const PreferencesLayout: React.FC = () => { - + From b95af0423dbf60d506390616b52056e44bfb49d9 Mon Sep 17 00:00:00 2001 From: Bruno Date: Thu, 7 Apr 2022 16:04:45 +0000 Subject: [PATCH 5/8] refactor: use Language object --- site/src/pages/preferences/account.tsx | 12 ++++++------ site/src/pages/preferences/index.tsx | 15 --------------- site/src/pages/preferences/linked-accounts.tsx | 13 +++++++------ site/src/pages/preferences/security.tsx | 7 ++++++- site/src/pages/preferences/ssh-keys.tsx | 13 +++++++------ 5 files changed, 26 insertions(+), 34 deletions(-) delete mode 100644 site/src/pages/preferences/index.tsx diff --git a/site/src/pages/preferences/account.tsx b/site/src/pages/preferences/account.tsx index 90f587e170182..20cd380c5adc9 100644 --- a/site/src/pages/preferences/account.tsx +++ b/site/src/pages/preferences/account.tsx @@ -1,11 +1,11 @@ import React from "react" import { Section } from "../../components/Section" +const Language = { + title: "Account", + description: "Update your display name, email, profile picture, and dotfiles preferences.", +} + export const PreferencesAccountPage: React.FC = () => { - return ( -
- ) + return
} diff --git a/site/src/pages/preferences/index.tsx b/site/src/pages/preferences/index.tsx deleted file mode 100644 index 931784b94c152..0000000000000 --- a/site/src/pages/preferences/index.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import Box from "@material-ui/core/Box" -import Paper from "@material-ui/core/Paper" -import React from "react" -import { Header } from "../../components/Header" -import { Footer } from "../../components/Page" - -export const PreferencesPage: React.FC = () => { - return ( - -
- Preferences here! -