Group ports by device in connection modal dropdown

Replaced the flat 1000-entry select with optgroup grouping by device.
Each device gets its own optgroup label, making it possible to find
the target port even with hundreds of ports in the system.
master
Joca 2026-06-09 18:53:21 -03:00
parent d9e7fb1ab1
commit 459eef5d10
Signed by: jocadbz
GPG Key ID: B1836DCE2F50BDF7
2 changed files with 29 additions and 8 deletions

View File

@ -23,6 +23,12 @@ type FlatPort struct {
DeviceModel string DeviceModel string
} }
type PortGroup struct {
DeviceName string
DeviceID int64
Ports []FlatPort
}
func (h *Handlers) mustGetAllRacks() []models.Rack { func (h *Handlers) mustGetAllRacks() []models.Rack {
racks, _ := h.Store.RackGetAll() racks, _ := h.Store.RackGetAll()
if racks == nil { if racks == nil {
@ -173,30 +179,36 @@ func (h *Handlers) renderConnectionModal(w http.ResponseWriter, returnPortID str
type ConnectionModalData struct { type ConnectionModalData struct {
Trace *services.TraceResult Trace *services.TraceResult
ConnectionTypes []models.ConnectionType ConnectionTypes []models.ConnectionType
AllPorts []FlatPort PortGroups []PortGroup
} }
allDevices, _ := h.Store.DeviceGetAllUnracked() allDevices, _ := h.Store.DeviceGetAllUnracked()
visitedMap := map[int64]bool{} visitedMap := map[int64]bool{}
groupMap := map[int64]*PortGroup{}
var groupOrder []int64
var flatPorts []FlatPort
addPorts := func(devices []models.Device) { addPorts := func(devices []models.Device) {
for _, d := range devices { for _, d := range devices {
if visitedMap[d.ID] { if visitedMap[d.ID] {
continue continue
} }
visitedMap[d.ID] = true visitedMap[d.ID] = true
if _, ok := groupMap[d.ID]; !ok {
groupMap[d.ID] = &PortGroup{DeviceName: d.Name, DeviceID: d.ID}
groupOrder = append(groupOrder, d.ID)
}
for _, p := range d.Ports { for _, p := range d.Ports {
flatPorts = append(flatPorts, FlatPort{ fp := FlatPort{
ID: p.ID, ID: p.ID,
Name: p.Name, Name: p.Name,
Side: p.Side, Side: p.Side,
DeviceID: d.ID, DeviceID: d.ID,
DeviceName: d.Name, DeviceName: d.Name,
})
if d.Model != nil {
flatPorts[len(flatPorts)-1].DeviceModel = d.Model.Name
} }
if d.Model != nil {
fp.DeviceModel = d.Model.Name
}
groupMap[d.ID].Ports = append(groupMap[d.ID].Ports, fp)
} }
} }
} }
@ -211,10 +223,15 @@ func (h *Handlers) renderConnectionModal(w http.ResponseWriter, returnPortID str
} }
} }
var groups []PortGroup
for _, id := range groupOrder {
groups = append(groups, *groupMap[id])
}
h.render(w, "connection_modal.html", ConnectionModalData{ h.render(w, "connection_modal.html", ConnectionModalData{
Trace: trace, Trace: trace,
ConnectionTypes: connTypes, ConnectionTypes: connTypes,
AllPorts: flatPorts, PortGroups: groups,
}) })
} }

View File

@ -15,7 +15,11 @@
<label>Other port <label>Other port
<select name="port_id_2"> <select name="port_id_2">
<option value="">-- select --</option> <option value="">-- select --</option>
{{range .AllPorts}}<option value="{{.ID}}">{{.DeviceName}} &mdash; {{.Name}} ({{.Side}})</option>{{end}} {{range .PortGroups}}
<optgroup label="{{.DeviceName}}">
{{range .Ports}}<option value="{{.ID}}">{{.Name}} ({{.Side}})</option>{{end}}
</optgroup>
{{end}}
</select> </select>
</label> </label>
<label>Label this end <input name="label_1"></label> <label>Label this end <input name="label_1"></label>