Skip to content

Commit f8ede9b

Browse files
authored
feat(ui/search): option to sort browse paths (#10268)
1 parent d546f65 commit f8ede9b

File tree

6 files changed

+115
-15
lines changed

6 files changed

+115
-15
lines changed

datahub-web-react/src/app/search/sidebar/BrowseNode.tsx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {
2222
import useSidebarAnalytics from './useSidebarAnalytics';
2323
import EntityLink from './EntityLink';
2424
import { EntityType } from '../../../types.generated';
25+
import { SortBy, useSort } from './useSort';
2526

2627
const FolderStyled = styled(FolderOutlined)`
2728
font-size: 16px;
@@ -34,7 +35,11 @@ const Count = styled(Typography.Text)`
3435
padding-right: 2px;
3536
`;
3637

37-
const BrowseNode = () => {
38+
interface EntityNodeProps {
39+
sortBy: string;
40+
}
41+
42+
const BrowseNode: React.FC<EntityNodeProps> = ({ sortBy }) => {
3843
const isBrowsePathPrefix = useIsBrowsePathPrefix();
3944
const isBrowsePathSelected = useIsBrowsePathSelected();
4045
const onSelectBrowsePath = useOnSelectBrowsePath();
@@ -71,6 +76,8 @@ const BrowseNode = () => {
7176

7277
const color = '#000';
7378

79+
const sortedGroups = useSort(groups, sortBy as SortBy);
80+
7481
return (
7582
<ExpandableNode
7683
isOpen={isOpen && !isClosing && loaded}
@@ -105,7 +112,7 @@ const BrowseNode = () => {
105112
}
106113
body={
107114
<ExpandableNode.Body>
108-
{groups.map((group) => (
115+
{sortedGroups.map((group) => (
109116
<BrowseProvider
110117
key={group.name}
111118
entityAggregation={entityAggregation}
@@ -114,7 +121,7 @@ const BrowseNode = () => {
114121
browseResultGroup={group}
115122
parentPath={path}
116123
>
117-
<BrowseNode />
124+
<BrowseNode sortBy={sortBy} />
118125
</BrowseProvider>
119126
))}
120127
{error && <SidebarLoadingError onClickRetry={retry} />}

datahub-web-react/src/app/search/sidebar/BrowseSidebar.tsx

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
import React, { useState } from 'react';
22
import styled from 'styled-components';
3-
import { Typography } from 'antd';
3+
import { Select, Tooltip, Typography } from 'antd';
4+
import Icon, { CaretDownFilled } from '@ant-design/icons';
45
import EntityNode from './EntityNode';
56
import { BrowseProvider } from './BrowseContext';
67
import SidebarLoadingError from './SidebarLoadingError';
78
import { SEARCH_RESULTS_BROWSE_SIDEBAR_ID } from '../../onboarding/config/SearchOnboardingConfig';
89
import useSidebarEntities from './useSidebarEntities';
9-
import { ANTD_GRAY_V2 } from '../../entity/shared/constants';
10+
import { ANTD_GRAY, ANTD_GRAY_V2 } from '../../entity/shared/constants';
1011
import { ProfileSidebarResizer } from '../../entity/shared/containers/profile/sidebar/ProfileSidebarResizer';
12+
import SortIcon from '../../../images/sort.svg?react';
1113

1214
export const MAX_BROWSER_WIDTH = 500;
1315
export const MIN_BROWSWER_WIDTH = 200;
@@ -24,6 +26,7 @@ export const SidebarWrapper = styled.div<{ visible: boolean; width: number }>`
2426
const SidebarHeader = styled.div`
2527
display: flex;
2628
align-items: center;
29+
justify-content: space-between;
2730
padding-left: 24px;
2831
height: 47px;
2932
border-bottom: 1px solid ${(props) => props.theme.styles['border-color-base']};
@@ -39,6 +42,26 @@ const SidebarBody = styled.div<{ visible: boolean }>`
3942
white-space: nowrap;
4043
`;
4144

45+
const SelectWrapper = styled.div`
46+
display: inline-flex;
47+
align-items: center;
48+
width: 200px .ant-select-selection-item {
49+
color: ${ANTD_GRAY[8]} !important;
50+
font-weight: 700;
51+
}
52+
53+
.ant-select-selection-placeholder {
54+
color: ${ANTD_GRAY[8]};
55+
font-weight: 700;
56+
}
57+
`;
58+
59+
const StyledIcon = styled(Icon)`
60+
color: ${ANTD_GRAY[8]};
61+
font-size: 16px;
62+
margin-right: -8px;
63+
`;
64+
4265
type Props = {
4366
visible: boolean;
4467
};
@@ -48,6 +71,7 @@ const BrowseSidebar = ({ visible }: Props) => {
4871
skip: !visible,
4972
});
5073
const [browserWidth, setBrowserWith] = useState(window.innerWidth * 0.2);
74+
const [sortBy, setSortBy] = useState('default');
5175

5276
return (
5377
<>
@@ -58,15 +82,38 @@ const BrowseSidebar = ({ visible }: Props) => {
5882
data-testid="browse-v2"
5983
>
6084
<SidebarHeader>
61-
<Typography.Text strong>Navigate</Typography.Text>
85+
<Typography.Text strong> Navigate</Typography.Text>
86+
<Tooltip title="Sort folder results" showArrow={false} placement="left">
87+
<SelectWrapper>
88+
<StyledIcon component={SortIcon} />
89+
<Select
90+
placeholder="Sort"
91+
placement="bottomRight"
92+
dropdownStyle={{ minWidth: '110px' }}
93+
onChange={(value) => setSortBy(value)}
94+
bordered={false}
95+
suffixIcon={<CaretDownFilled />}
96+
>
97+
<Select.Option key="sort" value="sort">
98+
Size (Default)
99+
</Select.Option>
100+
<Select.Option key="AtoZ" value="AtoZ">
101+
Name A to Z
102+
</Select.Option>
103+
<Select.Option key="ZtoA" value="ZtoA">
104+
Name Z to A
105+
</Select.Option>
106+
</Select>
107+
</SelectWrapper>
108+
</Tooltip>
62109
</SidebarHeader>
63110
<SidebarBody visible={visible}>
64111
{entityAggregations && !entityAggregations.length && <div>No results found</div>}
65112
{entityAggregations
66113
?.filter((entityAggregation) => entityAggregation?.value !== 'DATA_PRODUCT')
67114
?.map((entityAggregation) => (
68115
<BrowseProvider key={entityAggregation?.value} entityAggregation={entityAggregation}>
69-
<EntityNode />
116+
<EntityNode sortBy={sortBy} />
70117
</BrowseProvider>
71118
))}
72119
{error && <SidebarLoadingError onClickRetry={retry} />}

datahub-web-react/src/app/search/sidebar/EntityNode.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,11 @@ const Count = styled(Typography.Text)`
2222
padding-left: 4px;
2323
`;
2424

25-
const EntityNode = () => {
25+
interface EntityNodeProps {
26+
sortBy: string;
27+
}
28+
29+
const EntityNode: React.FC<EntityNodeProps> = ({ sortBy }) => {
2630
const isSelected = useIsEntitySelected();
2731
const entityType = useEntityType();
2832
const entityAggregation = useEntityAggregation();
@@ -83,7 +87,7 @@ const EntityNode = () => {
8387
entityAggregation={entityAggregation}
8488
environmentAggregation={environmentAggregation}
8589
>
86-
<EnvironmentNode />
90+
<EnvironmentNode sortBy={sortBy} />
8791
</BrowseProvider>
8892
))
8993
: platformAggregations?.map((platformAggregation) => (
@@ -92,7 +96,7 @@ const EntityNode = () => {
9296
entityAggregation={entityAggregation}
9397
platformAggregation={platformAggregation}
9498
>
95-
<PlatformNode />
99+
<PlatformNode sortBy={sortBy} />
96100
</BrowseProvider>
97101
))}
98102
{error && <SidebarLoadingError onClickRetry={retry} />}

datahub-web-react/src/app/search/sidebar/EnvironmentNode.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,11 @@ const Count = styled(Typography.Text)`
2222
padding-right: 8px;
2323
`;
2424

25-
const EnvironmentNode = () => {
25+
interface EntityNodeProps {
26+
sortBy: string;
27+
}
28+
29+
const EnvironmentNode: React.FC<EntityNodeProps> = ({ sortBy }) => {
2630
const isSelected = useIsEnvironmentSelected();
2731
const entityAggregation = useEntityAggregation();
2832
const environmentAggregation = useEnvironmentAggregation();
@@ -72,7 +76,7 @@ const EnvironmentNode = () => {
7276
environmentAggregation={environmentAggregation}
7377
platformAggregation={platformAggregation}
7478
>
75-
<PlatformNode />
79+
<PlatformNode sortBy={sortBy} />
7680
</BrowseProvider>
7781
))}
7882
{error && <SidebarLoadingError onClickRetry={retry} />}

datahub-web-react/src/app/search/sidebar/PlatformNode.tsx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
} from './BrowseContext';
2121
import useSidebarAnalytics from './useSidebarAnalytics';
2222
import { useHasFilterField } from './SidebarContext';
23+
import { SortBy, useSort } from './useSort';
2324

2425
const PlatformIconContainer = styled.div`
2526
width: 16px;
@@ -33,7 +34,11 @@ const Count = styled(Typography.Text)`
3334
padding-right: 8px;
3435
`;
3536

36-
const PlatformNode = () => {
37+
interface EntityNodeProps {
38+
sortBy: string;
39+
}
40+
41+
const PlatformNode: React.FC<EntityNodeProps> = ({ sortBy }) => {
3742
const isPlatformSelected = useIsPlatformSelected();
3843
const hasBrowseFilter = useHasFilterField(BROWSE_PATH_V2_FILTER_NAME);
3944
const isPlatformAndPathSelected = isPlatformSelected && hasBrowseFilter;
@@ -74,6 +79,9 @@ const PlatformNode = () => {
7479

7580
const color = '#000';
7681

82+
const sortedGroups = useSort(groups, sortBy as SortBy);
83+
console.log({ groups, sortedGroups });
84+
7785
return (
7886
<ExpandableNode
7987
isOpen={isOpen && !isClosing && loaded}
@@ -101,7 +109,7 @@ const PlatformNode = () => {
101109
}
102110
body={
103111
<ExpandableNode.Body>
104-
{groups.map((group) => (
112+
{sortedGroups.map((group) => (
105113
<BrowseProvider
106114
key={group.name}
107115
entityAggregation={entityAggregation}
@@ -110,7 +118,7 @@ const PlatformNode = () => {
110118
browseResultGroup={group}
111119
parentPath={path}
112120
>
113-
<BrowseNode />
121+
<BrowseNode sortBy={sortBy} />
114122
</BrowseProvider>
115123
))}
116124
{error && <SidebarLoadingError onClickRetry={retry} />}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { useEffect, useState } from 'react';
2+
3+
export type SortBy = 'AtoZ' | 'ZtoA';
4+
5+
export const useSort = (initialData, sortBy: SortBy) => {
6+
const [sortedData, setSortedData] = useState([...initialData]);
7+
8+
useEffect(() => {
9+
const sortData = () => {
10+
const newData = [...initialData];
11+
if (sortBy === 'AtoZ') {
12+
newData?.sort((a, b) => {
13+
const nameA = a?.entity?.properties?.name || a.name;
14+
const nameB = b?.entity?.properties?.name || b.name;
15+
return nameA?.localeCompare(nameB);
16+
});
17+
} else if (sortBy === 'ZtoA') {
18+
newData?.sort((a, b) => {
19+
const nameA = a?.entity?.properties?.name || a.name;
20+
const nameB = b?.entity?.properties?.name || b.name;
21+
return nameB?.localeCompare(nameA);
22+
});
23+
}
24+
setSortedData(newData);
25+
};
26+
sortData();
27+
}, [initialData, sortBy]);
28+
29+
return sortedData;
30+
};

0 commit comments

Comments
 (0)