mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-22 01:13:00 +02:00
webui: type-aware Config column in interface overview
The collapsed Interfaces list left DHCP/SLAAC/zeroconf invisible until a row was unfolded, so L3 interfaces showed only empty cells. Replace the Addresses column with a Config column whose pills are chosen by role, mirroring the Status > Interfaces data column but slanted to configured intent: vid for VLANs, mode for WiFi, 802.1Q for filtering bridges, and DHCPv4/DHCPv6/SLAAC/Zeroconf for IP interfaces, alongside any static addresses. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
@@ -94,6 +94,7 @@ type cfgIfaceRow struct {
|
||||
AdminEnabled bool // true when enabled leaf absent (YANG default) or explicitly true
|
||||
MemberOf string // bridge or lag name this interface belongs to
|
||||
AddrSummary string
|
||||
ConfigTags []string // type-aware overview pills (DHCP, SLAAC, vid N, …)
|
||||
BridgeMembers []string // interface names that are ports of this bridge/lag
|
||||
BridgeMemberSet map[string]bool // for checkbox pre-selection
|
||||
PortCandidates []string // free ports + current members of this bridge/lag
|
||||
@@ -2042,6 +2043,7 @@ func (h *ConfigureInterfacesHandler) buildRows(ifaces []ifaceJSON, oper []ifaceJ
|
||||
}
|
||||
}
|
||||
row.AddrSummary = addrSummary(iface)
|
||||
row.ConfigTags = configSummary(&row)
|
||||
|
||||
if row.IsBridge {
|
||||
members := bridgeMembers[iface.Name]
|
||||
@@ -2647,3 +2649,40 @@ func addrSummary(iface ifaceJSON) string {
|
||||
return fmt.Sprintf("%d addresses", len(addrs))
|
||||
}
|
||||
}
|
||||
|
||||
// configSummary builds the type-aware overview pills for an interface in the
|
||||
// Configure list. It mirrors the Status > Interfaces "Data" column but is
|
||||
// slanted to configured intent rather than operational result: each role
|
||||
// contributes the properties worth seeing without unfolding the row — IP
|
||||
// acquisition (DHCP, SLAAC, zeroconf) for L3 interfaces, the tag id for VLANs,
|
||||
// the radio mode for WiFi, and 802.1Q for VLAN-filtering bridges. Static
|
||||
// addresses are rendered separately via AddrSummary.
|
||||
func configSummary(row *cfgIfaceRow) []string {
|
||||
var tags []string
|
||||
|
||||
if row.IsVlan && row.Vlan != nil {
|
||||
tags = append(tags, fmt.Sprintf("vid %d", row.Vlan.ID))
|
||||
}
|
||||
if row.IsWifi && row.WifiMode != "" {
|
||||
tags = append(tags, row.WifiMode)
|
||||
}
|
||||
if row.IsBridge && row.BridgeIs8021Q {
|
||||
tags = append(tags, "802.1Q")
|
||||
}
|
||||
if row.HasIP {
|
||||
if row.DHCPv4Enabled {
|
||||
tags = append(tags, "DHCPv4")
|
||||
}
|
||||
if row.IPv4 != nil && row.IPv4.Autoconf != nil {
|
||||
tags = append(tags, "Zeroconf")
|
||||
}
|
||||
if row.DHCPv6Enabled {
|
||||
tags = append(tags, "DHCPv6")
|
||||
}
|
||||
if row.IPv6 != nil && row.IPv6.SLAACv6 != nil {
|
||||
tags = append(tags, "SLAAC")
|
||||
}
|
||||
}
|
||||
|
||||
return tags
|
||||
}
|
||||
|
||||
@@ -1099,6 +1099,25 @@ details[open].nav-group-top > summary.nav-group-summary-top::before {
|
||||
.badge-drop { background: var(--slate-100); color: var(--slate-600); }
|
||||
.badge-continue { background: #dbeafe; color: #1e40af; }
|
||||
|
||||
/* Type-aware Config column pills in the Configure > Interfaces overview. */
|
||||
.iface-cfg-cell { white-space: normal; }
|
||||
.iface-tag {
|
||||
display: inline-block;
|
||||
margin: 0.1rem 0.25rem 0.1rem 0;
|
||||
padding: 0.05rem 0.4rem;
|
||||
border-radius: var(--radius-sm);
|
||||
background: var(--slate-100);
|
||||
color: var(--slate-600);
|
||||
font-size: 0.7rem;
|
||||
font-weight: 600;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.iface-cfg-addr { color: var(--slate-600); }
|
||||
.dark .iface-tag { background: var(--slate-800); color: var(--slate-300); }
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.iface-tag { background: var(--slate-800); color: var(--slate-300); }
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.badge-accept { background: rgba(22, 163, 74, 0.2); color: #86efac; }
|
||||
.badge-reject { background: rgba(220, 38, 38, 0.2); color: #fca5a5; }
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
<th>Type</th>
|
||||
<th>Status</th>
|
||||
<th>Member of</th>
|
||||
<th>Addresses</th>
|
||||
<th>Config</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -54,7 +54,11 @@
|
||||
{{end}}
|
||||
</td>
|
||||
<td>{{if .MemberOf}}{{.MemberOf}}{{else}}<span class="text-muted">—</span>{{end}}</td>
|
||||
<td>{{if .AddrSummary}}{{.AddrSummary}}{{else}}<span class="text-muted">—</span>{{end}}</td>
|
||||
<td class="iface-cfg-cell">
|
||||
{{range .ConfigTags}}<span class="iface-tag">{{.}}</span>{{end}}
|
||||
{{if .AddrSummary}}<span class="iface-cfg-addr">{{.AddrSummary}}</span>{{end}}
|
||||
{{if and (not .ConfigTags) (not .AddrSummary)}}<span class="text-muted">—</span>{{end}}
|
||||
</td>
|
||||
<td style="text-align:right">
|
||||
{{if ne .TypeSlug "loopback"}}
|
||||
<button type="button" class="btn-icon btn-icon-danger"
|
||||
|
||||
Reference in New Issue
Block a user