Skip to content

Commit

Permalink
Add dataset field level tags to UI (#2729)
Browse files Browse the repository at this point in the history
* add dataset field level tags in UI

Signed-off-by: sharpd <[email protected]>

* set Auto Complete to small

Signed-off-by: sharpd <[email protected]>

* add decription to dataset tags if exits

Signed-off-by: sharpd <[email protected]>

* update dataset tags based on feedback

Signed-off-by: sharpd <[email protected]>

* change button icon/add translation/add additional var to tooltip

Signed-off-by: sharpd <[email protected]>

* add formatting to menu items to enhance readability

Signed-off-by: sharpd <[email protected]>

* more formatting changes to list drop down

Signed-off-by: sharpd <[email protected]>

* update dataset details to remove readonly

Signed-off-by: sharpd <[email protected]>

---------

Signed-off-by: sharpd <[email protected]>
Signed-off-by: sharpd <[email protected]>
Co-authored-by: sharpd <[email protected]>
  • Loading branch information
davidsharp7 and sharpd authored Feb 10, 2024
1 parent e93f951 commit b27cb30
Show file tree
Hide file tree
Showing 11 changed files with 331 additions and 184 deletions.
8 changes: 7 additions & 1 deletion web/src/components/core/text/MqText.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ interface OwnProps {
inverse?: boolean
highlight?: boolean
paragraph?: boolean
overflowHidden?: boolean
color?: string
link?: boolean
href?: string
Expand All @@ -48,6 +49,7 @@ const MqText: React.FC<MqTextProps> = ({
link,
linkTo,
paragraph,
overflowHidden,
href,
inverse,
inline,
Expand Down Expand Up @@ -119,6 +121,9 @@ const MqText: React.FC<MqTextProps> = ({
paragraph: {
marginBottom: theme.spacing(2),
},
overflowHidden: {
overflow: 'hidden',
},
}

const conditionalClasses = Object.assign(
Expand All @@ -135,7 +140,8 @@ const MqText: React.FC<MqTextProps> = ({
small ? classesObject.small : {},
link ? classesObject.link : {},
paragraph ? classesObject.paragraph : {},
subheading ? classesObject.subheading : {}
subheading ? classesObject.subheading : {},
overflowHidden ? classesObject.overflowHidden : {}
)

const style = {
Expand Down
4 changes: 3 additions & 1 deletion web/src/components/core/tooltip/MQTooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ import Tooltip from '@mui/material/Tooltip'
interface MqToolTipProps {
title: string | ReactElement
children: ReactElement
placement?: 'left' | 'right' | 'top'
}

const MQTooltip: React.FC<MqToolTipProps> = ({ title, children }) => {
const MQTooltip: React.FC<MqToolTipProps> = ({ title, children, placement }) => {
const theme = createTheme(useTheme())
return (
<Tooltip
title={title}
placement={placement || 'bottom'}
componentsProps={{
tooltip: {
sx: {
Expand Down
13 changes: 0 additions & 13 deletions web/src/components/datasets/DatasetDetailPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,6 @@ const DatasetDetailPage: FunctionComponent<IProps> = (props) => {
datasetTags={tags}
datasetName={lineageDataset.name}
namespace={lineageDataset.namespace}
readonly
/>
<Box display={'flex'} justifyContent={'space-between'} mb={2}>
<Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
Expand All @@ -158,11 +157,6 @@ const DatasetDetailPage: FunctionComponent<IProps> = (props) => {
{...a11yProps(3)}
disableRipple={true}
/>
<Tab
label={i18next.t('datasets.dataset_tags_tab')}
{...a11yProps(4)}
disableRipple={true}
/>
</Tabs>
</Box>
<Box display={'flex'} alignItems={'center'}>
Expand Down Expand Up @@ -222,13 +216,6 @@ const DatasetDetailPage: FunctionComponent<IProps> = (props) => {
{tabIndex === 1 && <Io />}
{tabIndex === 2 && <DatasetVersions versions={props.versions} />}
{tabIndex === 3 && <DatasetColumnLineage lineageDataset={props.lineageDataset} />}
{tabIndex === 4 && (
<DatasetTags
namespace={props.lineageDataset.namespace}
datasetName={props.lineageDataset.name}
datasetTags={firstVersion.tags}
/>
)}
</Box>
)
}
Expand Down
173 changes: 59 additions & 114 deletions web/src/components/datasets/DatasetInfo.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,29 @@
// Copyright 2018-2023 contributors to the Marquez project
// Copyright 2018-2024 contributors to the Marquez project
// SPDX-License-Identifier: Apache-2.0

import * as Redux from 'redux'
import {
Accordion,
Box,
Card,
CardContent,
Divider,
Table,
TableBody,
TableCell,
TableHead,
TableRow,
} from '@mui/material'
import { Chip, Drawer } from '@mui/material'
import { Field, Run, Tag } from '../../types/api'
import { Field, Run } from '../../types/api'
import { IState } from '../../store/reducers'
import { connect, useSelector } from 'react-redux'
import { createTheme } from '@mui/material/styles'
import { fetchJobFacets, fetchTags, resetFacets } from '../../store/actionCreators'
import { fetchJobFacets, resetFacets } from '../../store/actionCreators'
import { stopWatchDuration } from '../../helpers/time'
import { useTheme } from '@emotion/react'
import AccordionDetails from '@mui/material/AccordionDetails'
import AccordionSummary from '@mui/material/AccordionSummary'
import ExpandMoreIcon from '@mui/icons-material/ExpandMore'
import MQTooltip from '../core/tooltip/MQTooltip'
import Collapse from '@mui/material/Collapse'
import DatasetTags from './DatasetTags'
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'
import MqCode from '../core/code/MqCode'
import MqEmpty from '../core/empty/MqEmpty'
import MqJsonView from '../core/json-view/MqJsonView'
import MqText from '../core/text/MqText'
import React, { FunctionComponent, useEffect, useState } from 'react'
import ReadMoreIcon from '@mui/icons-material/ReadMore'
import RunStatus from '../jobs/RunStatus'

export interface DispatchProps {
Expand All @@ -58,61 +50,50 @@ type DatasetInfoProps = {
} & JobFacetsProps &
DispatchProps

const formatColumnTags = (tags: string[], tag_desc: Tag[]) => {
const theme = createTheme(useTheme())
return (
<>
{tags.map((tag, index) => {
const tagDescription = tag_desc.find((tagItem) => tagItem.name === tag)
const tooltipTitle = tagDescription?.description || 'No Tag Description'
return (
<MQTooltip title={tooltipTitle} key={tag}>
<Chip
label={tag}
size='small'
style={{
display: 'row',
marginRight: index < tags.length - 1 ? theme.spacing(1) : 0,
marginTop: 3,
}}
/>
</MQTooltip>
)
})}
</>
)
}

const DatasetInfo: FunctionComponent<DatasetInfoProps> = (props) => {
const { datasetFields, facets, run, jobFacets, fetchJobFacets, resetFacets } = props
const i18next = require('i18next')
const dsNamespace = useSelector(
(state: IState) => state.datasetVersions.result.versions[0].namespace
)
const dsName = useSelector((state: IState) => state.datasetVersions.result.versions[0].name)

const [open, setOpen] = useState(false)
const [selectedKey, setSelectedKey] = useState<string | undefined>(undefined)
const theme = createTheme(useTheme())
const loadCollapsedState = () => {
const storedState = localStorage.getItem(`dsi_${dsNamespace}_${dsName}`)
return storedState ? JSON.parse(storedState) : []
}

useEffect(() => {
run && fetchJobFacets(run.id)
run && fetchTags()
}, [run])

// unmounting
useEffect(
() => () => {
resetFacets()
},
[]
)
const [expandedRows, setExpandedRows] = useState<number[]>(loadCollapsedState)

const toggleRow = (index: number) => {
setExpandedRows((prevExpandedRows) => {
const newExpandedRows = prevExpandedRows.includes(index)
? prevExpandedRows.filter((rowIndex) => rowIndex !== index)
: [...prevExpandedRows, index]

const tagData = useSelector((state: IState) => state.tags.tags)
const handleOpen = (key: string) => {
setOpen(true)
setSelectedKey(key)
localStorage.setItem(`dsi_${dsNamespace}_${dsName}`, JSON.stringify(newExpandedRows))

return newExpandedRows
})
}

const selectedField = datasetFields.find((field) => field.name === selectedKey)
const selectedFieldTags = selectedField?.tags || []
const selectedFieldDesc = selectedField?.description || 'No Description'
useEffect(() => {
for (const key in localStorage) {
if (key !== `dsi_${dsNamespace}_${dsName}`) {
localStorage.removeItem(key)
}
}
}, [dsNamespace, dsName])

return (
<Box>
Expand Down Expand Up @@ -146,73 +127,38 @@ const DatasetInfo: FunctionComponent<DatasetInfoProps> = (props) => {
</TableRow>
</TableHead>
<TableBody>
{datasetFields.map((field) => {
{datasetFields.map((field, index) => {
return (
<TableRow key={field.name}>
<TableCell align='left'>{field.name}</TableCell>
<TableCell align='left'>{field.type}</TableCell>
<TableCell align='left'>{field.description || 'no description'}</TableCell>
<TableCell>
<ReadMoreIcon
onClick={() => handleOpen(field.name)}
sx={{ align: 'Right' }}
></ReadMoreIcon>
</TableCell>
</TableRow>
<React.Fragment key={field.name}>
<TableRow onClick={() => toggleRow(index)} className='expandable-row'>
<TableCell align='left'>{field.name}</TableCell>
<TableCell align='left'>{field.type}</TableCell>
<TableCell align='left'>{field.description || 'no description'}</TableCell>
<TableCell align='right'>
<KeyboardArrowDownIcon />
</TableCell>
</TableRow>
<TableRow>
<TableCell colSpan={4} style={{ padding: 0, border: 'none' }}>
<Collapse in={expandedRows.includes(index)} timeout='auto'>
<Card>
<CardContent>
<DatasetTags
namespace={dsNamespace}
datasetName={dsName}
datasetTags={field.tags}
datasetField={field.name}
/>
</CardContent>
</Card>
</Collapse>
</TableCell>
</TableRow>
</React.Fragment>
)
})}
</TableBody>
</Table>
<Drawer
elevation={0}
anchor='right'
open={open}
onClose={() => setOpen(false)}
sx={{ zIndex: theme.zIndex.drawer + 1 }}
PaperProps={{
sx: {
width: 400,
backgroundColor: theme.palette.background.paper,
border: `2px dashed ${theme.palette.secondary.main}`,
p: 1,
},
}}
>
<Card>
<CardContent sx={{ backgroundColor: theme.palette.background.paper }}>
<MqText heading bottomMargin>
{selectedKey}
</MqText>
</CardContent>
</Card>
<Divider />
<Card>
<CardContent sx={{ backgroundColor: theme.palette.background.paper }}>
<MqText bottomMargin>{selectedFieldDesc}</MqText>
</CardContent>
</Card>
<Accordion elevation={0}>
<AccordionSummary
expandIcon={<ExpandMoreIcon />}
sx={{
backgroundColor: theme.palette.background.paper,
}}
>
<MqText bold bottomMargin>
Tags
</MqText>
</AccordionSummary>
<AccordionDetails
sx={{
backgroundColor: theme.palette.background.paper,
}}
>
{selectedFieldTags.length > 0
? formatColumnTags(selectedFieldTags, tagData)
: 'No Tags'}
</AccordionDetails>
</Accordion>
</Drawer>
</>
)}
{facets && (
Expand Down Expand Up @@ -260,7 +206,6 @@ const mapDispatchToProps = (dispatch: Redux.Dispatch) =>
{
fetchJobFacets: fetchJobFacets,
resetFacets: resetFacets,
fetchTags: fetchTags,
},
dispatch
)
Expand Down
Loading

0 comments on commit b27cb30

Please sign in to comment.