From 8f2394c2566488ed5685b55a4adfaa5d28e5b9b1 Mon Sep 17 00:00:00 2001 From: Bruno Quaresma Date: Thu, 9 Oct 2025 10:09:37 -0300 Subject: [PATCH] chore: replace MUI tables (#20201) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I tried to break this work into smaller pieces, but since there are a lot of dependent components, I decided to handle it in one larger chunk and rely on Storybook to catch any bugs. That said, let me know if you’d prefer a different approach! --- biome.jsonc | 1 + site/e2e/api.ts | 12 +- site/e2e/tests/deployment/general.spec.ts | 2 +- site/e2e/tests/deployment/security.spec.ts | 2 +- site/src/components/Table/Table.tsx | 35 ++- .../TableEmpty/TableEmpty.stories.tsx | 16 +- site/src/components/TableEmpty/TableEmpty.tsx | 3 +- .../TableLoader/TableLoader.stories.tsx | 16 +- .../components/TableLoader/TableLoader.tsx | 7 +- .../components/Timeline/TimelineDateRow.tsx | 3 +- .../src/components/Timeline/TimelineEntry.tsx | 2 +- .../AuditLogRow/AuditLogRow.stories.tsx | 24 +- .../AuditPage/AuditLogRow/AuditLogRow.tsx | 2 +- site/src/pages/AuditPage/AuditPageView.tsx | 108 +++---- .../ConnectionLogPageView.tsx | 103 +++--- .../ConnectionLogRow.stories.tsx | 13 +- .../ConnectionLogRow/ConnectionLogRow.tsx | 2 +- .../AnnouncementBannerItem.tsx | 3 +- .../AnnouncementBannerSettings.tsx | 95 +++--- .../ExternalAuthSettingsPageView.tsx | 78 ++--- .../EditOAuth2AppPageView.tsx | 72 ++--- .../OAuth2AppsSettingsPageView.tsx | 58 ++-- .../DeploymentSettingsPage/OptionsTable.tsx | 137 ++++---- .../CreateEditRolePageView.tsx | 107 +++---- .../TemplateVersionsPage/VersionRow.tsx | 2 +- .../TemplateVersionsPage/VersionsTable.tsx | 70 ++--- .../TemplatePermissionsPageView.tsx | 296 +++++++++--------- .../ExternalAuthPage/ExternalAuthPageView.tsx | 83 +++-- .../OAuth2ProviderPageView.tsx | 58 ++-- .../TokensPage/TokensPageView.tsx | 161 +++++----- .../WorkspaceProxyPage/WorkspaceProxyRow.tsx | 3 +- .../WorkspaceProxyPage/WorkspaceProxyView.tsx | 76 +++-- site/src/theme/mui.ts | 68 ---- 33 files changed, 796 insertions(+), 922 deletions(-) diff --git a/biome.jsonc b/biome.jsonc index d1258a77d6..9d369e6dab 100644 --- a/biome.jsonc +++ b/biome.jsonc @@ -53,6 +53,7 @@ "@mui/material/Box": "Use a
instead.", "@mui/material/Button": "Use a components/Button/Button instead.", "@mui/material/styles": "Import from @emotion/react instead.", + "@mui/material/Table*": "Import from components/Table/Table instead.", "lodash": "Use lodash/ instead." } } diff --git a/site/e2e/api.ts b/site/e2e/api.ts index 342b08cb28..0a1765d464 100644 --- a/site/e2e/api.ts +++ b/site/e2e/api.ts @@ -213,7 +213,7 @@ export async function verifyConfigFlagBoolean( const value = opt.value ? "Enabled" : "Disabled"; const configOption = page.locator( - `div.options-table .option-${flag} .${type}`, + `table.options-table .option-${flag} .${type}`, ); await expect(configOption).toHaveText(value); } @@ -225,7 +225,7 @@ export async function verifyConfigFlagNumber( ) { const opt = findConfigOption(config, flag); const configOption = page.locator( - `div.options-table .option-${flag} .option-value-number`, + `table.options-table .option-${flag} .option-value-number`, ); await expect(configOption).toHaveText(String(opt.value)); } @@ -238,7 +238,7 @@ export async function verifyConfigFlagString( const opt = findConfigOption(config, flag); const configOption = page.locator( - `div.options-table .option-${flag} .option-value-string`, + `table.options-table .option-${flag} .option-value-string`, ); // biome-ignore lint/suspicious/noExplicitAny: opt.value is any await expect(configOption).toHaveText(opt.value as any); @@ -251,7 +251,7 @@ export async function verifyConfigFlagArray( ) { const opt = findConfigOption(config, flag); const configOption = page.locator( - `div.options-table .option-${flag} .option-array`, + `table.options-table .option-${flag} .option-array`, ); // Verify array of options with simple dots @@ -268,7 +268,7 @@ export async function verifyConfigFlagEntries( ) { const opt = findConfigOption(config, flag); const configOption = page.locator( - `div.options-table .option-${flag} .option-array`, + `table.options-table .option-${flag} .option-array`, ); // Verify array of options with green marks. @@ -296,7 +296,7 @@ export async function verifyConfigFlagDuration( ); } const configOption = page.locator( - `div.options-table .option-${flag} .option-value-string`, + `table.options-table .option-${flag} .option-value-string`, ); await expect(configOption).toHaveText(humanDuration(opt.value / 1e6)); } diff --git a/site/e2e/tests/deployment/general.spec.ts b/site/e2e/tests/deployment/general.spec.ts index 40c8342e89..a1dca0a820 100644 --- a/site/e2e/tests/deployment/general.spec.ts +++ b/site/e2e/tests/deployment/general.spec.ts @@ -19,7 +19,7 @@ test("experiments", async ({ page }) => { await page.goto("/deployment/overview", { waitUntil: "domcontentloaded" }); const experimentsLocator = page.locator( - "div.options-table tr.option-experiments ul.option-array", + "table.options-table tr.option-experiments ul.option-array", ); await expect(experimentsLocator).toBeVisible(); diff --git a/site/e2e/tests/deployment/security.spec.ts b/site/e2e/tests/deployment/security.spec.ts index 2d8bb00326..3f5e9a9b5c 100644 --- a/site/e2e/tests/deployment/security.spec.ts +++ b/site/e2e/tests/deployment/security.spec.ts @@ -47,7 +47,7 @@ async function verifyStrictTransportSecurity( } const configOption = page.locator( - `div.options-table .option-${flag} .option-value-string`, + `table.options-table .option-${flag} .option-value-string`, ); await expect(configOption).toHaveText("Disabled"); } diff --git a/site/src/components/Table/Table.tsx b/site/src/components/Table/Table.tsx index 03f13be1ee..99a8ba8187 100644 --- a/site/src/components/Table/Table.tsx +++ b/site/src/components/Table/Table.tsx @@ -47,7 +47,7 @@ export const TableBody = React.forwardRef< /> )); -const _TableFooter = React.forwardRef< +export const TableFooter = React.forwardRef< HTMLTableSectionElement, React.HTMLAttributes >(({ className, ...props }, ref) => ( @@ -82,22 +82,23 @@ const tableRowVariants = cva( }, ); -export const TableRow = React.forwardRef< - HTMLTableRowElement, - React.HTMLAttributes & - VariantProps ->(({ className, hover, ...props }, ref) => ( - -)); +export type TableRowProps = React.HTMLAttributes & + VariantProps; + +export const TableRow = React.forwardRef( + ({ className, hover, ...props }, ref) => ( + + ), +); export const TableHead = React.forwardRef< HTMLTableCellElement, diff --git a/site/src/components/TableEmpty/TableEmpty.stories.tsx b/site/src/components/TableEmpty/TableEmpty.stories.tsx index 3165ed5fe6..c189e3bfec 100644 --- a/site/src/components/TableEmpty/TableEmpty.stories.tsx +++ b/site/src/components/TableEmpty/TableEmpty.stories.tsx @@ -1,8 +1,6 @@ -import Table from "@mui/material/Table"; -import TableBody from "@mui/material/TableBody"; -import TableContainer from "@mui/material/TableContainer"; import type { Meta, StoryObj } from "@storybook/react-vite"; import { CodeExample } from "components/CodeExample/CodeExample"; +import { Table, TableBody } from "components/Table/Table"; import { TableEmpty } from "./TableEmpty"; const meta: Meta = { @@ -13,13 +11,11 @@ const meta: Meta = { }, decorators: [ (Story) => ( - - - - - -
-
+ + + + +
), ], }; diff --git a/site/src/components/TableEmpty/TableEmpty.tsx b/site/src/components/TableEmpty/TableEmpty.tsx index 4b1b72c5be..1dd2d08dbd 100644 --- a/site/src/components/TableEmpty/TableEmpty.tsx +++ b/site/src/components/TableEmpty/TableEmpty.tsx @@ -1,9 +1,8 @@ -import TableCell from "@mui/material/TableCell"; -import TableRow from "@mui/material/TableRow"; import { EmptyState, type EmptyStateProps, } from "components/EmptyState/EmptyState"; +import { TableCell, TableRow } from "components/Table/Table"; import type { FC } from "react"; type TableEmptyProps = EmptyStateProps; diff --git a/site/src/components/TableLoader/TableLoader.stories.tsx b/site/src/components/TableLoader/TableLoader.stories.tsx index 645b4e343c..c15b4eba48 100644 --- a/site/src/components/TableLoader/TableLoader.stories.tsx +++ b/site/src/components/TableLoader/TableLoader.stories.tsx @@ -1,7 +1,5 @@ -import Table from "@mui/material/Table"; -import TableBody from "@mui/material/TableBody"; -import TableContainer from "@mui/material/TableContainer"; import type { Meta, StoryObj } from "@storybook/react-vite"; +import { Table, TableBody } from "components/Table/Table"; import { TableLoader } from "./TableLoader"; const meta: Meta = { @@ -9,13 +7,11 @@ const meta: Meta = { component: TableLoader, decorators: [ (Story) => ( - - - - - -
-
+ + + + +
), ], }; diff --git a/site/src/components/TableLoader/TableLoader.tsx b/site/src/components/TableLoader/TableLoader.tsx index bdbb7efcd7..8b063b22a6 100644 --- a/site/src/components/TableLoader/TableLoader.tsx +++ b/site/src/components/TableLoader/TableLoader.tsx @@ -1,5 +1,8 @@ -import TableCell from "@mui/material/TableCell"; -import TableRow, { type TableRowProps } from "@mui/material/TableRow"; +import { + TableCell, + TableRow, + type TableRowProps, +} from "components/Table/Table"; import { cloneElement, type FC, isValidElement, type ReactNode } from "react"; import { Loader } from "../Loader/Loader"; diff --git a/site/src/components/Timeline/TimelineDateRow.tsx b/site/src/components/Timeline/TimelineDateRow.tsx index 3425b06abe..4f38f7b34a 100644 --- a/site/src/components/Timeline/TimelineDateRow.tsx +++ b/site/src/components/Timeline/TimelineDateRow.tsx @@ -1,6 +1,5 @@ import { css, useTheme } from "@emotion/react"; -import TableCell from "@mui/material/TableCell"; -import TableRow from "@mui/material/TableRow"; +import { TableCell, TableRow } from "components/Table/Table"; import type { FC } from "react"; import { createDisplayDate } from "./utils"; diff --git a/site/src/components/Timeline/TimelineEntry.tsx b/site/src/components/Timeline/TimelineEntry.tsx index 727d5933c2..2a9c157032 100644 --- a/site/src/components/Timeline/TimelineEntry.tsx +++ b/site/src/components/Timeline/TimelineEntry.tsx @@ -1,4 +1,4 @@ -import TableRow, { type TableRowProps } from "@mui/material/TableRow"; +import { TableRow, type TableRowProps } from "components/Table/Table"; import { forwardRef } from "react"; import { cn } from "utils/cn"; diff --git a/site/src/pages/AuditPage/AuditLogRow/AuditLogRow.stories.tsx b/site/src/pages/AuditPage/AuditLogRow/AuditLogRow.stories.tsx index 03ccfcf38d..7bbf0a06d8 100644 --- a/site/src/pages/AuditPage/AuditLogRow/AuditLogRow.stories.tsx +++ b/site/src/pages/AuditPage/AuditLogRow/AuditLogRow.stories.tsx @@ -8,13 +8,8 @@ import { MockAuditLogWithWorkspaceBuild, MockUserOwner, } from "testHelpers/entities"; -import Table from "@mui/material/Table"; -import TableBody from "@mui/material/TableBody"; -import TableCell from "@mui/material/TableCell"; -import TableContainer from "@mui/material/TableContainer"; -import TableHead from "@mui/material/TableHead"; -import TableRow from "@mui/material/TableRow"; import type { Meta, StoryObj } from "@storybook/react-vite"; +import { Table, TableBody } from "components/Table/Table"; import { AuditLogRow } from "./AuditLogRow"; const meta: Meta = { @@ -22,18 +17,11 @@ const meta: Meta = { component: AuditLogRow, decorators: [ (Story) => ( - - - - - Logs - - - - - -
-
+ + + + +
), ], }; diff --git a/site/src/pages/AuditPage/AuditLogRow/AuditLogRow.tsx b/site/src/pages/AuditPage/AuditLogRow/AuditLogRow.tsx index 9661fbab59..a1422e95de 100644 --- a/site/src/pages/AuditPage/AuditLogRow/AuditLogRow.tsx +++ b/site/src/pages/AuditPage/AuditLogRow/AuditLogRow.tsx @@ -1,13 +1,13 @@ import type { CSSObject, Interpolation, Theme } from "@emotion/react"; import Collapse from "@mui/material/Collapse"; import Link from "@mui/material/Link"; -import TableCell from "@mui/material/TableCell"; import Tooltip from "@mui/material/Tooltip"; import type { AuditLog, BuildReason } from "api/typesGenerated"; import { Avatar } from "components/Avatar/Avatar"; import { DropdownArrow } from "components/DropdownArrow/DropdownArrow"; import { Stack } from "components/Stack/Stack"; import { StatusPill } from "components/StatusPill/StatusPill"; +import { TableCell } from "components/Table/Table"; import { TimelineEntry } from "components/Timeline/TimelineEntry"; import { InfoIcon, NetworkIcon } from "lucide-react"; import { type FC, useState } from "react"; diff --git a/site/src/pages/AuditPage/AuditPageView.tsx b/site/src/pages/AuditPage/AuditPageView.tsx index ed19092c0a..080c3a0b2a 100644 --- a/site/src/pages/AuditPage/AuditPageView.tsx +++ b/site/src/pages/AuditPage/AuditPageView.tsx @@ -1,8 +1,3 @@ -import Table from "@mui/material/Table"; -import TableBody from "@mui/material/TableBody"; -import TableCell from "@mui/material/TableCell"; -import TableContainer from "@mui/material/TableContainer"; -import TableRow from "@mui/material/TableRow"; import type { AuditLog } from "api/typesGenerated"; import { ChooseOne, Cond } from "components/Conditionals/ChooseOne"; import { EmptyState } from "components/EmptyState/EmptyState"; @@ -18,6 +13,7 @@ import { } from "components/PaginationWidget/PaginationContainer"; import { Paywall } from "components/Paywall/Paywall"; import { Stack } from "components/Stack/Stack"; +import { Table, TableBody, TableCell, TableRow } from "components/Table/Table"; import { TableLoader } from "components/TableLoader/TableLoader"; import { Timeline } from "components/Timeline/Timeline"; import type { ComponentProps, FC } from "react"; @@ -76,62 +72,60 @@ export const AuditPageView: FC = ({ query={paginationResult} paginationUnitLabel="logs" > - - - - - {/* Error condition should just show an empty table. */} - - - - - - - +
+ + + {/* Error condition should just show an empty table. */} + + + + + + + - - - + + + - - - - - - - - - + + + + + + + + + - - - - - - - - - + + + + + + + + + - - {auditLogs && ( - new Date(log.time)} - row={(log) => ( - - )} - /> - )} - - - -
-
+ + {auditLogs && ( + new Date(log.time)} + row={(log) => ( + + )} + /> + )} + + + + diff --git a/site/src/pages/ConnectionLogPage/ConnectionLogPageView.tsx b/site/src/pages/ConnectionLogPage/ConnectionLogPageView.tsx index 0fcadf085f..b1223c1ee0 100644 --- a/site/src/pages/ConnectionLogPage/ConnectionLogPageView.tsx +++ b/site/src/pages/ConnectionLogPage/ConnectionLogPageView.tsx @@ -1,8 +1,3 @@ -import Table from "@mui/material/Table"; -import TableBody from "@mui/material/TableBody"; -import TableCell from "@mui/material/TableCell"; -import TableContainer from "@mui/material/TableContainer"; -import TableRow from "@mui/material/TableRow"; import type { ConnectionLog } from "api/typesGenerated"; import { ChooseOne, Cond } from "components/Conditionals/ChooseOne"; import { EmptyState } from "components/EmptyState/EmptyState"; @@ -18,6 +13,7 @@ import { } from "components/PaginationWidget/PaginationContainer"; import { Paywall } from "components/Paywall/Paywall"; import { Stack } from "components/Stack/Stack"; +import { Table, TableBody, TableCell, TableRow } from "components/Table/Table"; import { TableLoader } from "components/TableLoader/TableLoader"; import { Timeline } from "components/Timeline/Timeline"; import type { ComponentProps, FC } from "react"; @@ -75,61 +71,56 @@ export const ConnectionLogPageView: FC = ({ query={paginationResult} paginationUnitLabel="logs" > - - - - - {/* Error condition should just show an empty table. */} - - - - - - - +
+ + + {/* Error condition should just show an empty table. */} + + + + + + + - - - + + + - - - - - - - - - + + + + + + + + + - - - - - - - - - + + + + + + + + + - - {connectionLogs && ( - new Date(log.connect_time)} - row={(log) => ( - - )} - /> - )} - - - -
-
+ + {connectionLogs && ( + new Date(log.connect_time)} + row={(log) => ( + + )} + /> + )} + + + + diff --git a/site/src/pages/ConnectionLogPage/ConnectionLogRow/ConnectionLogRow.stories.tsx b/site/src/pages/ConnectionLogPage/ConnectionLogRow/ConnectionLogRow.stories.tsx index 03833917e5..c52f533eb2 100644 --- a/site/src/pages/ConnectionLogPage/ConnectionLogRow/ConnectionLogRow.stories.tsx +++ b/site/src/pages/ConnectionLogPage/ConnectionLogRow/ConnectionLogRow.stories.tsx @@ -3,7 +3,6 @@ import { MockDisconnectedSSHConnectionLog, MockWebConnectionLog, } from "testHelpers/entities"; -import TableContainer from "@mui/material/TableContainer"; import type { Meta, StoryObj } from "@storybook/react-vite"; import { Table, TableBody } from "components/Table/Table"; import { ConnectionLogRow } from "./ConnectionLogRow"; @@ -13,13 +12,11 @@ const meta: Meta = { component: ConnectionLogRow, decorators: [ (Story) => ( - - - - - -
-
+ + + + +
), ], }; diff --git a/site/src/pages/ConnectionLogPage/ConnectionLogRow/ConnectionLogRow.tsx b/site/src/pages/ConnectionLogPage/ConnectionLogRow/ConnectionLogRow.tsx index f66afde786..f9d14432d4 100644 --- a/site/src/pages/ConnectionLogPage/ConnectionLogRow/ConnectionLogRow.tsx +++ b/site/src/pages/ConnectionLogPage/ConnectionLogRow/ConnectionLogRow.tsx @@ -1,11 +1,11 @@ import type { CSSObject, Interpolation, Theme } from "@emotion/react"; import Link from "@mui/material/Link"; -import TableCell from "@mui/material/TableCell"; import Tooltip from "@mui/material/Tooltip"; import type { ConnectionLog } from "api/typesGenerated"; import { Avatar } from "components/Avatar/Avatar"; import { Stack } from "components/Stack/Stack"; import { StatusPill } from "components/StatusPill/StatusPill"; +import { TableCell } from "components/Table/Table"; import { TimelineEntry } from "components/Timeline/TimelineEntry"; import { InfoIcon, NetworkIcon } from "lucide-react"; import type { FC } from "react"; diff --git a/site/src/pages/DeploymentSettingsPage/AppearanceSettingsPage/AnnouncementBannerItem.tsx b/site/src/pages/DeploymentSettingsPage/AppearanceSettingsPage/AnnouncementBannerItem.tsx index 9f72601ea9..2b7b777e6e 100644 --- a/site/src/pages/DeploymentSettingsPage/AppearanceSettingsPage/AnnouncementBannerItem.tsx +++ b/site/src/pages/DeploymentSettingsPage/AppearanceSettingsPage/AnnouncementBannerItem.tsx @@ -1,7 +1,5 @@ import type { Interpolation, Theme } from "@emotion/react"; import Checkbox from "@mui/material/Checkbox"; -import TableCell from "@mui/material/TableCell"; -import TableRow from "@mui/material/TableRow"; import type { BannerConfig } from "api/typesGenerated"; import { Button } from "components/Button/Button"; import { @@ -10,6 +8,7 @@ import { DropdownMenuItem, DropdownMenuTrigger, } from "components/DropdownMenu/DropdownMenu"; +import { TableCell, TableRow } from "components/Table/Table"; import { EllipsisVertical } from "lucide-react"; import type { FC } from "react"; diff --git a/site/src/pages/DeploymentSettingsPage/AppearanceSettingsPage/AnnouncementBannerSettings.tsx b/site/src/pages/DeploymentSettingsPage/AppearanceSettingsPage/AnnouncementBannerSettings.tsx index d262597306..fb9978f84d 100644 --- a/site/src/pages/DeploymentSettingsPage/AppearanceSettingsPage/AnnouncementBannerSettings.tsx +++ b/site/src/pages/DeploymentSettingsPage/AppearanceSettingsPage/AnnouncementBannerSettings.tsx @@ -1,16 +1,18 @@ import { type CSSObject, useTheme } from "@emotion/react"; import Link from "@mui/material/Link"; -import Table from "@mui/material/Table"; -import TableBody from "@mui/material/TableBody"; -import TableCell from "@mui/material/TableCell"; -import TableContainer from "@mui/material/TableContainer"; -import TableHead from "@mui/material/TableHead"; -import TableRow from "@mui/material/TableRow"; import type { BannerConfig } from "api/typesGenerated"; import { Button } from "components/Button/Button"; import { ConfirmDialog } from "components/Dialogs/ConfirmDialog/ConfirmDialog"; import { EmptyState } from "components/EmptyState/EmptyState"; import { Stack } from "components/Stack/Stack"; +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "components/Table/Table"; import { PlusIcon } from "lucide-react"; import { type FC, useState } from "react"; import { AnnouncementBannerDialog } from "./AnnouncementBannerDialog"; @@ -71,7 +73,7 @@ export const AnnouncementBannerSettings: FC< overflow: "hidden", }} > -
+
-
- - - - - Enabled - Message - Color - - - - - {!isEntitled || banners.length < 1 ? ( - - - - ) : ( - banners.map((banner, i) => ( - setEditingBannerId(i)} - onUpdate={async (banner) => { - const newBanners = updateBanner(i, banner); - await onSubmit(newBanners); - }} - onDelete={() => setDeletingBannerId(i)} - /> - )) - )} - -
-
+
+ + + + Enabled + Message + Color + + + + + {!isEntitled || banners.length < 1 ? ( + + + + ) : ( + banners.map((banner, i) => ( + setEditingBannerId(i)} + onUpdate={async (banner) => { + const newBanners = updateBanner(i, banner); + await onSubmit(newBanners); + }} + onDelete={() => setDeletingBannerId(i)} + /> + )) + )} + +
diff --git a/site/src/pages/DeploymentSettingsPage/ExternalAuthSettingsPage/ExternalAuthSettingsPageView.tsx b/site/src/pages/DeploymentSettingsPage/ExternalAuthSettingsPage/ExternalAuthSettingsPageView.tsx index ad61a7c188..1f7d2d59ec 100644 --- a/site/src/pages/DeploymentSettingsPage/ExternalAuthSettingsPage/ExternalAuthSettingsPageView.tsx +++ b/site/src/pages/DeploymentSettingsPage/ExternalAuthSettingsPage/ExternalAuthSettingsPageView.tsx @@ -1,10 +1,4 @@ import { css } from "@emotion/react"; -import Table from "@mui/material/Table"; -import TableBody from "@mui/material/TableBody"; -import TableCell from "@mui/material/TableCell"; -import TableContainer from "@mui/material/TableContainer"; -import TableHead from "@mui/material/TableHead"; -import TableRow from "@mui/material/TableRow"; import type { DeploymentValues, ExternalAuthConfig } from "api/typesGenerated"; import { Alert } from "components/Alert/Alert"; import { PremiumBadge } from "components/Badges/Badges"; @@ -14,6 +8,14 @@ import { SettingsHeaderDocsLink, SettingsHeaderTitle, } from "components/SettingsHeader/SettingsHeader"; +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "components/Table/Table"; import type { FC } from "react"; import { docs } from "utils/docs"; @@ -60,9 +62,8 @@ export const ExternalAuthSettingsPageView: FC<
- - - + > + + + ID + Client ID + Match + + + + {((config.external_auth === null || + config.external_auth?.length === 0) && ( - ID - Client ID - Match + +
+ No providers have been configured! +
+
-
- - {((config.external_auth === null || - config.external_auth?.length === 0) && ( - - -
- No providers have been configured! -
-
-
- )) || - config.external_auth?.map((git: ExternalAuthConfig) => { - const name = git.id || git.type; - return ( - - {name} - {git.client_id} - {git.regex || "Not Set"} - - ); - })} -
-
-
+ )) || + config.external_auth?.map((git: ExternalAuthConfig) => { + const name = git.id || git.type; + return ( + + {name} + {git.client_id} + {git.regex || "Not Set"} + + ); + })} + + ); }; diff --git a/site/src/pages/DeploymentSettingsPage/OAuth2AppsSettingsPage/EditOAuth2AppPageView.tsx b/site/src/pages/DeploymentSettingsPage/OAuth2AppsSettingsPage/EditOAuth2AppPageView.tsx index 8b18d462e7..73149d2a30 100644 --- a/site/src/pages/DeploymentSettingsPage/OAuth2AppsSettingsPage/EditOAuth2AppPageView.tsx +++ b/site/src/pages/DeploymentSettingsPage/OAuth2AppsSettingsPage/EditOAuth2AppPageView.tsx @@ -1,11 +1,5 @@ import { type Interpolation, type Theme, useTheme } from "@emotion/react"; import Divider from "@mui/material/Divider"; -import Table from "@mui/material/Table"; -import TableBody from "@mui/material/TableBody"; -import TableCell from "@mui/material/TableCell"; -import TableContainer from "@mui/material/TableContainer"; -import TableHead from "@mui/material/TableHead"; -import TableRow from "@mui/material/TableRow"; import type * as TypesGen from "api/typesGenerated"; import { Alert } from "components/Alert/Alert"; import { ErrorAlert } from "components/Alert/ErrorAlert"; @@ -22,6 +16,14 @@ import { } from "components/SettingsHeader/SettingsHeader"; import { Spinner } from "components/Spinner/Spinner"; import { Stack } from "components/Stack/Stack"; +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "components/Table/Table"; import { TableLoader } from "components/TableLoader/TableLoader"; import { ChevronLeftIcon, CopyIcon } from "lucide-react"; import { type FC, useState } from "react"; @@ -233,38 +235,36 @@ const OAuth2AppSecretsTable: FC = ({ - - - +
+ + + Secret + Last Used + + + + + {isLoadingSecrets && } + {!isLoadingSecrets && (!secrets || secrets.length === 0) && ( - Secret - Last Used - + +
+ No client secrets have been generated. +
+
- - - {isLoadingSecrets && } - {!isLoadingSecrets && (!secrets || secrets.length === 0) && ( - - -
- No client secrets have been generated. -
-
-
- )} - {!isLoadingSecrets && - secrets?.map((secret) => ( - - ))} -
-
-
+ )} + {!isLoadingSecrets && + secrets?.map((secret) => ( + + ))} + + ); }; diff --git a/site/src/pages/DeploymentSettingsPage/OAuth2AppsSettingsPage/OAuth2AppsSettingsPageView.tsx b/site/src/pages/DeploymentSettingsPage/OAuth2AppsSettingsPage/OAuth2AppsSettingsPageView.tsx index 4b42f94675..da72549e42 100644 --- a/site/src/pages/DeploymentSettingsPage/OAuth2AppsSettingsPage/OAuth2AppsSettingsPageView.tsx +++ b/site/src/pages/DeploymentSettingsPage/OAuth2AppsSettingsPage/OAuth2AppsSettingsPageView.tsx @@ -1,10 +1,4 @@ import { useTheme } from "@emotion/react"; -import Table from "@mui/material/Table"; -import TableBody from "@mui/material/TableBody"; -import TableCell from "@mui/material/TableCell"; -import TableContainer from "@mui/material/TableContainer"; -import TableHead from "@mui/material/TableHead"; -import TableRow from "@mui/material/TableRow"; import type * as TypesGen from "api/typesGenerated"; import { ErrorAlert } from "components/Alert/ErrorAlert"; import { Avatar } from "components/Avatar/Avatar"; @@ -15,6 +9,14 @@ import { SettingsHeaderTitle, } from "components/SettingsHeader/SettingsHeader"; import { Stack } from "components/Stack/Stack"; +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "components/Table/Table"; import { TableLoader } from "components/TableLoader/TableLoader"; import { useClickableTableRow } from "hooks/useClickableTableRow"; import { ChevronRightIcon, PlusIcon } from "lucide-react"; @@ -58,31 +60,29 @@ const OAuth2AppsSettingsPageView: FC = ({ {error && } - - - +
+ + + Name + + + + + {isLoading && } + {apps?.map((app) => ( + + ))} + {apps?.length === 0 && ( - Name - + +
+ No OAuth2 applications have been configured. +
+
- - - {isLoading && } - {apps?.map((app) => ( - - ))} - {apps?.length === 0 && ( - - -
- No OAuth2 applications have been configured. -
-
-
- )} -
-
-
+ )} + + ); }; diff --git a/site/src/pages/DeploymentSettingsPage/OptionsTable.tsx b/site/src/pages/DeploymentSettingsPage/OptionsTable.tsx index ea9fadb4b0..11b5182e56 100644 --- a/site/src/pages/DeploymentSettingsPage/OptionsTable.tsx +++ b/site/src/pages/DeploymentSettingsPage/OptionsTable.tsx @@ -1,11 +1,13 @@ import { css } from "@emotion/react"; -import Table from "@mui/material/Table"; -import TableBody from "@mui/material/TableBody"; -import TableCell from "@mui/material/TableCell"; -import TableContainer from "@mui/material/TableContainer"; -import TableHead from "@mui/material/TableHead"; -import TableRow from "@mui/material/TableRow"; import type { SerpentOption } from "api/typesGenerated"; +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "components/Table/Table"; import type { FC } from "react"; import { OptionConfig, @@ -27,9 +29,9 @@ const OptionsTable: FC = ({ options, additionalValues }) => { } return ( - - = ({ options, additionalValues }) => { padding-left: 32px; } `} - > - - - Option - Value - - - - {Object.values(options).map((option) => { - return ( - - - {option.name} - {option.description} -
- {option.flag && ( - - CLI - --{option.flag} - - )} - {option.flag_shorthand && ( - - CLI- - {option.flag_shorthand} - - )} - {option.env && ( - - ENV - {option.env} - - )} - {option.yaml && ( - - YAML - {option.yaml} - - )} -
-
+ > + + + Option + Value + + + + {Object.values(options).map((option) => { + return ( + + + {option.name} + {option.description} +
+ {option.flag && ( + + CLI + --{option.flag} + + )} + {option.flag_shorthand && ( + + CLI- + {option.flag_shorthand} + + )} + {option.env && ( + + ENV + {option.env} + + )} + {option.yaml && ( + + YAML + {option.yaml} + + )} +
+
- - - {optionValue(option, additionalValues)} - - -
- ); - })} -
-
-
+ + + {optionValue(option, additionalValues)} + + + + ); + })} + + ); }; diff --git a/site/src/pages/OrganizationSettingsPage/CustomRolesPage/CreateEditRolePageView.tsx b/site/src/pages/OrganizationSettingsPage/CustomRolesPage/CreateEditRolePageView.tsx index 93ebabdae4..97a2030071 100644 --- a/site/src/pages/OrganizationSettingsPage/CustomRolesPage/CreateEditRolePageView.tsx +++ b/site/src/pages/OrganizationSettingsPage/CustomRolesPage/CreateEditRolePageView.tsx @@ -1,13 +1,6 @@ import type { Interpolation, Theme } from "@emotion/react"; import Checkbox from "@mui/material/Checkbox"; import FormControlLabel from "@mui/material/FormControlLabel"; -import Table from "@mui/material/Table"; -import TableBody from "@mui/material/TableBody"; -import TableCell from "@mui/material/TableCell"; -import TableContainer from "@mui/material/TableContainer"; -import TableFooter from "@mui/material/TableFooter"; -import TableHead from "@mui/material/TableHead"; -import TableRow from "@mui/material/TableRow"; import TextField from "@mui/material/TextField"; import { isApiValidationError } from "api/errors"; import { RBACResourceActions } from "api/rbacresourcesGenerated"; @@ -29,6 +22,15 @@ import { } from "components/SettingsHeader/SettingsHeader"; import { Spinner } from "components/Spinner/Spinner"; import { Stack } from "components/Stack/Stack"; +import { + Table, + TableBody, + TableCell, + TableFooter, + TableHead, + TableHeader, + TableRow, +} from "components/Table/Table"; import { useFormik } from "formik"; import { EyeIcon, EyeOffIcon } from "lucide-react"; import { type ChangeEvent, type FC, useState } from "react"; @@ -255,55 +257,46 @@ const ActionCheckboxes: FC = ({ }; return ( - - - - - Permission - - - - - - - {Object.entries(resourceActions).map(([resourceKey, value]) => { - return ( - a.resource_type === resourceKey, - )} - resourceKey={resourceKey} - value={value} - form={form} - handleActionCheckChange={handleActionCheckChange} - handleResourceCheckChange={handleResourceCheckChange} - /> - ); - })} - - - - - - - - -
-
+ + + + Permission + + + + + + + {Object.entries(resourceActions).map(([resourceKey, value]) => { + return ( + a.resource_type === resourceKey, + )} + resourceKey={resourceKey} + value={value} + form={form} + handleActionCheckChange={handleActionCheckChange} + handleResourceCheckChange={handleResourceCheckChange} + /> + ); + })} + + + + + + + + +
); }; @@ -333,7 +326,7 @@ const PermissionCheckboxGroup: FC = ({ }) => { return ( - +
  • = ({ )?.id; return ( - - - - {versions ? ( - new Date(version.created_at)} - row={(version) => ( - - )} - /> - ) : ( - - )} +
    + + {versions ? ( + new Date(version.created_at)} + row={(version) => ( + + )} + /> + ) : ( + + )} - {versions && versions.length === 0 && ( - - -
    - -
    -
    -
    - )} -
    -
    -
    + {versions && versions.length === 0 && ( + + +
    + +
    +
    +
    + )} + + ); }; diff --git a/site/src/pages/TemplateSettingsPage/TemplatePermissionsPage/TemplatePermissionsPageView.tsx b/site/src/pages/TemplateSettingsPage/TemplatePermissionsPage/TemplatePermissionsPageView.tsx index f9460f88af..07047bbc3d 100644 --- a/site/src/pages/TemplateSettingsPage/TemplatePermissionsPage/TemplatePermissionsPageView.tsx +++ b/site/src/pages/TemplateSettingsPage/TemplatePermissionsPage/TemplatePermissionsPageView.tsx @@ -1,12 +1,6 @@ import type { Interpolation, Theme } from "@emotion/react"; import MenuItem from "@mui/material/MenuItem"; import Select, { type SelectProps } from "@mui/material/Select"; -import Table from "@mui/material/Table"; -import TableBody from "@mui/material/TableBody"; -import TableCell from "@mui/material/TableCell"; -import TableContainer from "@mui/material/TableContainer"; -import TableHead from "@mui/material/TableHead"; -import TableRow from "@mui/material/TableRow"; import type { Group, ReducedUser, @@ -29,6 +23,14 @@ import { EmptyState } from "components/EmptyState/EmptyState"; import { PageHeader, PageHeaderTitle } from "components/PageHeader/PageHeader"; import { Spinner } from "components/Spinner/Spinner"; import { Stack } from "components/Stack/Stack"; +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "components/Table/Table"; import { TableLoader } from "components/TableLoader/TableLoader"; import { EllipsisVertical, UserPlusIcon } from "lucide-react"; import { type FC, useState } from "react"; @@ -227,153 +229,151 @@ export const TemplatePermissionsPageView: FC< } /> )} - - - - - Member - Role - - - - - - - - - - - - + + + Member + Role + + + + + + + + + + + + + + + + + {templateACL?.group.map((group) => ( + + + + } + title={group.display_name || group.name} + subtitle={getGroupSubtitle(group)} /> + + + + { + onUpdateGroup( + group, + event.target.value as TemplateRole, + ); + }} + /> + + +
    {group.role}
    +
    +
    +
    + + + {canUpdatePermissions && ( + + + + + + onRemoveGroup(group)} + > + Remove + + + + )} +
    -
    - - {templateACL?.group.map((group) => ( - - - - } - title={group.display_name || group.name} - subtitle={getGroupSubtitle(group)} - /> - - - - - { - onUpdateGroup( - group, - event.target.value as TemplateRole, - ); - }} - /> - - -
    {group.role}
    -
    -
    -
    + ))} - - {canUpdatePermissions && ( - - - - - - onRemoveGroup(group)} - > - Remove - - - - )} - -
    - ))} + {templateACL?.users.map((user) => ( + + + + + + + + { + onUpdateUser( + user, + event.target.value as TemplateRole, + ); + }} + /> + + +
    {user.role}
    +
    +
    +
    - {templateACL?.users.map((user) => ( - - - - - - - - { - onUpdateUser( - user, - event.target.value as TemplateRole, - ); - }} - /> - - -
    {user.role}
    -
    -
    -
    - - - {canUpdatePermissions && ( - - - - - - onRemoveUser(user)} - > - Remove - - - - )} - -
    - ))} -
    -
    -
    -
    -
    + + {canUpdatePermissions && ( + + + + + + onRemoveUser(user)} + > + Remove + + + + )} + + + ))} + + + + ); diff --git a/site/src/pages/UserSettingsPage/ExternalAuthPage/ExternalAuthPageView.tsx b/site/src/pages/UserSettingsPage/ExternalAuthPage/ExternalAuthPageView.tsx index 01f468a232..14252c625d 100644 --- a/site/src/pages/UserSettingsPage/ExternalAuthPage/ExternalAuthPageView.tsx +++ b/site/src/pages/UserSettingsPage/ExternalAuthPage/ExternalAuthPageView.tsx @@ -1,12 +1,5 @@ import { useTheme } from "@emotion/react"; -import Table from "@mui/material/Table"; -import TableBody from "@mui/material/TableBody"; -import TableCell from "@mui/material/TableCell"; -import TableContainer from "@mui/material/TableContainer"; -import TableHead from "@mui/material/TableHead"; -import TableRow from "@mui/material/TableRow"; import Tooltip from "@mui/material/Tooltip"; -import visuallyHidden from "@mui/utils/visuallyHidden"; import { externalAuthProvider } from "api/queries/externalAuth"; import type { ExternalAuthLink, @@ -25,6 +18,14 @@ import { import { Loader } from "components/Loader/Loader"; import { Spinner } from "components/Spinner/Spinner"; import { Stack } from "components/Stack/Stack"; +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "components/Table/Table"; import { TableEmpty } from "components/TableEmpty/TableEmpty"; import type { ExternalAuthPollingState } from "hooks/useExternalAuth"; import { EllipsisVertical, RefreshCcwIcon } from "lucide-react"; @@ -58,41 +59,39 @@ export const ExternalAuthPageView: FC = ({ } return ( - - - - - Application - - - Link to connect - - - - - - - {auths.providers === null || auths.providers?.length === 0 ? ( - - ) : ( - auths.providers?.map((app) => ( - l.provider_id === app.id)} - onUnlinkExternalAuth={() => { - onUnlinkExternalAuth(app); - }} - onValidateExternalAuth={() => { - onValidateExternalAuth(app.id); - }} - /> - )) - )} - -
    -
    + + + + Application + + + Link to connect + + + + + + + {auths.providers === null || auths.providers?.length === 0 ? ( + + ) : ( + auths.providers?.map((app) => ( + l.provider_id === app.id)} + onUnlinkExternalAuth={() => { + onUnlinkExternalAuth(app); + }} + onValidateExternalAuth={() => { + onValidateExternalAuth(app.id); + }} + /> + )) + )} + +
    ); }; diff --git a/site/src/pages/UserSettingsPage/OAuth2ProviderPage/OAuth2ProviderPageView.tsx b/site/src/pages/UserSettingsPage/OAuth2ProviderPage/OAuth2ProviderPageView.tsx index beb1ca09b8..7d2ee3a884 100644 --- a/site/src/pages/UserSettingsPage/OAuth2ProviderPage/OAuth2ProviderPageView.tsx +++ b/site/src/pages/UserSettingsPage/OAuth2ProviderPage/OAuth2ProviderPageView.tsx @@ -1,14 +1,16 @@ -import Table from "@mui/material/Table"; -import TableBody from "@mui/material/TableBody"; -import TableCell from "@mui/material/TableCell"; -import TableContainer from "@mui/material/TableContainer"; -import TableHead from "@mui/material/TableHead"; -import TableRow from "@mui/material/TableRow"; import type * as TypesGen from "api/typesGenerated"; import { ErrorAlert } from "components/Alert/ErrorAlert"; import { Avatar } from "components/Avatar/Avatar"; import { Button } from "components/Button/Button"; import { Stack } from "components/Stack/Stack"; +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "components/Table/Table"; import { TableLoader } from "components/TableLoader/TableLoader"; import type { FC } from "react"; @@ -29,31 +31,29 @@ const OAuth2ProviderPageView: FC = ({ <> {error && } - - - +
    + + + Name + + + + + {isLoading && } + {apps?.map((app) => ( + + ))} + {apps?.length === 0 && ( - Name - + +
    + No OAuth2 applications have been authorized. +
    +
    - - - {isLoading && } - {apps?.map((app) => ( - - ))} - {apps?.length === 0 && ( - - -
    - No OAuth2 applications have been authorized. -
    -
    -
    - )} -
    -
    -
    + )} + + ); }; diff --git a/site/src/pages/UserSettingsPage/TokensPage/TokensPageView.tsx b/site/src/pages/UserSettingsPage/TokensPage/TokensPageView.tsx index 786a96712e..5174d95886 100644 --- a/site/src/pages/UserSettingsPage/TokensPage/TokensPageView.tsx +++ b/site/src/pages/UserSettingsPage/TokensPage/TokensPageView.tsx @@ -1,15 +1,17 @@ import { useTheme } from "@emotion/react"; import IconButton from "@mui/material/IconButton"; -import Table from "@mui/material/Table"; -import TableBody from "@mui/material/TableBody"; -import TableCell from "@mui/material/TableCell"; -import TableContainer from "@mui/material/TableContainer"; -import TableHead from "@mui/material/TableHead"; -import TableRow from "@mui/material/TableRow"; import type { APIKeyWithOwner } from "api/typesGenerated"; import { ErrorAlert } from "components/Alert/ErrorAlert"; import { ChooseOne, Cond } from "components/Conditionals/ChooseOne"; import { Stack } from "components/Stack/Stack"; +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "components/Table/Table"; import { TableEmpty } from "components/TableEmpty/TableEmpty"; import { TableLoader } from "components/TableLoader/TableLoader"; import dayjs from "dayjs"; @@ -49,84 +51,83 @@ export const TokensPageView: FC = ({ {Boolean(getTokensError) && } {Boolean(deleteTokenError) && } - - - - - ID - Name - Last Used - Expires At - Created At - - - - - - - - - - - - - {tokens?.map((token) => { - return ( - - - - {token.id} - - - - - {token.token_name} - - +
    + + + ID + Name + Last Used + Expires At + Created At + + + + + + + + + + + + + {tokens?.map((token) => { + return ( + + + + {token.id} + + - {lastUsedOrNever(token.last_used)} + + + {token.token_name} + + - - {lastUsedOrNever(token.last_used)} + + + + {dayjs(token.expires_at).fromNow()} + + + + + + {dayjs(token.created_at).fromNow()} + + + + + + { + onDelete(token); + }} + size="medium" + aria-label="Delete token" > - {dayjs(token.expires_at).fromNow()} - - - - - - {dayjs(token.created_at).fromNow()} - - - - - - { - onDelete(token); - }} - size="medium" - aria-label="Delete token" - > - - - - - - ); - })} - - - -
    -
    + + + + + + ); + })} + + + +
    ); }; diff --git a/site/src/pages/UserSettingsPage/WorkspaceProxyPage/WorkspaceProxyRow.tsx b/site/src/pages/UserSettingsPage/WorkspaceProxyPage/WorkspaceProxyRow.tsx index 417a5d731e..17fa32fc84 100644 --- a/site/src/pages/UserSettingsPage/WorkspaceProxyPage/WorkspaceProxyRow.tsx +++ b/site/src/pages/UserSettingsPage/WorkspaceProxyPage/WorkspaceProxyRow.tsx @@ -1,6 +1,4 @@ import { useTheme } from "@emotion/react"; -import TableCell from "@mui/material/TableCell"; -import TableRow from "@mui/material/TableRow"; import type { Region, WorkspaceProxy } from "api/typesGenerated"; import { Avatar } from "components/Avatar/Avatar"; import { AvatarData } from "components/Avatar/AvatarData"; @@ -10,6 +8,7 @@ import { NotReachableBadge, NotRegisteredBadge, } from "components/Badges/Badges"; +import { TableCell, TableRow } from "components/Table/Table"; import type { ProxyLatencyReport } from "contexts/useProxyLatency"; import type { FC, ReactNode } from "react"; import { getLatencyColor } from "utils/latency"; diff --git a/site/src/pages/UserSettingsPage/WorkspaceProxyPage/WorkspaceProxyView.tsx b/site/src/pages/UserSettingsPage/WorkspaceProxyPage/WorkspaceProxyView.tsx index d066d15428..ea903b0444 100644 --- a/site/src/pages/UserSettingsPage/WorkspaceProxyPage/WorkspaceProxyView.tsx +++ b/site/src/pages/UserSettingsPage/WorkspaceProxyPage/WorkspaceProxyView.tsx @@ -1,9 +1,3 @@ -import Table from "@mui/material/Table"; -import TableBody from "@mui/material/TableBody"; -import TableCell from "@mui/material/TableCell"; -import TableContainer from "@mui/material/TableContainer"; -import TableHead from "@mui/material/TableHead"; -import TableRow from "@mui/material/TableRow"; import type { Region } from "api/typesGenerated"; import { ErrorAlert } from "components/Alert/ErrorAlert"; import { ChooseOne, Cond } from "components/Conditionals/ChooseOne"; @@ -13,6 +7,13 @@ import { SettingsHeaderTitle, } from "components/SettingsHeader/SettingsHeader"; import { Stack } from "components/Stack/Stack"; +import { + Table, + TableBody, + TableHead, + TableHeader, + TableRow, +} from "components/Table/Table"; import { TableEmpty } from "components/TableEmpty/TableEmpty"; import { TableLoader } from "components/TableLoader/TableLoader"; import type { ProxyLatencyReport } from "contexts/useProxyLatency"; @@ -51,40 +52,35 @@ export const WorkspaceProxyView: FC = ({ )} {Boolean(selectProxyError) && } - - - - - Proxy - - Status - - - Latency - - - - - - - - - - - - - {proxies?.map((proxy) => ( - - ))} - - - -
    -
    + + + + + Proxy + Status + Latency + + + + + + + + + + + + {proxies?.map((proxy) => ( + + ))} + + + +
    ); }; diff --git a/site/src/theme/mui.ts b/site/src/theme/mui.ts index 4435579a33..f7b5ab1bc5 100644 --- a/site/src/theme/mui.ts +++ b/site/src/theme/mui.ts @@ -6,7 +6,6 @@ import { BODY_FONT_FAMILY, BUTTON_LG_HEIGHT, BUTTON_MD_HEIGHT, - borderRadius, } from "./constants"; import tw from "./tailwindColors"; @@ -59,73 +58,6 @@ export const components = { }), }, }, - MuiTableContainer: { - styleOverrides: { - root: ({ theme }) => ({ - borderRadius, - border: `1px solid ${theme.palette.divider}`, - }), - }, - }, - MuiTable: { - styleOverrides: { - root: ({ theme }) => ({ - borderCollapse: "unset", - border: "none", - boxShadow: `0 0 0 1px ${theme.palette.background.default} inset`, - overflow: "hidden", - - "& td": { - paddingTop: 16, - paddingBottom: 16, - background: "transparent", - }, - - [theme.breakpoints.down("md")]: { - minWidth: 1000, - }, - }), - }, - }, - MuiTableCell: { - styleOverrides: { - head: ({ theme }) => ({ - fontSize: 14, - color: theme.palette.text.secondary, - fontWeight: 500, - background: theme.palette.background.paper, - borderWidth: 2, - }), - root: ({ theme }) => ({ - fontSize: 14, - background: theme.palette.background.paper, - borderBottom: `1px solid ${theme.palette.divider}`, - padding: "12px 8px", - // This targets the first+last td elements, and also the first+last elements - // of a TableCellLink. - "&:not(:only-child):first-of-type, &:not(:only-child):first-of-type > a": - { - paddingLeft: 32, - }, - "&:not(:only-child):last-child, &:not(:only-child):last-child > a": { - paddingRight: 32, - }, - }), - }, - }, - MuiTableRow: { - styleOverrides: { - root: ({ theme }) => ({ - "&:last-child .MuiTableCell-body": { - borderBottom: 0, - }, - - "&.MuiTableRow-hover:hover": { - backgroundColor: theme.palette.background.paper, - }, - }), - }, - }, MuiLink: { defaultProps: { underline: "hover",