Skip to content

Commit

Permalink
Merge branch 'main' into feature/optimize-column-lineage-query-perf
Browse files Browse the repository at this point in the history
  • Loading branch information
vinhnemo authored May 29, 2024
2 parents d17a469 + 6a5262b commit bc4eacf
Show file tree
Hide file tree
Showing 16 changed files with 265 additions and 177 deletions.
2 changes: 1 addition & 1 deletion web/src/components/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ const App = (): ReactElement => {
<title>{TITLE}</title>
</Helmet>
<CssBaseline />
<Box ml={12}>
<Box ml={'80px'}>
<Sidenav />
<Container maxWidth={'lg'} disableGutters={true}>
<Header />
Expand Down
25 changes: 13 additions & 12 deletions web/src/components/core/icon-button/MqIconButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@

import React, { ReactElement } from 'react'

import { theme } from '../../../helpers/theme'
import { Link as RouterLink } from 'react-router-dom'
import { THEME_EXTRA, theme } from '../../../helpers/theme'
import { lighten } from '@mui/material'
import Box from '@mui/material/Box'
import ButtonBase from '@mui/material/ButtonBase'

Expand All @@ -12,40 +14,39 @@ interface OwnProps {
title: string
children: ReactElement
active: boolean
to: string
}

type IconButtonProps = OwnProps

const MqIconButton: React.FC<IconButtonProps> = ({ id, title, active, children }) => {
const MqIconButton: React.FC<IconButtonProps> = ({ id, title, active, children, to }) => {
return (
<Box
sx={{
color: 'transparent',
transition: theme.transitions.create(['color']),
'&:hover': {
color: theme.palette.primary.main,
color: THEME_EXTRA.typography.subdued,
},
}}
>
<ButtonBase
id={id}
component={RouterLink}
to={to}
disableRipple={true}
sx={Object.assign(
{
width: theme.spacing(8),
height: theme.spacing(8),
borderRadius: theme.spacing(2),
width: theme.spacing(6),
height: theme.spacing(6),
borderRadius: theme.spacing(1),
color: theme.palette.secondary.main,
background: theme.palette.background.default,
transition: theme.transitions.create(['background-color', 'color']),
border: '2px solid transparent',
'&:hover': {
border: `2px dashed ${theme.palette.primary.main}`,
},
},
active
? {
background: theme.palette.primary.main,
background: lighten(theme.palette.background.default, 0.05),
color: theme.palette.common.white,
}
: {}
Expand All @@ -56,10 +57,10 @@ const MqIconButton: React.FC<IconButtonProps> = ({ id, title, active, children }
<Box
display={'flex'}
justifyContent={'center'}
width={theme.spacing(8)}
sx={{
fontFamily: 'Karla',
userSelect: 'none',
fontSize: '.625rem',
}}
>
{title}
Expand Down
32 changes: 2 additions & 30 deletions web/src/components/core/input-base/MqInputBase.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright 2018-2023 contributors to the Marquez project
// SPDX-License-Identifier: Apache-2.0

import { alpha, createTheme } from '@mui/material/styles'
import { createTheme } from '@mui/material/styles'
import { useTheme } from '@emotion/react'
import InputBase, { InputBaseProps } from '@mui/material/InputBase'
import React from 'react'
Expand All @@ -19,23 +19,9 @@ export const MqInputBase: React.FC<MqInputBaseProps> = (props) => {
borderRadius: theme.spacing(4),
position: 'relative',
backgroundColor: 'transparent',
border: `2px solid ${theme.palette.common.white}`,
fontSize: 16,
padding: `${theme.spacing(1)} ${theme.spacing(5)}`,
padding: `${theme.spacing(1)} ${theme.spacing(2)}`,
transition: theme.transitions.create(['border-color', 'box-shadow']),
'&:focus': {
borderColor: theme.palette.primary.main,
boxShadow: `${alpha(theme.palette.primary.main, 0.25)} 0 0 0 3px`,
borderRadius: theme.spacing(4),
},
'&:hover': {
borderColor: theme.palette.primary.main,
boxShadow: `${alpha(theme.palette.primary.main, 0.25)} 0 0 0 3px`,
'& > label': {
color: theme.palette.primary.main,
transition: theme.transitions.create(['color']),
},
},
}}
/>
)
Expand All @@ -51,23 +37,9 @@ export const MqInputNoIcon: React.FC<InputBaseProps> = (props) => {
borderRadius: theme.spacing(4),
position: 'relative',
backgroundColor: 'transparent',
border: `2px solid ${theme.palette.common.white}`,
fontSize: 16,
padding: `${theme.spacing(1)} 0 ${theme.spacing(1)} ${theme.spacing(1)}`,
transition: theme.transitions.create(['border-color', 'box-shadow']),
'&:focus': {
borderColor: theme.palette.primary.main,
boxShadow: `${alpha(theme.palette.primary.main, 0.25)} 0 0 0 3px`,
borderRadius: theme.spacing(4),
},
'&:hover': {
borderColor: theme.palette.primary.main,
boxShadow: `${alpha(theme.palette.primary.main, 0.25)} 0 0 0 3px`,
'& > label': {
color: theme.palette.primary.main,
transition: theme.transitions.create(['color']),
},
},
}}
/>
)
Expand Down
18 changes: 1 addition & 17 deletions web/src/components/header/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,15 @@
// Copyright 2018-2023 contributors to the Marquez project
// SPDX-License-Identifier: Apache-2.0

import { API_DOCS_URL } from '../../globals'
import { AppBar, Toolbar } from '@mui/material'
import { DRAWER_WIDTH } from '../../helpers/theme'
import { Link } from 'react-router-dom'
import { createTheme } from '@mui/material/styles'
import { useTheme } from '@emotion/react'
import Box from '@mui/material/Box'
import MqText from '../core/text/MqText'
import NamespaceSelect from '../namespace-select/NamespaceSelect'
import React, { ReactElement } from 'react'
import Search from '../search/Search'
import marquez_logo from './marquez_logo.svg'

const Header = (): ReactElement => {
const i18next = require('i18next')
const theme = createTheme(useTheme())

return (
Expand All @@ -26,11 +20,10 @@ const Header = (): ReactElement => {
zIndex: theme.zIndex.drawer + 1,
backgroundColor: theme.palette.background.default,
borderBottom: `2px dashed ${theme.palette.secondary.main}`,
padding: `${theme.spacing(2)} 0`,
left: `${DRAWER_WIDTH + 1}px`,
}}
>
<Toolbar>
<Toolbar disableGutters>
<Box
sx={{
display: 'flex',
Expand All @@ -39,17 +32,8 @@ const Header = (): ReactElement => {
width: 'calc(100% - 97px)',
}}
>
<Link to='/'>
<img src={marquez_logo} height={48} alt='Marquez Logo' />
</Link>
<Box display={'flex'} alignItems={'center'}>
<Search />
<NamespaceSelect />
<Box ml={2}>
<MqText link href={API_DOCS_URL}>
{i18next.t('header.docs_link')}
</MqText>
</Box>
</Box>
</Box>
</Toolbar>
Expand Down
2 changes: 1 addition & 1 deletion web/src/components/namespace-select/NamespaceSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ const NamespaceSelect: React.FC<NamespaceSelectProps> = ({
<Box
sx={{
position: 'absolute',
left: '12px',
left: '-4px',
display: 'flex',
alignItems: 'center',
height: '100%',
Expand Down
63 changes: 49 additions & 14 deletions web/src/components/search/Search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,23 @@
// SPDX-License-Identifier: Apache-2.0

import * as Redux from 'redux'
import { Box } from '@mui/material'
import { Box, Chip } from '@mui/material'
import { DRAWER_WIDTH, THEME_EXTRA, theme } from '../../helpers/theme'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { GroupedSearch } from '../../types/api'
import { IState } from '../../store/reducers'
import { MqInputBase } from '../core/input-base/MqInputBase'
import { THEME_EXTRA, theme } from '../../helpers/theme'
import { SearchOutlined } from '@mui/icons-material'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
import { faCog, faDatabase, faSearch, faSort, faTimes } from '@fortawesome/free-solid-svg-icons'
import { faCog, faDatabase, faSort, faTimes } from '@fortawesome/free-solid-svg-icons'
import { fetchSearch, setSelectedNode } from '../../store/actionCreators'
import { parseSearchGroup } from '../../helpers/nodes'
import { useLocation } from 'react-router'
import ClickAwayListener from '@mui/material/ClickAwayListener'
import MqChipGroup from '../core/chip/MqChipGroup'
import MqText from '../core/text/MqText'
import React from 'react'
import React, { useEffect, useRef } from 'react'
import SearchListItem from './SearchListItem'
import SearchPlaceholder from './SearchPlaceholder'
import debounce from '@mui/material/utils/debounce'
Expand Down Expand Up @@ -84,6 +85,23 @@ interface SearchState {

type SearchProps = StateProps & DispatchProps

const useCmdKShortcut = (callback: () => void) => {
useEffect(() => {
const handleKeyDown = (event: KeyboardEvent) => {
if ((event.metaKey || event.ctrlKey) && event.key === 'k') {
event.preventDefault() // Prevent the default browser action
callback()
}
}

window.addEventListener('keydown', handleKeyDown)

return () => {
window.removeEventListener('keydown', handleKeyDown)
}
}, [callback])
}

const Search: React.FC<SearchProps> = (props: SearchProps) => {
const [state, setState] = React.useState<SearchState>({
open: true,
Expand All @@ -97,14 +115,26 @@ const Search: React.FC<SearchProps> = (props: SearchProps) => {
props.fetchSearch(q, filter, sort)
}

const inputRef = useRef<HTMLInputElement>(null)

// focus on cmd + k
useCmdKShortcut(() => {
console.log('focus', inputRef)
if (inputRef.current) {
inputRef.current.focus()
}
})

debounce(fetchSearch, 300)

const location = useLocation()
React.useEffect(() => {
useEffect(() => {
// close search on a route change
setState({ ...state, open: false })
}, [location])

// listen for cmd + k to focus search

const onSearch = (event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
setState({ ...state, search: event.target.value, open: true })
if (event.target.value.length > 0) {
Expand Down Expand Up @@ -137,19 +167,17 @@ const Search: React.FC<SearchProps> = (props: SearchProps) => {
const { isSearching, isSearchingInit } = props

return (
<Box width={538} position={'relative'} px={10} mr={-8} id={'searchContainer'}>
<Box width={`calc(100vw - ${DRAWER_WIDTH}px)`} position={'relative'} id={'searchContainer'}>
<Box
sx={{
zIndex: theme.zIndex.appBar + 3,
position: 'absolute',
left: theme.spacing(12),
left: theme.spacing(4),
display: 'flex',
alignItems: 'center',
height: '100%',
}}
>
<FontAwesomeIcon icon={faSearch} color={THEME_EXTRA.typography.disabled} />
</Box>
></Box>
{state.search.length === 0 && <SearchPlaceholder />}
{state.search.length > 0 && (
<Box
Expand Down Expand Up @@ -178,8 +206,13 @@ const Search: React.FC<SearchProps> = (props: SearchProps) => {
spellCheck={false}
sx={{
zIndex: theme.zIndex.appBar + 2,
height: '64px',
}}
inputRef={inputRef}
fullWidth={true}
autoFocus
startAdornment={<SearchOutlined />}
endAdornment={<Chip size={'small'} variant={'outlined'} label={'⌘K'}></Chip>}
onFocus={() => setState({ ...state, open: true })}
onChange={(event) => onSearch(event)}
value={state.search}
Expand All @@ -198,14 +231,16 @@ const Search: React.FC<SearchProps> = (props: SearchProps) => {
width={'100%'}
sx={{
position: 'absolute',
top: theme.spacing(-2),
width: '100%',
top: 0,
right: 0,
left: 0,
left: '-3px',
zIndex: theme.zIndex.appBar + 1,
border: `2px dashed ${theme.palette.secondary.main}`,
borderRadius: theme.spacing(1),
backgroundColor: theme.palette.background.default,
borderTopLeftRadius: 0,
borderBottomLeftRadius: 0,
}}
>
<Box
Expand All @@ -231,7 +266,7 @@ const Search: React.FC<SearchProps> = (props: SearchProps) => {
sx={{
margin: 0,
overflow: 'auto',
maxHeight: `calc(100vh - ${theme.spacing(30)})`,
maxHeight: `calc(100vh - ${theme.spacing(20)})`,
paddingLeft: 0,
borderBottomLeftRadius: theme.spacing(1),
borderBottomRightRadius: theme.spacing(1),
Expand All @@ -256,7 +291,7 @@ const Search: React.FC<SearchProps> = (props: SearchProps) => {
sx={{
borderTop: `2px dashed ${theme.palette.secondary.main}`,
borderBottom: `2px dashed ${theme.palette.secondary.main}`,
padding: `${theme.spacing(1)} ${theme.spacing(3)} ${theme.spacing(
padding: `${theme.spacing(0)} ${theme.spacing(3)} ${theme.spacing(
0.5
)} ${theme.spacing(1)}`,
backgroundColor: theme.palette.background.paper,
Expand Down
17 changes: 5 additions & 12 deletions web/src/components/search/SearchPlaceholder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Box } from '@mui/material'
import { theme } from '../../helpers/theme'
import MqText from '../core/text/MqText'
import React from 'react'
import Typewriter from './Typewriter'

const importI18next = () => {
return require('i18next')
Expand All @@ -19,7 +20,7 @@ const SearchPlaceholder: React.FC<SearchPlaceholderProps> = () => {
sx={{
zIndex: theme.zIndex.appBar + 3,
position: 'absolute',
left: 122,
left: 40,
height: '100%',
display: 'flex',
alignItems: 'center',
Expand All @@ -35,19 +36,11 @@ const SearchPlaceholder: React.FC<SearchPlaceholderProps> = () => {
aria-label={i18next.t('search.search_aria')}
aria-required='true'
>
{i18next.t('search.search')}
Search your
</MqText>
<MqText bold inline font={'mono'} color={theme.palette.common.white}>
<MqText bold inline>
{' '}
{i18next.t('search.jobs')}
</MqText>
<MqText disabled inline font={'mono'}>
{' '}
{i18next.t('search.and')}
</MqText>
<MqText bold inline font={'mono'} color={theme.palette.common.white}>
{' '}
{i18next.t('search.datasets')}
<Typewriter words={['Jobs and Datasets…']} repeatCount={3} />
</MqText>
</Box>
</Box>
Expand Down
Loading

0 comments on commit bc4eacf

Please sign in to comment.