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)}
+ >
+ );
+ }}
+ />
+
+