diff --git a/src/assets/styles/common.less b/src/assets/styles/common.less index 54aa1629..0dbff123 100644 --- a/src/assets/styles/common.less +++ b/src/assets/styles/common.less @@ -232,3 +232,7 @@ list-style-type: decimal; padding-left: 16px; } + +.gap-16 { + gap: 16px; +} diff --git a/src/components/seal-table/components/row-skeleton.tsx b/src/components/seal-table/components/row-skeleton.tsx new file mode 100644 index 00000000..2940bbad --- /dev/null +++ b/src/components/seal-table/components/row-skeleton.tsx @@ -0,0 +1,13 @@ +import { Checkbox } from 'antd'; +import '../styles/skeleton.less'; + +const RowSkeleton = () => { + return ( +
+
+ +
+ ); +}; + +export default RowSkeleton; diff --git a/src/components/seal-table/index.tsx b/src/components/seal-table/index.tsx index 45f1a055..0a9eccf5 100644 --- a/src/components/seal-table/index.tsx +++ b/src/components/seal-table/index.tsx @@ -118,7 +118,10 @@ const SealTable: React.FC = ( if (!props.dataSource.length) { return (
- +
); } diff --git a/src/components/seal-table/styles/skeleton.less b/src/components/seal-table/styles/skeleton.less new file mode 100644 index 00000000..ae8c0a58 --- /dev/null +++ b/src/components/seal-table/styles/skeleton.less @@ -0,0 +1,13 @@ +.row-skeleton { + display: flex; + justify-content: flex-start; + background-color: var(--color-fill-sider); + padding: 16px; + height: 68px; + border-radius: var(--border-radius-base); + align-items: center; + + .holder { + width: 33px; + } +} diff --git a/src/pages/api-keys/index.tsx b/src/pages/api-keys/index.tsx index 011e058e..820e49c4 100644 --- a/src/pages/api-keys/index.tsx +++ b/src/pages/api-keys/index.tsx @@ -10,7 +10,15 @@ import { handleBatchRequest } from '@/utils'; import { DeleteOutlined, PlusOutlined, SyncOutlined } from '@ant-design/icons'; import { PageContainer } from '@ant-design/pro-components'; import { useIntl } from '@umijs/max'; -import { Button, Input, Space, Table, Tooltip } from 'antd'; +import { + Button, + ConfigProvider, + Empty, + Input, + Space, + Table, + Tooltip +} from 'antd'; import dayjs from 'dayjs'; import _ from 'lodash'; import { useEffect, useRef, useState } from 'react'; @@ -31,10 +39,12 @@ const APIKeys: React.FC = () => { const [dataSource, setDataSource] = useState<{ dataList: ListItem[]; loading: boolean; + loadend: boolean; total: number; }>({ dataList: [], loading: false, + loadend: false, total: 0 }); const [openAddModal, setOpenAddModal] = useState(false); @@ -71,6 +81,7 @@ const APIKeys: React.FC = () => { setDataSource({ dataList: res.items || [], loading: false, + loadend: true, total: res.pagination.total }); } catch (error) { @@ -78,6 +89,7 @@ const APIKeys: React.FC = () => { setDataSource({ dataList: [], loading: false, + loadend: true, total: dataSource.total }); } @@ -139,6 +151,18 @@ const APIKeys: React.FC = () => { }); }; + const renderEmpty = (type?: string) => { + if (type !== 'Table') return; + if ( + !dataSource.loading && + dataSource.loadend && + !dataSource.dataList.length + ) { + return ; + } + return
; + }; + useEffect(() => { fetchData(); }, [queryParams]); @@ -205,110 +229,112 @@ const APIKeys: React.FC = () => { } > - - +
{ - return ( - - {text} - - ); - }} - /> + > + { + return ( + + {text} + + ); + }} + /> - { - return ( - - {text - ? dayjs(text).format('YYYY-MM-DD HH:mm:ss') - : intl.formatMessage({ - id: 'apikeys.form.expiration.never' - })} - - ); - }} - /> - { - return {text}; - }} - /> - { - return ( - - {dayjs(text).format('YYYY-MM-DD HH:mm:ss')} - - ); - }} - /> - { - return ( - - - - - - ); - }} - /> -
+ { + return ( + + {text + ? dayjs(text).format('YYYY-MM-DD HH:mm:ss') + : intl.formatMessage({ + id: 'apikeys.form.expiration.never' + })} + + ); + }} + /> + { + return {text}; + }} + /> + { + return ( + + {dayjs(text).format('YYYY-MM-DD HH:mm:ss')} + + ); + }} + /> + { + return ( + + + + + + ); + }} + /> + + { const updateInstanceHandler = (list: any) => { // filter the data _.each(list, (data: any) => { - console.log('updateInstanceHandler====', data); updateInstanceChunkedList(data); }); }; diff --git a/src/pages/resources/components/gpus.tsx b/src/pages/resources/components/gpus.tsx index be7e7470..2eb3e417 100644 --- a/src/pages/resources/components/gpus.tsx +++ b/src/pages/resources/components/gpus.tsx @@ -5,7 +5,7 @@ import useTableSort from '@/hooks/use-table-sort'; import { convertFileSize } from '@/utils'; import { SyncOutlined } from '@ant-design/icons'; import { useIntl } from '@umijs/max'; -import { Button, Input, Space, Table } from 'antd'; +import { Button, ConfigProvider, Empty, Input, Space, Table } from 'antd'; import _ from 'lodash'; import { memo, useEffect, useState } from 'react'; import { queryGpuDevicesList } from '../apis'; @@ -21,10 +21,12 @@ const GPUList: React.FC = () => { const [dataSource, setDataSource] = useState<{ dataList: GPUDeviceItem[]; loading: boolean; + loadend: boolean; total: number; }>({ dataList: [], loading: false, + loadend: false, total: 0 }); const [queryParams, setQueryParams] = useState({ @@ -60,12 +62,14 @@ const GPUList: React.FC = () => { setDataSource({ dataList: res.items || [], loading: false, + loadend: true, total: res.pagination.total }); } catch (error) { setDataSource({ dataList: [], loading: false, + loadend: true, total: dataSource.total }); console.log('error', error); @@ -83,6 +87,18 @@ const GPUList: React.FC = () => { }); }; + const renderEmpty = (type?: string) => { + if (type !== 'Table') return; + if ( + !dataSource.loading && + dataSource.loadend && + !dataSource.dataList.length + ) { + return ; + } + return
; + }; + useEffect(() => { fetchData(); }, [queryParams]); @@ -111,131 +127,127 @@ const GPUList: React.FC = () => { } > - - { - return ( - - {text} - - ); + +
- { - return {record.index}; - }} - /> - { - return ( - - + > + { + return ( + {text} - - ); - }} - /> - + ); + }} + /> + { + return {record.index}; + }} + /> + { + return ( + + + {text} + + + ); + }} + /> + - { - return {text ? _.round(text, 1) : '-'}; - }} - /> - {/* { - return <>{record.core ? {record.core?.total} : '-'}; - }} - /> */} - { - return ( - <> - {record.core ? ( - - ) : ( - '-' - )} - - ); - }} - /> + { + return {text ? _.round(text, 1) : '-'}; + }} + /> + { + return ( + <> + {record.core ? ( + + ) : ( + '-' + )} + + ); + }} + /> - { - return ( - - - {intl.formatMessage({ id: 'resources.table.total' })}:{' '} - {convertFileSize(record.memory?.total, 0)} + { + return ( + + + {intl.formatMessage({ id: 'resources.table.total' })}:{' '} + {convertFileSize(record.memory?.total, 0)} + + + {intl.formatMessage({ id: 'resources.table.used' })}:{' '} + {convertFileSize( + record.memory?.used || record.memory?.allocated, + 0 + )} + - - {intl.formatMessage({ id: 'resources.table.used' })}:{' '} - {convertFileSize( - record.memory?.used || record.memory?.allocated, - 0 - )} - - - } - > - ); - }} - /> -
+ } + > + ); + }} + /> + + ); }; diff --git a/src/pages/resources/components/workers.tsx b/src/pages/resources/components/workers.tsx index 79e83488..be5ef37c 100644 --- a/src/pages/resources/components/workers.tsx +++ b/src/pages/resources/components/workers.tsx @@ -16,7 +16,16 @@ import { SyncOutlined } from '@ant-design/icons'; import { useIntl } from '@umijs/max'; -import { Button, Input, Space, Table, Tooltip, message } from 'antd'; +import { + Button, + ConfigProvider, + Empty, + Input, + Space, + Table, + Tooltip, + message +} from 'antd'; import _ from 'lodash'; import { memo, useCallback, useEffect, useRef, useState } from 'react'; import { useHotkeys } from 'react-hotkeys-hook'; @@ -55,10 +64,12 @@ const Resources: React.FC = () => { const [dataSource, setDataSource] = useState<{ dataList: ListItem[]; loading: boolean; + loadend: boolean; total: number; }>({ dataList: [], loading: false, + loadend: false, total: 0 }); const [queryParams, setQueryParams] = useState({ @@ -88,12 +99,14 @@ const Resources: React.FC = () => { setDataSource({ dataList: res.items, loading: false, + loadend: true, total: res.pagination.total }); } catch (error) { setDataSource({ dataList: [], loading: false, + loadend: true, total: dataSource.total }); console.log('error', error); @@ -239,6 +252,18 @@ const Resources: React.FC = () => { } }; + const renderEmpty = (type?: string) => { + if (type !== 'Table') return; + if ( + !dataSource.loading && + dataSource.loadend && + !dataSource.dataList.length + ) { + return ; + } + return
; + }; + useEffect(() => { fetchData(); }, [queryParams]); @@ -295,256 +320,259 @@ const Resources: React.FC = () => { } > - - { - return ( - - {record.name} - - ); + +
- { - return ( -
- {_.map(record.labels, (item: any, index: string) => { - return ( - - {index}:{item} - - ); - })} -
- ); - }} - /> - { - return ( - - ); - }} - /> - - { - return ( - - ); - }} - /> - { - return ( - - - {intl.formatMessage({ id: 'resources.table.total' })}:{' '} - {convertFileSize(record?.status?.memory?.total, 0)} - - - {intl.formatMessage({ id: 'resources.table.used' })}:{' '} - {convertFileSize(record?.status?.memory?.used, 0)} - - - } - > - ); - }} - /> - { - return ( - - {_.map( - _.sortBy(record?.status?.gpu_devices || [], ['index']), - (item: GPUDeviceItem, index: string) => { + > + { + return ( + + {record.name} + + ); + }} + /> + { + return ( +
+ {_.map(record.labels, (item: any, index: string) => { return ( - - - [{item.index}] - - {item.core ? ( - - ) : ( - '-' - )} - + + {index}:{item} + ); + })} +
+ ); + }} + /> + { + return ( + + ); + }} + /> + + { + return ( + + ); + }} + /> + { + return ( + + + {intl.formatMessage({ id: 'resources.table.total' })}:{' '} + {convertFileSize(record?.status?.memory?.total, 0)} + + + {intl.formatMessage({ id: 'resources.table.used' })}:{' '} + {convertFileSize(record?.status?.memory?.used, 0)} + +
} - )} - - ); - }} - /> - - { - return ( - - {_.map( - _.sortBy(record?.status?.gpu_devices || [], ['index']), - (item: GPUDeviceItem, index: string) => { - return ( - - + > + ); + }} + /> + { + return ( + + {_.map( + _.sortBy(record?.status?.gpu_devices || [], ['index']), + (item: GPUDeviceItem, index: string) => { + return ( + [{item.index}] - - - {intl.formatMessage({ - id: 'resources.table.total' - })} - : {convertFileSize(item.memory?.total, 0)} - - - {intl.formatMessage({ - id: 'resources.table.used' - })} - :{' '} - {convertFileSize( - item.memory?.used || item.memory?.allocated, - 0 - )} - - - } - > - {item.memory.is_unified_memory && ( - - - + {item.core ? ( + + ) : ( + '-' )} - - ); - } - )} - - ); - }} - /> - { - return ( - - ); - }} - /> - { - return ( - handleSelect(val, record)} - > - ); - }} - /> -
+ ); + } + )} + + ); + }} + /> + + { + return ( + + {_.map( + _.sortBy(record?.status?.gpu_devices || [], ['index']), + (item: GPUDeviceItem, index: string) => { + return ( + + + + [{item.index}] + + + + {intl.formatMessage({ + id: 'resources.table.total' + })} + : {convertFileSize(item.memory?.total, 0)} + + + {intl.formatMessage({ + id: 'resources.table.used' + })} + :{' '} + {convertFileSize( + item.memory?.used || + item.memory?.allocated, + 0 + )} + + + } + > + {item.memory.is_unified_memory && ( + + + + )} + + + ); + } + )} + + ); + }} + /> + { + return ( + + ); + }} + /> + { + return ( + handleSelect(val, record)} + > + ); + }} + /> + + setOpen(false)}> { const [dataSource, setDataSource] = useState<{ dataList: ListItem[]; loading: boolean; + loadend: boolean; total: number; }>({ dataList: [], loading: false, + loadend: false, total: 0 }); const [action, setAction] = useState(PageAction.CREATE); @@ -85,12 +95,14 @@ const Users: React.FC = () => { setDataSource({ dataList: res.items || [], loading: false, + loadend: true, total: res.pagination.total }); } catch (error) { setDataSource({ dataList: [], loading: false, + loadend: true, total: dataSource.total }); console.log('error', error); @@ -199,6 +211,18 @@ const Users: React.FC = () => { } }; + const renderEmpty = (type?: string) => { + if (type !== 'Table') return; + if ( + !dataSource.loading && + dataSource.loadend && + !dataSource.dataList.length + ) { + return ; + } + return
; + }; + useEffect(() => { fetchData(); }, [queryParams]); @@ -265,111 +289,113 @@ const Users: React.FC = () => { } > - - +
{ - return ( - - {text} - - ); - }} - /> - { - return record.is_admin ? ( - - - - {intl.formatMessage({ id: 'users.form.admin' })} - - - ) : ( - - - - {intl.formatMessage({ id: 'users.form.user' })} - - - ); - }} - /> - { - return ( - - {text} - - ); - }} - /> - { - return ( - - {dayjs(text).format('YYYY-MM-DD HH:mm:ss')} - - ); - }} - /> - { - return ( - handleSelect(val, record)} - > - ); - }} - /> -
+ > + { + return ( + + {text} + + ); + }} + /> + { + return record.is_admin ? ( + + + + {intl.formatMessage({ id: 'users.form.admin' })} + + + ) : ( + + + + {intl.formatMessage({ id: 'users.form.user' })} + + + ); + }} + /> + { + return ( + + {text} + + ); + }} + /> + { + return ( + + {dayjs(text).format('YYYY-MM-DD HH:mm:ss')} + + ); + }} + /> + { + return ( + handleSelect(val, record)} + > + ); + }} + /> + +