节点列表去除横向滚动,公钥截断显示+复制按钮
This commit is contained in:
@@ -27,11 +27,33 @@ const canNext = computed(() => props.page < totalPages.value)
|
|||||||
const menuNode = ref<NodeInfo | null>(null)
|
const menuNode = ref<NodeInfo | null>(null)
|
||||||
const menuX = ref(0)
|
const menuX = ref(0)
|
||||||
const menuY = ref(0)
|
const menuY = ref(0)
|
||||||
|
const copiedNodeId = ref<string | null>(null)
|
||||||
|
|
||||||
function formatTime(value: string): string {
|
function formatTime(value: string): string {
|
||||||
return new Date(value).toLocaleString()
|
return new Date(value).toLocaleString()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function truncateKey(key: string): string {
|
||||||
|
if (key.length <= 12) return key
|
||||||
|
return key.slice(0, 8) + '…' + key.slice(-4)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function copyPublicKey(node: NodeInfo, event: MouseEvent) {
|
||||||
|
event.stopPropagation()
|
||||||
|
if (!node.public_key) return
|
||||||
|
try {
|
||||||
|
await navigator.clipboard.writeText(node.public_key)
|
||||||
|
copiedNodeId.value = node.node_id
|
||||||
|
setTimeout(() => {
|
||||||
|
if (copiedNodeId.value === node.node_id) {
|
||||||
|
copiedNodeId.value = null
|
||||||
|
}
|
||||||
|
}, 2000)
|
||||||
|
} catch {
|
||||||
|
/* clipboard not available */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function closeNodeMenu() {
|
function closeNodeMenu() {
|
||||||
menuNode.value = null
|
menuNode.value = null
|
||||||
}
|
}
|
||||||
@@ -95,7 +117,7 @@ onBeforeUnmount(() => {
|
|||||||
<span class="badge">共 {{ total }} 条</span>
|
<span class="badge">共 {{ total }} 条</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="node-table-wrap" @scroll="closeNodeMenu">
|
<div class="node-table-wrap node-list-wrap" @scroll="closeNodeMenu">
|
||||||
<table class="node-table">
|
<table class="node-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -122,7 +144,18 @@ onBeforeUnmount(() => {
|
|||||||
<td>{{ node.short_name || '-' }}</td>
|
<td>{{ node.short_name || '-' }}</td>
|
||||||
<td>{{ node.hw_model || '-' }}</td>
|
<td>{{ node.hw_model || '-' }}</td>
|
||||||
<td>{{ node.role || '-' }}</td>
|
<td>{{ node.role || '-' }}</td>
|
||||||
<td>{{ node.public_key || '-' }}</td>
|
<td>
|
||||||
|
<span v-if="node.public_key" class="pubkey-cell">
|
||||||
|
<code class="pubkey-text">{{ truncateKey(node.public_key) }}</code>
|
||||||
|
<button
|
||||||
|
class="copy-btn"
|
||||||
|
type="button"
|
||||||
|
:title="copiedNodeId === node.node_id ? '已复制' : '复制完整公钥'"
|
||||||
|
@click.stop="copyPublicKey(node, $event)"
|
||||||
|
>{{ copiedNodeId === node.node_id ? '已复制' : '复制' }}</button>
|
||||||
|
</span>
|
||||||
|
<span v-else>-</span>
|
||||||
|
</td>
|
||||||
<td>{{ formatTime(node.updated_at) }}</td>
|
<td>{{ formatTime(node.updated_at) }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@@ -1127,6 +1127,47 @@ h3 {
|
|||||||
background: var(--color-primary-soft);
|
background: var(--color-primary-soft);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* === 节点列表:去除横向滚动,内容自适应换行 === */
|
||||||
|
.node-list-wrap {
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.node-list-wrap .node-table th,
|
||||||
|
.node-list-wrap .node-table td {
|
||||||
|
white-space: normal;
|
||||||
|
word-break: break-all;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pubkey-cell {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pubkey-text {
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.copy-btn {
|
||||||
|
flex-shrink: 0;
|
||||||
|
padding: 2px 8px;
|
||||||
|
font-size: 12px;
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
border-radius: var(--radius-sm);
|
||||||
|
background: var(--color-surface);
|
||||||
|
color: var(--color-muted);
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.15s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.copy-btn:hover {
|
||||||
|
background: var(--color-primary-soft);
|
||||||
|
color: var(--color-primary);
|
||||||
|
border-color: var(--color-primary);
|
||||||
|
}
|
||||||
|
|
||||||
.admin-loading {
|
.admin-loading {
|
||||||
padding: 24px;
|
padding: 24px;
|
||||||
color: var(--color-muted);
|
color: var(--color-muted);
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
export const FRONTEND_VERSION = '0.1.0'
|
export const FRONTEND_VERSION = '0.1.1'
|
||||||
Reference in New Issue
Block a user