NodeView carried only the category counts, so the nodes page chips could hover to nothing but the category title. GetAll/recountByGuid now emit online/active/disabled/depleted email lists from the same bucketing pass as the counts (statuses gain the client email; the online list is the counted set), and the chips pop the list over with the inbounds page's popover pattern.
156 lines
2.2 KiB
CSS
156 lines
2.2 KiB
CSS
.toolbar {
|
|
margin-bottom: 12px;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
}
|
|
|
|
.name-cell {
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.name-cell .name {
|
|
font-weight: 500;
|
|
}
|
|
|
|
.name-cell .remark {
|
|
font-size: 12px;
|
|
opacity: 0.65;
|
|
}
|
|
|
|
.address-header {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
}
|
|
|
|
.ip-toggle-icon {
|
|
cursor: pointer;
|
|
font-size: 14px;
|
|
opacity: 0.7;
|
|
}
|
|
|
|
.ip-toggle-icon:hover {
|
|
opacity: 1;
|
|
}
|
|
|
|
.address-hidden {
|
|
filter: blur(5px);
|
|
transition: filter 0.2s ease;
|
|
}
|
|
|
|
.address-visible {
|
|
filter: none;
|
|
}
|
|
|
|
.node-cards {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 12px;
|
|
margin-top: 4px;
|
|
}
|
|
|
|
.node-card {
|
|
border: 1px solid var(--ant-color-border-secondary);
|
|
border-radius: 10px;
|
|
padding: 12px;
|
|
background: var(--ant-color-fill-quaternary);
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
}
|
|
|
|
.card-head {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
cursor: pointer;
|
|
user-select: none;
|
|
}
|
|
|
|
.card-expand {
|
|
font-size: 12px;
|
|
opacity: 0.6;
|
|
transition: transform 150ms ease;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.card-expand.is-expanded {
|
|
transform: rotate(90deg);
|
|
}
|
|
|
|
.node-name {
|
|
font-weight: 600;
|
|
flex: 1;
|
|
min-width: 0;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.card-actions {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.row-action-trigger {
|
|
font-size: 20px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.card-stats {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 6px;
|
|
}
|
|
|
|
.stat-row {
|
|
display: flex;
|
|
align-items: center;
|
|
flex-wrap: wrap;
|
|
gap: 6px;
|
|
}
|
|
|
|
.stat-label {
|
|
font-size: 10px;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.04em;
|
|
opacity: 0.6;
|
|
min-width: 96px;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.card-stats .ant-tag {
|
|
margin: 0;
|
|
}
|
|
|
|
/* Category chip hover list (same values as the inbounds page). */
|
|
.client-email-list {
|
|
max-height: 200px;
|
|
overflow-y: auto;
|
|
min-width: 150px;
|
|
}
|
|
|
|
.client-email-list > div {
|
|
padding: 2px 0;
|
|
}
|
|
|
|
.card-history {
|
|
margin-top: 4px;
|
|
padding-top: 8px;
|
|
border-top: 1px solid var(--ant-color-border-secondary);
|
|
}
|
|
|
|
.card-empty {
|
|
text-align: center;
|
|
color: var(--ant-color-text-secondary);
|
|
padding: 24px 12px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
gap: 8px;
|
|
}
|