From 2bb6064d1cf6e080bea7795624d95597a1327907 Mon Sep 17 00:00:00 2001 From: cgu Date: Wed, 16 Dec 2020 18:19:01 -0500 Subject: [PATCH 1/4] Add search filters for table search --- .../DataTableNavigator.scss | 8 - .../DataTableNavigator/DataTableNavigator.tsx | 428 ++++++++---------- .../DataTableNavigatorSearch.scss | 46 ++ .../DataTableNavigatorSearch.tsx | 135 ++++++ .../DataTableTags/CreateDataTableTag.tsx | 4 +- .../DataTableTags/TableTagGroupSelect.tsx | 45 ++ .../QuerySnippetNavigator.tsx | 2 +- .../QueryViewNavigator/QueryViewFilter.tsx | 2 +- .../QueryViewFilterPicker.tsx | 4 +- .../components/Search/SearchOverview.scss | 2 +- .../components/Search/SearchOverview.tsx | 41 +- .../webapp/redux/dataTableSearch/action.ts | 11 + .../webapp/redux/dataTableSearch/reducer.ts | 4 + datahub/webapp/redux/dataTableSearch/types.ts | 6 + datahub/webapp/ui/Button/IconButton.scss | 1 + 15 files changed, 456 insertions(+), 283 deletions(-) create mode 100644 datahub/webapp/components/DataTableNavigator/DataTableNavigatorSearch.scss create mode 100644 datahub/webapp/components/DataTableNavigator/DataTableNavigatorSearch.tsx create mode 100644 datahub/webapp/components/DataTableTags/TableTagGroupSelect.tsx diff --git a/datahub/webapp/components/DataTableNavigator/DataTableNavigator.scss b/datahub/webapp/components/DataTableNavigator/DataTableNavigator.scss index cac5c931a..af1341a4c 100644 --- a/datahub/webapp/components/DataTableNavigator/DataTableNavigator.scss +++ b/datahub/webapp/components/DataTableNavigator/DataTableNavigator.scss @@ -13,14 +13,6 @@ } } - .navigator-search-input { - display: flex; - border-bottom: var(--border); - .SearchBar { - flex-grow: 1; - } - } - .table-scroll-wrapper { flex: 1; } diff --git a/datahub/webapp/components/DataTableNavigator/DataTableNavigator.tsx b/datahub/webapp/components/DataTableNavigator/DataTableNavigator.tsx index 05187cfbb..4117b1ec9 100644 --- a/datahub/webapp/components/DataTableNavigator/DataTableNavigator.tsx +++ b/datahub/webapp/components/DataTableNavigator/DataTableNavigator.tsx @@ -1,10 +1,7 @@ -import React from 'react'; +import React, { useCallback, useState, useEffect } from 'react'; import classNames from 'classnames'; -import { decorate } from 'core-decorators'; -import { bind } from 'lodash-decorators'; -import memoizeOne from 'memoize-one'; -import { connect } from 'react-redux'; -import { withRouter, RouteComponentProps } from 'react-router-dom'; +import { useSelector, useDispatch } from 'react-redux'; +import { useHistory } from 'react-router-dom'; import * as dataTableSearchActions from 'redux/dataTableSearch/action'; import { IStoreState, Dispatch } from 'redux/store/types'; @@ -13,257 +10,216 @@ import { ITableSearchFilters, } from 'redux/dataTableSearch/types'; import { queryMetastoresSelector } from 'redux/dataSources/selector'; -import { IQueryMetastore } from 'const/metastore'; import { InfinityScroll } from 'ui/InfinityScroll/InfinityScroll'; -import { ListLink } from 'ui/Link/ListLink'; -import { SearchBar } from 'ui/SearchBar/SearchBar'; import { Select, makeSelectOptions } from 'ui/Select/Select'; -import { Tabs } from 'ui/Tabs/Tabs'; +import { ListLink } from 'ui/Link/ListLink'; +import { DataTableNavigatorSearch } from './DataTableNavigatorSearch'; import './DataTableNavigator.scss'; -const DATA_TABLE_TABS = [ - { - name: 'Featured', - key: 'golden', - }, - { - name: 'All', - key: 'all', - }, -]; - interface ITableResultWithSelection extends ITableSearchResult { selected: boolean; } -interface IDataTableNavigatorOwnProps extends RouteComponentProps { - onTableRowClick?: (tableId: number, e: MouseEvent) => any; +interface IDataTableNavigatorProps { + onTableRowClick?: (tableId: number, e: React.MouseEvent) => any; selectedTableId?: number; } -type StateProps = ReturnType; -type DispatchProps = ReturnType; -type IDataTableNavigatorProps = IDataTableNavigatorOwnProps & - StateProps & - DispatchProps; -interface IDataTableNavigatorState { - selectedTabKey: string; -} -class DataTableNavigatorComponent extends React.PureComponent< - IDataTableNavigatorProps, - IDataTableNavigatorState -> { - public constructor(props) { - super(props); - - const index = this.props.searchFilters['golden'] === true ? 0 : 1; - this.state = { - selectedTabKey: DATA_TABLE_TABS[index].key, - }; - } +const useDataTableNavigatorReduxState = () => { + const queryMetastores = useSelector(queryMetastoresSelector); + const dataTableSearchState = useSelector((state: IStoreState) => ({ + dataTables: state.dataTableSearch.results, + numDataTables: state.dataTableSearch.count, + searchString: state.dataTableSearch.searchString, + searchFilters: state.dataTableSearch.searchFilters, + metastoreId: state.dataTableSearch.metastoreId, + isSearching: !!state.dataTableSearch.searchRequest, + })); + return { + ...dataTableSearchState, + queryMetastores, + }; +}; - @bind - public setDefaultMetastoreForEnvironment() { - this._autoClearMetastoreResults(this.props.queryMetastores.length); - this._setDefaultMetastoreForEnvironment( - this.props.queryMetastores, - this.props.metastoreId - ); - } +const useDataTableNavigatorReduxDispatch = () => { + const dispatch: Dispatch = useDispatch(); - @bind - @decorate(memoizeOne) - public _autoClearMetastoreResults(metastoreLength: number) { - if (metastoreLength === 0) { - this.props.resetSearch(); + return { + resetSearchFilter: useCallback( + () => dispatch(dataTableSearchActions.resetSearchFilter()), + [] + ), + updateSearchString: useCallback( + (searchString: string) => + dispatch( + dataTableSearchActions.updateSearchString(searchString) + ), + [] + ), + updateSearchFilter: useCallback( + ( + filterKey: K, + filterVal: ITableSearchFilters[K] + ) => + dispatch( + dataTableSearchActions.updateSearchFilter( + filterKey, + filterVal + ) + ), + [] + ), + selectMetastore: useCallback( + (metastoreId: number) => + dispatch(dataTableSearchActions.selectMetastore(metastoreId)), + [] + ), + getMoreDataTable: useCallback( + () => dispatch(dataTableSearchActions.getMoreDataTable()), + [] + ), + resetSearch: useCallback( + () => dispatch(dataTableSearchActions.resetSearch()), + [] + ), + }; +}; + +export const DataTableNavigator: React.FC = ({ + onTableRowClick, + selectedTableId, +}) => { + const history = useHistory(); + const { + queryMetastores, + dataTables, + numDataTables, + searchString, + searchFilters, + metastoreId, + isSearching, + } = useDataTableNavigatorReduxState(); + const { + resetSearchFilter, + updateSearchString, + updateSearchFilter, + selectMetastore, + getMoreDataTable, + resetSearch, + } = useDataTableNavigatorReduxDispatch(); + + const noMetastore = queryMetastores.length === 0; + useEffect(() => { + if (noMetastore) { + resetSearch(); } - } + }, [noMetastore]); - @bind - @decorate(memoizeOne) - public _setDefaultMetastoreForEnvironment( - queryMetastores: IQueryMetastore[], - metastoreId: number - ) { + useEffect(() => { if ( queryMetastores.length > 0 && !queryMetastores.find((metastore) => metastore.id === metastoreId) ) { - this.props.selectMetastore(queryMetastores[0].id); - } - } - - @bind - public handleMetastoreChange(evt: React.ChangeEvent) { - this.props.selectMetastore(Number(evt.target.value)); - } - - @bind - public onSegmentChange(selectedTabKey: string) { - let newValue = null; - if (selectedTabKey === 'golden') { - newValue = true; + selectMetastore(queryMetastores[0].id); } - this.setState({ selectedTabKey }); - this.props.updateSearchFilter('golden', newValue); - } - - @bind - public tableRowRenderer(table: ITableResultWithSelection) { - const tableName = `${table.schema}.${table.name}`; - const className = classNames({ - selected: table.selected, - }); - - return ( - - ); - } - - @bind - public handleTableRowClick(tableId: number, event: MouseEvent) { - if (this.props.onTableRowClick) { - this.props.onTableRowClick(tableId, event); - } else { - // default behavior - this.props.history.push(`/table/${tableId}/`); - } - } - - @bind - public handleSearch(searchString: string) { - this.props.updateSearchString(searchString); - } - - public componentDidMount() { - this.props.mapQueryParamToState(); - this.setDefaultMetastoreForEnvironment(); - } - - public componentDidUpdate() { - this.setDefaultMetastoreForEnvironment(); - } - - public render() { - const { - dataTables, - searchString, - selectedTableId, - queryMetastores, - metastoreId, - numDataTables, - isSearching, - } = this.props; - - const metastorePicker = - queryMetastores.length > 1 ? ( -
- -
- ) : null; - - const searchDOM = ( -
- -
- ); - - const tabsDOM = ( -
- ) => { + selectMetastore(Number(evt.target.value)); + }, + [selectMetastore] + ); + + const handleTableRowClick = useCallback( + (tableId: number, event: React.MouseEvent) => { + if (onTableRowClick) { + onTableRowClick(tableId, event); + } else { + // default behavior + history.push(`/table/${tableId}/`); + } + }, + [onTableRowClick, history] + ); + + const handleSearch = useCallback( + (searchString: string) => { + updateSearchString(searchString); + }, + [updateSearchString] + ); + + const tableRowRenderer = useCallback( + (table: ITableResultWithSelection) => { + const tableName = `${table.schema}.${table.name}`; + const className = classNames({ + selected: table.selected, + }); + + return ( + handleTableRowClick(table.id, event)} + isRow + title={tableName} /> + ); + }, + [handleTableRowClick] + ); + + const metastorePicker = + queryMetastores.length > 1 ? ( +
+
- ); - - const dataTablesWithSelection: ITableResultWithSelection[] = dataTables.map( - (table) => ({ - ...table, - selected: selectedTableId === table.id, - }) - ); - - const tablesDOM = ( -
- - elements={dataTablesWithSelection} - onLoadMore={this.props.getMoreDataTable} - hasMore={numDataTables > dataTables.length || isSearching} - itemRenderer={this.tableRowRenderer} - itemHeight={28} - /> -
- ); - - return ( -
- {metastorePicker} - {searchDOM} - {tabsDOM} - {tablesDOM} -
- ); - } -} - -function mapStateToProps(state: IStoreState) { - return { - queryMetastores: queryMetastoresSelector(state), - dataTables: state.dataTableSearch.results, - numDataTables: state.dataTableSearch.count, - searchString: state.dataTableSearch.searchString, - searchFilters: state.dataTableSearch.searchFilters, - metastoreId: state.dataTableSearch.metastoreId, - isSearching: !!state.dataTableSearch.searchRequest, - }; -} - -const mapDispatchToProps = (dispatch: Dispatch) => ({ - mapQueryParamToState: () => - dispatch(dataTableSearchActions.mapQueryParamToState()), - updateSearchString: (searchString: string) => - dispatch(dataTableSearchActions.updateSearchString(searchString)), - updateSearchFilter: ( - filterKey: K, - filterVal: ITableSearchFilters[K] - ) => - dispatch( - dataTableSearchActions.updateSearchFilter(filterKey, filterVal) - ), - selectMetastore: (metastoreId: number) => - dispatch(dataTableSearchActions.selectMetastore(metastoreId)), - getMoreDataTable: () => dispatch(dataTableSearchActions.getMoreDataTable()), - resetSearch: () => dispatch(dataTableSearchActions.resetSearch()), -}); - -export const DataTableNavigator = withRouter( - connect(mapStateToProps, mapDispatchToProps)(DataTableNavigatorComponent) -); + ) : null; + + const dataTablesWithSelection: ITableResultWithSelection[] = dataTables.map( + (table) => ({ + ...table, + selected: selectedTableId === table.id, + }) + ); + + const tablesDOM = ( +
+ + elements={dataTablesWithSelection} + onLoadMore={getMoreDataTable} + hasMore={numDataTables > dataTables.length || isSearching} + itemRenderer={tableRowRenderer} + itemHeight={28} + /> +
+ ); + + return ( +
+ {metastorePicker} + + {tablesDOM} +
+ ); +}; diff --git a/datahub/webapp/components/DataTableNavigator/DataTableNavigatorSearch.scss b/datahub/webapp/components/DataTableNavigator/DataTableNavigatorSearch.scss new file mode 100644 index 000000000..156e2ac72 --- /dev/null +++ b/datahub/webapp/components/DataTableNavigator/DataTableNavigatorSearch.scss @@ -0,0 +1,46 @@ +.DataTableNavigatorSearch { + border-bottom: var(--border); + > .SearchBar { + flex-grow: 1; + } + > .IconButton { + padding-right: 12px; + .ping-message { + top: -5px; + right: 6px; + padding: 0px 5px 0px 5px; + font-size: var(--xxsmall-text-size); + } + } +} + +.DataTableNavigatorSearchFilter { + padding: 0px 10px; + + .search-filter-row { + display: flex; + align-items: flex-start; + padding: 10px 0px; + + &.toggle-padding { + padding-top: 7px; + padding-bottom: 2px; + } + + &:not(:last-child) { + border-bottom: var(--border); + } + + .Title { + margin-left: 10px; + min-width: 70px; + } + + .search-filter-row-item { + flex: 1; + .DebouncedInput input { + padding: 2px 8px; + } + } + } +} diff --git a/datahub/webapp/components/DataTableNavigator/DataTableNavigatorSearch.tsx b/datahub/webapp/components/DataTableNavigator/DataTableNavigatorSearch.tsx new file mode 100644 index 000000000..0c0208e48 --- /dev/null +++ b/datahub/webapp/components/DataTableNavigator/DataTableNavigatorSearch.tsx @@ -0,0 +1,135 @@ +import React, { useState, useRef, useMemo, useCallback } from 'react'; +import { ITableSearchFilters } from 'redux/dataTableSearch/types'; + +import { useToggle } from 'hooks/useToggle'; + +import { Popover } from 'ui/Popover/Popover'; +import { ToggleSwitch } from 'ui/ToggleSwitch/ToggleSwitch'; +import { Title } from 'ui/Title/Title'; +import { IconButton } from 'ui/Button/IconButton'; +import { SearchBar } from 'ui/SearchBar/SearchBar'; +import { TableTagGroupSelect } from 'components/DataTableTags/TableTagGroupSelect'; + +import './DataTableNavigatorSearch.scss'; +import { Button } from 'ui/Button/Button'; + +export const DataTableNavigatorSearch: React.FC<{ + searchString: string; + onSearch: (s: string) => void; + searchFilters: ITableSearchFilters; + updateSearchFilter: ( + filterKey: K, + filterVal: ITableSearchFilters[K] + ) => void; + resetSearchFilter: () => void; +}> = ({ + searchString, + onSearch, + searchFilters, + updateSearchFilter, + resetSearchFilter, +}) => { + const [showSearchFilter, setShowSearchFilter] = useState(false); + const toggleSearchFilter = useToggle(setShowSearchFilter); + const filterButtonRef = useRef(); + const searchFiltersSize = useMemo(() => Object.keys(searchFilters).length, [ + searchFilters, + ]); + + const updateTags = useCallback( + (newTags: string[]) => { + updateSearchFilter('tags', newTags.length ? newTags : null); + }, + [updateSearchFilter] + ); + + const searchFiltersPickerDOM = showSearchFilter && ( + +
+
+
+
+ + + updateSearchFilter( + 'golden', + checked ? true : null + ) + } + /> + + + + updateSearchFilter( + 'schema', + s.length ? s : null + ) + } + placeholder="Full schema name" + /> + + + + +
+
+
+ ); + + return ( +
+ + 0} + ping={searchFiltersSize > 0 ? String(searchFiltersSize) : null} + /> + {searchFiltersPickerDOM} +
+ ); +}; + +const SearchFilterRow: React.FC<{ title: string; className?: string }> = ({ + title, + children, + className, +}) => ( +
+ + {title} + +
{children}
+
+); diff --git a/datahub/webapp/components/DataTableTags/CreateDataTableTag.tsx b/datahub/webapp/components/DataTableTags/CreateDataTableTag.tsx index eaa33a1ef..3d62e04ab 100644 --- a/datahub/webapp/components/DataTableTags/CreateDataTableTag.tsx +++ b/datahub/webapp/components/DataTableTags/CreateDataTableTag.tsx @@ -39,7 +39,7 @@ export const CreateDataTableTag: React.FunctionComponent = ({ }, []); const handleCreateTag = React.useCallback( - (val) => { + (val: string) => { createTag(val).finally(() => setShowSelect(false)); }, [createTag] @@ -50,7 +50,7 @@ export const CreateDataTableTag: React.FunctionComponent = ({ {showSelect ? (
handleCreateTag(val)} + onSelect={handleCreateTag} isValidCheck={isValidCheck} existingTags={existingTags} /> diff --git a/datahub/webapp/components/DataTableTags/TableTagGroupSelect.tsx b/datahub/webapp/components/DataTableTags/TableTagGroupSelect.tsx new file mode 100644 index 000000000..2e32f2123 --- /dev/null +++ b/datahub/webapp/components/DataTableTags/TableTagGroupSelect.tsx @@ -0,0 +1,45 @@ +import React, { useMemo } from 'react'; +import { HoverIconTag } from 'ui/Tag/Tag'; +import { TableTagSelect } from './TableTagSelect'; + +export const TableTagGroupSelect: React.FC<{ + tags?: string[]; + updateTags: (newTags: string[]) => void; +}> = ({ tags: propsTag, updateTags }) => { + const tags = useMemo(() => propsTag ?? [], [propsTag]); + + const handleTagSelect = React.useCallback( + (tag: string) => { + updateTags([...tags, tag]); + }, + [tags, updateTags] + ); + + const handleTagRemove = React.useCallback( + (tag: string) => { + updateTags(tags.filter((existingTag) => existingTag !== tag)); + }, + [tags, updateTags] + ); + + const tagsListDOM = tags.length ? ( +
+ {tags.map((tag) => ( + handleTagRemove(tag)} + > + {tag} + + ))} +
+ ) : null; + + return ( +
+ {tagsListDOM} + +
+ ); +}; diff --git a/datahub/webapp/components/QuerySnippetNavigator/QuerySnippetNavigator.tsx b/datahub/webapp/components/QuerySnippetNavigator/QuerySnippetNavigator.tsx index 3de05fa73..dfccb179f 100644 --- a/datahub/webapp/components/QuerySnippetNavigator/QuerySnippetNavigator.tsx +++ b/datahub/webapp/components/QuerySnippetNavigator/QuerySnippetNavigator.tsx @@ -242,7 +242,7 @@ class QuerySnippetNavigatorComponent extends React.PureComponent< /> diff --git a/datahub/webapp/components/QueryViewNavigator/QueryViewFilterPicker.tsx b/datahub/webapp/components/QueryViewNavigator/QueryViewFilterPicker.tsx index 4b6ae76e6..3adf154f0 100644 --- a/datahub/webapp/components/QueryViewNavigator/QueryViewFilterPicker.tsx +++ b/datahub/webapp/components/QueryViewNavigator/QueryViewFilterPicker.tsx @@ -12,7 +12,7 @@ import { IQueryViewFilter } from 'redux/queryView/types'; import { Title } from 'ui/Title/Title'; const StyledPicker = styled.div` - padding: 30px; + padding: 10px; `; interface IQueryViewFilterPickerProps { @@ -29,7 +29,7 @@ export const QueryViewFilterPicker: React.FunctionComponent { const enginePickerField = ( -
+
Filter by Engine
diff --git a/datahub/webapp/components/Search/SearchOverview.scss b/datahub/webapp/components/Search/SearchOverview.scss index a0917d733..5f89a18fa 100644 --- a/datahub/webapp/components/Search/SearchOverview.scss +++ b/datahub/webapp/components/Search/SearchOverview.scss @@ -122,7 +122,7 @@ .add-authors { margin-top: 4px; } - .tables-tag-list { + .TableTagGroupSelect .tables-tag-list { margin-left: -4px; } } diff --git a/datahub/webapp/components/Search/SearchOverview.tsx b/datahub/webapp/components/Search/SearchOverview.tsx index 649b7538d..fcd597c53 100644 --- a/datahub/webapp/components/Search/SearchOverview.tsx +++ b/datahub/webapp/components/Search/SearchOverview.tsx @@ -41,6 +41,7 @@ import { HoverIconTag } from 'ui/Tag/Tag'; import { PrettyNumber } from 'ui/PrettyNumber/PrettyNumber'; import './SearchOverview.scss'; +import { TableTagGroupSelect } from 'components/DataTableTags/TableTagGroupSelect'; const secondsPerDay = 60 * 60 * 24; const inputDateFormat = 'YYYY-MM-DD'; @@ -237,42 +238,18 @@ export const SearchOverview: React.FunctionComponent = () => {
); - const handleTagSelect = React.useCallback( - (tag: string) => { - const tagFilter = [...(searchFilters.tags || []), tag]; - updateSearchFilter('tags', tagFilter); + const updateTags = React.useCallback( + (newTags: string[]) => { + updateSearchFilter('tags', newTags.length ? newTags : null); }, - [searchFilters?.tags] - ); - - const handleTagRemove = React.useCallback( - (tag: string) => { - const tagFilter = (searchFilters?.tags || []).filter( - (existingTag) => existingTag !== tag - ); - updateSearchFilter('tags', tagFilter.length ? tagFilter : null); - }, - [searchFilters?.tags] + [updateSearchFilter] ); const tagDOM = ( -
-
- {(searchFilters?.tags || []).map((tag) => ( - handleTagRemove(tag)} - > - {tag} - - ))} -
- -
+ ); const metastoreSelectDOM = diff --git a/datahub/webapp/redux/dataTableSearch/action.ts b/datahub/webapp/redux/dataTableSearch/action.ts index be6133f16..ba2e210f5 100644 --- a/datahub/webapp/redux/dataTableSearch/action.ts +++ b/datahub/webapp/redux/dataTableSearch/action.ts @@ -8,6 +8,7 @@ import { IDataTableSearchState, ITableSearchFilters, } from './types'; +import { dispatch } from 'd3'; const BATCH_LOAD_SIZE = 100; @@ -206,6 +207,16 @@ export function updateSearchFilter( }; } +export function resetSearchFilter(): ThunkResult { + return (dispatch, getState) => { + dispatch({ + type: '@@dataTableSearch/DATA_TABLE_FILTER_RESET', + }); + mapStateToQueryParam(getState().dataTableSearch); + dispatch(searchDataTable()); + }; +} + export function selectMetastore( metastoreId: number ): ThunkResult> { diff --git a/datahub/webapp/redux/dataTableSearch/reducer.ts b/datahub/webapp/redux/dataTableSearch/reducer.ts index 194cb57a3..77a0f2a5e 100644 --- a/datahub/webapp/redux/dataTableSearch/reducer.ts +++ b/datahub/webapp/redux/dataTableSearch/reducer.ts @@ -75,6 +75,10 @@ export default function dataTableSearch( } return; } + case '@@dataTableSearch/DATA_TABLE_FILTER_RESET': { + draft.searchFilters = {}; + return; + } case '@@dataTableSearch/DATA_TABLE_SEARCH_SELECT_METASTORE': { draft.metastoreId = action.payload.metastoreId; return; diff --git a/datahub/webapp/redux/dataTableSearch/types.ts b/datahub/webapp/redux/dataTableSearch/types.ts index ab434703c..c806e93c0 100644 --- a/datahub/webapp/redux/dataTableSearch/types.ts +++ b/datahub/webapp/redux/dataTableSearch/types.ts @@ -14,6 +14,7 @@ export interface ITableSearchFilters { tags?: string[]; startDate?: number; endDate?: number; + schema?: string; } export interface IDataTableSearchResultResetAction extends Action { @@ -75,6 +76,10 @@ export interface IDataTableSearchFilterUpdateAction extends Action { }; } +export interface IDataTableSearchResetFilterAction extends Action { + type: '@@dataTableSearch/DATA_TABLE_FILTER_RESET'; +} + export interface IDataTableSearchMoreAction extends Action { type: '@@dataTableSearch/DATA_TABLE_SEARCH_MORE'; payload: { @@ -91,6 +96,7 @@ export type DataTableSearchAction = | IDataTableSearchReceiveQueryParamAction | IDataTableSearchStringUpdateAction | IDataTableSearchFilterUpdateAction + | IDataTableSearchResetFilterAction | IDataTableSearchMoreAction | IDataTableSearchSelectMetastoreAction; diff --git a/datahub/webapp/ui/Button/IconButton.scss b/datahub/webapp/ui/Button/IconButton.scss index 98daa0bff..1be051078 100644 --- a/datahub/webapp/ui/Button/IconButton.scss +++ b/datahub/webapp/ui/Button/IconButton.scss @@ -5,6 +5,7 @@ transition: color 0.2s ease-out; transition: fill 0.2s ease-out; display: inline-flex; + position: relative; &.invert-circle { background-color: var(--color-primary-3); From b66f10ac6cd53c704cb92d764fe5527c2f867c2a Mon Sep 17 00:00:00 2001 From: cgu Date: Wed, 16 Dec 2020 19:56:58 -0500 Subject: [PATCH 2/4] Resolved comments --- .../DataTableNavigatorSearch.scss | 18 ++++++++++-------- .../DataTableNavigatorSearch.tsx | 17 ++++++++--------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/datahub/webapp/components/DataTableNavigator/DataTableNavigatorSearch.scss b/datahub/webapp/components/DataTableNavigator/DataTableNavigatorSearch.scss index 156e2ac72..ebda3c4ea 100644 --- a/datahub/webapp/components/DataTableNavigator/DataTableNavigatorSearch.scss +++ b/datahub/webapp/components/DataTableNavigator/DataTableNavigatorSearch.scss @@ -8,29 +8,31 @@ .ping-message { top: -5px; right: 6px; - padding: 0px 5px 0px 5px; + padding: 0px 4px 0px 4px; font-size: var(--xxsmall-text-size); } } } .DataTableNavigatorSearchFilter { - padding: 0px 10px; + padding: 4px 12px; + position: relative; + + .filter-reset-button { + position: absolute; + right: 12px; + top: 12px; + } .search-filter-row { display: flex; align-items: flex-start; - padding: 10px 0px; + padding: 8px 0px; &.toggle-padding { - padding-top: 7px; padding-bottom: 2px; } - &:not(:last-child) { - border-bottom: var(--border); - } - .Title { margin-left: 10px; min-width: 70px; diff --git a/datahub/webapp/components/DataTableNavigator/DataTableNavigatorSearch.tsx b/datahub/webapp/components/DataTableNavigator/DataTableNavigatorSearch.tsx index 0c0208e48..c1cde826d 100644 --- a/datahub/webapp/components/DataTableNavigator/DataTableNavigatorSearch.tsx +++ b/datahub/webapp/components/DataTableNavigator/DataTableNavigatorSearch.tsx @@ -50,15 +50,14 @@ export const DataTableNavigatorSearch: React.FC<{ layout={['right', 'top']} >
-
-
+