forked from labring/sealos
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtable.tsx
More file actions
121 lines (108 loc) · 3.6 KB
/
Copy pathtable.tsx
File metadata and controls
121 lines (108 loc) · 3.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import { Section } from '@/components/common/section/section';
import Title from '@/components/common/title/title';
import { useWatcher } from '@/hooks/useWatcher';
import { KubeObject } from '@/k8slens/kube-object';
import { KubeStoreAction } from '@/types/state';
import { Table, TableProps } from 'antd';
import { useEffect, useMemo, useState } from 'react';
import { PanelPagination } from './pagination';
import { useSearchNameFilterProps } from './search-filter';
type DefaultRecordType = Record<string, any>;
export interface DetailDrawerProps<T = any> {
open: boolean;
obj: T | null;
onClose: () => void;
}
interface Props<RecordType = unknown, Item = any> extends Omit<TableProps<RecordType>, 'title'> {
sectionTitle: string;
getRowKey: (record: RecordType) => string;
getDetailItem: (record: RecordType) => Item;
initializers: Array<KubeStoreAction<any>['initialize']>;
DetailDrawer: (props: DetailDrawerProps<Item>) => JSX.Element | null;
}
export const PanelTable = <RecordType extends DefaultRecordType, Item extends KubeObject>(
tableProps: Props<RecordType, Item>
) => {
const {
scroll = { x: true },
sectionTitle: title,
columns = [],
DetailDrawer,
getRowKey,
getDetailItem,
initializers
} = tableProps;
const [selectedItem, setSelectedItem] = useState<Item | null>(null);
const [openDetail, setOpenDetail] = useState(false);
const [currentPage, setCurrentPage] = useState(1);
const PAGE_SIZE = 15;
const cxtHolder = useWatcher({ initializers });
const searchNameFilterProps = useSearchNameFilterProps<RecordType>((_, record) =>
getDetailItem(record).getName()
);
const dataSource = useMemo(() => tableProps.dataSource || [], [tableProps.dataSource]);
// Apply filter based on searchText
const filteredData = useMemo(() => {
return dataSource.filter(searchNameFilterProps.filterFn);
}, [dataSource, searchNameFilterProps.filterFn]);
const total = filteredData.length;
// Reset to page 1 when search text changes
useEffect(() => {
setCurrentPage(1);
}, [searchNameFilterProps.searchText]);
// Calculate current page data after filtering
const currentData = useMemo(() => {
const start = (currentPage - 1) * PAGE_SIZE;
const end = start + PAGE_SIZE;
return filteredData.slice(start, end);
}, [filteredData, currentPage]);
const modifiedCols = useMemo(() => {
const { searchText, filterFn, ...filterProps } = searchNameFilterProps;
return [
{
title: 'Name',
key: 'name',
className: 'min-w-[150px]',
ellipsis: true,
filteredValue: searchText ? [searchText] : [],
...filterProps
},
...columns
];
}, [columns, searchNameFilterProps]);
return (
<Section>
{cxtHolder}
<Title type="primary">{title}</Title>
<Table
className="kubepanel-table"
size="middle"
{...tableProps}
dataSource={currentData}
columns={modifiedCols}
rowKey={getRowKey}
scroll={scroll}
pagination={false}
rowClassName="cursor-pointer"
onRow={(record) => ({
onClick: () => {
setSelectedItem(getDetailItem(record));
setOpenDetail(true);
}
})}
/>
{total > 0 && (
<PanelPagination
total={total}
current={currentPage}
pageSize={PAGE_SIZE}
onChange={(page) => setCurrentPage(page)}
/>
)}
{/* nextjs prerender fix */}
{DetailDrawer && (
<DetailDrawer open={openDetail} obj={selectedItem} onClose={() => setOpenDetail(false)} />
)}
</Section>
);
};