From fd7ce9027ac1439c03d16ee636dfa7bfdb29ac68 Mon Sep 17 00:00:00 2001 From: jialin Date: Wed, 5 Mar 2025 12:14:14 +0800 Subject: [PATCH] feat: add expand all rows --- src/components/auto-image/index.tsx | 12 ++++----- src/components/auto-image/single-image.tsx | 2 +- src/components/logs-viewer/logs-list.tsx | 6 ++--- .../logs-viewer/virtual-log-list.tsx | 2 +- .../seal-table/components/header-prefix.tsx | 25 ++++++++++++++++--- src/components/seal-table/index.tsx | 13 ++++++++++ src/components/seal-table/types.ts | 1 + src/hooks/use-expanded-row-keys.ts | 15 ++++++++++- src/layouts/index.tsx | 20 +++++++++------ src/pages/llmodels/components/table-list.tsx | 16 ++++++++++++ .../llmodels/components/view-logs-modal.tsx | 12 +++------ src/pages/llmodels/index.tsx | 1 + 12 files changed, 92 insertions(+), 33 deletions(-) diff --git a/src/components/auto-image/index.tsx b/src/components/auto-image/index.tsx index 06750c87..bb736fea 100644 --- a/src/components/auto-image/index.tsx +++ b/src/components/auto-image/index.tsx @@ -45,7 +45,7 @@ const AutoImage: React.FC< return; } const { ratio } = await getImgRatio(props.src || ''); - console.log('ratio', ratio); + if (typeof height === 'number') { setWidth(height * ratio); } else { @@ -53,7 +53,7 @@ const AutoImage: React.FC< } }, [getImgRatio, height, props.src]); - const onDownload = () => { + const onDownload = useCallback(() => { const url = props.src || ''; const filename = Date.now() + ''; @@ -63,16 +63,16 @@ const AutoImage: React.FC< document.body.appendChild(link); link.click(); link.remove(); - }; + }, [props.src]); const handleImgLoad = useCallback(() => { props.onLoad?.(); setIsError(false); }, [props.onLoad]); - const handleOnError = () => { + const handleOnError = useCallback(() => { setIsError(true); - }; + }, []); useEffect(() => { handleOnLoad(); @@ -127,4 +127,4 @@ const AutoImage: React.FC< ); }; -export default AutoImage; +export default React.memo(AutoImage); diff --git a/src/components/auto-image/single-image.tsx b/src/components/auto-image/single-image.tsx index c2f4c7be..0e322de5 100644 --- a/src/components/auto-image/single-image.tsx +++ b/src/components/auto-image/single-image.tsx @@ -197,4 +197,4 @@ const SingleImage: React.FC = (props) => { ); }; -export default React.memo(SingleImage); +export default SingleImage; diff --git a/src/components/logs-viewer/logs-list.tsx b/src/components/logs-viewer/logs-list.tsx index 23e8f8cf..08662b96 100644 --- a/src/components/logs-viewer/logs-list.tsx +++ b/src/components/logs-viewer/logs-list.tsx @@ -34,9 +34,9 @@ const LogsList: React.FC = forwardRef((props, ref) => { theme: 'os-theme-light' } }); - const viewportHeight = window.innerHeight; - const viewHeight = viewportHeight - diffHeight; - const [innerHieght, setInnerHeight] = useState(viewHeight); + const [innerHieght, setInnerHeight] = useState( + window.innerHeight - diffHeight + ); const scroller = useRef({}); const stopScroll = useRef(false); diff --git a/src/components/logs-viewer/virtual-log-list.tsx b/src/components/logs-viewer/virtual-log-list.tsx index fbde9994..1ef12a7a 100644 --- a/src/components/logs-viewer/virtual-log-list.tsx +++ b/src/components/logs-viewer/virtual-log-list.tsx @@ -17,7 +17,7 @@ import './styles/index.less'; import useLogsPagination from './use-logs-pagination'; interface LogsViewerProps { - height: number; + height?: number; content?: string; url: string; params?: object; diff --git a/src/components/seal-table/components/header-prefix.tsx b/src/components/seal-table/components/header-prefix.tsx index 0a979ebe..5f71e77f 100644 --- a/src/components/seal-table/components/header-prefix.tsx +++ b/src/components/seal-table/components/header-prefix.tsx @@ -1,4 +1,4 @@ -import { RightOutlined } from '@ant-design/icons'; +import { DownOutlined, RightOutlined } from '@ant-design/icons'; import { Button, Checkbox } from 'antd'; import _ from 'lodash'; import React from 'react'; @@ -7,6 +7,8 @@ interface HeaderPrefixProps { expandable?: boolean | React.ReactNode; enableSelection?: boolean; onSelectAll?: (e: any) => void; + onExpandAll?: (e: any) => void; + expandAll?: boolean; indeterminate?: boolean; selectAll?: boolean; hasColumns?: boolean; @@ -18,16 +20,31 @@ const HeaderPrefix: React.FC = (props) => { expandable, enableSelection, onSelectAll, + onExpandAll, indeterminate, - selectAll + selectAll, + expandAll } = props; + + const handleToggleExpand = () => { + onExpandAll?.(!expandAll); + }; + if (!hasColumns) { return null; } if (expandable && enableSelection) { return ( -
- +
+ + {_.isBoolean(expandable) ? ( + + ) : ( + expandable + )} + = ( rowKey, childParentKey, onExpand, + onExpandAll, onSort, onCell, expandedRowKeys, @@ -51,6 +52,12 @@ const SealTable: React.FC = ( }); }, [columns, children]); + const expandAll = useMemo(() => { + const allKeys = new Set(expandedRowKeys); + const currentDataKeys = props.dataSource.map((record) => record[rowKey]); + return currentDataKeys.every((key) => allKeys.has(key)); + }, [props.dataSource, expandedRowKeys]); + const selectState = useMemo(() => { const selectedRowKeys = rowSelection?.selectedRowKeys || []; const selectedKeys = new Set(selectedRowKeys); @@ -99,6 +106,10 @@ const SealTable: React.FC = ( } }; + const handleExpandAll = (value: boolean) => { + onExpandAll?.(value); + }; + const handlePageChange = (page: number, pageSize: number) => { pagination?.onChange?.(page, pageSize); }; @@ -115,6 +126,8 @@ const SealTable: React.FC = ( selectAll={selectState.selectAll} indeterminate={selectState.indeterminate} onSelectAll={handleSelectAllChange} + onExpandAll={handleExpandAll} + expandAll={expandAll} expandable={expandable} enableSelection={rowSelection?.enableSelection} hasColumns={parsedColumns.length > 0} diff --git a/src/components/seal-table/types.ts b/src/components/seal-table/types.ts index c641c3c1..22a09047 100644 --- a/src/components/seal-table/types.ts +++ b/src/components/seal-table/types.ts @@ -58,6 +58,7 @@ export interface SealTableProps { onCell?: (record: any, dataIndex: string) => void; onSort?: (dataIndex: string, order: 'ascend' | 'descend') => void; onExpand?: (expanded: boolean, record: any, rowKey: any) => void; + onExpandAll?: (expanded: boolean) => void; renderChildren?: (data: any, parent?: any) => React.ReactNode; loadChildren?: (record: any, options?: any) => Promise; loadChildrenAPI?: (record: any) => string; diff --git a/src/hooks/use-expanded-row-keys.ts b/src/hooks/use-expanded-row-keys.ts index e92c960c..0f23298e 100644 --- a/src/hooks/use-expanded-row-keys.ts +++ b/src/hooks/use-expanded-row-keys.ts @@ -15,6 +15,18 @@ export default function useExpandedRowKeys(defaultKeys: React.Key[] = []) { [] ); + const handleExpandAll = useCallback( + (expanded: boolean, keys: React.Key[] = []) => { + if (!expanded) { + setExpandedRowKeys([]); + } + if (expanded) { + setExpandedRowKeys((prevKeys) => [...new Set([...prevKeys, ...keys])]); + } + }, + [] + ); + const updateExpandedRowKeys = (keys: React.Key[]) => { setExpandedRowKeys(keys); }; @@ -36,6 +48,7 @@ export default function useExpandedRowKeys(defaultKeys: React.Key[] = []) { clearExpandedRowKeys, updateExpandedRowKeys, removeExpandedRowKey, - handleExpandChange + handleExpandChange, + handleExpandAll }; } diff --git a/src/layouts/index.tsx b/src/layouts/index.tsx index 9261b78a..e77f5ab0 100644 --- a/src/layouts/index.tsx +++ b/src/layouts/index.tsx @@ -348,6 +348,16 @@ export default (props: any) => { [userInfo?.require_password_change, initialState?.currentUser] ); + const onMenuHeaderClick = useCallback((e) => { + e.stopPropagation(); + e.preventDefault(); + navigate('/dashboard'); + }, []); + + const onCollapse = (value) => { + setCollapsed(value); + }; + useEffect(() => { // 先清除旧的性能标记 performance.clearMarks(); @@ -403,14 +413,8 @@ export default (props: any) => { title:
gpuStack
}} siderWidth={220} - onCollapse={(collapsed) => { - setCollapsed(collapsed); - }} - onMenuHeaderClick={(e) => { - e.stopPropagation(); - e.preventDefault(); - navigate('/dashboard'); - }} + onCollapse={onCollapse} + onMenuHeaderClick={onMenuHeaderClick} menuHeaderRender={renderMenuHeader} collapsed={collapsed} onPageChange={onPageChange} diff --git a/src/pages/llmodels/components/table-list.tsx b/src/pages/llmodels/components/table-list.tsx index dcf9f13e..c4bcad21 100644 --- a/src/pages/llmodels/components/table-list.tsx +++ b/src/pages/llmodels/components/table-list.tsx @@ -84,6 +84,7 @@ interface ModelsProps { handleCategoryChange: (val: any) => void; onViewLogs: () => void; onCancelViewLogs: () => void; + handleOnToggleExpandAll: () => void; queryParams: { page: number; perPage: number; @@ -172,6 +173,7 @@ const Models: React.FC = ({ onViewLogs, onCancelViewLogs, handleCategoryChange, + handleOnToggleExpandAll, deleteIds, dataSource, workerList, @@ -202,6 +204,7 @@ const Models: React.FC = ({ const rowSelection = useTableRowSelection(); const { handleExpandChange, + handleExpandAll, updateExpandedRowKeys, removeExpandedRowKey, expandedRowKeys @@ -843,6 +846,18 @@ const Models: React.FC = ({ setIsLoading(false); } }; + + const handleToggleExpandAll = useCallback( + (expanded: boolean) => { + const keys = dataSource.map((item) => item.id); + handleExpandAll(expanded, keys); + if (expanded) { + handleOnToggleExpandAll(); + } + }, + [dataSource] + ); + const renderEmpty = useMemo(() => { if (dataSource.length || !isFirstLogin || !catalogList?.length) { return null; @@ -990,6 +1005,7 @@ const Models: React.FC = ({ rowSelection={rowSelection} expandedRowKeys={expandedRowKeys} onExpand={handleExpandChange} + onExpandAll={handleToggleExpandAll} loading={loading} loadend={loadend} rowKey="id" diff --git a/src/pages/llmodels/components/view-logs-modal.tsx b/src/pages/llmodels/components/view-logs-modal.tsx index ca7a35cd..92e446ca 100644 --- a/src/pages/llmodels/components/view-logs-modal.tsx +++ b/src/pages/llmodels/components/view-logs-modal.tsx @@ -15,15 +15,10 @@ type ViewModalProps = { onCancel: () => void; }; -const ViewCodeModal: React.FC = (props) => { - const viewportHeight = window.innerHeight; +const ViewLogsModal: React.FC = (props) => { const intl = useIntl(); const { setChunkRequest } = useSetChunkRequest(); const { open, url, onCancel, tail } = props || {}; - const [modalSize] = useState({ - width: '100%', - height: viewportHeight - 86 - }); const [enableScorllLoad, setEnableScorllLoad] = useState(true); const logsViewerRef = React.useRef(null); const requestRef = React.useRef(null); @@ -106,13 +101,12 @@ const ViewCodeModal: React.FC = (props) => { borderRadius: 0 } }} - width={modalSize.width} + width="100%" footer={null} >
= (props) => { ); }; -export default React.memo(ViewCodeModal); +export default ViewLogsModal; diff --git a/src/pages/llmodels/index.tsx b/src/pages/llmodels/index.tsx index f9c4b7b3..095c9cfb 100644 --- a/src/pages/llmodels/index.tsx +++ b/src/pages/llmodels/index.tsx @@ -349,6 +349,7 @@ const Models: React.FC = () => { handleSearch={handleSearch} handlePageChange={handlePageChange} handleDeleteSuccess={fetchData} + handleOnToggleExpandAll={createModelsInstanceChunkRequest} onViewLogs={handleOnViewLogs} onCancelViewLogs={handleOnCancelViewLogs} queryParams={queryParams}