1
1
// components/DeployableItemsList.tsx
2
- import React from 'react' ;
3
- import { Table , Tag , Empty , Spin , Switch , Space , Button , Tooltip } from 'antd' ;
4
- import { CloudUploadOutlined } from '@ant-design/icons' ;
2
+ import React , { useState } from 'react' ;
3
+ import { Table , Tag , Empty , Spin , Switch , Space , Button , Tooltip , Input } from 'antd' ;
4
+ import { CloudUploadOutlined , SearchOutlined } from '@ant-design/icons' ;
5
5
import history from '@lowcoder-ee/util/history' ;
6
6
import { DeployableItem , BaseStats , DeployableItemConfig } from '../types/deployable-item.types' ;
7
7
import { Environment } from '../types/environment.types' ;
8
8
import { useDeployModal } from '../context/DeployModalContext' ;
9
9
10
+ const { Search } = Input ;
11
+
10
12
interface DeployableItemsListProps < T extends DeployableItem , S extends BaseStats > {
11
13
items : T [ ] ;
12
14
loading : boolean ;
@@ -30,6 +32,14 @@ function DeployableItemsList<T extends DeployableItem, S extends BaseStats>({
30
32
} : DeployableItemsListProps < T , S > ) {
31
33
32
34
const { openDeployModal } = useDeployModal ( ) ;
35
+ const [ searchText , setSearchText ] = useState ( '' ) ;
36
+
37
+ // Filter items based on search
38
+ const filteredItems = searchText
39
+ ? items . filter ( item =>
40
+ item . name . toLowerCase ( ) . includes ( searchText . toLowerCase ( ) ) ||
41
+ item . id . toLowerCase ( ) . includes ( searchText . toLowerCase ( ) ) )
42
+ : items ;
33
43
34
44
// Handle row click for navigation
35
45
const handleRowClick = ( item : T ) => {
@@ -53,8 +63,7 @@ function DeployableItemsList<T extends DeployableItem, S extends BaseStats>({
53
63
onToggleManaged,
54
64
openDeployModal,
55
65
additionalParams
56
- } )
57
-
66
+ } ) ;
58
67
59
68
if ( loading ) {
60
69
return (
@@ -76,18 +85,36 @@ function DeployableItemsList<T extends DeployableItem, S extends BaseStats>({
76
85
const hasNavigation = config . buildDetailRoute ( { } ) !== '#' ;
77
86
78
87
return (
79
- < Table
80
- columns = { columns }
81
- dataSource = { items }
82
- rowKey = { config . idField }
83
- pagination = { { pageSize : 10 } }
84
- size = "middle"
85
- scroll = { { x : 'max-content' } }
86
- onRow = { ( record ) => ( {
87
- onClick : hasNavigation ? ( ) => handleRowClick ( record ) : undefined ,
88
- style : hasNavigation ? { cursor : 'pointer' } : undefined ,
89
- } ) }
90
- />
88
+ < >
89
+ { /* Search Bar */ }
90
+ < div style = { { marginBottom : 16 } } >
91
+ < Search
92
+ placeholder = { `Search ${ config . pluralLabel } by name or ID` }
93
+ allowClear
94
+ onSearch = { value => setSearchText ( value ) }
95
+ onChange = { e => setSearchText ( e . target . value ) }
96
+ style = { { width : 300 } }
97
+ />
98
+ { searchText && filteredItems . length !== items . length && (
99
+ < div style = { { marginTop : 8 } } >
100
+ Showing { filteredItems . length } of { items . length } { config . pluralLabel . toLowerCase ( ) }
101
+ </ div >
102
+ ) }
103
+ </ div >
104
+
105
+ < Table
106
+ columns = { columns }
107
+ dataSource = { filteredItems }
108
+ rowKey = { config . idField }
109
+ pagination = { { pageSize : 10 } }
110
+ size = "middle"
111
+ scroll = { { x : 'max-content' } }
112
+ onRow = { ( record ) => ( {
113
+ onClick : hasNavigation ? ( ) => handleRowClick ( record ) : undefined ,
114
+ style : hasNavigation ? { cursor : 'pointer' } : undefined ,
115
+ } ) }
116
+ />
117
+ </ >
91
118
) ;
92
119
}
93
120
0 commit comments