Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
5b6c149
Saving graph progress.
May 30, 2024
ab5eb03
Saving screen demos.
May 31, 2024
9dd0581
Saving progress on label selectors.
May 31, 2024
9a7a0f6
Saving progress on new mock.
May 31, 2024
09181a4
Saving progress on mocks.
Jun 1, 2024
686e3fc
Better visuals.
Jun 3, 2024
c4081cd
Adding sidenav example.
Jun 4, 2024
c5d80c2
Saving iteration progress.
Jun 4, 2024
ee65c44
Merge branch 'refs/heads/main' into feature/ops-dashboard
phixMe Aug 23, 2024
37f0100
Basic branding adjustments.
phixMe Aug 23, 2024
5a33ce3
Linting and fixing variables.
phixMe Aug 23, 2024
ebf6158
Adding split button component.
phixMe Aug 23, 2024
6496efd
Adding a timeline drawer.
phixMe Sep 4, 2024
2e7e8fa
Adding a timeline drawer and refocusing some style elements.
phixMe Sep 4, 2024
a212ea4
Saving progress on chart.
phixMe Sep 4, 2024
acf40b2
Checkpoint on stable graph.
phixMe Sep 5, 2024
fe6391a
Better framing of graph in window.
phixMe Sep 5, 2024
57b39a2
Adding sum.
phixMe Sep 5, 2024
8f1689d
Adding loading states.
phixMe Sep 5, 2024
20bb8c3
Formatting.
phixMe Sep 5, 2024
cc3a8c4
Removing log.
phixMe Sep 5, 2024
3b5a9fd
Fixing the timezone.
phixMe Sep 5, 2024
d8715ba
Minor ordering optimizations.
phixMe Sep 5, 2024
36e449c
Implementing existing jobs api.
phixMe Sep 9, 2024
f4efaf1
Fixing refresh bug.
phixMe Sep 10, 2024
f2817e8
Updating timeframe
phixMe Sep 10, 2024
33c3d24
Fix timeframe issue.
phixMe Sep 10, 2024
7e593b3
Saving action types for job state fetch.
phixMe Sep 10, 2024
f97954f
Changes for api adjustments.
phixMe Sep 10, 2024
f51777a
Merge branch 'refs/heads/main' into feature/ops-dashboard
phixMe Sep 12, 2024
604dbe2
Fixing z-index issue.
phixMe Sep 30, 2024
c309242
Visual update for job runs.
phixMe Sep 30, 2024
ddfef2a
Job and Dataset Metrics.
phixMe Sep 30, 2024
ae1bbe2
Adding source metrics.
phixMe Oct 1, 2024
4491973
Number formatting.
phixMe Oct 1, 2024
66881b0
Adding timezone.
phixMe Oct 1, 2024
f3a87f0
Adding complete colors.
phixMe Oct 1, 2024
6556072
Fixing small corner rounding.
phixMe Oct 1, 2024
cb16ee3
Small optimizations.
phixMe Oct 1, 2024
85fdc32
Fixing test.
phixMe Oct 1, 2024
5e457ab
Removing some packages.
phixMe Oct 1, 2024
424d336
Bumping install version
phixMe Oct 1, 2024
1c38096
A new version
phixMe Oct 1, 2024
059c4ac
Adding panel and latest run data to panel.
phixMe Oct 9, 2024
316fb22
Adding panel and latest run data to panel.
phixMe Oct 9, 2024
63967b2
Merge branch 'refs/heads/main' into feature/ops-dashboard
phixMe Oct 9, 2024
f5dd7c8
Navigation.
phixMe Oct 9, 2024
2f5a167
Remove extra logo
phixMe Oct 10, 2024
5896e03
Merge branch 'main' into feature/ops-dashboard
wslulciuc Oct 10, 2024
48ce692
Merge branch 'main' into feature/ops-dashboard
wslulciuc Oct 11, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,167 changes: 346 additions & 821 deletions web/package-lock.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@
"@fortawesome/react-fontawesome": "^0.2.0",
"@lagunovsky/redux-react-router": "^4.3.0",
"@mui/icons-material": "^5.11.16",
"@mui/lab": "^5.0.0-alpha.170",
"@mui/material": "^5.13.2",
"@mui/system": "^5.13.2",
"@mui/x-charts": "^7.15.0",
"@mui/x-date-pickers": "^6.5.0",
"@types/jest": "^29.5.2",
"@types/react-router-dom": "^5.3.3",
Expand All @@ -40,13 +42,11 @@
"d3-format": "^3.1.0",
"d3-scale": "^4.0.2",
"d3-selection": "^3.0.0",
"dagre": "^0.8.5",
"dayjs": "^1.11.8",
"file-saver": "^2.0.5",
"http-proxy-middleware": "^2.0.6",
"i18next": "^22.5.0",
"i18next-browser-languagedetector": "^7.0.1",
"json-server": "^0.17.3",
"lodash": "^4.17.21",
"moment": "^2.29.4",
"postcss-loader": "^7.3.0",
Expand Down
4 changes: 3 additions & 1 deletion web/src/components/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { composeWithDevTools } from '@redux-devtools/extension'
import { createBrowserHistory } from 'history'
import { theme } from '../helpers/theme'
import ColumnLevel from '../routes/column-level/ColumnLevel'
import Dashboard from '../routes/dashboard/Dashboard'
import Datasets from '../routes/datasets/Datasets'
import Events from '../routes/events/Events'
import Header from './header/Header'
Expand Down Expand Up @@ -62,7 +63,8 @@ const App = (): ReactElement => {
<Header />
</Container>
<Routes>
<Route path={'/'} element={<Jobs />} />
<Route path={'/'} element={<Dashboard />} />
<Route path={'/jobs'} element={<Jobs />} />
<Route path={'/datasets'} element={<Datasets />} />
<Route path={'/events'} element={<Events />} />
<Route
Expand Down
1 change: 0 additions & 1 deletion web/src/components/core/date-picker/MqDatePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ const MqDatePicker: React.FC<DatePickerProps> = ({
},
},
'.MuiOutlinedInput-notchedOutline': {
border: `2px solid ${theme.palette.common.white}`,
borderRadius: theme.spacing(4),
'> legend': {
marginLeft: theme.spacing(2),
Expand Down
2 changes: 1 addition & 1 deletion web/src/components/core/input-base/MqInputBase.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ export const MqInputBase: React.FC<MqInputBaseProps> = (props) => {
<InputBase
{...props}
sx={{
...props.sx,
borderRadius: theme.spacing(4),
position: 'relative',
backgroundColor: 'transparent',
fontSize: 16,
padding: `${theme.spacing(1)} ${theme.spacing(2)}`,
transition: theme.transitions.create(['border-color', 'box-shadow']),
...props.sx,
}}
/>
)
Expand Down
7 changes: 7 additions & 0 deletions web/src/components/core/text/MqText.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ interface OwnProps {
linkTo?: string
font?: 'primary' | 'mono'
small?: boolean
large?: boolean
bottomMargin?: boolean
block?: boolean
sx?: SxProps
Expand Down Expand Up @@ -58,6 +59,7 @@ const MqText: React.FC<MqTextProps> = ({
highlight,
color,
small,
large,
block,
onClick,
sx,
Expand Down Expand Up @@ -126,6 +128,10 @@ const MqText: React.FC<MqTextProps> = ({
fontSize: '.625rem',
lineHeight: 'inherit',
},
large: {
fontSize: '1.25rem',
lineHeight: 'inherit',
},
paragraph: {
marginBottom: theme.spacing(2),
},
Expand All @@ -146,6 +152,7 @@ const MqText: React.FC<MqTextProps> = ({
inverse ? classesObject.inverse : {},
inline ? classesObject.inline : {},
small ? classesObject.small : {},
large ? classesObject.large : {},
link ? classesObject.link : {},
block ? classesObject.block : {},
paragraph ? classesObject.paragraph : {},
Expand Down
106 changes: 106 additions & 0 deletions web/src/components/dashboard/SplitButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import * as React from 'react'
import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown'
import Button from '@mui/material/Button'
import ButtonGroup from '@mui/material/ButtonGroup'
import ClickAwayListener from '@mui/material/ClickAwayListener'
import Grow from '@mui/material/Grow'
import MenuItem from '@mui/material/MenuItem'
import MenuList from '@mui/material/MenuList'
import Paper from '@mui/material/Paper'
import Popper from '@mui/material/Popper'

interface Props {
options: string[]
onClick: (option: string) => void
}

export default function SplitButton({ options, onClick }: Props) {
const [open, setOpen] = React.useState(false)
const anchorRef = React.useRef<HTMLDivElement>(null)
const [selectedIndex, setSelectedIndex] = React.useState(0)

const handleClick = () => {
onClick(options[selectedIndex])
}

const handleMenuItemClick = (
event: React.MouseEvent<HTMLLIElement, MouseEvent>,
index: number
) => {
setSelectedIndex(index)
setOpen(false)
}

const handleToggle = () => {
setOpen((prevOpen) => !prevOpen)
}

const handleClose = (event: Event) => {
if (anchorRef.current && anchorRef.current.contains(event.target as HTMLElement)) {
return
}

setOpen(false)
}

return (
<>
<ButtonGroup
variant={'outlined'}
ref={anchorRef}
aria-label='Button group with a nested menu'
color={'secondary'}
>
<Button size={'small'} color={'secondary'} variant={'contained'} onClick={handleClick}>
{options[selectedIndex]}
</Button>
<Button
color={'secondary'}
size={'small'}
aria-controls={open ? 'split-button-menu' : undefined}
aria-expanded={open ? 'true' : undefined}
aria-label='select merge strategy'
aria-haspopup='menu'
onClick={handleToggle}
>
<ArrowDropDownIcon />
</Button>
</ButtonGroup>
<Popper
sx={{
zIndex: 1,
}}
open={open}
anchorEl={anchorRef.current}
role={undefined}
transition
disablePortal
>
{({ TransitionProps, placement }) => (
<Grow
{...TransitionProps}
style={{
transformOrigin: placement === 'bottom' ? 'center top' : 'center bottom',
}}
>
<Paper>
<ClickAwayListener onClickAway={handleClose}>
<MenuList id='split-button-menu' autoFocusItem>
{options.map((option, index) => (
<MenuItem
key={option}
selected={index === selectedIndex}
onClick={(event) => handleMenuItemClick(event, index)}
>
{option}
</MenuItem>
))}
</MenuList>
</ClickAwayListener>
</Paper>
</Grow>
)}
</Popper>
</>
)
}
6 changes: 5 additions & 1 deletion web/src/components/datasets/DatasetInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,11 @@ const DatasetInfo: FunctionComponent<DatasetInfoProps> = (props) => {
<TableCell align='left'>
<Chip
size={'small'}
label={<MqText font={'mono'} small>{field.type || 'N/A'}</MqText>}
label={
<MqText font={'mono'} small>
{field.type || 'N/A'}
</MqText>
}
variant={'outlined'}
/>
</TableCell>
Expand Down
2 changes: 1 addition & 1 deletion web/src/components/paging/MqPaging.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ interface Props {
const MqPaging: FunctionComponent<Props> = (props) => {
const { pageSize, currentPage, incrementPage, decrementPage, totalCount } = props
return (
<Box display={'flex'} justifyContent={'flex-end'} alignItems={'center'} mb={2}>
<Box display={'flex'} justifyContent={'flex-end'} alignItems={'center'}>
<MqText subdued>
<>
{pageSize * currentPage + 1} - {Math.min(pageSize * (currentPage + 1), totalCount)} of{' '}
Expand Down
9 changes: 5 additions & 4 deletions web/src/components/search/Search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@ import { Close, SearchOutlined } from '@mui/icons-material'
import { DRAWER_WIDTH, HEADER_HEIGHT, theme } from '../../helpers/theme'
import { IState } from '../../store/reducers'
import { MqInputBase } from '../core/input-base/MqInputBase'
import { REACT_APP_ADVANCED_SEARCH } from '../../globals'
import { connect } from 'react-redux'
import { useLocation } from 'react-router'
import BaseSearch from './base-search/BaseSearch'
import CircularProgress from '@mui/material/CircularProgress/CircularProgress'
import ClickAwayListener from '@mui/material/ClickAwayListener'
import OpenSearch from './open-search/OpenSearch'
import IconButton from '@mui/material/IconButton'
import OpenSearch from './open-search/OpenSearch'
import React, { useEffect, useRef, useState } from 'react'
import SearchPlaceholder from './SearchPlaceholder'
import { REACT_APP_ADVANCED_SEARCH } from "../../globals";

const useCmdKShortcut = (callback: () => void) => {
useEffect(() => {
Expand Down Expand Up @@ -114,7 +114,8 @@ const Search: React.FC = ({ isLoading }: StateProps) => {
spellCheck={false}
sx={{
zIndex: theme.zIndex.appBar + 2,
height: '64px',
height: HEADER_HEIGHT - 1,
paddingRight: theme.spacing(3),
}}
inputRef={inputRef}
fullWidth={true}
Expand Down Expand Up @@ -181,7 +182,7 @@ const Search: React.FC = ({ isLoading }: StateProps) => {
}}
>
<Box
mt={'64px'}
mt={`${HEADER_HEIGHT - 1}px`}
borderTop={1}
borderColor={'divider'}
overflow={'auto'}
Expand Down
42 changes: 27 additions & 15 deletions web/src/components/search/open-search/OpenSearch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ import MqStatus from '../../core/status/MqStatus'
import MqText from '../../core/text/MqText'
import React, { useCallback, useEffect } from 'react'
import airflow_logo from './airlfow-logo.svg'
import spark_logo from './spark-logo.svg'
import dbt_logo from './dbt-logo.svg'
import spark_logo from './spark-logo.svg'

interface StateProps {
openSearchJobs: IOpenSearchJobsState
Expand All @@ -51,7 +51,7 @@ const LOGO_MAP = {
spark: spark_logo,
airflow: airflow_logo,
dbt: dbt_logo,
};
}

function parseStringToSegments(input: string): TextSegment[] {
return input.split(/(<em>.*?<\/em>)/).map((segment) => {
Expand Down Expand Up @@ -121,28 +121,28 @@ const OpenSearch: React.FC<StateProps & DispatchProps & Props> = ({
const jobHit = openSearchJobs.data.hits[selectedIndex]
navigate(`/lineage/${encodeNode('JOB', jobHit.namespace, jobHit.name)}`)
} else {
const datasetHit = openSearchDatasets.data.hits[selectedIndex - openSearchJobs.data.hits.length]
const datasetHit =
openSearchDatasets.data.hits[selectedIndex - openSearchJobs.data.hits.length]
navigate(`/lineage/${encodeNode('DATASET', datasetHit.namespace, datasetHit.name)}`)
}
}
})

const debouncedFetchJobs = useCallback(
debounce(async (searchTerm) => {
fetchOpenSearchJobs(searchTerm);
setIsDebouncing(false); // Set loading to false after the fetch completes
fetchOpenSearchJobs(searchTerm)
setIsDebouncing(false) // Set loading to false after the fetch completes
}, DEBOUNCE_TIME_MS),
[]
);

)

const debouncedFetchDatasets = useCallback(
debounce(async (searchTerm) => {
fetchOpenSearchDatasets(searchTerm);
setIsDebouncing(false); // Set loading to false after the fetch completes
fetchOpenSearchDatasets(searchTerm)
setIsDebouncing(false) // Set loading to false after the fetch completes
}, DEBOUNCE_TIME_MS),
[]
);
)

useEffect(() => {
setIsDebouncing(true)
Expand All @@ -154,7 +154,11 @@ const OpenSearch: React.FC<StateProps & DispatchProps & Props> = ({
setSelectedIndex(null)
}, [openSearchJobs.data.hits, openSearchDatasets.data.hits])

if (openSearchJobs.data.hits.length === 0 && openSearchDatasets.data.hits.length === 0 && !isDebouncing) {
if (
openSearchJobs.data.hits.length === 0 &&
openSearchDatasets.data.hits.length === 0 &&
!isDebouncing
) {
return (
<Box my={4}>
<MqEmpty title={'No Hits'} body={'Keep typing or try a more precise search.'} />
Expand Down Expand Up @@ -217,12 +221,16 @@ const OpenSearch: React.FC<StateProps & DispatchProps & Props> = ({
{'Integration'}
</MqText>
{(() => {
const engineName = hit.runFacets.processing_engine.name.toLowerCase();
const engineName = hit.runFacets.processing_engine.name.toLowerCase()
return LOGO_MAP[engineName as keyof typeof LOGO_MAP] ? (
<img src={LOGO_MAP[engineName as keyof typeof LOGO_MAP]} height={24} alt={engineName.charAt(0).toUpperCase() + engineName.slice(1)} />
<img
src={LOGO_MAP[engineName as keyof typeof LOGO_MAP]}
height={24}
alt={engineName.charAt(0).toUpperCase() + engineName.slice(1)}
/>
) : (
<Chip size={'small'} label={hit.runFacets?.processing_engine.name} />
);
)
})()}
</Box>
</>
Expand Down Expand Up @@ -376,7 +384,11 @@ const OpenSearch: React.FC<StateProps & DispatchProps & Props> = ({
key={field.name}
label={field.name}
variant={'outlined'}
color={field.name.toLowerCase().includes(search.toLowerCase()) ? 'primary' : 'default'}
color={
field.name.toLowerCase().includes(search.toLowerCase())
? 'primary'
: 'default'
}
size={'small'}
sx={{ mr: 1 }}
/>
Expand Down
11 changes: 10 additions & 1 deletion web/src/components/sidenav/Sidenav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { FormControl, MenuItem, Select } from '@mui/material'
import { MqInputNoIcon } from '../core/input-base/MqInputBase'
import { useTheme } from '@emotion/react'

import { Dashboard } from '@mui/icons-material'
import iconSearchArrow from '../../img/iconSearchArrow.svg'
import marquez_logo from './marquez-icon-white-solid.svg'

Expand Down Expand Up @@ -79,8 +80,16 @@ const Sidenav: React.FC<SidenavProps> = () => {
<MqIconButton
to={'/'}
id={'homeDrawerButton'}
title={i18next.t('sidenav.jobs')}
title={i18next.t('sidenav.dataOps')}
active={location.pathname === '/'}
>
<Dashboard />
</MqIconButton>
<MqIconButton
to={'/jobs'}
id={'jobsDrawerButton'}
title={i18next.t('sidenav.jobs')}
active={location.pathname === '/jobs'}
>
<FontAwesomeIcon icon={faCogs} fontSize={20} />
</MqIconButton>
Expand Down
Loading