Initial Commit : Network Map
This commit is contained in:
@@ -0,0 +1,143 @@
|
||||
import 'network_device.dart';
|
||||
import 'network_link.dart';
|
||||
import 'network_location.dart';
|
||||
import 'network_port.dart';
|
||||
import 'network_site.dart';
|
||||
import 'network_vlan.dart';
|
||||
|
||||
/// Client-side aggregate view-model assembled from raw network_* rows.
|
||||
///
|
||||
/// The canvas consumes this directly rather than re-querying tables for every
|
||||
/// pan/zoom event. Built once per site by [TopologyGraph.build] and cached in
|
||||
/// the topology provider.
|
||||
class TopologyNode {
|
||||
TopologyNode({
|
||||
required this.device,
|
||||
required this.ports,
|
||||
});
|
||||
|
||||
final NetworkDevice device;
|
||||
final List<NetworkPort> ports;
|
||||
|
||||
String get id => device.id;
|
||||
}
|
||||
|
||||
class TopologyEdge {
|
||||
TopologyEdge({
|
||||
required this.link,
|
||||
required this.fromDeviceId,
|
||||
required this.toDeviceId,
|
||||
required this.fromPortLabel,
|
||||
required this.toPortLabel,
|
||||
});
|
||||
|
||||
final NetworkLink link;
|
||||
final String fromDeviceId;
|
||||
final String toDeviceId;
|
||||
final String fromPortLabel;
|
||||
final String toPortLabel;
|
||||
}
|
||||
|
||||
enum TopologyViewMode {
|
||||
physical,
|
||||
logical;
|
||||
|
||||
String get label {
|
||||
switch (this) {
|
||||
case TopologyViewMode.physical:
|
||||
return 'Physical';
|
||||
case TopologyViewMode.logical:
|
||||
return 'Logical';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class TopologyGraph {
|
||||
TopologyGraph({
|
||||
required this.site,
|
||||
required this.locations,
|
||||
required this.nodes,
|
||||
required this.edges,
|
||||
required this.vlans,
|
||||
});
|
||||
|
||||
final NetworkSite? site;
|
||||
final List<NetworkLocation> locations;
|
||||
final List<TopologyNode> nodes;
|
||||
final List<TopologyEdge> edges;
|
||||
final List<NetworkVlan> vlans;
|
||||
|
||||
bool get isEmpty => nodes.isEmpty;
|
||||
|
||||
/// Build a graph for a specific site from raw tables.
|
||||
///
|
||||
/// Filters devices to those in the site's location subtree. If [site] is
|
||||
/// null, all devices with no location are included (orphan view).
|
||||
static TopologyGraph build({
|
||||
required NetworkSite? site,
|
||||
required List<NetworkLocation> allLocations,
|
||||
required List<NetworkDevice> allDevices,
|
||||
required List<NetworkPort> allPorts,
|
||||
required List<NetworkLink> allLinks,
|
||||
required List<NetworkVlan> allVlans,
|
||||
}) {
|
||||
final siteLocations = site == null
|
||||
? <NetworkLocation>[]
|
||||
: allLocations.where((l) => l.siteId == site.id).toList();
|
||||
final siteLocationIds = siteLocations.map((l) => l.id).toSet();
|
||||
|
||||
final siteDevices = site == null
|
||||
? allDevices.where((d) => d.locationId == null).toList()
|
||||
: allDevices
|
||||
.where((d) =>
|
||||
d.locationId != null && siteLocationIds.contains(d.locationId))
|
||||
.toList();
|
||||
final siteDeviceIds = siteDevices.map((d) => d.id).toSet();
|
||||
|
||||
final portsByDevice = <String, List<NetworkPort>>{};
|
||||
for (final port in allPorts) {
|
||||
if (!siteDeviceIds.contains(port.deviceId)) continue;
|
||||
portsByDevice.putIfAbsent(port.deviceId, () => []).add(port);
|
||||
}
|
||||
|
||||
final portToDevice = <String, String>{};
|
||||
final portLabel = <String, String>{};
|
||||
for (final port in allPorts) {
|
||||
portToDevice[port.id] = port.deviceId;
|
||||
portLabel[port.id] = port.portNumber;
|
||||
}
|
||||
|
||||
final nodes = siteDevices
|
||||
.map((d) => TopologyNode(
|
||||
device: d,
|
||||
ports: portsByDevice[d.id] ?? const [],
|
||||
))
|
||||
.toList();
|
||||
|
||||
final edges = <TopologyEdge>[];
|
||||
for (final link in allLinks) {
|
||||
final fromDeviceId = portToDevice[link.portA];
|
||||
final toDeviceId = portToDevice[link.portB];
|
||||
if (fromDeviceId == null || toDeviceId == null) continue;
|
||||
if (!siteDeviceIds.contains(fromDeviceId) ||
|
||||
!siteDeviceIds.contains(toDeviceId)) {
|
||||
continue;
|
||||
}
|
||||
edges.add(TopologyEdge(
|
||||
link: link,
|
||||
fromDeviceId: fromDeviceId,
|
||||
toDeviceId: toDeviceId,
|
||||
fromPortLabel: portLabel[link.portA] ?? '',
|
||||
toPortLabel: portLabel[link.portB] ?? '',
|
||||
));
|
||||
}
|
||||
|
||||
return TopologyGraph(
|
||||
site: site,
|
||||
locations: siteLocations,
|
||||
nodes: nodes,
|
||||
edges: edges,
|
||||
vlans: allVlans,
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user