Skip to content

Commit a107e08

Browse files
davidsharp7sharpd
andauthored
Add dataset field level tags to UI (#2729)
* add dataset field level tags in UI Signed-off-by: sharpd <number6labs@gmail.com> * set Auto Complete to small Signed-off-by: sharpd <number6labs@gmail.com> * add decription to dataset tags if exits Signed-off-by: sharpd <number6labs@gmail.com> * update dataset tags based on feedback Signed-off-by: sharpd <number6labs@gmail.com> * change button icon/add translation/add additional var to tooltip Signed-off-by: sharpd <number6labs@gmail.com> * add formatting to menu items to enhance readability Signed-off-by: sharpd <davidsharp7@gmail.com> * more formatting changes to list drop down Signed-off-by: sharpd <davidsharp7@gmail.com> * update dataset details to remove readonly Signed-off-by: sharpd <davidsharp7@gmail.com> --------- Signed-off-by: sharpd <number6labs@gmail.com> Signed-off-by: sharpd <davidsharp7@gmail.com> Co-authored-by: sharpd <number6labs@gmail.com>
1 parent 85a6273 commit a107e08

11 files changed

Lines changed: 331 additions & 184 deletions

File tree

web/src/components/core/text/MqText.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ interface OwnProps {
2222
inverse?: boolean
2323
highlight?: boolean
2424
paragraph?: boolean
25+
overflowHidden?: boolean
2526
color?: string
2627
link?: boolean
2728
href?: string
@@ -48,6 +49,7 @@ const MqText: React.FC<MqTextProps> = ({
4849
link,
4950
linkTo,
5051
paragraph,
52+
overflowHidden,
5153
href,
5254
inverse,
5355
inline,
@@ -119,6 +121,9 @@ const MqText: React.FC<MqTextProps> = ({
119121
paragraph: {
120122
marginBottom: theme.spacing(2),
121123
},
124+
overflowHidden: {
125+
overflow: 'hidden',
126+
},
122127
}
123128

124129
const conditionalClasses = Object.assign(
@@ -135,7 +140,8 @@ const MqText: React.FC<MqTextProps> = ({
135140
small ? classesObject.small : {},
136141
link ? classesObject.link : {},
137142
paragraph ? classesObject.paragraph : {},
138-
subheading ? classesObject.subheading : {}
143+
subheading ? classesObject.subheading : {},
144+
overflowHidden ? classesObject.overflowHidden : {}
139145
)
140146

141147
const style = {

web/src/components/core/tooltip/MQTooltip.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@ import Tooltip from '@mui/material/Tooltip'
99
interface MqToolTipProps {
1010
title: string | ReactElement
1111
children: ReactElement
12+
placement?: 'left' | 'right' | 'top'
1213
}
1314

14-
const MQTooltip: React.FC<MqToolTipProps> = ({ title, children }) => {
15+
const MQTooltip: React.FC<MqToolTipProps> = ({ title, children, placement }) => {
1516
const theme = createTheme(useTheme())
1617
return (
1718
<Tooltip
1819
title={title}
20+
placement={placement || 'bottom'}
1921
componentsProps={{
2022
tooltip: {
2123
sx: {

web/src/components/datasets/DatasetDetailPage.tsx

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,6 @@ const DatasetDetailPage: FunctionComponent<IProps> = (props) => {
132132
datasetTags={tags}
133133
datasetName={lineageDataset.name}
134134
namespace={lineageDataset.namespace}
135-
readonly
136135
/>
137136
<Box display={'flex'} justifyContent={'space-between'} mb={2}>
138137
<Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
@@ -158,11 +157,6 @@ const DatasetDetailPage: FunctionComponent<IProps> = (props) => {
158157
{...a11yProps(3)}
159158
disableRipple={true}
160159
/>
161-
<Tab
162-
label={i18next.t('datasets.dataset_tags_tab')}
163-
{...a11yProps(4)}
164-
disableRipple={true}
165-
/>
166160
</Tabs>
167161
</Box>
168162
<Box display={'flex'} alignItems={'center'}>
@@ -222,13 +216,6 @@ const DatasetDetailPage: FunctionComponent<IProps> = (props) => {
222216
{tabIndex === 1 && <Io />}
223217
{tabIndex === 2 && <DatasetVersions versions={props.versions} />}
224218
{tabIndex === 3 && <DatasetColumnLineage lineageDataset={props.lineageDataset} />}
225-
{tabIndex === 4 && (
226-
<DatasetTags
227-
namespace={props.lineageDataset.namespace}
228-
datasetName={props.lineageDataset.name}
229-
datasetTags={firstVersion.tags}
230-
/>
231-
)}
232219
</Box>
233220
)
234221
}

web/src/components/datasets/DatasetInfo.tsx

Lines changed: 59 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,29 @@
1-
// Copyright 2018-2023 contributors to the Marquez project
1+
// Copyright 2018-2024 contributors to the Marquez project
22
// SPDX-License-Identifier: Apache-2.0
3-
43
import * as Redux from 'redux'
54
import {
6-
Accordion,
75
Box,
86
Card,
97
CardContent,
10-
Divider,
118
Table,
129
TableBody,
1310
TableCell,
1411
TableHead,
1512
TableRow,
1613
} from '@mui/material'
17-
import { Chip, Drawer } from '@mui/material'
18-
import { Field, Run, Tag } from '../../types/api'
14+
import { Field, Run } from '../../types/api'
1915
import { IState } from '../../store/reducers'
2016
import { connect, useSelector } from 'react-redux'
21-
import { createTheme } from '@mui/material/styles'
22-
import { fetchJobFacets, fetchTags, resetFacets } from '../../store/actionCreators'
17+
import { fetchJobFacets, resetFacets } from '../../store/actionCreators'
2318
import { stopWatchDuration } from '../../helpers/time'
24-
import { useTheme } from '@emotion/react'
25-
import AccordionDetails from '@mui/material/AccordionDetails'
26-
import AccordionSummary from '@mui/material/AccordionSummary'
27-
import ExpandMoreIcon from '@mui/icons-material/ExpandMore'
28-
import MQTooltip from '../core/tooltip/MQTooltip'
19+
import Collapse from '@mui/material/Collapse'
20+
import DatasetTags from './DatasetTags'
21+
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown'
2922
import MqCode from '../core/code/MqCode'
3023
import MqEmpty from '../core/empty/MqEmpty'
3124
import MqJsonView from '../core/json-view/MqJsonView'
3225
import MqText from '../core/text/MqText'
3326
import React, { FunctionComponent, useEffect, useState } from 'react'
34-
import ReadMoreIcon from '@mui/icons-material/ReadMore'
3527
import RunStatus from '../jobs/RunStatus'
3628

3729
export interface DispatchProps {
@@ -58,61 +50,50 @@ type DatasetInfoProps = {
5850
} & JobFacetsProps &
5951
DispatchProps
6052

61-
const formatColumnTags = (tags: string[], tag_desc: Tag[]) => {
62-
const theme = createTheme(useTheme())
63-
return (
64-
<>
65-
{tags.map((tag, index) => {
66-
const tagDescription = tag_desc.find((tagItem) => tagItem.name === tag)
67-
const tooltipTitle = tagDescription?.description || 'No Tag Description'
68-
return (
69-
<MQTooltip title={tooltipTitle} key={tag}>
70-
<Chip
71-
label={tag}
72-
size='small'
73-
style={{
74-
display: 'row',
75-
marginRight: index < tags.length - 1 ? theme.spacing(1) : 0,
76-
marginTop: 3,
77-
}}
78-
/>
79-
</MQTooltip>
80-
)
81-
})}
82-
</>
83-
)
84-
}
85-
8653
const DatasetInfo: FunctionComponent<DatasetInfoProps> = (props) => {
8754
const { datasetFields, facets, run, jobFacets, fetchJobFacets, resetFacets } = props
8855
const i18next = require('i18next')
56+
const dsNamespace = useSelector(
57+
(state: IState) => state.datasetVersions.result.versions[0].namespace
58+
)
59+
const dsName = useSelector((state: IState) => state.datasetVersions.result.versions[0].name)
8960

90-
const [open, setOpen] = useState(false)
91-
const [selectedKey, setSelectedKey] = useState<string | undefined>(undefined)
92-
const theme = createTheme(useTheme())
61+
const loadCollapsedState = () => {
62+
const storedState = localStorage.getItem(`dsi_${dsNamespace}_${dsName}`)
63+
return storedState ? JSON.parse(storedState) : []
64+
}
9365

9466
useEffect(() => {
9567
run && fetchJobFacets(run.id)
96-
run && fetchTags()
9768
}, [run])
9869

99-
// unmounting
10070
useEffect(
10171
() => () => {
10272
resetFacets()
10373
},
10474
[]
10575
)
76+
const [expandedRows, setExpandedRows] = useState<number[]>(loadCollapsedState)
77+
78+
const toggleRow = (index: number) => {
79+
setExpandedRows((prevExpandedRows) => {
80+
const newExpandedRows = prevExpandedRows.includes(index)
81+
? prevExpandedRows.filter((rowIndex) => rowIndex !== index)
82+
: [...prevExpandedRows, index]
10683

107-
const tagData = useSelector((state: IState) => state.tags.tags)
108-
const handleOpen = (key: string) => {
109-
setOpen(true)
110-
setSelectedKey(key)
84+
localStorage.setItem(`dsi_${dsNamespace}_${dsName}`, JSON.stringify(newExpandedRows))
85+
86+
return newExpandedRows
87+
})
11188
}
11289

113-
const selectedField = datasetFields.find((field) => field.name === selectedKey)
114-
const selectedFieldTags = selectedField?.tags || []
115-
const selectedFieldDesc = selectedField?.description || 'No Description'
90+
useEffect(() => {
91+
for (const key in localStorage) {
92+
if (key !== `dsi_${dsNamespace}_${dsName}`) {
93+
localStorage.removeItem(key)
94+
}
95+
}
96+
}, [dsNamespace, dsName])
11697

11798
return (
11899
<Box>
@@ -146,73 +127,38 @@ const DatasetInfo: FunctionComponent<DatasetInfoProps> = (props) => {
146127
</TableRow>
147128
</TableHead>
148129
<TableBody>
149-
{datasetFields.map((field) => {
130+
{datasetFields.map((field, index) => {
150131
return (
151-
<TableRow key={field.name}>
152-
<TableCell align='left'>{field.name}</TableCell>
153-
<TableCell align='left'>{field.type}</TableCell>
154-
<TableCell align='left'>{field.description || 'no description'}</TableCell>
155-
<TableCell>
156-
<ReadMoreIcon
157-
onClick={() => handleOpen(field.name)}
158-
sx={{ align: 'Right' }}
159-
></ReadMoreIcon>
160-
</TableCell>
161-
</TableRow>
132+
<React.Fragment key={field.name}>
133+
<TableRow onClick={() => toggleRow(index)} className='expandable-row'>
134+
<TableCell align='left'>{field.name}</TableCell>
135+
<TableCell align='left'>{field.type}</TableCell>
136+
<TableCell align='left'>{field.description || 'no description'}</TableCell>
137+
<TableCell align='right'>
138+
<KeyboardArrowDownIcon />
139+
</TableCell>
140+
</TableRow>
141+
<TableRow>
142+
<TableCell colSpan={4} style={{ padding: 0, border: 'none' }}>
143+
<Collapse in={expandedRows.includes(index)} timeout='auto'>
144+
<Card>
145+
<CardContent>
146+
<DatasetTags
147+
namespace={dsNamespace}
148+
datasetName={dsName}
149+
datasetTags={field.tags}
150+
datasetField={field.name}
151+
/>
152+
</CardContent>
153+
</Card>
154+
</Collapse>
155+
</TableCell>
156+
</TableRow>
157+
</React.Fragment>
162158
)
163159
})}
164160
</TableBody>
165161
</Table>
166-
<Drawer
167-
elevation={0}
168-
anchor='right'
169-
open={open}
170-
onClose={() => setOpen(false)}
171-
sx={{ zIndex: theme.zIndex.drawer + 1 }}
172-
PaperProps={{
173-
sx: {
174-
width: 400,
175-
backgroundColor: theme.palette.background.paper,
176-
border: `2px dashed ${theme.palette.secondary.main}`,
177-
p: 1,
178-
},
179-
}}
180-
>
181-
<Card>
182-
<CardContent sx={{ backgroundColor: theme.palette.background.paper }}>
183-
<MqText heading bottomMargin>
184-
{selectedKey}
185-
</MqText>
186-
</CardContent>
187-
</Card>
188-
<Divider />
189-
<Card>
190-
<CardContent sx={{ backgroundColor: theme.palette.background.paper }}>
191-
<MqText bottomMargin>{selectedFieldDesc}</MqText>
192-
</CardContent>
193-
</Card>
194-
<Accordion elevation={0}>
195-
<AccordionSummary
196-
expandIcon={<ExpandMoreIcon />}
197-
sx={{
198-
backgroundColor: theme.palette.background.paper,
199-
}}
200-
>
201-
<MqText bold bottomMargin>
202-
Tags
203-
</MqText>
204-
</AccordionSummary>
205-
<AccordionDetails
206-
sx={{
207-
backgroundColor: theme.palette.background.paper,
208-
}}
209-
>
210-
{selectedFieldTags.length > 0
211-
? formatColumnTags(selectedFieldTags, tagData)
212-
: 'No Tags'}
213-
</AccordionDetails>
214-
</Accordion>
215-
</Drawer>
216162
</>
217163
)}
218164
{facets && (
@@ -260,7 +206,6 @@ const mapDispatchToProps = (dispatch: Redux.Dispatch) =>
260206
{
261207
fetchJobFacets: fetchJobFacets,
262208
resetFacets: resetFacets,
263-
fetchTags: fetchTags,
264209
},
265210
dispatch
266211
)

0 commit comments

Comments
 (0)