diff --git a/package-lock.json b/package-lock.json index 8a2370e4f1..5946ea87ef 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11595,9 +11595,9 @@ "integrity": "sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==" }, "node_modules/iconoir-react": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/iconoir-react/-/iconoir-react-7.11.0.tgz", - "integrity": "sha512-uvTKtnHYwbbTsmQ6HCcliYd50WK0GbjP497RwdISxKzfS01x4cK1Mn/F2mT/t2roSaJQ0I+KnHxMcyvmNMXWsQ==", + "version": "7.11.1", + "resolved": "https://registry.npmjs.org/iconoir-react/-/iconoir-react-7.11.1.tgz", + "integrity": "sha512-uUdoKZ5SvvleMWf+mJWbAxLt5WaEcvBAU3YmO5Ho+JA5JLxBKntT0KNXpJqQArq7b5DxiN5xobIVoDBIPAvA/w==", "license": "MIT", "funding": { "type": "opencollective", diff --git a/src/app/Layout.tsx b/src/app/Layout.tsx index fa58df8c80..e89f78caa3 100644 --- a/src/app/Layout.tsx +++ b/src/app/Layout.tsx @@ -1,6 +1,6 @@ import { useEffect, useState } from 'react'; -import { Box, Toolbar, useMediaQuery, useTheme } from '@mui/material'; +import { Box, useMediaQuery, useTheme } from '@mui/material'; import { useShallow } from 'zustand/react/shallow'; @@ -8,7 +8,7 @@ import { ReflexContainer, ReflexElement, ReflexSplitter } from 'react-reflex'; import { Outlet } from 'react-router'; import { useLocalStorage } from 'react-use'; -import { Toast } from 'src/components/AgentSkills/Toast'; +import { AgentSkillsToast } from 'src/components/AgentSkills/Toast'; import Navigation from 'src/components/navigation/Navigation'; import ErrorBoundryWrapper from 'src/components/shared/ErrorBoundryWrapper'; import PageContainer from 'src/components/shared/PageContainer'; @@ -75,38 +75,44 @@ function AppLayout() { }; return ( - - - - - - - - + + `grid-template-columns ${t.transitions.duration.shortest}ms`, + }} + > + + + + + {/* Top strip the removed top bar used to occupy. Padding the whole + content column (not just PageContainer) keeps the docs side panel + top-aligned with the page content, and lines the breadcrumb bar up + with the first sidebar nav item below the logo header. */} + - + - - + diff --git a/src/components/AgentSkills/HeaderPill.tsx b/src/components/AgentSkills/HeaderPill.tsx index b15bf6e35c..fec0ad1a40 100644 --- a/src/components/AgentSkills/HeaderPill.tsx +++ b/src/components/AgentSkills/HeaderPill.tsx @@ -1,21 +1,17 @@ import { Box, Link, Paper, Tooltip, Typography, useTheme } from '@mui/material'; -import { usePostHog } from '@posthog/react'; import { NavArrowRight } from 'iconoir-react'; import { useIntl } from 'react-intl'; import { AGENT_SKILLS_URL, - BG_GRADIENT, - GRADIENT, LINK_COLOR, SECONDARY_TEXT_COLOR, SHIMMER_STYLES, - useAgentSkillsStore, } from 'src/components/AgentSkills/shared'; import { SparkleIcon } from 'src/components/AgentSkills/SparkleIcon'; -function TooltipContent({ onClick }: { onClick: () => void }) { +function TooltipContent() { const theme = useTheme(); const mode = theme.palette.mode; const intl = useIntl(); @@ -23,7 +19,6 @@ function TooltipContent({ onClick }: { onClick: () => void }) { return ( void }) { {intl.formatMessage({ id: 'agentSkills.cta', })} - + ); } -export function HeaderPill() { - const theme = useTheme(); - const mode = theme.palette.mode; - const intl = useIntl(); - const postHog = usePostHog(); - const toastDismissed = useAgentSkillsStore((s) => s.toastDismissed); +interface HeaderPillProps { + isOpen?: boolean; +} - if (!toastDismissed) { - return null; - } +export function HeaderPill({ isOpen = true }: HeaderPillProps) { + const intl = useIntl(); return ( { - postHog.capture('AgentSkills:Click', { - source: 'popover', - }); - window.open( - AGENT_SKILLS_URL, - '_blank', - 'noopener,noreferrer' - ); - }} - /> - } - placement="bottom-end" + title={} + placement={isOpen ? 'bottom-start' : 'right'} enterDelay={200} - leaveDelay={150} + leaveDelay={100} slotProps={{ tooltip: { sx: { @@ -131,51 +109,36 @@ export function HeaderPill() { target="_blank" rel="noopener noreferrer" underline="none" - onClick={() => - postHog.capture('AgentSkills:Click', { - source: 'pill', - }) - } sx={{ - 'display': 'inline-flex', + 'display': 'flex', + 'width': '100%', 'alignItems': 'center', + 'justifyContent': 'flex-start', 'gap': 1, - 'height': 36, - 'px': '14px', - 'pl': '10px', + 'py': '6px', + 'px': '10px', 'borderRadius': '999px', - 'background': BG_GRADIENT[mode], - 'border': '1px solid rgba(46,100,235,0.22)', 'fontSize': 13, 'fontWeight': 600, - 'transition': 'transform 200ms ease', + 'cursor': 'pointer', + 'transition': + 'background 180ms ease, transform 180ms ease, box-shadow 180ms ease', '&:hover': { background: 'linear-gradient(135deg, rgba(46,100,235,0.14) 0%, rgba(54,197,176,0.16) 100%)', - borderColor: 'rgba(46,100,235,0.42)', boxShadow: '0 6px 16px -6px rgba(46,100,235,0.35)', transform: 'translateY(-1px)', }, }} > - - - + /> s.toastDismissed); - const dismissToast = useAgentSkillsStore((s) => s.dismissToast); + const [dismissed, setDismissed] = useLocalStorage( + LocalStorageKeys.AGENT_SKILLS_TOAST_DISMISSED, + false + ); - // If the docs panel is open just hide the toast. That way it cannot cover up - // the cookie consent banner in the docs. - if (toastDismissed || docsPanelOpen) { + // Hide the toast while the docs panel is open so it cannot cover the + // cookie-consent banner that renders inside the docs. + if (dismissed || docsPanelOpen) { return null; } const handleClick = () => { - postHog.capture('AgentSkills:Click', { source: 'toast' }); window.open(AGENT_SKILLS_URL, '_blank', 'noopener,noreferrer'); }; @@ -71,13 +69,13 @@ export function Toast({ docsPanelOpen }: ToastProps) { 'display': 'block', 'animation': `${toastIn} 750ms cubic-bezier(.2,.9,.25,1) 1s both`, 'transition': 'transform 200ms ease, box-shadow 200ms ease', - 'zIndex': toastIndex, + 'zIndex': 1200, '&:hover': { transform: 'translateY(-2px)', boxShadow: '0 1px 2px rgba(15, 23, 42, 0.04), 0 18px 40px -8px rgba(15, 23, 42, 0.22), 0 36px 80px -12px rgba(46, 100, 235, 0.28)', }, - '&:hover .cta-arrow': { + '&:hover .est-toast-cta-arrow': { transform: 'translateX(3px)', }, }} @@ -113,7 +111,7 @@ export function Toast({ docsPanelOpen }: ToastProps) { }} > @@ -127,21 +125,22 @@ export function Toast({ docsPanelOpen }: ToastProps) { mb: 0.5, }} > - + > + {intl.formatMessage({ id: 'agentSkills.badge' })} + {intl.formatMessage({ id: 'agentSkills.cta' })} @@ -211,10 +207,7 @@ export function Toast({ docsPanelOpen }: ToastProps) { size="small" onClick={(e) => { e.stopPropagation(); - postHog.capture('AgentSkills:Click', { - source: 'dismiss', - }); - dismissToast(); + setDismissed(true); }} aria-label={intl.formatMessage({ id: 'agentSkills.dismiss', @@ -227,7 +220,7 @@ export function Toast({ docsPanelOpen }: ToastProps) { '&:hover': { color: '#475569', background: 'none' }, }} > - + diff --git a/src/components/AgentSkills/shared.ts b/src/components/AgentSkills/shared.ts index e1b0495ada..c78e2e6fee 100644 --- a/src/components/AgentSkills/shared.ts +++ b/src/components/AgentSkills/shared.ts @@ -1,33 +1,5 @@ -import type { PersistOptions } from 'zustand/middleware'; - import { keyframes } from '@mui/material'; -import { create } from 'zustand'; -import { persist } from 'zustand/middleware'; - -import { LocalStorageKeys } from 'src/utils/localStorage-utils'; - -interface AgentSkillsState { - toastDismissed: boolean; - dismissToast: () => void; -} - -// v0 - {"state":{"toastDismissed":false},"version":0} -const persistOptions: PersistOptions = { - name: LocalStorageKeys.AGENT_SKILLS_TOAST_DISMISSED, - version: 0, -}; - -export const useAgentSkillsStore = create()( - persist( - (set) => ({ - toastDismissed: false, - dismissToast: () => set({ toastDismissed: true }), - }), - persistOptions - ) -); - export const AGENT_SKILLS_URL = 'https://docs.estuary.dev/guides/agent-skills/'; export const GRADIENT = { diff --git a/src/components/graphics/CompanyLogo.tsx b/src/components/graphics/CompanyLogo.tsx index 0be8ed03a3..2645d90f94 100644 --- a/src/components/graphics/CompanyLogo.tsx +++ b/src/components/graphics/CompanyLogo.tsx @@ -12,8 +12,8 @@ function CompanyLogo() { return ( {intl.formatMessage({ ); diff --git a/src/components/graphics/CompanyMark.tsx b/src/components/graphics/CompanyMark.tsx new file mode 100644 index 0000000000..eeace76cea --- /dev/null +++ b/src/components/graphics/CompanyMark.tsx @@ -0,0 +1,22 @@ +import { useTheme } from '@mui/material'; + +import { useIntl } from 'react-intl'; + +import darkMark from 'src/images/pictorial-marks/pictorial-mark__multi-blue.png'; +import lightMark from 'src/images/pictorial-marks/pictorial-mark__white.png'; + +function CompanyMark() { + const intl = useIntl(); + const theme = useTheme(); + + return ( + {intl.formatMessage({ + ); +} + +export default CompanyMark; diff --git a/src/components/menus/HelpMenu.tsx b/src/components/menus/HelpMenu.tsx index c1855ce0a8..eff64c1f6e 100644 --- a/src/components/menus/HelpMenu.tsx +++ b/src/components/menus/HelpMenu.tsx @@ -1,18 +1,31 @@ -import { HelpCircle } from 'iconoir-react'; +import { Menu } from '@mui/material'; + import { FormattedMessage, useIntl } from 'react-intl'; -import IconMenu from 'src/components/menus/IconMenu'; import ExternalLinkMenuItem from 'src/components/shared/ExternalLinkMenuItem'; -function HelpMenu() { +interface HelpMenuProps { + anchorEl: HTMLElement | null; + onClose: () => void; +} + +export function HelpMenu({ anchorEl, onClose }: HelpMenuProps) { const intl = useIntl(); return ( - } - identifier="help-menu" - tooltip={intl.formatMessage({ id: 'helpMenu.tooltip' })} + - + ); } - -export default HelpMenu; diff --git a/src/components/navigation/ListItemLink.tsx b/src/components/navigation/ListItemLink.tsx index c55533c5db..ac872306a1 100644 --- a/src/components/navigation/ListItemLink.tsx +++ b/src/components/navigation/ListItemLink.tsx @@ -1,6 +1,7 @@ -import type { ReactElement } from 'react'; +import type { MouseEvent, ReactNode } from 'react'; import { + Badge, ListItemButton, ListItemIcon, ListItemText, @@ -11,41 +12,48 @@ import { useIntl } from 'react-intl'; import { Link, useMatch, useResolvedPath } from 'react-router-dom'; interface Props { - icon: ReactElement; + icon: ReactNode; title: string; - link: string; + link?: string; + onClick?: (event: MouseEvent) => void; + isOpen?: boolean; + badgeContent?: number; + tooltipDelay?: number; } -export const ListItemLink = ({ icon, title, link }: Props) => { - const resolved = useResolvedPath(link); - const selected = Boolean( - useMatch({ - path: resolved.pathname, - end: false, // `end: false` matches nested routes e.g. `/admin/billing` - }) - ); +export const ListItemLink = ({ + icon, + title, + link, + onClick, + isOpen, + badgeContent, + tooltipDelay, +}: Props) => { + // Hooks must run unconditionally; for action items (no `link`) the resolved + // match is ignored because `selected` is gated on `link` being present. + const resolved = useResolvedPath(link ?? ''); + const match = useMatch({ path: resolved.pathname, end: false }); + const selected = Boolean(link) && Boolean(match); return (
  • - + - theme.palette.text.primary, - }} - > - {icon} - + {icon ? ( + + {icon} + + ) : null} diff --git a/src/components/navigation/Navigation.tsx b/src/components/navigation/Navigation.tsx index 82ef0714bd..945f931f47 100644 --- a/src/components/navigation/Navigation.tsx +++ b/src/components/navigation/Navigation.tsx @@ -1,31 +1,47 @@ -//TODO (UI / UX) - These icons are not final +import React from 'react'; + import { Box, + Divider, List, ListItemButton, ListItemIcon, ListItemText, + Menu, + MenuItem, Stack, - Toolbar, - Tooltip, + Typography, useTheme, } from '@mui/material'; import MuiDrawer, { drawerClasses } from '@mui/material/Drawer'; +import { useShallow } from 'zustand/react/shallow'; + import { CloudDownload, CloudUpload, DatabaseScript, FastArrowLeft, + HalfMoon, + HelpCircle, HomeSimple, + LogOut, + MoreHoriz, Settings, + SunLight, } from 'iconoir-react'; -import { useIntl } from 'react-intl'; +import { FormattedMessage, useIntl } from 'react-intl'; import { authenticatedRoutes } from 'src/app/routes'; +import { HeaderPill } from 'src/components/AgentSkills/HeaderPill'; +import CompanyLogo from 'src/components/graphics/CompanyLogo'; +import CompanyMark from 'src/components/graphics/CompanyMark'; +import { HelpMenu } from 'src/components/menus/HelpMenu'; import ListItemLink from 'src/components/navigation/ListItemLink'; -import ModeSwitch from 'src/components/navigation/ModeSwitch'; -import { paperBackground } from 'src/context/Theme'; +import UserAvatar from 'src/components/shared/UserAvatar'; +import { supabaseClient } from 'src/context/GlobalProviders'; +import { useColorMode } from 'src/context/Theme'; +import { useUserStore } from 'src/context/User/useUserContextStore'; interface NavigationProps { open: boolean; @@ -36,6 +52,18 @@ interface NavigationProps { const Navigation = ({ open, width, onNavigationToggle }: NavigationProps) => { const intl = useIntl(); const theme = useTheme(); + const colorMode = useColorMode(); + + const userDetails = useUserStore(useShallow((state) => state.userDetails)); + + const [menuAnchor, setMenuAnchor] = React.useState( + null + ); + const menuOpen = Boolean(menuAnchor); + + const [helpAnchor, setHelpAnchor] = React.useState( + null + ); const openNavigation = () => { onNavigationToggle(true); @@ -55,109 +83,218 @@ const Navigation = ({ open, width, onNavigationToggle }: NavigationProps) => { sx={{ [`& .${drawerClasses.paper}`]: { boxSizing: 'border-box', + position: 'static', + height: '100%', transition: (paperTheme) => `${paperTheme.transitions.duration.shortest}ms`, width, - border: 0, - background: paperBackground[theme.palette.mode], }, transition: (drawerTheme) => `${drawerTheme.transitions.duration.shortest}ms`, width, }} > - - - - - } - title={authenticatedRoutes.home.title} - link={authenticatedRoutes.home.path} - /> - } - title={authenticatedRoutes.captures.title} - link={authenticatedRoutes.captures.path} - /> - } - title={authenticatedRoutes.collections.title} - link={authenticatedRoutes.collections.path} - /> - } - title={authenticatedRoutes.materializations.title} - link={authenticatedRoutes.materializations.path} - /> - } - title={authenticatedRoutes.admin.title} - link={authenticatedRoutes.admin.path} - /> - + + {open ? : } - - + } + title={authenticatedRoutes.home.title} + link={authenticatedRoutes.home.path} + isOpen={open} + /> + } + title={authenticatedRoutes.captures.title} + link={authenticatedRoutes.captures.path} + isOpen={open} + /> + } + title={authenticatedRoutes.collections.title} + link={authenticatedRoutes.collections.path} + isOpen={open} + /> + } + title={authenticatedRoutes.materializations.title} + link={authenticatedRoutes.materializations.path} + isOpen={open} + /> + } + title={authenticatedRoutes.admin.title} + link={authenticatedRoutes.admin.path} + isOpen={open} + /> + + + + - - - - + + + } + title="helpMenu.tooltip" + onClick={(e) => setHelpAnchor(e.currentTarget)} + isOpen={open} + /> + setHelpAnchor(null)} + /> + + - - - + /> + } + title="navigation.collapse" + onClick={openNavigation} + isOpen={open} + /> + {userDetails ? ( + <> + setMenuAnchor(e.currentTarget)} + sx={{ mx: 1, my: 0.25 }} + > + + - - + + setMenuAnchor(null)} + onClick={() => setMenuAnchor(null)} + anchorOrigin={{ + horizontal: 'left', + vertical: 'top', + }} + transformOrigin={{ + horizontal: 'left', + vertical: 'bottom', + }} + > + + + + {userDetails.userName ?? + userDetails.email} + + + {userDetails.email} + + + + + + + colorMode.toggleColorMode()} + > + + {theme.palette.mode === 'dark' ? ( + + ) : ( + + )} + + + + + + { + void supabaseClient.auth.signOut(); + }} + > + + + + + + + + ) : null} diff --git a/src/components/navigation/PageTitle.tsx b/src/components/navigation/PageTitle.tsx index ac16c3db5f..a41d158e4b 100644 --- a/src/components/navigation/PageTitle.tsx +++ b/src/components/navigation/PageTitle.tsx @@ -25,7 +25,7 @@ function PageTitle() { alignItems: 'baseline', }} > - + diff --git a/src/components/navigation/TopBar.tsx b/src/components/navigation/TopBar.tsx deleted file mode 100644 index 5d35e1a122..0000000000 --- a/src/components/navigation/TopBar.tsx +++ /dev/null @@ -1,59 +0,0 @@ -import { Divider, Stack, Toolbar } from '@mui/material'; -import MuiAppBar from '@mui/material/AppBar'; -import { useTheme } from '@mui/material/styles'; - -import { HeaderPill } from 'src/components/AgentSkills/HeaderPill'; -import CompanyLogo from 'src/components/graphics/CompanyLogo'; -import HelpMenu from 'src/components/menus/HelpMenu'; -import UserMenu from 'src/components/menus/UserMenu'; -import PageTitle from 'src/components/navigation/PageTitle'; -import SidePanelDocsOpenButton from 'src/components/sidePanelDocs/OpenButton'; -import { UpdateAlert } from 'src/components/UpdateAlert'; -import { zIndexIncrement } from 'src/context/Theme'; - -const Topbar = () => { - const theme = useTheme(); - - return ( - - - } - > - - - - - - - - - - - - - - - - - - - ); -}; - -export default Topbar; diff --git a/src/components/shared/ChipList/Wrapper.tsx b/src/components/shared/ChipList/Wrapper.tsx index 59a973f9e4..236c35c16b 100644 --- a/src/components/shared/ChipList/Wrapper.tsx +++ b/src/components/shared/ChipList/Wrapper.tsx @@ -8,7 +8,6 @@ import { Box, styled, Tooltip } from '@mui/material'; import { useIntl } from 'react-intl'; import LinkWrapper from 'src/components/shared/LinkWrapper'; -import { underlineTextSx } from 'src/context/Theme'; import { OutlinedChip } from 'src/styledComponents/chips/OutlinedChip'; import { stripPathing } from 'src/utils/misc-utils'; @@ -60,7 +59,6 @@ function ChipWrapper({ if (val.link) { chipSX = { ...chipSX, - ...underlineTextSx, color: (theme) => theme.palette.primary.main, }; } diff --git a/src/components/shared/PageContainer.tsx b/src/components/shared/PageContainer.tsx index a331571946..cad256ce1e 100644 --- a/src/components/shared/PageContainer.tsx +++ b/src/components/shared/PageContainer.tsx @@ -3,22 +3,32 @@ import type { Notification } from 'src/stores/NotificationStore'; import { useEffect, useMemo, useState } from 'react'; -import { Container, Paper, Snackbar, useTheme } from '@mui/material'; +import { Box, Paper, Snackbar, Typography, useTheme } from '@mui/material'; + +import { useIntl } from 'react-intl'; -import Topbar from 'src/components/navigation/TopBar'; import AlertBox from 'src/components/shared/AlertBox'; +import SidePanelDocsOpenButton from 'src/components/sidePanelDocs/OpenButton'; import { paperBackground } from 'src/context/Theme'; import useNotificationStore, { notificationStoreSelectors, } from 'src/stores/NotificationStore'; +import { useTopBarStore } from 'src/stores/TopBar/Store'; interface Props { children: ReactNode | ReactNode[]; hideBackground?: boolean; + navigationOpen?: boolean; } -function PageContainer({ children, hideBackground }: Props) { +function PageContainer({ + children, + hideBackground, + navigationOpen = true, +}: Props) { + const intl = useIntl(); const theme = useTheme(); + const header = useTopBarStore((state) => state.header); const notification = useNotificationStore( notificationStoreSelectors.notification @@ -77,10 +87,12 @@ function PageContainer({ children, hideBackground }: Props) { }, [notification]); return ( - {notification && alertBody ? ( @@ -112,20 +124,54 @@ function PageContainer({ children, hideBackground }: Props) { ) : null} - + {header ? ( + + + {intl.formatMessage({ id: header })} + + + + + + + ) : null} + `padding ${t.transitions.duration.shortest}ms`, + py: 2, + flex: 1, + minHeight: 0, + overflow: 'auto', + overscrollBehavior: 'none', width: '100%', + mb: 1, boxShadow: boxShadowMixin, - borderRadius: 3, + borderRadius: header ? '0 0 16px 16px' : 8, background: backgroundMixin, }} > {children} - + ); } diff --git a/src/components/tables/Collections/index.tsx b/src/components/tables/Collections/index.tsx index 3ccfed366f..e810fdff6a 100644 --- a/src/components/tables/Collections/index.tsx +++ b/src/components/tables/Collections/index.tsx @@ -1,7 +1,5 @@ import { useMemo } from 'react'; -import { Box } from '@mui/material'; - import { getLiveSpecs_collections } from 'src/api/liveSpecsExt'; import CollectionExportButton from 'src/components/tables/Collections/Export'; import Rows from 'src/components/tables/Collections/Rows'; @@ -42,58 +40,47 @@ function CollectionsTable() { }, [columnToSort, pagination, searchQuery, sortDirection]); return ( - - - + + ( + + )} + rowsPerPage={rowsPerPage} + setRowsPerPage={setRowsPerPage} + pagination={pagination} + setPagination={setPagination} + searchQuery={searchQuery} + setSearchQuery={setSearchQuery} + sortDirection={sortDirection} + setSortDirection={setSortDirection} + columnToSort={columnToSort} + setColumnToSort={setColumnToSort} + header={ENTITY_SETTINGS.collection.table.headerIntlKey} + filterLabel={ENTITY_SETTINGS.collection.table.filterIntlKey} + showEntityStatus selectableTableStoreName={selectableTableStoreName} - > - ( - - )} - rowsPerPage={rowsPerPage} - setRowsPerPage={setRowsPerPage} - pagination={pagination} - setPagination={setPagination} - searchQuery={searchQuery} - setSearchQuery={setSearchQuery} - sortDirection={sortDirection} - setSortDirection={setSortDirection} - columnToSort={columnToSort} - setColumnToSort={setColumnToSort} - header={ENTITY_SETTINGS.collection.table.headerIntlKey} - filterLabel={ - ENTITY_SETTINGS.collection.table.filterIntlKey - } - showEntityStatus - selectableTableStoreName={selectableTableStoreName} - showToolbar - toolbar={ - - } - /> - - - + showToolbar + toolbar={ + + } + /> + + ); } diff --git a/src/components/tables/EntityTable/index.tsx b/src/components/tables/EntityTable/index.tsx index cf04214274..d244efea66 100644 --- a/src/components/tables/EntityTable/index.tsx +++ b/src/components/tables/EntityTable/index.tsx @@ -245,13 +245,7 @@ function EntityTable({ {hideHeaderAndFooter || (!showToolbar && hideFilter && !ExportComponent) ? null : ( - - - {showToolbar ? ( - - ) : null} - </Stack> - + <Box> <Toolbar disableGutters sx={{ @@ -297,7 +291,7 @@ function EntityTable({ </Box> )} - <Box sx={hideHeaderAndFooter ? {} : { mb: 2, mx: 2 }}> + <Box sx={hideHeaderAndFooter ? {} : { mb: 2 }}> <TableContainer component={Box}> <Table size="small" diff --git a/src/context/Theme.tsx b/src/context/Theme.tsx index 62174da645..07f1cc692c 100644 --- a/src/context/Theme.tsx +++ b/src/context/Theme.tsx @@ -94,7 +94,7 @@ declare module '@mui/material/Typography' { // Navigation Width export enum NavWidths { MOBILE = 0, - RAIL = 48, + RAIL = 54, FULL = 200, } @@ -702,20 +702,11 @@ export const jsonFormsPadding: SxProps<Theme> = { }, }; -export const underlineTextSx: SxProps<Theme> = { - 'textDecoration': 'underline', - '&:hover, &:focus': { - textDecoration: 'underline', - }, -}; - // Used to make buttons look like a normal(ish) link export const linkButtonSx: SxProps<Theme> = { - ...underlineTextSx, px: 1, py: 0, fontWeight: 500, - zIndex: headerLinkIndex, }; // Light is an RGB translation of #E1E9F4; Light is an RGB translation of #F7F9FC. @@ -990,6 +981,11 @@ const themeSettings = createTheme({ }, }, }, + MuiLink: { + defaultProps: { + underline: 'hover', + }, + }, MuiButton: { defaultProps: { variant: 'contained', @@ -998,11 +994,19 @@ const themeSettings = createTheme({ styleOverrides: { root: { fontSize: 14, - borderRadius: 4, + borderRadius: 8, textTransform: 'none', }, }, }, + MuiIconButton: { + styleOverrides: { + root: { + fontSize: 14, + borderRadius: 8, + }, + }, + }, MuiCheckbox: { defaultProps: { icon: <Square style={{ fontSize: 14 }} />, @@ -1148,17 +1152,53 @@ const ThemeProvider = ({ children }: BaseComponentProps) => { }, }, MuiAppBar: { + defaultProps: { + position: 'static' as const, + elevation: 0, + }, styleOverrides: { root: { - background: - palette.mode === 'dark' - ? sample_grey[800] - : 'white', + background: palette.background?.default, boxShadow: 'none', color: palette.text?.primary, }, }, }, + MuiDrawer: { + styleOverrides: { + paper: { + background: palette.background?.default, + border: 0, + }, + }, + }, + MuiListItemButton: { + styleOverrides: { + root: { + gap: 8, + whiteSpace: 'nowrap', + padding: '6px 10px', + borderRadius: 8, + }, + }, + }, + MuiListItemIcon: { + styleOverrides: { + root: { + minWidth: 'auto', + color: 'inherit', + }, + }, + }, + MuiListItemText: { + styleOverrides: { + primary: { + fontSize: 13, + overflow: 'hidden', + textOverflow: 'ellipsis', + }, + }, + }, MuiDialog: { styleOverrides: { paper: { diff --git a/src/lang/en-US/Captures.ts b/src/lang/en-US/Captures.ts index 20e35f423e..61402d7e77 100644 --- a/src/lang/en-US/Captures.ts +++ b/src/lang/en-US/Captures.ts @@ -4,7 +4,7 @@ import { RouteTitles } from 'src/lang/en-US/RouteTitles'; export const Captures: Record<string, string> = { 'captureTable.header': `Captures`, - 'capturesTable.title': `Your Captures`, + 'capturesTable.title': `Captures`, 'capturesTable.cta.new': `New Capture`, 'capturesTable.filterLabel': `Filter captures`, 'capturesTable.delete.removeCollectionsOption': `Delete all collections associated with this capture. Collections used by active tasks will be skipped.`, diff --git a/src/lang/en-US/Navigation.ts b/src/lang/en-US/Navigation.ts index 304f759a81..177e937ea7 100644 --- a/src/lang/en-US/Navigation.ts +++ b/src/lang/en-US/Navigation.ts @@ -2,15 +2,15 @@ import { CommonMessages } from 'src/lang/en-US/CommonMessages'; import { CTAs } from 'src/lang/en-US/CTAs'; export const Navigation: Record<string, string> = { - 'navigation.toggle.ariaLabel': `Toggle Navigation`, - 'navigation.expand': `Expand Navigation`, - 'navigation.collapse': `Collapse Navigation`, + 'navigation.toggle.ariaLabel': `Toggle Sidebar`, + 'navigation.expand': `Expand`, + 'navigation.collapse': `Collapse`, // Header 'mainMenu.tooltip': `Open Main Menu`, 'helpMenu.ariaLabel': `Open Help Menu`, - 'helpMenu.tooltip': `Helpful Links`, + 'helpMenu.tooltip': `Help`, 'helpMenu.docs': `Docs`, 'helpMenu.docs.link': `https://docs.estuary.dev/`, 'helpMenu.slack': `Estuary Slack`, @@ -27,7 +27,8 @@ export const Navigation: Record<string, string> = { 'accountMenu.tooltip': `My Account`, 'accountMenu.emailVerified': `verified`, - 'modeSwitch.label': `Toggle Color Mode`, + 'modeSwitch.darkLabel': `Dark Mode`, + 'modeSwitch.lightLabel': `Light Mode`, 'updateAlert.cta': `Update`, 'updateAlert.title': `Dashboard Updated`, diff --git a/src/lang/en-US/RouteTitles.ts b/src/lang/en-US/RouteTitles.ts index 64c4469df1..17711a8011 100644 --- a/src/lang/en-US/RouteTitles.ts +++ b/src/lang/en-US/RouteTitles.ts @@ -1,19 +1,19 @@ import { CommonMessages } from 'src/lang/en-US/CommonMessages'; export const RouteTitles: Record<string, string> = { - 'routeTitle.home': `Welcome`, + 'routeTitle.home': `Overview`, 'routeTitle.dashboard': `Dashboard`, 'routeTitle.admin': `Admin`, 'routeTitle.admin.accessGrants': `Access Grants`, 'routeTitle.admin.api': `CLI - API`, 'routeTitle.admin.billing': `Billing`, 'routeTitle.admin.settings': `Settings`, - 'routeTitle.captureCreate': `Create Capture`, + 'routeTitle.captureCreate': `New Capture`, 'routeTitle.captureDetails': `Capture Details`, 'routeTitle.captureEdit': `Edit Capture`, 'routeTitle.captures': `${CommonMessages['terms.sources']}`, 'routeTitle.collections': `Collections`, - 'routeTitle.collectionCreate': `Create Transformation`, + 'routeTitle.collectionCreate': `New Transformation`, 'routeTitle.collectionDetails': `Collection Details`, 'routeTitle.dataPlaneAuthReq': `Data Plane Authorization Checkpoint`, 'routeTitle.directives': `Directives`, @@ -23,7 +23,7 @@ export const RouteTitles: Record<string, string> = { 'routeTitle.loginLoading': `Checking Credentials`, 'routeTitle.noGrants': `Signed Up`, 'routeTitle.legal': `Legal`, - 'routeTitle.materializationCreate': `Create Materialization`, + 'routeTitle.materializationCreate': `New Materialization`, 'routeTitle.materializationDetails': `Materialization Details`, 'routeTitle.materializationEdit': `Edit Materialization`, 'routeTitle.materializations': `${CommonMessages['terms.destinations']}`, diff --git a/src/utils/workflow-utils.ts b/src/utils/workflow-utils.ts index 859d2c5f2e..c3434e9f34 100644 --- a/src/utils/workflow-utils.ts +++ b/src/utils/workflow-utils.ts @@ -43,7 +43,7 @@ export const getBackfillCounter = (binding: any): number => { }; export const getSourceOrTarget = (binding: any) => { - return Object.hasOwn(binding ?? {}, 'source') + return Object.hasOwn(binding ?? {}, '3source') ? binding.source : Object.hasOwn(binding ?? {}, 'target') ? binding.target