From 073ff4ce0ba080f55d671405d10437cc6b120d1e Mon Sep 17 00:00:00 2001 From: Bruno Quaresma Date: Fri, 20 Jan 2023 19:25:13 +0000 Subject: [PATCH] Afeat: dd use template button to teemplate row --- site/src/hooks/useClickable.ts | 2 +- site/src/hooks/useClickableTableRow.ts | 31 +++ .../pages/TemplatesPage/TemplatesPageView.tsx | 218 ++++++++---------- 3 files changed, 131 insertions(+), 120 deletions(-) create mode 100644 site/src/hooks/useClickableTableRow.ts diff --git a/site/src/hooks/useClickable.ts b/site/src/hooks/useClickable.ts index a694a5f6821af..0c761d7106c1c 100644 --- a/site/src/hooks/useClickable.ts +++ b/site/src/hooks/useClickable.ts @@ -1,6 +1,6 @@ import { KeyboardEvent } from "react" -interface UseClickableResult { +export interface UseClickableResult { tabIndex: 0 role: "button" onClick: () => void diff --git a/site/src/hooks/useClickableTableRow.ts b/site/src/hooks/useClickableTableRow.ts new file mode 100644 index 0000000000000..26c62c46f3700 --- /dev/null +++ b/site/src/hooks/useClickableTableRow.ts @@ -0,0 +1,31 @@ +import { makeStyles } from "@material-ui/core/styles" +import { useClickable, UseClickableResult } from "./useClickable" + +interface UseClickableTableRowResult extends UseClickableResult { + className: string + hover: true +} + +export const useClickableTableRow = ( + onClick: () => void, +): UseClickableTableRowResult => { + const styles = useStyles() + const clickable = useClickable(onClick) + + return { + ...clickable, + className: styles.row, + hover: true, + } +} + +const useStyles = makeStyles((theme) => ({ + row: { + cursor: "pointer", + + "&:focus": { + outline: `1px solid ${theme.palette.secondary.dark}`, + outlineOffset: -1, + }, + }, +})) diff --git a/site/src/pages/TemplatesPage/TemplatesPageView.tsx b/site/src/pages/TemplatesPage/TemplatesPageView.tsx index b97f5c777041f..7ca1d6b9485ca 100644 --- a/site/src/pages/TemplatesPage/TemplatesPageView.tsx +++ b/site/src/pages/TemplatesPage/TemplatesPageView.tsx @@ -1,15 +1,13 @@ import Button from "@material-ui/core/Button" import Link from "@material-ui/core/Link" -import { makeStyles, Theme } from "@material-ui/core/styles" +import { makeStyles } from "@material-ui/core/styles" import Table from "@material-ui/core/Table" import TableBody from "@material-ui/core/TableBody" import TableCell from "@material-ui/core/TableCell" import TableContainer from "@material-ui/core/TableContainer" import TableHead from "@material-ui/core/TableHead" import TableRow from "@material-ui/core/TableRow" -import KeyboardArrowRight from "@material-ui/icons/KeyboardArrowRight" import AddIcon from "@material-ui/icons/AddOutlined" -import useTheme from "@material-ui/styles/useTheme" import { AlertBanner } from "components/AlertBanner/AlertBanner" import { ChooseOne, Cond } from "components/Conditionals/ChooseOne" import { Maybe } from "components/Conditionals/Maybe" @@ -28,7 +26,6 @@ import { PageHeaderTitle, } from "../../components/PageHeader/PageHeader" import { Stack } from "../../components/Stack/Stack" -import { TableCellLink } from "../../components/TableCellLink/TableCellLink" import { TableLoader } from "../../components/TableLoader/TableLoader" import { HelpTooltip, @@ -39,6 +36,11 @@ import { } from "../../components/Tooltips/HelpTooltip/HelpTooltip" import { EmptyTemplates } from "./EmptyTemplates" import { TemplatesContext } from "xServices/templates/templatesXService" +import { useClickableTableRow } from "hooks/useClickableTableRow" +import { Template } from "api/typesGenerated" +import { combineClasses } from "util/combineClasses" +import { colors } from "theme/colors" +import ArrowForwardOutlined from "@material-ui/icons/ArrowForwardOutlined" export const Language = { developerCount: (activeCount: number): string => { @@ -54,7 +56,6 @@ export const Language = { templateTooltipText: "With templates you can create a common configuration for your workspaces using Terraform.", templateTooltipLink: "Manage templates", - createdByLabel: "Created by", } const TemplateHelpTooltip: React.FC = () => { @@ -71,6 +72,73 @@ const TemplateHelpTooltip: React.FC = () => { ) } +const TemplateRow: FC<{ template: Template }> = ({ template }) => { + const templatePageLink = `/templates/${template.name}` + const hasIcon = template.icon && template.icon !== "" + const navigate = useNavigate() + const styles = useStyles() + const { className: clickableClassName, ...clickableRow } = + useClickableTableRow(() => { + navigate(templatePageLink) + }) + + return ( + + + 0 + ? template.display_name + : template.name + } + subtitle={template.description} + highlightTitle + avatar={ + hasIcon && ( +
+ +
+ ) + } + /> +
+ + + {Language.developerCount(template.active_user_count)} + + + + {formatTemplateBuildTime(template.build_time_stats.start.P50)} + + + + {createDayString(template.updated_at)} + + + + + +
+ ) +} + export interface TemplatesPageViewProps { context: TemplatesContext } @@ -78,9 +146,6 @@ export interface TemplatesPageViewProps { export const TemplatesPageView: FC< React.PropsWithChildren > = ({ context }) => { - const styles = useStyles() - const navigate = useNavigate() - const theme: Theme = useTheme() const { templates, error, examples, permissions } = context const isLoading = !templates const isEmpty = Boolean(templates && templates.length === 0) @@ -136,11 +201,10 @@ export const TemplatesPageView: FC< - {Language.nameLabel} - {Language.usedByLabel} - {Language.buildTimeLabel} - {Language.lastUpdatedLabel} - {Language.createdByLabel} + {Language.nameLabel} + {Language.usedByLabel} + {Language.buildTimeLabel} + {Language.lastUpdatedLabel} @@ -158,91 +222,9 @@ export const TemplatesPageView: FC< - {templates?.map((template) => { - const templatePageLink = `/templates/${template.name}` - const hasIcon = template.icon && template.icon !== "" - - return ( - { - if (event.key === "Enter") { - navigate(templatePageLink) - } - }} - className={styles.clickableTableRow} - > - - 0 - ? template.display_name - : template.name - } - subtitle={template.description} - highlightTitle - avatar={ - hasIcon && ( -
- -
- ) - } - /> -
- - - - {Language.developerCount( - template.active_user_count, - )} - - - - - - {formatTemplateBuildTime( - template.build_time_stats.start.P50, - )} - - - - - - {createDayString(template.updated_at)} - - - - - - {template.created_by_name} - - - - -
- -
-
-
- ) - })} + {templates?.map((template) => ( + + ))}
@@ -255,27 +237,6 @@ export const TemplatesPageView: FC< } const useStyles = makeStyles((theme) => ({ - clickableTableRow: { - "&:hover td": { - backgroundColor: theme.palette.action.hover, - }, - - "&:focus": { - outline: `1px solid ${theme.palette.secondary.dark}`, - }, - - "& .MuiTableCell-root:last-child": { - paddingRight: theme.spacing(2), - }, - }, - arrowRight: { - color: theme.palette.text.secondary, - width: 20, - height: 20, - }, - arrowCell: { - display: "flex", - }, templateIconWrapper: { // Same size then the avatar component width: 36, @@ -286,4 +247,23 @@ const useStyles = makeStyles((theme) => ({ width: "100%", }, }, + actionCell: { + whiteSpace: "nowrap", + }, + secondary: { + color: theme.palette.text.secondary, + }, + tableRow: { + "&:hover $actionButton": { + color: theme.palette.text.primary, + borderColor: colors.gray[11], + "&:hover": { + borderColor: theme.palette.text.primary, + }, + }, + }, + actionButton: { + color: theme.palette.text.secondary, + transition: "none", + }, }))