fix: 修复服务监控列表右侧留白
This commit is contained in:
1 parent
951b19edeb
commit
89b5dbf2d5
13 files changed
+47
-45
No files matched your search
@@ -126,10 +126,10 @@ const AgentInstallOneClick = () => {
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div className="mb-1 text-gray-600 dark:text-slate-400">选择 API Token</div>
|
||||
<div className="mb-1 text-gray-600 dark:text-slate-400">选择通信密钥</div>
|
||||
{apiKeys.length === 0 ? (
|
||||
<Alert
|
||||
message="暂无可用的 API Token"
|
||||
message="暂无可用的通信密钥"
|
||||
description={
|
||||
<span>
|
||||
请先前往 <a href="/admin/api-keys">通信密钥管理</a> 页面生成一个通信密钥
|
||||
@@ -146,7 +146,7 @@ const AgentInstallOneClick = () => {
|
||||
onChange={setSelectedApiKeyId}
|
||||
options={apiKeyOptions}
|
||||
loading={loading}
|
||||
placeholder="请选择 API Token"
|
||||
placeholder="请选择通信密钥"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -71,10 +71,10 @@ export const ApiChooser = ({
|
||||
}: ApiChooserProps) => (
|
||||
<Card type="inner" title="配置选项">
|
||||
<div>
|
||||
<div className="mb-1 text-gray-600 dark:text-slate-400">选择 API Token</div>
|
||||
<div className="mb-1 text-gray-600 dark:text-slate-400">选择通信密钥</div>
|
||||
{apiKeys.length === 0 ? (
|
||||
<Alert
|
||||
message="暂无可用的 API Token"
|
||||
message="暂无可用的通信密钥"
|
||||
description={
|
||||
<span>
|
||||
请先前往 <a href="/admin/api-keys">通信密钥管理</a> 页面生成一个通信密钥
|
||||
@@ -91,7 +91,7 @@ export const ApiChooser = ({
|
||||
onChange={onSelectApiKey}
|
||||
options={apiKeyOptions}
|
||||
loading={loading}
|
||||
placeholder="请选择 API Token"
|
||||
placeholder="请选择通信密钥"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -182,6 +182,7 @@ const AgentList = () => {
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
fixed: 'left',
|
||||
width: 220,
|
||||
render: (_, record) => (
|
||||
<div className="space-y-1">
|
||||
<div className="font-medium">
|
||||
@@ -559,7 +560,7 @@ const AgentList = () => {
|
||||
dataSource={filteredAgents}
|
||||
loading={isLoading || isFetching}
|
||||
rowKey="id"
|
||||
scroll={{x: 'max-content'}}
|
||||
scroll={{x: 1600}}
|
||||
tableLayout="fixed"
|
||||
rowSelection={{
|
||||
selectedRowKeys,
|
||||
|
||||
@@ -174,7 +174,7 @@ const SSHLoginEvents: React.FC<SSHLoginEventsProps> = ({agentId}) => {
|
||||
dataSource={eventsPaging?.items || []}
|
||||
loading={isLoading || isFetching}
|
||||
rowKey="id"
|
||||
scroll={{x: 'max-content'}}
|
||||
scroll={{x: 1000}}
|
||||
pagination={{
|
||||
current: pageIndex,
|
||||
pageSize,
|
||||
|
||||
@@ -146,7 +146,7 @@ const TamperProtectionEvents: React.FC<TamperProtectionEventsProps> = ({agentId}
|
||||
dataSource={eventsPaging?.data.items || []}
|
||||
loading={isLoading || isFetching}
|
||||
rowKey="id"
|
||||
scroll={{x: 'max-content'}}
|
||||
scroll={{x: 1000}}
|
||||
pagination={{
|
||||
current: pageIndex,
|
||||
pageSize,
|
||||
|
||||
@@ -26,7 +26,7 @@ export const useAgentInstallConfig = (): UseAgentInstallConfigResult => {
|
||||
const [rawKey, setRawKey] = useState<string>('');
|
||||
const { message } = App.useApp();
|
||||
|
||||
// 加载 API 密钥列表(key 已遮蔽)
|
||||
// 加载通信密钥列表(key 已遮蔽)
|
||||
useEffect(() => {
|
||||
const fetchApiKeys = async () => {
|
||||
setLoading(true);
|
||||
@@ -37,7 +37,7 @@ export const useAgentInstallConfig = (): UseAgentInstallConfigResult => {
|
||||
setSelectedApiKeyId((prev) => prev || enabledKeys[0]?.id || '');
|
||||
} catch (error) {
|
||||
console.error('Failed to load API keys:', error);
|
||||
message.error('加载 API Token 失败');
|
||||
message.error('加载通信密钥失败');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
@@ -164,6 +164,7 @@ const AlertRecordList = () => {
|
||||
{
|
||||
title: '告警消息',
|
||||
dataIndex: 'message',
|
||||
width: 320,
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
@@ -297,7 +298,7 @@ const AlertRecordList = () => {
|
||||
loading={isLoading || isFetching}
|
||||
rowKey="id"
|
||||
size={'small'}
|
||||
scroll={{x: 'max-content'}}
|
||||
scroll={{x: 1700}}
|
||||
tableLayout="fixed"
|
||||
pagination={{
|
||||
current: pageIndex,
|
||||
|
||||
@@ -3,7 +3,7 @@ import {useSearchParams} from 'react-router-dom';
|
||||
import {App, Button, Divider, Input, Popconfirm, Space, Table, Tag} from 'antd';
|
||||
import type {ColumnsType, TablePaginationConfig} from 'antd/es/table';
|
||||
import {Copy, Edit, Plus, RefreshCw, Trash2} from 'lucide-react';
|
||||
import {deleteApiKey, disableApiKey, enableApiKey, listApiKeys} from '@/api/apiKey.ts';
|
||||
import {deleteApiKey, disableApiKey, enableApiKey, getApiKeyRaw, listApiKeys} from '@/api/apiKey.ts';
|
||||
import type {ApiKey} from '@/types';
|
||||
import dayjs from 'dayjs';
|
||||
import {getErrorMessage} from '@/lib/utils';
|
||||
@@ -123,9 +123,14 @@ const ApiKeyList = () => {
|
||||
queryClient.invalidateQueries({queryKey: ['admin', 'api-keys']});
|
||||
};
|
||||
|
||||
const handleCopyApiKey = (key: string) => {
|
||||
copy(key);
|
||||
messageApi.success('复制成功');
|
||||
const handleCopyApiKey = async (id: string) => {
|
||||
try {
|
||||
const response = await getApiKeyRaw(id);
|
||||
copy(response.data.key || '');
|
||||
messageApi.success('复制成功');
|
||||
} catch (error: unknown) {
|
||||
messageApi.error(getErrorMessage(error, '复制密钥失败'));
|
||||
}
|
||||
};
|
||||
|
||||
const columns: ColumnsType<ApiKey> = [
|
||||
@@ -133,12 +138,14 @@ const ApiKeyList = () => {
|
||||
title: '名称',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
width: 220,
|
||||
render: (text) => <span className="font-medium text-gray-900 dark:text-white">{text}</span>,
|
||||
},
|
||||
{
|
||||
title: '通信密钥',
|
||||
dataIndex: 'key',
|
||||
key: 'key',
|
||||
width: 260,
|
||||
render: (_, record) => {
|
||||
return (
|
||||
<div className="flex items-center gap-2">
|
||||
@@ -150,8 +157,8 @@ const ApiKeyList = () => {
|
||||
type="text"
|
||||
size="small"
|
||||
icon={<Copy size={14}/>}
|
||||
onClick={() => handleCopyApiKey(record.key || '')}
|
||||
title="复制密钥"
|
||||
onClick={() => void handleCopyApiKey(record.id)}
|
||||
title="复制完整密钥"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
@@ -269,7 +276,7 @@ const ApiKeyList = () => {
|
||||
dataSource={apiKeyPaging?.items || []}
|
||||
loading={isLoading || isFetching}
|
||||
rowKey="id"
|
||||
scroll={{x: 'max-content'}}
|
||||
scroll={{x: 900}}
|
||||
tableLayout="fixed"
|
||||
pagination={{
|
||||
current: pageIndex,
|
||||
|
||||
@@ -134,6 +134,7 @@ const DDNSPage = () => {
|
||||
{
|
||||
title: '配置名称',
|
||||
dataIndex: 'name',
|
||||
width: 220,
|
||||
render: (_, record) => (
|
||||
<div className="flex items-center gap-2">
|
||||
<Globe className="h-4 w-4 text-blue-500"/>
|
||||
@@ -306,7 +307,7 @@ const DDNSPage = () => {
|
||||
dataSource={ddnsPaging?.items || []}
|
||||
loading={isLoading || isFetching}
|
||||
rowKey="id"
|
||||
scroll={{x: 'max-content'}}
|
||||
scroll={{x: 1150}}
|
||||
tableLayout="fixed"
|
||||
pagination={{
|
||||
current: pageIndex,
|
||||
|
||||
@@ -2,13 +2,12 @@ import {useEffect, useState} from 'react';
|
||||
import {useSearchParams} from 'react-router-dom';
|
||||
import {App, Button, Input, Popconfirm, Space, Table, Tag} from 'antd';
|
||||
import type {ColumnsType, TablePaginationConfig} from 'antd/es/table';
|
||||
import {Copy, Edit, Plus, RefreshCw, Trash2} from 'lucide-react';
|
||||
import {Edit, Plus, RefreshCw, Trash2} from 'lucide-react';
|
||||
import {deleteManageApiKey, disableManageApiKey, enableManageApiKey, listManageApiKeys} from '@/api/manageApiKey.ts';
|
||||
import type {ApiKey} from '@/types';
|
||||
import dayjs from 'dayjs';
|
||||
import {getErrorMessage} from '@/lib/utils';
|
||||
import {PageHeader} from '@admin/components';
|
||||
import copy from 'copy-to-clipboard';
|
||||
import ManageApiKeyModal from './ManageApiKeyModal';
|
||||
import ShowManageApiKeyModal from './ShowManageApiKeyModal';
|
||||
import {useMutation, useQuery, useQueryClient} from '@tanstack/react-query';
|
||||
@@ -120,22 +119,19 @@ const ManageApiKeyList = () => {
|
||||
queryClient.invalidateQueries({queryKey: ['admin', 'manage-api-keys']});
|
||||
};
|
||||
|
||||
const handleCopyApiKey = (key: string) => {
|
||||
copy(key);
|
||||
messageApi.success('复制成功');
|
||||
};
|
||||
|
||||
const columns: ColumnsType<ApiKey> = [
|
||||
{
|
||||
title: '名称',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
width: 220,
|
||||
render: (text) => <span className="font-medium text-gray-900 dark:text-white">{text}</span>,
|
||||
},
|
||||
{
|
||||
title: 'API密钥',
|
||||
dataIndex: 'key',
|
||||
key: 'key',
|
||||
width: 260,
|
||||
render: (_, record) => {
|
||||
return (
|
||||
<div className="flex items-center gap-2">
|
||||
@@ -143,13 +139,6 @@ const ManageApiKeyList = () => {
|
||||
className="text-xs bg-gray-100 dark:bg-gray-800 dark:text-gray-200 px-2 py-1 rounded font-mono">
|
||||
{record.key || ''}
|
||||
</code>
|
||||
<Button
|
||||
type="text"
|
||||
size="small"
|
||||
icon={<Copy size={14}/>}
|
||||
onClick={() => handleCopyApiKey(record.key || '')}
|
||||
title="复制密钥"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
@@ -266,7 +255,7 @@ const ManageApiKeyList = () => {
|
||||
dataSource={apiKeyPaging?.items || []}
|
||||
loading={isLoading || isFetching}
|
||||
rowKey="id"
|
||||
scroll={{x: 'max-content'}}
|
||||
scroll={{x: 900}}
|
||||
tableLayout="fixed"
|
||||
pagination={{
|
||||
current: pageIndex,
|
||||
|
||||
@@ -106,6 +106,7 @@ const MonitorList = () => {
|
||||
{
|
||||
title: '名称',
|
||||
dataIndex: 'name',
|
||||
width: 220,
|
||||
render: (_, record) => (
|
||||
<div className="flex flex-col">
|
||||
<span className="font-medium text-gray-900 dark:text-white">{record.name}</span>
|
||||
@@ -134,11 +135,13 @@ const MonitorList = () => {
|
||||
{
|
||||
title: '目标',
|
||||
dataIndex: 'target',
|
||||
width: 320,
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: '探针范围',
|
||||
dataIndex: 'agentIds',
|
||||
width: 260,
|
||||
render: (_, record) => {
|
||||
const hasAgents = record.agentIds && record.agentIds.length > 0;
|
||||
const hasTags = record.tags && record.tags.length > 0;
|
||||
@@ -270,7 +273,7 @@ const MonitorList = () => {
|
||||
dataSource={dataSource}
|
||||
loading={isLoading || isFetching}
|
||||
rowKey="id"
|
||||
scroll={{x: 'max-content'}}
|
||||
scroll={{x: 1200}}
|
||||
tableLayout="fixed"
|
||||
pagination={{
|
||||
current: pageIndex,
|
||||
|
||||
@@ -6,12 +6,12 @@ export interface ListApiKeysResponse {
|
||||
total: number;
|
||||
}
|
||||
|
||||
// 生成 API Key
|
||||
// 生成通信密钥
|
||||
export const generateApiKey = (data: GenerateApiKeyRequest) => {
|
||||
return post<ApiKey>('/admin/api-keys', data);
|
||||
};
|
||||
|
||||
// 获取 API Key 列表
|
||||
// 获取通信密钥列表
|
||||
export const listApiKeys = (pageIndex: number = 1, pageSize: number = 10, name?: string) => {
|
||||
const params = new URLSearchParams();
|
||||
params.append('pageIndex', pageIndex.toString());
|
||||
@@ -23,32 +23,32 @@ export const listApiKeys = (pageIndex: number = 1, pageSize: number = 10, name?:
|
||||
return get<ListApiKeysResponse>(`/admin/api-keys?${params.toString()}`);
|
||||
};
|
||||
|
||||
// 获取 API Key 详情
|
||||
// 获取通信密钥详情
|
||||
export const getApiKey = (id: string) => {
|
||||
return get<ApiKey>(`/admin/api-keys/${id}`);
|
||||
};
|
||||
|
||||
// 更新 API Key 名称
|
||||
// 更新通信密钥名称
|
||||
export const updateApiKeyName = (id: string, data: UpdateApiKeyNameRequest) => {
|
||||
return put(`/admin/api-keys/${id}`, data);
|
||||
};
|
||||
|
||||
// 启用 API Key
|
||||
// 启用通信密钥
|
||||
export const enableApiKey = (id: string) => {
|
||||
return post(`/admin/api-keys/${id}/enable`, {});
|
||||
};
|
||||
|
||||
// 禁用 API Key
|
||||
// 禁用通信密钥
|
||||
export const disableApiKey = (id: string) => {
|
||||
return post(`/admin/api-keys/${id}/disable`, {});
|
||||
};
|
||||
|
||||
// 删除 API Key
|
||||
// 删除通信密钥
|
||||
export const deleteApiKey = (id: string) => {
|
||||
return del(`/admin/api-keys/${id}`);
|
||||
};
|
||||
|
||||
// 获取 API Key 完整值
|
||||
// 获取通信密钥完整值
|
||||
export const getApiKeyRaw = (id: string) => {
|
||||
return get<{ key: string }>(`/admin/api-keys/${id}/raw`);
|
||||
};
|
||||
@@ -431,7 +431,7 @@ export interface LatestMetrics {
|
||||
temperature?: TemperatureMetric[]; // 温度传感器列表
|
||||
}
|
||||
|
||||
// API Key 相关(探针通信密钥)
|
||||
// 通信密钥 / 管理 API Key 相关
|
||||
export interface ApiKey {
|
||||
id: string;
|
||||
name: string;
|
||||
|
||||
Reference in new issue
Block a user