Skip to content

Commit d4c8fc4

Browse files
authored
add search to the services tree in ISV and CSP view (#1073)
1 parent 881ecd7 commit d4c8fc4

File tree

6 files changed

+124
-63
lines changed

6 files changed

+124
-63
lines changed

src/components/content/catalog/services/tree/CatalogFullView.tsx

+23-2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
serviceVersionKeyQuery,
1818
} from '../../../../utils/constants';
1919
import { getAllKeysFromCatalogTree } from '../../../common/catalog/catalogProps';
20+
import { filterNodes } from '../../../common/tree/filterTreeData';
2021
import ServiceProvider from '../details/ServiceProvider';
2122
import { ServiceTree } from './ServiceTree';
2223

@@ -30,6 +31,8 @@ export function CatalogFullView({
3031
category: category;
3132
}): React.JSX.Element {
3233
const [urlParams] = useSearchParams();
34+
const [searchValue, setSearchValue] = useState('');
35+
3336
const serviceNameInQuery = useMemo(() => {
3437
const queryInUri = decodeURI(urlParams.get(serviceNameKeyQuery) ?? '');
3538
if (queryInUri.length > 0) {
@@ -102,6 +105,23 @@ export function CatalogFullView({
102105
// eslint-disable-next-line react-hooks/exhaustive-deps
103106
}, [selectKey]);
104107

108+
function isParentTreeSelected(selectedKeyInTree: React.Key): boolean {
109+
let isParentNode: boolean = false;
110+
treeData.forEach((dataNode: DataNode) => {
111+
if (dataNode.key === selectedKeyInTree) {
112+
isParentNode = true;
113+
}
114+
});
115+
return isParentNode;
116+
}
117+
118+
const onSelect = (selectedKeys: React.Key[]) => {
119+
if (selectedKeys.length === 0 || isParentTreeSelected(selectedKeys[0])) {
120+
return;
121+
}
122+
setSelectKey(selectedKeys[0]);
123+
};
124+
105125
return (
106126
<>
107127
<div className={catalogStyles.leftClass}>
@@ -110,9 +130,10 @@ export function CatalogFullView({
110130
&nbsp;Service Tree
111131
</div>
112132
<ServiceTree
113-
treeData={treeData}
133+
treeData={filterNodes(treeData, searchValue)}
114134
selectKey={selectKey}
115-
setSelectKey={setSelectKey}
135+
onSelect={onSelect}
136+
setSearchValue={setSearchValue}
116137
isViewDisabled={isViewDisabled}
117138
/>
118139
</div>

src/components/content/catalog/services/tree/ServiceTree.tsx

+29-29
Original file line numberDiff line numberDiff line change
@@ -3,47 +3,47 @@
33
* SPDX-FileCopyrightText: Huawei Inc.
44
*/
55

6-
import { Tree } from 'antd';
6+
import { Input, Tree } from 'antd';
77
import { DataNode } from 'antd/es/tree';
88
import React from 'react';
99

10+
const { Search } = Input;
11+
1012
export function ServiceTree({
1113
treeData,
1214
selectKey,
13-
setSelectKey,
15+
onSelect,
16+
setSearchValue,
1417
isViewDisabled,
1518
}: {
1619
treeData: DataNode[];
1720
selectKey: React.Key;
18-
setSelectKey: (selectedKey: React.Key) => void;
21+
onSelect: (selectedKey: React.Key[]) => void;
22+
setSearchValue: (searchValue: string) => void;
1923
isViewDisabled: boolean;
2024
}): React.JSX.Element {
21-
function isParentTreeSelected(selectKey: React.Key): boolean {
22-
let isParentNode: boolean = false;
23-
treeData.forEach((dataNode: DataNode) => {
24-
if (dataNode.key === selectKey) {
25-
isParentNode = true;
26-
}
27-
});
28-
return isParentNode;
29-
}
30-
31-
const onSelect = (selectedKeys: React.Key[]) => {
32-
if (selectedKeys.length === 0 || isParentTreeSelected(selectedKeys[0])) {
33-
return;
34-
}
35-
setSelectKey(selectedKeys[0]);
36-
};
37-
3825
return (
39-
<Tree
40-
showIcon={true}
41-
defaultExpandAll={true}
42-
autoExpandParent={true}
43-
onSelect={onSelect}
44-
selectedKeys={[selectKey]}
45-
treeData={treeData}
46-
disabled={isViewDisabled}
47-
/>
26+
<>
27+
<Search
28+
style={{ marginBottom: 8 }}
29+
placeholder={'Search by name or version'}
30+
title={'Search by name or version'}
31+
onChange={(e) => {
32+
setSearchValue(e.target.value);
33+
}}
34+
onSearch={(e) => {
35+
setSearchValue(e);
36+
}}
37+
/>
38+
<Tree
39+
showIcon={true}
40+
defaultExpandAll={true}
41+
autoExpandParent={true}
42+
onSelect={onSelect}
43+
selectedKeys={[selectKey]}
44+
treeData={treeData}
45+
disabled={isViewDisabled}
46+
/>
47+
</>
4848
);
4949
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* SPDX-FileCopyrightText: Huawei Inc.
4+
*/
5+
6+
import { DataNode } from 'antd/es/tree';
7+
8+
export function filterNodes(nodes: DataNode[], searchValue: string): DataNode[] {
9+
return nodes
10+
.map((node) => {
11+
const matches = node.key.toString().toLowerCase().includes(searchValue.toLowerCase());
12+
13+
if (!node.children) {
14+
return matches ? node : null;
15+
}
16+
const filteredChildren = filterNodes(node.children, searchValue);
17+
return filteredChildren.length > 0 || matches ? { ...node, children: filteredChildren } : null;
18+
})
19+
.filter(Boolean) as DataNode[];
20+
}

src/components/content/registeredServices/tree/RegisteredServicesFullView.tsx

+22-2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
serviceVersionKeyQuery,
1818
} from '../../../utils/constants.tsx';
1919
import { getFourthLevelKeysFromAvailableServicesTree } from '../../common/registeredServices/registeredServiceProps.ts';
20+
import { filterNodes } from '../../common/tree/filterTreeData';
2021
import { RegisteredServicesTree } from './RegisteredServicesTree.tsx';
2122
import ServiceContent from './ServiceContent.tsx';
2223

@@ -28,6 +29,7 @@ export function RegisteredServicesFullView({
2829
availableServiceList: ServiceTemplateDetailVo[];
2930
}): React.JSX.Element {
3031
const [urlParams] = useSearchParams();
32+
const [searchValue, setSearchValue] = useState('');
3133

3234
const serviceNamespaceInQuery = useMemo(() => {
3335
const queryInUri = decodeURI(urlParams.get(serviceNamespaceQuery) ?? '');
@@ -121,6 +123,23 @@ export function RegisteredServicesFullView({
121123
// eslint-disable-next-line react-hooks/exhaustive-deps
122124
}, [selectedKeyInTree]);
123125

126+
function isParentTreeSelected(selectedKeyInTree: React.Key): boolean {
127+
let isParentNode: boolean = false;
128+
treeData.forEach((dataNode: DataNode) => {
129+
if (dataNode.key === selectedKeyInTree) {
130+
isParentNode = true;
131+
}
132+
});
133+
return isParentNode;
134+
}
135+
136+
const onSelect = (selectedKeys: React.Key[]) => {
137+
if (selectedKeys.length === 0 || isParentTreeSelected(selectedKeys[0])) {
138+
return;
139+
}
140+
setSelectedKeyInTree(selectedKeys[0]);
141+
};
142+
124143
return (
125144
<>
126145
<div className={catalogStyles.leftClass}>
@@ -129,9 +148,10 @@ export function RegisteredServicesFullView({
129148
&nbsp;Services
130149
</div>
131150
<RegisteredServicesTree
132-
treeData={treeData}
151+
treeData={filterNodes(treeData, searchValue)}
133152
selectedKeyInTree={selectedKeyInTree}
134-
setSelectedKeyInTree={setSelectedKeyInTree}
153+
onSelect={onSelect}
154+
setSearchValue={setSearchValue}
135155
/>
136156
</div>
137157
<div className={catalogStyles.middleClass} />

src/components/content/registeredServices/tree/RegisteredServicesTree.tsx

+28-28
Original file line numberDiff line numberDiff line change
@@ -3,44 +3,44 @@
33
* SPDX-FileCopyrightText: Huawei Inc.
44
*/
55

6-
import { Tree } from 'antd';
6+
import { Input, Tree } from 'antd';
77
import { DataNode } from 'antd/es/tree';
88
import React from 'react';
99

10+
const { Search } = Input;
11+
1012
export function RegisteredServicesTree({
1113
treeData,
1214
selectedKeyInTree,
13-
setSelectedKeyInTree,
15+
onSelect,
16+
setSearchValue,
1417
}: {
1518
treeData: DataNode[];
1619
selectedKeyInTree: React.Key;
17-
setSelectedKeyInTree: (selectedKey: React.Key) => void;
20+
onSelect: (selectedKey: React.Key[]) => void;
21+
setSearchValue: (searchValue: string) => void;
1822
}): React.JSX.Element {
19-
function isParentTreeSelected(selectedKeyInTree: React.Key): boolean {
20-
let isParentNode: boolean = false;
21-
treeData.forEach((dataNode: DataNode) => {
22-
if (dataNode.key === selectedKeyInTree) {
23-
isParentNode = true;
24-
}
25-
});
26-
return isParentNode;
27-
}
28-
29-
const onSelect = (selectedKeys: React.Key[]) => {
30-
if (selectedKeys.length === 0 || isParentTreeSelected(selectedKeys[0])) {
31-
return;
32-
}
33-
setSelectedKeyInTree(selectedKeys[0]);
34-
};
35-
3623
return (
37-
<Tree
38-
showIcon={true}
39-
defaultExpandAll={true}
40-
autoExpandParent={true}
41-
onSelect={onSelect}
42-
selectedKeys={[selectedKeyInTree]}
43-
treeData={treeData}
44-
/>
24+
<>
25+
<Search
26+
style={{ marginBottom: 8 }}
27+
placeholder={'Search by category,name,version'}
28+
title={'Search by category, service name or version'}
29+
onChange={(e) => {
30+
setSearchValue(e.target.value);
31+
}}
32+
onSearch={(e) => {
33+
setSearchValue(e);
34+
}}
35+
/>
36+
<Tree
37+
showIcon={true}
38+
defaultExpandAll={true}
39+
autoExpandParent={true}
40+
onSelect={onSelect}
41+
selectedKeys={[selectedKeyInTree]}
42+
treeData={treeData}
43+
/>
44+
</>
4545
);
4646
}

src/styles/catalog.module.css

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414

1515
.catalog-middleware .left-class {
1616
height: 100%;
17-
padding: 24px;
18-
width: 300px;
17+
padding: 8px;
18+
width: 18%;
1919
}
2020

2121
.catalog-middleware .left-title-class {

0 commit comments

Comments
 (0)