From 52c70faa43592352f9dcd6adedc2bc890924135a Mon Sep 17 00:00:00 2001 From: sharpd Date: Sun, 7 Jan 2024 22:44:51 +1300 Subject: [PATCH 1/8] add dataset field level tags in UI Signed-off-by: sharpd --- web/src/components/datasets/DatasetInfo.tsx | 173 +++++++------------- web/src/components/datasets/DatasetTags.tsx | 39 ++++- web/src/store/actionCreators/actionTypes.ts | 6 +- web/src/store/actionCreators/index.ts | 46 +++++- web/src/store/reducers/datasets.ts | 20 ++- web/src/store/requests/datasets.ts | 26 ++- web/src/store/sagas/index.ts | 46 +++++- 7 files changed, 227 insertions(+), 129 deletions(-) diff --git a/web/src/components/datasets/DatasetInfo.tsx b/web/src/components/datasets/DatasetInfo.tsx index 164abd1481..50eab61b64 100644 --- a/web/src/components/datasets/DatasetInfo.tsx +++ b/web/src/components/datasets/DatasetInfo.tsx @@ -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 { @@ -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 ( - - - - ) - })} - - ) -} - const DatasetInfo: FunctionComponent = (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(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(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 ( @@ -146,73 +127,38 @@ const DatasetInfo: FunctionComponent = (props) => { - {datasetFields.map((field) => { + {datasetFields.map((field, index) => { return ( - - {field.name} - {field.type} - {field.description || 'no description'} - - handleOpen(field.name)} - sx={{ align: 'Right' }} - > - - + + toggleRow(index)} className='expandable-row'> + {field.name} + {field.type} + {field.description || 'no description'} + + + + + + + + + + + + + + + + ) })} - 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, - }, - }} - > - - - - {selectedKey} - - - - - - - {selectedFieldDesc} - - - - } - sx={{ - backgroundColor: theme.palette.background.paper, - }} - > - - Tags - - - - {selectedFieldTags.length > 0 - ? formatColumnTags(selectedFieldTags, tagData) - : 'No Tags'} - - - )} {facets && ( @@ -260,7 +206,6 @@ const mapDispatchToProps = (dispatch: Redux.Dispatch) => { fetchJobFacets: fetchJobFacets, resetFacets: resetFacets, - fetchTags: fetchTags, }, dispatch ) diff --git a/web/src/components/datasets/DatasetTags.tsx b/web/src/components/datasets/DatasetTags.tsx index 5b6b412286..4135e5d10b 100644 --- a/web/src/components/datasets/DatasetTags.tsx +++ b/web/src/components/datasets/DatasetTags.tsx @@ -1,9 +1,15 @@ -// 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 { IState } from '../../store/reducers' import { Tag } from '../../types/api' -import { addDatasetTag, deleteDatasetTag, fetchTags } from '../../store/actionCreators' +import { + addDatasetFieldTag, + addDatasetTag, + deleteDatasetFieldTag, + deleteDatasetTag, + fetchTags, +} from '../../store/actionCreators' import { bindActionCreators } from 'redux' import { connect, useSelector } from 'react-redux' import { createTheme } from '@mui/material' @@ -21,27 +27,36 @@ interface DatasetTagsProps { namespace: string datasetName: string datasetTags: string[] + datasetField?: string } interface DispatchProps { deleteDatasetTag: typeof deleteDatasetTag addDatasetTag: typeof addDatasetTag + deleteDatasetFieldTag: typeof deleteDatasetFieldTag + addDatasetFieldTag: typeof addDatasetFieldTag fetchTags: typeof fetchTags } type IProps = DatasetTagsProps & DispatchProps const DatasetTags: React.FC = (props) => { - const { namespace, datasetName, datasetTags, deleteDatasetTag, addDatasetTag, fetchTags } = props + const { + namespace, + datasetName, + datasetTags, + deleteDatasetTag, + addDatasetTag, + deleteDatasetFieldTag, + addDatasetFieldTag, + fetchTags, + datasetField, + } = props useEffect(() => { fetchTags() }, []) - useEffect(() => { - fetchTags() - }, [deleteDatasetTag, addDatasetTag]) - const tagData = useSelector((state: IState) => state.tags.tags) const handleTagChange = ( @@ -51,12 +66,16 @@ const DatasetTags: React.FC = (props) => { details?: AutocompleteChangeDetails | undefined ) => { if (reason === 'selectOption' && details) { - addDatasetTag(namespace, datasetName, details.option) + datasetField + ? addDatasetFieldTag(namespace, datasetName, details.option, datasetField) + : addDatasetTag(namespace, datasetName, details.option) } } const handleDelete = (deletedTag: string) => { - deleteDatasetTag(namespace, datasetName, deletedTag) + datasetField + ? deleteDatasetFieldTag(namespace, datasetName, deletedTag, datasetField) + : deleteDatasetTag(namespace, datasetName, deletedTag) } const formatTags = (tags: string[], tag_desc: Tag[]) => { @@ -107,6 +126,8 @@ const mapDispatchToProps = (dispatch: Redux.Dispatch) => fetchTags: fetchTags, deleteDatasetTag: deleteDatasetTag, addDatasetTag: addDatasetTag, + deleteDatasetFieldTag: deleteDatasetFieldTag, + addDatasetFieldTag: addDatasetFieldTag, }, dispatch ) diff --git a/web/src/store/actionCreators/actionTypes.ts b/web/src/store/actionCreators/actionTypes.ts index dea36c06b0..c67278ec68 100644 --- a/web/src/store/actionCreators/actionTypes.ts +++ b/web/src/store/actionCreators/actionTypes.ts @@ -1,4 +1,4 @@ -// Copyright 2018-2023 contributors to the Marquez project +// Copyright 2018-2024 contributors to the Marquez project // SPDX-License-Identifier: Apache-2.0 export const APPLICATION_ERROR = 'APPLICATION_ERROR' @@ -41,6 +41,10 @@ export const DELETE_DATASET_TAG = 'DELETE_DATASET_TAG' export const DELETE_DATASET_TAG_SUCCESS = 'DELETE_DATASET_TAG_SUCCESS' export const ADD_DATASET_TAG = 'ADD_DATASET_TAG' export const ADD_DATASET_TAG_SUCCESS = 'ADD_DATASET_TAG_SUCCESS' +export const DELETE_DATASET_FIELD_TAG = 'DELETE_DATASET_FIELD_TAG' +export const DELETE_DATASET_FIELD_TAG_SUCCESS = 'DELETE_DATASET_FIELD_TAG_SUCCESS' +export const ADD_DATASET_FIELD_TAG = 'ADD_DATASET_FIELD_TAG' +export const ADD_DATASET_FIELD_TAG_SUCCESS = 'ADD_DATASET_FIELD_TAG_SUCCESS' // events export const FETCH_EVENTS = 'FETCH_EVENTS' diff --git a/web/src/store/actionCreators/index.ts b/web/src/store/actionCreators/index.ts index 2eae898942..d709be5ca8 100644 --- a/web/src/store/actionCreators/index.ts +++ b/web/src/store/actionCreators/index.ts @@ -1,4 +1,4 @@ -// Copyright 2018-2023 contributors to the Marquez project +// Copyright 2018-2024 contributors to the Marquez project // SPDX-License-Identifier: Apache-2.0 import * as actionTypes from './actionTypes' @@ -124,6 +124,28 @@ export const deleteDatasetTagSuccess = (datasetName: string) => ({ }, }) +export const deleteDatasetFieldTag = ( + namespace: string, + datasetName: string, + tag: string, + field: string +) => ({ + type: actionTypes.DELETE_DATASET_FIELD_TAG, + payload: { + namespace, + datasetName, + tag, + field, + }, +}) + +export const deleteDatasetFieldTagSuccess = (datasetName: string) => ({ + type: actionTypes.DELETE_DATASET_FIELD_TAG_SUCCESS, + payload: { + datasetName, + }, +}) + export const addDatasetTag = (namespace: string, datasetName: string, tag: string) => ({ type: actionTypes.ADD_DATASET_TAG, payload: { @@ -140,6 +162,28 @@ export const addDatasetTagSuccess = (datasetName: string) => ({ }, }) +export const addDatasetFieldTag = ( + namespace: string, + datasetName: string, + tag: string, + field: string +) => ({ + type: actionTypes.ADD_DATASET_FIELD_TAG, + payload: { + namespace, + datasetName, + tag, + field, + }, +}) + +export const addDatasetFieldTagSuccess = (datasetName: string) => ({ + type: actionTypes.ADD_DATASET_FIELD_TAG_SUCCESS, + payload: { + datasetName, + }, +}) + export const resetDatasets = () => ({ type: actionTypes.RESET_DATASETS, }) diff --git a/web/src/store/reducers/datasets.ts b/web/src/store/reducers/datasets.ts index 67040ecc15..1952674430 100644 --- a/web/src/store/reducers/datasets.ts +++ b/web/src/store/reducers/datasets.ts @@ -1,10 +1,14 @@ -// Copyright 2018-2023 contributors to the Marquez project +// Copyright 2018-2024 contributors to the Marquez project // SPDX-License-Identifier: Apache-2.0 import { + ADD_DATASET_FIELD_TAG, + ADD_DATASET_FIELD_TAG_SUCCESS, ADD_DATASET_TAG, ADD_DATASET_TAG_SUCCESS, DELETE_DATASET, + DELETE_DATASET_FIELD_TAG, + DELETE_DATASET_FIELD_TAG_SUCCESS, DELETE_DATASET_SUCCESS, DELETE_DATASET_TAG, DELETE_DATASET_TAG_SUCCESS, @@ -14,8 +18,10 @@ import { } from '../actionCreators/actionTypes' import { Dataset } from '../../types/api' import { + addDatasetFieldTag, addDatasetTag, deleteDataset, + deleteDatasetFieldTag, deleteDatasetTag, fetchDatasetsSuccess, } from '../actionCreators' @@ -41,7 +47,9 @@ export const initialState: IDatasetsState = { export type IDatasetsAction = ReturnType & ReturnType & ReturnType & - ReturnType + ReturnType & + ReturnType & + ReturnType export default (state: IDatasetsState = initialState, action: IDatasetsAction): IDatasetsState => { const { type, payload } = action @@ -67,10 +75,18 @@ export default (state: IDatasetsState = initialState, action: IDatasetsAction): return { ...state, refreshTags: false } case DELETE_DATASET_TAG_SUCCESS: return { ...state, refreshTags: true } + case DELETE_DATASET_FIELD_TAG: + return { ...state, refreshTags: false } + case DELETE_DATASET_FIELD_TAG_SUCCESS: + return { ...state, refreshTags: true } case ADD_DATASET_TAG: return { ...state, refreshTags: false } case ADD_DATASET_TAG_SUCCESS: return { ...state, refreshTags: true } + case ADD_DATASET_FIELD_TAG: + return { ...state, refreshTags: false } + case ADD_DATASET_FIELD_TAG_SUCCESS: + return { ...state, refreshTags: true } default: return state } diff --git a/web/src/store/requests/datasets.ts b/web/src/store/requests/datasets.ts index c61d5d92a5..bfc039b04c 100644 --- a/web/src/store/requests/datasets.ts +++ b/web/src/store/requests/datasets.ts @@ -1,4 +1,4 @@ -// Copyright 2018-2023 contributors to the Marquez project +// Copyright 2018-2024 contributors to the Marquez project // SPDX-License-Identifier: Apache-2.0 import { API_URL } from '../../globals' @@ -56,3 +56,27 @@ export const addDatasetTag = async (namespace: string, datasetName: string, tag: )}/datasets/${datasetName}/tags/${tag}` return genericFetchWrapper(url, { method: 'POST' }, 'addDatasetTag') } + +export const deleteDatasetFieldTag = async ( + namespace: string, + datasetName: string, + tag: string, + field: string +) => { + const url = `${API_URL}/namespaces/${encodeURIComponent( + namespace + )}/datasets/${datasetName}/fields/${field}/tags/${tag}` + return genericFetchWrapper(url, { method: 'DELETE' }, 'deleteDatasetFieldTag') +} + +export const addDatasetFieldTag = async ( + namespace: string, + datasetName: string, + tag: string, + field: string +) => { + const url = `${API_URL}/namespaces/${encodeURIComponent( + namespace + )}/datasets/${datasetName}/fields/${field}/tags/${tag}` + return genericFetchWrapper(url, { method: 'POST' }, 'addDatasetFieldTag') +} diff --git a/web/src/store/sagas/index.ts b/web/src/store/sagas/index.ts index b0c81f6e3e..db01c61eac 100644 --- a/web/src/store/sagas/index.ts +++ b/web/src/store/sagas/index.ts @@ -1,10 +1,12 @@ -// Copyright 2018-2023 contributors to the Marquez project +// Copyright 2018-2024 contributors to the Marquez project // SPDX-License-Identifier: Apache-2.0 import * as Effects from 'redux-saga/effects' import { + ADD_DATASET_FIELD_TAG, ADD_DATASET_TAG, DELETE_DATASET, + DELETE_DATASET_FIELD_TAG, DELETE_DATASET_TAG, DELETE_JOB, FETCH_DATASET, @@ -36,8 +38,10 @@ const call: any = Effects.call import { Job } from '../../types/api' import { Search } from '../../types/api' import { + addDatasetFieldTag, addDatasetTag, deleteDataset, + deleteDatasetFieldTag, deleteDatasetTag, deleteJob, getDataset, @@ -52,8 +56,10 @@ import { getTags, } from '../requests' import { + addDatasetFieldTagSuccess, addDatasetTagSuccess, applicationError, + deleteDatasetFieldTagSuccess, deleteDatasetSuccess, deleteDatasetTagSuccess, deleteJobSuccess, @@ -234,6 +240,24 @@ export function* deleteDatasetTagSaga() { } } +export function* deleteDatasetFieldTagSaga() { + while (true) { + try { + const { payload } = yield take(DELETE_DATASET_FIELD_TAG) + const dataset: Dataset = yield call( + deleteDatasetFieldTag, + payload.namespace, + payload.datasetName, + payload.tag, + payload.field + ) + yield put(deleteDatasetFieldTagSuccess(dataset.name)) + } catch (e) { + yield put(applicationError('Something went wrong while removing tag from dataset field')) + } + } +} + export function* addDatasetTagSaga() { while (true) { try { @@ -251,6 +275,24 @@ export function* addDatasetTagSaga() { } } +export function* addDatasetFieldTagSaga() { + while (true) { + try { + const { payload } = yield take(ADD_DATASET_FIELD_TAG) + const dataset: Dataset = yield call( + addDatasetFieldTag, + payload.namespace, + payload.datasetName, + payload.tag, + payload.field + ) + yield put(addDatasetFieldTagSuccess(dataset.name)) + } catch (e) { + yield put(applicationError('Something went wrong while adding tag to dataset field.')) + } + } +} + export function* fetchDatasetVersionsSaga() { while (true) { try { @@ -308,6 +350,8 @@ export default function* rootSaga(): Generator { deleteDatasetSaga(), deleteDatasetTagSaga(), addDatasetTagSaga(), + deleteDatasetFieldTagSaga(), + addDatasetFieldTagSaga(), ] yield all([...sagasThatAreKickedOffImmediately, ...sagasThatWatchForAction]) From c566656694ffcdbe0355e64f607b09ac0dc41212 Mon Sep 17 00:00:00 2001 From: sharpd Date: Thu, 11 Jan 2024 17:54:55 +1300 Subject: [PATCH 2/8] set Auto Complete to small Signed-off-by: sharpd --- web/src/components/datasets/DatasetTags.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/web/src/components/datasets/DatasetTags.tsx b/web/src/components/datasets/DatasetTags.tsx index 4135e5d10b..fc0afa3e16 100644 --- a/web/src/components/datasets/DatasetTags.tsx +++ b/web/src/components/datasets/DatasetTags.tsx @@ -103,6 +103,7 @@ const DatasetTags: React.FC = (props) => { option.name)} defaultValue={datasetTags} From 2a6fd3bc4b3daef78b46b72820ed9cad20df1c62 Mon Sep 17 00:00:00 2001 From: sharpd Date: Sat, 27 Jan 2024 19:40:19 +1300 Subject: [PATCH 3/8] add decription to dataset tags if exits Signed-off-by: sharpd --- web/src/components/datasets/DatasetTags.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/web/src/components/datasets/DatasetTags.tsx b/web/src/components/datasets/DatasetTags.tsx index fc0afa3e16..44d5f921e3 100644 --- a/web/src/components/datasets/DatasetTags.tsx +++ b/web/src/components/datasets/DatasetTags.tsx @@ -98,7 +98,7 @@ const DatasetTags: React.FC = (props) => { ) }) } - + return ( = (props) => { size='small' disableClearable options={tagData.map((option) => option.name)} + getOptionLabel={(option) => `${option} - ${tagData.find((tagItem) => tagItem.name === option)?.description || 'No Tag Description'}`} defaultValue={datasetTags} onChange={handleTagChange} renderTags={(value: string[]) => formatTags(value, tagData)} From b61cddcd2fae46c2722a785884959e8ea0bae99b Mon Sep 17 00:00:00 2001 From: sharpd Date: Thu, 1 Feb 2024 18:14:22 +1300 Subject: [PATCH 4/8] update dataset tags based on feedback Signed-off-by: sharpd --- .../components/datasets/DatasetDetailPage.tsx | 17 +--- web/src/components/datasets/DatasetTags.tsx | 98 ++++++++++++------- web/src/i18n/config.ts | 1 - 3 files changed, 66 insertions(+), 50 deletions(-) diff --git a/web/src/components/datasets/DatasetDetailPage.tsx b/web/src/components/datasets/DatasetDetailPage.tsx index 51842bacbc..67bfe4739d 100644 --- a/web/src/components/datasets/DatasetDetailPage.tsx +++ b/web/src/components/datasets/DatasetDetailPage.tsx @@ -126,6 +126,11 @@ const DatasetDetailPage: FunctionComponent = (props) => { padding: `0 ${theme.spacing(2)}`, }} > + @@ -151,11 +156,6 @@ const DatasetDetailPage: FunctionComponent = (props) => { {...a11yProps(3)} disableRipple={true} /> - @@ -215,13 +215,6 @@ const DatasetDetailPage: FunctionComponent = (props) => { {tabIndex === 1 && } {tabIndex === 2 && } {tabIndex === 3 && } - {tabIndex === 4 && ( - - )} ) } diff --git a/web/src/components/datasets/DatasetTags.tsx b/web/src/components/datasets/DatasetTags.tsx index 44d5f921e3..355db96c18 100644 --- a/web/src/components/datasets/DatasetTags.tsx +++ b/web/src/components/datasets/DatasetTags.tsx @@ -14,14 +14,17 @@ import { bindActionCreators } from 'redux' import { connect, useSelector } from 'react-redux' import { createTheme } from '@mui/material' import { useTheme } from '@emotion/react' -import Autocomplete, { - AutocompleteChangeDetails, - AutocompleteChangeReason, -} from '@mui/material/Autocomplete' +import Button from '@mui/material/Button' import Chip from '@mui/material/Chip' +import Dialog from '@mui/material/Dialog' +import DialogActions from '@mui/material/DialogActions' +import DialogContent from '@mui/material/DialogContent' +import DialogTitle from '@mui/material/DialogTitle' +import FormControl from '@mui/material/FormControl' import MQTooltip from '../core/tooltip/MQTooltip' -import React, { useEffect } from 'react' -import TextField from '@mui/material/TextField' +import MenuItem from '@mui/material/MenuItem' +import React, { useEffect, useState } from 'react' +import Select from '@mui/material/Select' interface DatasetTagsProps { namespace: string @@ -53,23 +56,26 @@ const DatasetTags: React.FC = (props) => { datasetField, } = props + const [isDialogOpen, setDialogOpen] = useState(false) + const [listTag, setListTag] = useState('') + + const openDialog = () => setDialogOpen(true) + const closeDialog = () => setDialogOpen(false) + useEffect(() => { fetchTags() }, []) const tagData = useSelector((state: IState) => state.tags.tags) - const handleTagChange = ( - _event: React.SyntheticEvent, - _value: string[], - reason: AutocompleteChangeReason, - details?: AutocompleteChangeDetails | undefined - ) => { - if (reason === 'selectOption' && details) { - datasetField - ? addDatasetFieldTag(namespace, datasetName, details.option, datasetField) - : addDatasetTag(namespace, datasetName, details.option) - } + const handleTagListChange = (event: any) => { + setListTag(event.target.value) + } + + const handleTagChange = () => { + datasetField + ? addDatasetFieldTag(namespace, datasetName, listTag, datasetField) + : addDatasetTag(namespace, datasetName, listTag) } const handleDelete = (deletedTag: string) => { @@ -98,27 +104,45 @@ const DatasetTags: React.FC = (props) => { ) }) } - + return ( - option.name)} - getOptionLabel={(option) => `${option} - ${tagData.find((tagItem) => tagItem.name === option)?.description || 'No Tag Description'}`} - defaultValue={datasetTags} - onChange={handleTagChange} - renderTags={(value: string[]) => formatTags(value, tagData)} - renderInput={(params) => ( - - )} - /> + <> + + {formatTags(datasetTags, tagData)} + + Add Tags + + + + + + + + + + + ) } diff --git a/web/src/i18n/config.ts b/web/src/i18n/config.ts index 99a4ed2eb5..fb4118b76f 100644 --- a/web/src/i18n/config.ts +++ b/web/src/i18n/config.ts @@ -82,7 +82,6 @@ i18next datasets: { latest_tab: 'LATEST SCHEMA', history_tab: 'VERSION HISTORY', - dataset_tags_tab: 'TAGS', column_lineage_tab: 'COLUMN LINEAGE', dialog_delete: 'DELETE', dialog_confirmation_title: 'Are you sure?', From 049bc1b417299f3f470056a3be641e9f2e4d917f Mon Sep 17 00:00:00 2001 From: sharpd Date: Fri, 2 Feb 2024 12:28:51 +1300 Subject: [PATCH 5/8] change button icon/add translation/add additional var to tooltip Signed-off-by: sharpd --- web/src/components/core/tooltip/MQTooltip.tsx | 4 ++- web/src/components/datasets/DatasetTags.tsx | 21 ++++++++---- web/src/i18n/config.ts | 32 ++++++++++++++++--- 3 files changed, 45 insertions(+), 12 deletions(-) diff --git a/web/src/components/core/tooltip/MQTooltip.tsx b/web/src/components/core/tooltip/MQTooltip.tsx index a058de010e..976fac0e47 100644 --- a/web/src/components/core/tooltip/MQTooltip.tsx +++ b/web/src/components/core/tooltip/MQTooltip.tsx @@ -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 = ({ title, children }) => { +const MQTooltip: React.FC = ({ title, children, placement }) => { const theme = createTheme(useTheme()) return ( = (props) => { const openDialog = () => setDialogOpen(true) const closeDialog = () => setDialogOpen(false) + const i18next = require('i18next') useEffect(() => { fetchTags() @@ -107,12 +110,16 @@ const DatasetTags: React.FC = (props) => { return ( <> - + + + {formatTags(datasetTags, tagData)} - Add Tags + {i18next.t('dataset_tags.dialogtitle')} From 4889bf4b2fbdbc9a3dbfc452a4b2761ae93bee4b Mon Sep 17 00:00:00 2001 From: sharpd Date: Tue, 6 Feb 2024 13:12:19 +1300 Subject: [PATCH 7/8] more formatting changes to list drop down Signed-off-by: sharpd --- web/src/components/core/text/MqText.tsx | 8 +++++++- web/src/components/datasets/DatasetTags.tsx | 4 +++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/web/src/components/core/text/MqText.tsx b/web/src/components/core/text/MqText.tsx index cf918eef2a..169f90cd03 100644 --- a/web/src/components/core/text/MqText.tsx +++ b/web/src/components/core/text/MqText.tsx @@ -22,6 +22,7 @@ interface OwnProps { inverse?: boolean highlight?: boolean paragraph?: boolean + overflowHidden?: boolean color?: string link?: boolean href?: string @@ -48,6 +49,7 @@ const MqText: React.FC = ({ link, linkTo, paragraph, + overflowHidden, href, inverse, inline, @@ -119,6 +121,9 @@ const MqText: React.FC = ({ paragraph: { marginBottom: theme.spacing(2), }, + overflowHidden: { + overflow: 'hidden', + }, } const conditionalClasses = Object.assign( @@ -135,7 +140,8 @@ const MqText: React.FC = ({ small ? classesObject.small : {}, link ? classesObject.link : {}, paragraph ? classesObject.paragraph : {}, - subheading ? classesObject.subheading : {} + subheading ? classesObject.subheading : {}, + overflowHidden ? classesObject.overflowHidden : {} ) const style = { diff --git a/web/src/components/datasets/DatasetTags.tsx b/web/src/components/datasets/DatasetTags.tsx index d29cb9604a..068e0867ec 100644 --- a/web/src/components/datasets/DatasetTags.tsx +++ b/web/src/components/datasets/DatasetTags.tsx @@ -141,7 +141,9 @@ const DatasetTags: React.FC = (props) => { >
{option.name} - {option.description || 'No Tag Description'} + + {option.description || 'No Tag Description'} +
))} From a54067e77cac0b05ba4c7e1b20c6cf3cc2f2c64a Mon Sep 17 00:00:00 2001 From: sharpd Date: Sat, 10 Feb 2024 15:20:33 +1300 Subject: [PATCH 8/8] update dataset details to remove readonly Signed-off-by: sharpd --- web/src/components/datasets/DatasetDetailPage.tsx | 6 ------ 1 file changed, 6 deletions(-) diff --git a/web/src/components/datasets/DatasetDetailPage.tsx b/web/src/components/datasets/DatasetDetailPage.tsx index 174ce7064f..663b854075 100644 --- a/web/src/components/datasets/DatasetDetailPage.tsx +++ b/web/src/components/datasets/DatasetDetailPage.tsx @@ -127,17 +127,11 @@ const DatasetDetailPage: FunctionComponent = (props) => { padding: `0 ${theme.spacing(2)}`, }} > -