From 8426b3c5e7913bc1ba3c1ee35e1517eb4245d424 Mon Sep 17 00:00:00 2001 From: Kira Pilot Date: Mon, 8 Aug 2022 15:32:12 +0000 Subject: [PATCH 1/4] resolves #3356 --- site/src/AppRouter.tsx | 21 ++++++++++++- .../components/NavbarView/NavbarView.test.tsx | 30 +++++++++++++++++++ site/src/components/NavbarView/NavbarView.tsx | 9 ++++++ site/src/pages/AuditPage/AuditPage.tsx | 8 +++++ 4 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 site/src/pages/AuditPage/AuditPage.tsx diff --git a/site/src/AppRouter.tsx b/site/src/AppRouter.tsx index d76dbc687da77..b7b0d0e6b9cf0 100644 --- a/site/src/AppRouter.tsx +++ b/site/src/AppRouter.tsx @@ -1,5 +1,5 @@ import { FC, lazy, Suspense } from "react" -import { Route, Routes } from "react-router-dom" +import { Navigate, Route, Routes } from "react-router-dom" import { AuthAndFrame } from "./components/AuthAndFrame/AuthAndFrame" import { RequireAuth } from "./components/RequireAuth/RequireAuth" import { SettingsLayout } from "./components/SettingsLayout/SettingsLayout" @@ -25,6 +25,7 @@ const WorkspaceAppErrorPage = lazy( const TerminalPage = lazy(() => import("./pages/TerminalPage/TerminalPage")) const WorkspacesPage = lazy(() => import("./pages/WorkspacesPage/WorkspacesPage")) const CreateWorkspacePage = lazy(() => import("./pages/CreateWorkspacePage/CreateWorkspacePage")) +const AuditPage = lazy(() => import("./pages/AuditPage/AuditPage")) export const AppRouter: FC = () => ( }> @@ -109,6 +110,24 @@ export const AppRouter: FC = () => ( /> + {/* REMARK: Route under construction + Eventually, we should gate this page + with permissions and licensing */} + + + ) : ( + + + + ) + } + > + + }> } /> } /> diff --git a/site/src/components/NavbarView/NavbarView.test.tsx b/site/src/components/NavbarView/NavbarView.test.tsx index 60740a8a4426b..c0755dbda196e 100644 --- a/site/src/components/NavbarView/NavbarView.test.tsx +++ b/site/src/components/NavbarView/NavbarView.test.tsx @@ -7,6 +7,19 @@ describe("NavbarView", () => { const noop = () => { return } + + const env = process.env + + // REMARK: copying process.env so we don't mutate that object or encounter conflicts between tests + beforeEach(() => { + process.env = { ...env } + }) + + // REMARK: restoring process.env + afterEach(() => { + process.env = env + }) + it("renders content", async () => { // When render() @@ -48,4 +61,21 @@ describe("NavbarView", () => { const element = await screen.findByText("B") expect(element).toBeDefined() }) + + it("audit nav link has the correct href", async () => { + render() + const auditLink = await screen.findByText(navLanguage.audit) + expect((auditLink as HTMLAnchorElement).href).toContain("/audit") + }) + + it("audit nav link is only visible in development", async () => { + process.env = { + ...env, + NODE_ENV: "production", + } + + render() + const auditLink = screen.queryByText(navLanguage.audit) + expect(auditLink).not.toBeInTheDocument() + }) }) diff --git a/site/src/components/NavbarView/NavbarView.tsx b/site/src/components/NavbarView/NavbarView.tsx index d982b35e3ad29..98dc8dd985e44 100644 --- a/site/src/components/NavbarView/NavbarView.tsx +++ b/site/src/components/NavbarView/NavbarView.tsx @@ -21,6 +21,7 @@ export const Language = { workspaces: "Workspaces", templates: "Templates", users: "Users", + audit: "Audit", } const NavItems: React.FC<{ className?: string; linkClassName?: string }> = ({ className }) => { @@ -47,6 +48,14 @@ const NavItems: React.FC<{ className?: string; linkClassName?: string }> = ({ cl {Language.users} + {/* REMARK: the below link is under-construction */} + {process.env.NODE_ENV !== "production" && ( + + + {Language.audit} + + + )} ) } diff --git a/site/src/pages/AuditPage/AuditPage.tsx b/site/src/pages/AuditPage/AuditPage.tsx new file mode 100644 index 0000000000000..c285ea2176eed --- /dev/null +++ b/site/src/pages/AuditPage/AuditPage.tsx @@ -0,0 +1,8 @@ +import { FC } from "react" + +// REMARK: This page is in-progress and hidden from users +const AuditPage: FC = () => { + return
Audit
+} + +export default AuditPage From 7ee0ab0c027cb27b445440a8e9be041e283b6fad Mon Sep 17 00:00:00 2001 From: Kira Pilot Date: Mon, 8 Aug 2022 19:57:49 +0000 Subject: [PATCH 2/4] scaffolded out new audit page header resolves #3357 --- .../components/CodeExample/CodeExample.tsx | 14 ++++- site/src/components/CopyButton/CopyButton.tsx | 8 ++- site/src/components/Stack/Stack.tsx | 23 ++++---- .../components/Tooltips/AuditHelpTooltip.tsx | 16 +++++ site/src/components/Tooltips/index.ts | 1 + site/src/pages/AuditPage/AuditPage.tsx | 3 +- site/src/pages/AuditPage/AuditPageView.tsx | 59 +++++++++++++++++++ 7 files changed, 108 insertions(+), 16 deletions(-) create mode 100644 site/src/components/Tooltips/AuditHelpTooltip.tsx create mode 100644 site/src/pages/AuditPage/AuditPageView.tsx diff --git a/site/src/components/CodeExample/CodeExample.tsx b/site/src/components/CodeExample/CodeExample.tsx index 95adc25ad4fc3..6736c103a4b09 100644 --- a/site/src/components/CodeExample/CodeExample.tsx +++ b/site/src/components/CodeExample/CodeExample.tsx @@ -8,18 +8,28 @@ export interface CodeExampleProps { code: string className?: string buttonClassName?: string + tooltipTitle?: string } /** * Component to show single-line code examples, with a copy button */ -export const CodeExample: FC = ({ code, className, buttonClassName }) => { +export const CodeExample: FC = ({ + code, + className, + buttonClassName, + tooltipTitle, +}) => { const styles = useStyles() return (
{code} - +
) } diff --git a/site/src/components/CopyButton/CopyButton.tsx b/site/src/components/CopyButton/CopyButton.tsx index 030ca4623a59a..844467258fe15 100644 --- a/site/src/components/CopyButton/CopyButton.tsx +++ b/site/src/components/CopyButton/CopyButton.tsx @@ -11,6 +11,11 @@ interface CopyButtonProps { ctaCopy?: string wrapperClassName?: string buttonClassName?: string + tooltipTitle?: string +} + +const Language = { + tooltipTitle: "Copy to clipboard", } /** @@ -21,6 +26,7 @@ export const CopyButton: React.FC = ({ ctaCopy, wrapperClassName = "", buttonClassName = "", + tooltipTitle = Language.tooltipTitle, }) => { const styles = useStyles() const [isCopied, setIsCopied] = useState(false) @@ -56,7 +62,7 @@ export const CopyButton: React.FC = ({ } return ( - +
+ const useStyles = makeStyles((theme) => ({ stack: { display: "flex", flexDirection: ({ direction }: StyleProps) => direction, - gap: ({ spacing }: StyleProps) => theme.spacing(spacing), + gap: ({ spacing }: StyleProps) => spacing && theme.spacing(spacing), alignItems: ({ alignItems }: StyleProps) => alignItems, + justifyContent: ({ justifyContent }: StyleProps) => justifyContent, [theme.breakpoints.down("sm")]: { width: "100%", @@ -24,21 +29,15 @@ const useStyles = makeStyles((theme) => ({ }, })) -export interface StackProps { - className?: string - direction?: Direction - spacing?: number - alignItems?: CSSProperties["alignItems"] -} - export const Stack: FC = ({ children, className, direction = "column", spacing = 2, alignItems, + justifyContent, }) => { - const styles = useStyles({ spacing, direction, alignItems }) + const styles = useStyles({ spacing, direction, alignItems, justifyContent }) return
{children}
} diff --git a/site/src/components/Tooltips/AuditHelpTooltip.tsx b/site/src/components/Tooltips/AuditHelpTooltip.tsx new file mode 100644 index 0000000000000..fe22cbd4fbd0f --- /dev/null +++ b/site/src/components/Tooltips/AuditHelpTooltip.tsx @@ -0,0 +1,16 @@ +import { FC } from "react" +import { HelpTooltip, HelpTooltipText, HelpTooltipTitle } from "./HelpTooltip" + +const Language = { + title: "What is an audit log?", + body: "An audit log is a record of events and changes made throughout a system.", +} + +export const AuditHelpTooltip: FC = () => { + return ( + + {Language.title} + {Language.body} + + ) +} diff --git a/site/src/components/Tooltips/index.ts b/site/src/components/Tooltips/index.ts index f2813adc68f0c..e5935792f862c 100644 --- a/site/src/components/Tooltips/index.ts +++ b/site/src/components/Tooltips/index.ts @@ -2,3 +2,4 @@ export { AgentHelpTooltip } from "./AgentHelpTooltip" export { OutdatedHelpTooltip } from "./OutdatedHelpTooltip" export { ResourcesHelpTooltip } from "./ResourcesHelpTooltip" export { WorkspaceHelpTooltip } from "./WorkspaceHelpTooltip" +export { AuditHelpTooltip } from "./AuditHelpTooltip" diff --git a/site/src/pages/AuditPage/AuditPage.tsx b/site/src/pages/AuditPage/AuditPage.tsx index c285ea2176eed..1ee1f465b67cf 100644 --- a/site/src/pages/AuditPage/AuditPage.tsx +++ b/site/src/pages/AuditPage/AuditPage.tsx @@ -1,8 +1,9 @@ import { FC } from "react" +import { AuditPageView } from "./AuditPageView" // REMARK: This page is in-progress and hidden from users const AuditPage: FC = () => { - return
Audit
+ return } export default AuditPage diff --git a/site/src/pages/AuditPage/AuditPageView.tsx b/site/src/pages/AuditPage/AuditPageView.tsx new file mode 100644 index 0000000000000..c284717fe2c9c --- /dev/null +++ b/site/src/pages/AuditPage/AuditPageView.tsx @@ -0,0 +1,59 @@ +import { makeStyles } from "@material-ui/core/styles" +import { CodeExample } from "components/CodeExample/CodeExample" +import { Margins } from "components/Margins/Margins" +import { PageHeader, PageHeaderSubtitle, PageHeaderTitle } from "components/PageHeader/PageHeader" +import { Stack } from "components/Stack/Stack" +import { AuditHelpTooltip } from "components/Tooltips" +import { FC } from "react" + +export const Language = { + title: "Audit", + subtitle: "View events in your audit log.", + tooltipTitle: "Copy to clipboard and try the Coder CLI", +} + +export const AuditPageView: FC = () => { + const styles = useStyles() + + return ( + + + + + + {Language.title} + + + + {Language.subtitle} + + + + + ) +} + +const useStyles = makeStyles((theme) => ({ + headingContainer: { + marginTop: theme.spacing(6), + marginBottom: theme.spacing(5), + flexDirection: "row", + alignItems: "center", + + [theme.breakpoints.down("sm")]: { + flexDirection: "column", + alignItems: "start", + }, + }, + headingStyles: { + paddingTop: "0px", + paddingBottom: "0px", + }, + codeExampleStyles: { + height: "fit-content", + }, +})) From 5ee10a4a2a7a6fd212a58a04d2acc040a380cbc4 Mon Sep 17 00:00:00 2001 From: Kira Pilot Date: Mon, 8 Aug 2022 20:52:33 +0000 Subject: [PATCH 3/4] added tests and stories --- site/src/components/CopyButton/CopyButton.tsx | 4 ++- .../components/Tooltips/AuditHelpTooltip.tsx | 2 +- .../Tooltips/HelpTooltip/HelpTooltip.tsx | 5 +++ site/src/pages/AuditPage/AuditPage.test.tsx | 32 +++++++++++++++++++ .../pages/AuditPage/AuditPageView.stories.tsx | 16 ++++++++++ 5 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 site/src/pages/AuditPage/AuditPage.test.tsx create mode 100644 site/src/pages/AuditPage/AuditPageView.stories.tsx diff --git a/site/src/components/CopyButton/CopyButton.tsx b/site/src/components/CopyButton/CopyButton.tsx index 844467258fe15..fee7a09fd8a07 100644 --- a/site/src/components/CopyButton/CopyButton.tsx +++ b/site/src/components/CopyButton/CopyButton.tsx @@ -14,8 +14,9 @@ interface CopyButtonProps { tooltipTitle?: string } -const Language = { +export const Language = { tooltipTitle: "Copy to clipboard", + ariaLabel: "Copy to clipboard", } /** @@ -68,6 +69,7 @@ export const CopyButton: React.FC = ({ className={combineClasses([styles.copyButton, buttonClassName])} onClick={copyToClipboard} size="small" + aria-label={Language.ariaLabel} > {isCopied ? ( diff --git a/site/src/components/Tooltips/AuditHelpTooltip.tsx b/site/src/components/Tooltips/AuditHelpTooltip.tsx index fe22cbd4fbd0f..33305668f2f9f 100644 --- a/site/src/components/Tooltips/AuditHelpTooltip.tsx +++ b/site/src/components/Tooltips/AuditHelpTooltip.tsx @@ -1,7 +1,7 @@ import { FC } from "react" import { HelpTooltip, HelpTooltipText, HelpTooltipTitle } from "./HelpTooltip" -const Language = { +export const Language = { title: "What is an audit log?", body: "An audit log is a record of events and changes made throughout a system.", } diff --git a/site/src/components/Tooltips/HelpTooltip/HelpTooltip.tsx b/site/src/components/Tooltips/HelpTooltip/HelpTooltip.tsx index 7c70d9146743a..3bbfc4dab4558 100644 --- a/site/src/components/Tooltips/HelpTooltip/HelpTooltip.tsx +++ b/site/src/components/Tooltips/HelpTooltip/HelpTooltip.tsx @@ -15,6 +15,10 @@ export interface HelpTooltipProps { size?: Size } +export const Language = { + ariaLabel: "tooltip", +} + const HelpTooltipContext = createContext<{ open: boolean; onClose: () => void } | undefined>( undefined, ) @@ -52,6 +56,7 @@ export const HelpTooltip: React.FC = ({ children, open, size = onMouseEnter={() => { setIsOpen(true) }} + aria-label={Language.ariaLabel} > diff --git a/site/src/pages/AuditPage/AuditPage.test.tsx b/site/src/pages/AuditPage/AuditPage.test.tsx new file mode 100644 index 0000000000000..8c98281207e86 --- /dev/null +++ b/site/src/pages/AuditPage/AuditPage.test.tsx @@ -0,0 +1,32 @@ +import { fireEvent, screen } from "@testing-library/react" +import { Language as CopyButtonLanguage } from "components/CopyButton/CopyButton" +import { Language as AuditTooltipLanguage } from "components/Tooltips/AuditHelpTooltip" +import { Language as TooltipLanguage } from "components/Tooltips/HelpTooltip/HelpTooltip" +import { render } from "testHelpers/renderHelpers" +import AuditPage from "./AuditPage" +import { Language as AuditViewLanguage } from "./AuditPageView" + +describe("AuditPage", () => { + it("renders a page with a title and subtitle", async () => { + // When + render() + + // Then + await screen.findByText(AuditViewLanguage.title) + await screen.findByText(AuditViewLanguage.subtitle) + const tooltipIcon = await screen.findByRole("button", { name: TooltipLanguage.ariaLabel }) + fireEvent.mouseOver(tooltipIcon) + expect(await screen.findByText(AuditTooltipLanguage.title)).toBeInTheDocument() + }) + + it("describes the CLI command", async () => { + // When + render() + + // Then + await screen.findByText("coder audit [organization_ID]") // CLI command; untranslated + const copyIcon = await screen.findByRole("button", { name: CopyButtonLanguage.ariaLabel }) + fireEvent.mouseOver(copyIcon) + expect(await screen.findByText(AuditViewLanguage.tooltipTitle)).toBeInTheDocument() + }) +}) diff --git a/site/src/pages/AuditPage/AuditPageView.stories.tsx b/site/src/pages/AuditPage/AuditPageView.stories.tsx new file mode 100644 index 0000000000000..7ad3725855264 --- /dev/null +++ b/site/src/pages/AuditPage/AuditPageView.stories.tsx @@ -0,0 +1,16 @@ +import { ComponentMeta, Story } from "@storybook/react" +import { AuditPageView } from "./AuditPageView" + +export default { + title: "pages/AuditPageView", + component: AuditPageView, +} as ComponentMeta + +const Template: Story = (args) => + +export const AuditPage = Template.bind({}) + +export const AuditPageSmallViewport = Template.bind({}) +AuditPageSmallViewport.parameters = { + chromatic: { viewports: [600] }, +} From a4506d7fce83fcfea4301fa431af658475728f04 Mon Sep 17 00:00:00 2001 From: Kira Pilot Date: Mon, 8 Aug 2022 21:10:57 +0000 Subject: [PATCH 4/4] run prettier --- site/src/components/Tooltips/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/src/components/Tooltips/index.ts b/site/src/components/Tooltips/index.ts index e5935792f862c..4f7eabac682c7 100644 --- a/site/src/components/Tooltips/index.ts +++ b/site/src/components/Tooltips/index.ts @@ -1,5 +1,5 @@ export { AgentHelpTooltip } from "./AgentHelpTooltip" +export { AuditHelpTooltip } from "./AuditHelpTooltip" export { OutdatedHelpTooltip } from "./OutdatedHelpTooltip" export { ResourcesHelpTooltip } from "./ResourcesHelpTooltip" export { WorkspaceHelpTooltip } from "./WorkspaceHelpTooltip" -export { AuditHelpTooltip } from "./AuditHelpTooltip" pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy