From 4ddf9c1947407d8a05147fb0857e2ea00de2c0e7 Mon Sep 17 00:00:00 2001 From: selankon Date: Sun, 12 May 2024 13:28:31 +0200 Subject: [PATCH 01/22] chore(meshwide): refactor link datatype --- .../src/lib/links/PointToPointLink.ts | 19 +- .../src/lib/links/getLinksCoordinates.ts | 26 +- .../src/meshWideMocks.tsx | 927 ++---------------- .../src/meshWideTypes.tsx | 13 +- 4 files changed, 108 insertions(+), 877 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts b/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts index 508e7972..067c458f 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts @@ -95,27 +95,12 @@ export class MacToMacLink { private _id: MacToMacLinkId; public type: T; - constructor(data: ILocatedLink, type: T) { + constructor(id: MacToMacLinkId, data: ILocatedLink, type: T) { this._data = data; - this._id = MacToMacLink.generateId(data); + this._id = id; this.type = type; } - /** - * Deterministically generation of a unique id using the macs of this link. Concatenate the sorted macs that - * are involved on this link - * @param data - */ - static generateId(data: ILocatedLink): MacToMacLinkId { - return [ - ...Object.entries(data).map(([k, v]) => { - return v.src_mac?.toLowerCase().replace(/:/g, ""); - }), - ] - .sort() - .join(""); - } - get id() { return this._id; } diff --git a/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts b/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts index 61518356..e620c716 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts @@ -6,7 +6,6 @@ import { ILinks, ILocatedLink, INodes, - LinkDataTypes, LinkType, LocatedLinkData, } from "plugins/lime-plugin-mesh-wide/src/meshWideTypes"; @@ -25,7 +24,7 @@ export const mergeLinksAndCoordinates = ( // for every node check all links for (const linkNodeName in links) { if (isEmpty(links[linkNodeName])) continue; - for (const linkData of Object.values(links[linkNodeName])) { + for (const [linkKey, linkData] of Object.entries(links[linkNodeName])) { if (!linkData.dst_mac) continue; // Get the nodeName of the destination node const dstNodeName = Object.keys(nodes).find((pid) => { @@ -39,12 +38,15 @@ export const mergeLinksAndCoordinates = ( // just ignore it if (!dstNodeName || !links[dstNodeName]) continue; + // If the destination node is not the same as the link node + // and the destination node is on the list of nodes + // and the link is not already added if ( dstNodeName && dstNodeName !== linkNodeName && - nodes[linkNodeName] // If is the link for a non geolocated node + nodes[linkNodeName] ) { - // Generate a unique id of the point to point link based on the coordinates + // Generate a unique id of the point to point link based on the coordinates to check if already exists const linkKey = PontToPointLink.generateId( nodes[linkNodeName].coordinates, nodes[dstNodeName].coordinates @@ -57,7 +59,7 @@ export const mergeLinksAndCoordinates = ( nodes[dstNodeName!].coordinates ); } - // Else if the link is not already added don't do it. + // If the link PontToPointLink already exists and the link is already added, ignore it else if ( result[linkKey].linkExists( linkData.src_mac, @@ -68,16 +70,8 @@ export const mergeLinksAndCoordinates = ( continue; } - // Get the destination link info - const destPointData = ( - links[dstNodeName] as Array - ).find( - (data: LinkDataTypes[T]) => - data.dst_mac.toLowerCase() === - linkData.src_mac.toLowerCase() && - data.src_mac.toLowerCase() === - linkData.dst_mac.toLowerCase() - ); + // Find destination link info from shared state + const destPointData = links[dstNodeName][linkKey]; const entry = { [linkNodeName]: { @@ -90,7 +84,7 @@ export const mergeLinksAndCoordinates = ( }, } as ILocatedLink; - result[linkKey].addLink(new MacToMacLink(entry, type)); + result[linkKey].addLink(new MacToMacLink(linkKey, entry, type)); } } } diff --git a/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx b/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx index 00bb979b..5cf4e78f 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx @@ -1,5 +1,4 @@ import { - IBatManLinkData, IBatmanLinks, ILinks, IMeshWideConfig, @@ -7,6 +6,7 @@ import { IWifiLinkData, IWifiLinks, LinkType, + MacToMacLinkId, } from "plugins/lime-plugin-mesh-wide/src/meshWideTypes"; export const nodesReferenceState: INodes = { @@ -97,218 +97,219 @@ export const nodesReferenceState: INodes = { }; export const linksReferenceState: IWifiLinks = { - primero: [ - { + primero: { + A0F3C1462897a840411df935: { tx_rate: 150000, - dst_mac: "A0:F3:C1:46:28:97", + rx_rate: 180000, chains: [-63, -59], signal: -58, - rx_rate: 180000, src_mac: "a8:40:41:1d:f9:35", + dst_mac: "A0:F3:C1:46:28:97", }, - { + "14CC20DA4EACa840411df935": { tx_rate: 162000, - dst_mac: "14:CC:20:DA:4E:AC", + rx_rate: 240000, chains: [-57, -51], signal: -50, - rx_rate: 240000, src_mac: "a8:40:41:1d:f9:35", + dst_mac: "14:CC:20:DA:4E:AC", }, - ], - segundo: [ - { + }, + segundo: { + A0F3C1461197a840411df9ff: { tx_rate: 150000, - dst_mac: "A0:F3:C1:46:11:97", + rx_rate: 180000, chains: [-58, -59], signal: -58, - rx_rate: 180000, src_mac: "a8:40:41:1d:f9:ff", + dst_mac: "A0:F3:C1:46:11:97", }, - { + "14CC20DA4EACa840411df9aa": { tx_rate: 162000, - dst_mac: "14:CC:20:DA:4E:AC", + rx_rate: 240000, chains: [-52, -51], signal: -50, - rx_rate: 240000, src_mac: "a8:40:41:1d:f9:aa", + dst_mac: "14:CC:20:DA:4E:AC", }, - ] as IWifiLinkData[], - "LiMe-da4eaa": [ - { + }, + "LiMe-da4eaa": { + "14cc20da4eabA0F3C1462896": { tx_rate: 65000, - dst_mac: "A0:F3:C1:46:28:96", - chains: [-25, -25], - src_mac: "14:cc:20:da:4e:ab", rx_rate: 65000, + chains: [-25, -25], signal: -25, + src_mac: "14:cc:20:da:4e:ab", + dst_mac: "A0:F3:C1:46:28:96", }, - { + "14cc20da4eacA0F3C1462897": { tx_rate: 270000, - dst_mac: "A0:F3:C1:46:28:97", - chains: [-50, -47], - src_mac: "14:cc:20:da:4e:ac", rx_rate: 150000, + chains: [-50, -47], signal: -45, + src_mac: "14:cc:20:da:4e:ac", + dst_mac: "A0:F3:C1:46:28:97", }, - { + "14cc20da4eacA840411DF935": { tx_rate: 243000, - dst_mac: "A8:40:41:1D:F9:35", - chains: [-75, -64], - src_mac: "14:cc:20:da:4e:ac", rx_rate: 162000, + chains: [-75, -64], signal: -64, + src_mac: "14:cc:20:da:4e:ac", + dst_mac: "A8:40:41:1D:F9:35", }, - { + "14cc20da4eacA840411DF9aa": { tx_rate: 243000, - dst_mac: "A8:40:41:1D:F9:aa", - chains: [-75, -64], - src_mac: "14:cc:20:da:4e:ac", rx_rate: 162000, + chains: [-75, -64], signal: -64, + src_mac: "14:cc:20:da:4e:ac", + dst_mac: "A8:40:41:1D:F9:aa", }, - ] as IWifiLinkData[], - "LiMe-462895": [ - { + }, + "LiMe-462895": { + "14CC20DA4EABa0f3c1462896": { tx_rate: 78000, - dst_mac: "14:CC:20:DA:4E:AB", - chains: [-43, -46], - src_mac: "a0:f3:c1:46:28:96", rx_rate: 78000, + chains: [-43, -46], signal: 2, + src_mac: "a0:f3:c1:46:28:96", + dst_mac: "14:CC:20:DA:4E:AB", }, - { + "14CC20DA4EACa0f3c1462897": { tx_rate: 243000, - dst_mac: "14:CC:20:DA:4E:AC", - chains: [-68, -41], - src_mac: "a0:f3:c1:46:28:97", rx_rate: 216000, + chains: [-68, -41], signal: -41, + src_mac: "a0:f3:c1:46:28:97", + dst_mac: "14:CC:20:DA:4E:AC", }, - { + A840411DF935a0f3c1462897: { tx_rate: 240000, - dst_mac: "A8:40:41:1D:F9:35", - chains: [-77, -65], - src_mac: "a0:f3:c1:46:28:97", rx_rate: 135000, + chains: [-77, -65], signal: -65, + src_mac: "a0:f3:c1:46:28:97", + dst_mac: "A8:40:41:1D:F9:35", }, - { + A840411DF9ffa0f3c1461197: { tx_rate: 240000, - dst_mac: "A8:40:41:1D:F9:ff", - chains: [-64, -65], - src_mac: "a0:f3:c1:46:11:97", rx_rate: 135000, + chains: [-64, -65], signal: -65, - }, - ] as IWifiLinkData[], -}; + src_mac: "a0:f3:c1:46:11:97", + dst_mac: "A8:40:41:1D:F9:ff", + dsad: "saddsa", + } as IWifiLinkData, + } as { [linkKey: MacToMacLinkId]: IWifiLinkData }, +} as ILinks<"wifi_links_info">; export const batManReferenceState: IBatmanLinks = { - primero: [ - { + primero: { + "02dbd646289502dbd6da4eaa": { hard_ifindex: 18, last_seen_msecs: 1300, iface: "eth0-1_250", dst_mac: "02:db:d6:da:4e:aa", src_mac: "02:db:d6:46:28:95", }, - { + "02ab4646289502ab46da4eaa": { hard_ifindex: 26, last_seen_msecs: 20, iface: "wlan1-mesh_250", dst_mac: "02:ab:46:da:4e:aa", src_mac: "02:ab:46:46:28:95", }, - { + "02ab4646289502ab46fc3abd": { hard_ifindex: 26, last_seen_msecs: 40, iface: "wlan1-mesh_250", dst_mac: "02:ab:46:fc:3a:bd", src_mac: "02:ab:46:46:28:95", }, - { + "025847462895025847fc3abd": { hard_ifindex: 28, last_seen_msecs: 1710, iface: "wlan0-mesh_250", dst_mac: "02:58:47:fc:3a:bd", src_mac: "02:58:47:46:28:95", }, - { + "025847462895025847da4eaa": { hard_ifindex: 28, last_seen_msecs: 1450, iface: "wlan0-mesh_250", dst_mac: "02:58:47:da:4e:aa", src_mac: "02:58:47:46:28:95", }, - ] as IBatManLinkData[], - "LiMe-da4eaa": [ - { + }, + "LiMe-da4eaa": { + "02ab46da4eaa02ab46fc3abd": { hard_ifindex: 26, last_seen_msecs: 1670, iface: "wlan1-mesh_250", dst_mac: "02:ab:46:da:4e:aa", src_mac: "02:ab:46:fc:3a:bd", }, - { + "02ab4646289502ab46fc3abd": { hard_ifindex: 26, last_seen_msecs: 1350, iface: "wlan1-mesh_250", dst_mac: "02:ab:46:46:28:95", src_mac: "02:ab:46:fc:3a:bd", }, - { + "025847462895025847fc3abd": { hard_ifindex: 28, last_seen_msecs: 1430, iface: "wlan0-mesh_250", dst_mac: "02:58:47:46:28:95", src_mac: "02:58:47:fc:3a:bd", }, - { + "025847da4eaa025847fc3abd": { hard_ifindex: 28, last_seen_msecs: 1030, iface: "wlan0-mesh_250", dst_mac: "02:58:47:da:4e:aa", src_mac: "02:58:47:fc:3a:bd", }, - ], - segundo: [ - { + }, + segundo: { + "02dbd646289502dbd6da4eaa": { hard_ifindex: 18, last_seen_msecs: 1670, src_mac: "02:db:d6:da:4e:aa", dst_mac: "02:db:d6:46:28:95", iface: "eth0-1_250", }, - { + "025847462895025847da4eaa": { hard_ifindex: 26, last_seen_msecs: 550, src_mac: "02:58:47:da:4e:aa", dst_mac: "02:58:47:46:28:95", iface: "wlan0-mesh_250", }, - { + "025847da4eaa025847fc3abd": { hard_ifindex: 26, last_seen_msecs: 260, src_mac: "02:58:47:da:4e:aa", dst_mac: "02:58:47:fc:3a:bd", iface: "wlan0-mesh_250", }, - { + "02ab46da4eaa02ab46fc3abd": { hard_ifindex: 28, last_seen_msecs: 340, src_mac: "02:ab:46:da:4e:aa", dst_mac: "02:ab:46:fc:3a:bd", iface: "wlan1-mesh_250", }, - { + "02ab4646289502ab46da4eaa": { hard_ifindex: 28, last_seen_msecs: 550, src_mac: "02:ab:46:da:4e:aa", dst_mac: "02:ab:46:46:28:95", iface: "wlan1-mesh_250", }, - ] as IBatManLinkData[], -}; + }, +} as ILinks<"bat_links_info">; // Use the same as on the reference state deleting a specific node // const nodeName = "LiMe-462895"; @@ -320,7 +321,7 @@ const macToDelete = ""; // const macToDelete = "a0:f3:c1:46:11:97"; // delete a link where the src_mac is // const linkToDelete = macToDelete; -const linkToDelete = "a0:f3:c1:46:11:97"; +const linkToDelete = "A840411DF9ffa0f3c1461197"; // const linkToDelete = ""; export const links = (type: T): ILinks => { @@ -330,26 +331,23 @@ export const links = (type: T): ILinks => { // Create a deep copy of the state to avoid mutating the original object const newState: ILinks = JSON.parse(JSON.stringify(data)); - let source_macs_to_remove = []; + let source_links_to_remove = []; if (nodeName) { // Get source_macs from the node to be removed - source_macs_to_remove = newState[nodeName].map((item: any) => - item.src_mac.toLowerCase() - ); - + source_links_to_remove = Object.keys(newState[nodeName]); // Remove the specified node delete newState[nodeName]; } // Remove data items with matching dest_mac in other objects - Object.keys(newState).forEach((key: string) => { - newState[key] = newState[key].filter((item) => { - return ( - !source_macs_to_remove.includes(item.dst_mac.toLowerCase()) || - // Added to delete a specific link of a node and not an entire node - item.src_mac.toLowerCase() === linkToDelete.toLowerCase() || - item.dst_mac.toLowerCase() === linkToDelete.toLowerCase() - ); + Object.keys(newState).forEach((nodeKey: string) => { + Object.keys(newState[nodeKey]).forEach((linkKey: string) => { + if ( + source_links_to_remove.includes(linkKey) || + linkKey === linkToDelete + ) { + delete newState[nodeKey][linkKey]; + } }); }); @@ -399,752 +397,3 @@ const meshWideConfig: IMeshWideConfig = [ options, }, ]; -// export const getRadioData = async () => radioDataResponse_simplified; - -// -// export const radioDataResponse_simplified: IMeshWideStatusResponse = { -// result: { -// "ql-czuk-bbone": { -// bleachTTL: 28, -// data: { -// hostname: "ql-czuk-bbone", -// coordinates: { -// lon: "-64.41515", -// lat: "-31.80130", -// }, -// macs: [ -// "a8:40:41:1d:f8:5c", -// "a8:40:41:1d:2a:a0", -// "02:cc:4e:1d:2a:a2", -// "aa:40:41:1d:f8:5c", -// "a8:40:41:1c:86:73", -// "aa:40:41:1c:86:73", -// "02:ab:46:1d:2a:a2", -// ], -// links: ["a8:40:41:1c:83:dd", "a8:40:41:1d:fa:29"], -// }, -// author: "ql-czuk-bbone", -// }, -// "ql-graciela-bbone": { -// bleachTTL: 28, -// data: { -// hostname: "ql-graciela-bbone", -// coordinates: { -// lon: "-64.42703", -// lat: "-31.80874", -// }, -// macs: [ -// "02:cc:4e:1c:85:aa", -// "a8:40:41:1c:83:f8", -// "02:ab:46:1c:85:aa", -// "ae:40:41:1c:85:a8", -// "a8:40:41:1c:83:dd", -// "a8:40:41:1c:85:a8", -// "aa:40:41:1c:85:a8", -// "02:58:47:1c:85:aa", -// ], -// links: ["a8:40:41:1c:86:73", "a8:40:41:1d:f9:f2"], -// }, -// author: "ql-graciela-bbone", -// }, -// "ql-berta": { -// bleachTTL: 28, -// data: { -// coordinates: { -// lon: "-64.41609", -// lat: "-31.80461", -// }, -// macs: [ -// "a8:40:41:1d:fa:29", -// "aa:40:41:1f:71:60", -// "a8:40:41:1f:71:60", -// "a8:40:41:1d:f9:f2", -// "02:cc:4e:1f:71:62", -// "02:ab:46:1f:71:62", -// ], -// links: ["a8:40:41:1c:83:f8", "a8:40:41:1d:f8:5c"], -// hostname: "ql-berta", -// }, -// author: "ql-berta", -// }, -// }, -// }; -// -// export const radioDataResponse: IMeshWideStatusResponse = { -// result: { -// "si-radio": { -// bleachTTL: 23, -// data: { -// hostname: "si-radio", -// coordinates: { -// lon: "-64.39240", -// lat: "-31.82056", -// }, -// macs: [ -// "aa:40:41:1c:85:50", -// "02:cc:4e:1c:85:52", -// "a8:40:41:1c:84:1a", -// "a8:40:41:1c:85:50", -// "02:58:47:1c:85:52", -// "ae:40:41:1c:85:50", -// "02:ab:46:1c:85:52", -// "a8:40:41:1c:84:16", -// ], -// links: [ -// "64:66:b3:87:4e:d1", -// "14:cc:20:ad:b0:d9", -// "a8:40:41:1c:83:eb", -// ], -// }, -// author: "si-radio", -// }, -// "ql-berta": { -// bleachTTL: 28, -// data: { -// links: ["a8:40:41:1c:83:f8"], -// coordinates: { -// lon: "-64.41609", -// lat: "-31.80461", -// }, -// macs: [ -// "a8:40:41:1d:fa:29", -// "aa:40:41:1f:71:60", -// "a8:40:41:1f:71:60", -// "a8:40:41:1d:f9:f2", -// "02:cc:4e:1f:71:62", -// "02:ab:46:1f:71:62", -// ], -// hostname: "ql-berta", -// }, -// author: "ql-berta", -// }, -// "ql-esteban": { -// bleachTTL: 25, -// data: { -// links: ["", ""], -// coordinates: { -// lon: "-64.41600680351257", -// lat: "-31.801688993108318", -// }, -// macs: [ -// "a0:f3:c1:48:cf:ec", -// "a0:f3:c1:48:cf:ed", -// "a2:f3:c1:48:cf:ec", -// "a2:f3:c1:48:cf:ed", -// ], -// hostname: "ql-esteban", -// }, -// author: "ql-esteban", -// }, -// "rl-hogardecristo": { -// bleachTTL: 22, -// data: { -// hostname: "rl-hogardecristo", -// coordinates: { -// lon: "-64.41609", -// lat: "-31.80461", -// }, -// macs: ["02:58:47:c2:e2:1a", "28:87:ba:c2:e2:1a"], -// links: ["a8:40:41:1c:85:a4"], -// }, -// author: "rl-hogardecristo", -// }, -// "ql-czuk-bbone": { -// bleachTTL: 28, -// data: { -// hostname: "ql-czuk-bbone", -// coordinates: { -// lon: "-64.41515", -// lat: "-31.80130", -// }, -// macs: [ -// "a8:40:41:1d:f8:5c", -// "a8:40:41:1d:2a:a0", -// "02:cc:4e:1d:2a:a2", -// "aa:40:41:1d:f8:5c", -// "a8:40:41:1c:86:73", -// "aa:40:41:1c:86:73", -// "02:ab:46:1d:2a:a2", -// ], -// links: ["a8:40:41:1c:84:20", "a8:40:41:1c:83:dd"], -// }, -// author: "ql-czuk-bbone", -// }, -// "ql-czuk": { -// bleachTTL: 25, -// data: { -// links: [ -// "14:cc:20:ad:b0:83", -// "64:66:b3:87:4b:39", -// "a2:f3:c1:48:cf:ed", -// ], -// coordinates: { -// lon: "-64.41506", -// lat: "-31.80137", -// }, -// macs: [ -// "a8:40:41:1f:71:f0", -// "02:58:47:1f:71:f2", -// "a8:40:41:1c:86:7f", -// "a8:40:41:1c:86:96", -// "02:ab:46:1f:71:f2", -// "02:cc:4e:1f:71:f2", -// ], -// hostname: "ql-czuk", -// }, -// author: "ql-czuk", -// }, -// "ql-refu-bbone": { -// bleachTTL: 25, -// data: { -// links: [ -// "a8:40:41:1d:f8:5c", -// "9c:a2:f4:8c:b8:58", -// "a8:40:41:1c:85:a4", -// "9c:a2:f4:8c:b9:48", -// "a8:40:41:1d:27:b4", -// "a8:40:41:1d:f8:f9", -// ], -// coordinates: { -// lon: "-64.385177", -// lat: "-31.837354", -// }, -// macs: [ -// "02:cc:4e:1c:85:46", -// "a8:40:41:1c:85:44", -// "02:ab:46:1c:85:46", -// "a8:40:41:1c:84:20", -// "02:58:47:1c:85:46", -// "a8:40:41:1c:84:28", -// ], -// hostname: "ql-refu-bbone", -// }, -// author: "ql-refu-bbone", -// }, -// "rl-vacas": { -// bleachTTL: 25, -// data: { -// hostname: "rl-vacas", -// coordinates: { -// lon: "-64.41609", -// lat: "-31.80461", -// }, -// macs: ["9c:a2:f4:8c:b9:48", "02:58:47:8c:b9:48"], -// links: [ -// "a8:40:41:1c:85:44", -// "a8:40:41:1c:85:a4", -// "a8:40:41:1d:27:b4", -// ], -// }, -// author: "rl-vacas", -// }, -// "mc-escuela-larrea": { -// bleachTTL: 23, -// data: { -// links: [ -// "a8:40:41:1c:85:5a", -// "a8:40:41:1c:84:99", -// "a8:40:41:1c:86:6d", -// "a8:40:41:1d:f9:26", -// "a8:40:41:1c:85:5a", -// "a8:40:41:1c:84:99", -// ], -// coordinates: { -// lon: "-64.37752", -// lat: "-31.85442", -// }, -// macs: [ -// "a8:40:41:1c:86:6e", -// "aa:40:41:1c:86:6d", -// "a8:40:41:1c:86:6d", -// "aa:40:41:1d:2a:b0", -// "a8:40:41:1d:2a:b0", -// "02:cc:4e:1d:2a:b2", -// "02:ab:46:1d:2a:b2", -// ], -// hostname: "mc-escuela-larrea", -// }, -// author: "mc-escuela-larrea", -// }, -// "ql-graciela": { -// bleachTTL: 28, -// data: { -// hostname: "ql-graciela", -// coordinates: { -// lon: "-64.42705", -// lat: "-31.80873", -// }, -// macs: [ -// "02:58:47:1c:85:3e", -// "ae:40:41:1c:85:3c", -// "02:cc:4e:1c:85:3e", -// "02:ab:46:1c:85:3e", -// "a8:40:41:1c:84:18", -// "a8:40:41:1c:84:05", -// "aa:40:41:1c:85:3c", -// "a8:40:41:1c:85:3c", -// ], -// links: [ -// "a8:40:41:1c:86:1d", -// "a8:40:41:1d:2a:40", -// "a0:f3:c1:85:fb:42", -// "a8:40:41:1c:86:2d", -// ], -// }, -// author: "ql-graciela", -// }, -// "ql-quinteros": { -// bleachTTL: 27, -// data: { -// hostname: "ql-quinteros", -// coordinates: { -// lon: "-64.4300052523613", -// lat: "-31.805773853144796", -// }, -// macs: [ -// "aa:40:41:1d:2a:40", -// "02:cc:4e:1d:2a:42", -// "a8:40:41:1c:86:2d", -// "a8:40:41:1d:2a:40", -// "02:ab:46:1d:2a:42", -// "ae:40:41:1d:2a:40", -// "02:58:47:1d:2a:42", -// "a8:40:41:1c:86:1d", -// ], -// links: [ -// "a0:f3:c1:85:fb:43", -// "a8:40:41:1d:f9:2c", -// "a8:40:41:1c:84:05", -// "a8:40:41:1c:85:3c", -// "a0:f3:c1:85:fb:42", -// "a8:40:41:1d:f8:fb", -// "a8:40:41:1c:84:18", -// ], -// }, -// author: "ql-quinteros", -// }, -// "mc-lidia": { -// bleachTTL: 22, -// data: { -// links: [ -// "a8:40:41:1c:85:5a", -// "a8:40:41:1c:84:99", -// "a8:40:41:1c:86:6d", -// ], -// coordinates: { -// lon: "-64.37990", -// lat: "-31.85474", -// }, -// macs: [ -// "a8:40:41:1d:27:7c", -// "a8:40:41:1c:85:2e", -// "02:ab:46:1d:27:7e", -// "aa:40:41:1d:27:7c", -// ], -// hostname: "mc-lidia", -// }, -// author: "mc-lidia", -// }, -// "ql-ipem265": { -// bleachTTL: 13, -// data: { -// links: ["a8:40:41:1c:86:96"], -// coordinates: { -// lon: "-64.41609", -// lat: "-31.80461", -// }, -// macs: [ -// "a8:40:41:1c:85:98", -// "02:ab:46:1c:85:9a", -// "aa:40:41:1c:85:98", -// "a8:40:41:1c:84:0b", -// "02:58:47:1c:85:9a", -// "02:cc:4e:1c:85:9a", -// "a8:40:41:1c:84:2e", -// "ae:40:41:1c:85:98", -// ], -// hostname: "ql-ipem265", -// }, -// author: "ql-ipem265", -// }, -// "ql-irenecasa": { -// bleachTTL: 25, -// data: { -// hostname: "ql-irenecasa", -// coordinates: { -// lon: "-64.41609", -// lat: "-31.80461", -// }, -// macs: [ -// "66:70:02:4e:cc:e2", -// "02:ab:46:4e:cc:e1", -// "64:70:02:4e:cc:e2", -// "62:70:02:4e:cc:e2", -// "64:70:02:4e:cc:e3", -// "02:58:47:4e:cc:e1", -// ], -// links: ["64:66:b3:87:4b:38", "64:66:b3:87:4b:39"], -// }, -// author: "ql-irenecasa", -// }, -// "ql-flor": { -// bleachTTL: 25, -// data: { -// links: ["a8:40:41:1c:86:7f"], -// coordinates: { -// lon: "-64.41365", -// lat: "-31.79897", -// }, -// macs: [ -// "16:cc:20:ad:b0:82", -// "02:ab:46:ad:b0:81", -// "14:cc:20:ad:b0:83", -// "02:58:47:ad:b0:81", -// "14:cc:20:ad:b0:82", -// ], -// hostname: "ql-flor", -// }, -// author: "ql-flor", -// }, -// "si-andrea": { -// bleachTTL: 23, -// data: { -// links: ["a8:40:41:1c:85:50", "a8:40:41:1c:85:a4"], -// coordinates: { -// lon: "-64.40097", -// lat: "-31.81854", -// }, -// macs: [ -// "16:cc:20:ad:b0:d9", -// "14:cc:20:ad:b0:d9", -// "12:cc:20:ad:b0:d9", -// "02:ab:46:ad:b0:d8", -// "02:58:47:ad:b0:d8", -// "14:cc:20:ad:b0:da", -// ], -// hostname: "si-andrea", -// }, -// author: "si-andrea", -// }, -// "rl-tanque": { -// bleachTTL: 23, -// data: { -// links: [], -// coordinates: { -// lon: "-64.38414", -// lat: "-31.84013", -// }, -// macs: ["a8:40:41:1d:f9:05", "a8:40:41:1d:fa:26"], -// hostname: "rl-tanque", -// }, -// author: "rl-tanque", -// }, -// "mc-yohana": { -// bleachTTL: 23, -// data: { -// links: ["a8:40:41:1c:85:a4", "a8:40:41:1d:27:b4"], -// coordinates: { -// lon: "-64.37864", -// lat: "-31.83969", -// }, -// macs: ["9c:a2:f4:8c:b8:58", "02:58:47:8c:b8:58"], -// hostname: "mc-yohana", -// }, -// author: "mc-yohana", -// }, -// "mc-eli": { -// bleachTTL: 21, -// data: { -// links: ["a8:40:41:1d:29:68", "a8:40:41:1d:2a:1c"], -// coordinates: { -// lon: "-64.38097", -// lat: "-31.85566", -// }, -// macs: ["9c:a2:f4:8c:b6:f4", "02:58:47:8c:b6:f4"], -// hostname: "mc-eli", -// }, -// author: "mc-eli", -// }, -// "si-soniam": { -// bleachTTL: 23, -// data: { -// links: [ -// "a8:40:41:1c:85:50", -// "64:70:02:4e:cd:0b", -// "a8:40:41:1c:84:16", -// ], -// coordinates: { -// lon: "-64.39240", -// lat: "-31.82056", -// }, -// macs: [ -// "66:66:b3:87:4e:d0", -// "64:66:b3:87:4e:d0", -// "62:66:b3:87:4e:d0", -// "64:66:b3:87:4e:d1", -// "02:ab:46:87:4e:cf", -// "02:58:47:87:4e:cf", -// ], -// hostname: "si-soniam", -// }, -// author: "si-soniam", -// }, -// "mc-martinez": { -// bleachTTL: 22, -// data: { -// hostname: "mc-martinez", -// coordinates: { -// lon: "-64.37988", -// lat: "-31.85802", -// }, -// macs: [ -// "ae:40:41:1d:29:68", -// "02:ab:46:1d:29:6a", -// "02:58:47:1d:29:6a", -// "a8:40:41:1c:84:99", -// "02:cc:4e:1d:29:6a", -// "a8:40:41:1c:85:1f", -// "a8:40:41:1d:29:68", -// "aa:40:41:1d:29:68", -// ], -// links: [ -// "a8:40:41:1c:85:5a", -// "a8:40:41:1c:86:6d", -// "a8:40:41:1c:85:2e", -// "9c:a2:f4:8c:b6:f4", -// "a8:40:41:1d:2a:1c", -// "a8:40:41:1c:85:5c", -// ], -// }, -// author: "mc-martinez", -// }, -// "mc-capilla": { -// bleachTTL: 23, -// data: { -// links: [ -// "a8:40:41:1c:84:28", -// "a8:40:41:1c:86:6e", -// "a8:40:41:1c:86:6d", -// ], -// coordinates: { -// lon: "-64.37827", -// lat: "-31.85482", -// }, -// macs: [ -// "a8:40:41:1d:f9:26", -// "aa:40:41:1f:74:f4", -// "a8:40:41:1d:f8:f9", -// "02:cc:4e:1f:74:f6", -// "02:ab:46:1f:74:f6", -// "a8:40:41:1f:74:f4", -// ], -// hostname: "mc-capilla", -// }, -// author: "mc-capilla", -// }, -// "ql-refu-bbone-2": { -// bleachTTL: 22, -// data: { -// links: [ -// "a8:40:41:1c:84:1a", -// "9c:a2:f4:8c:b8:58", -// "a8:40:41:1d:27:b4", -// "28:87:ba:c2:e2:1a", -// ], -// coordinates: { -// lon: "-64.385177", -// lat: "-31.837354", -// }, -// macs: [ -// "02:cc:4e:1c:85:a6", -// "a8:40:41:1c:85:a4", -// "a8:40:41:1c:83:eb", -// "aa:40:41:1c:83:e3", -// "a8:40:41:1c:83:e3", -// "aa:40:41:1c:83:eb", -// "02:58:47:1c:85:a6", -// "02:ab:46:1c:85:a6", -// ], -// hostname: "ql-refu-bbone-2", -// }, -// author: "ql-refu-bbone-2", -// }, -// "mc-rocio": { -// bleachTTL: 22, -// data: { -// links: [ -// "a8:40:41:1c:85:1f", -// "a8:40:41:1d:29:68", -// "9c:a2:f4:8c:b6:f4", -// "a8:40:41:1c:84:99", -// "a8:40:41:1c:86:6d", -// "a8:40:41:1c:85:2e", -// ], -// coordinates: { -// lon: "-64.38025", -// lat: "-31.85570", -// }, -// macs: [ -// "a8:40:41:1c:85:5a", -// "02:cc:4e:1d:2a:1e", -// "aa:40:41:1c:85:5a", -// "a8:40:41:1c:85:5c", -// "aa:40:41:1c:85:5c", -// "02:ab:46:1d:2a:1e", -// "02:58:47:1d:2a:1e", -// "a8:40:41:1d:2a:1c", -// ], -// hostname: "mc-rocio", -// }, -// author: "mc-rocio", -// }, -// "lbl-mikigonza": { -// bleachTTL: 28, -// data: { -// hostname: "lbl-mikigonza", -// coordinates: { -// lon: "-64.425602", -// lat: "-31.734109", -// }, -// macs: [ -// "a0:f3:c1:86:1e:f2", -// "a0:f3:c1:86:1e:f3", -// "a2:f3:c1:86:1e:f2", -// ], -// links: [""], -// }, -// author: "lbl-mikigonza", -// }, -// "ql-graciela-bbone": { -// bleachTTL: 28, -// data: { -// hostname: "ql-graciela-bbone", -// coordinates: { -// lon: "-64.42703", -// lat: "-31.80874", -// }, -// macs: [ -// "02:cc:4e:1c:85:aa", -// "a8:40:41:1c:83:f8", -// "02:ab:46:1c:85:aa", -// "ae:40:41:1c:85:a8", -// "a8:40:41:1c:83:dd", -// "a8:40:41:1c:85:a8", -// "aa:40:41:1c:85:a8", -// "02:58:47:1c:85:aa", -// ], -// links: ["a8:40:41:1c:86:73", "a8:40:41:1d:f9:f2"], -// }, -// author: "ql-graciela-bbone", -// }, -// "rl-tanque-2": { -// bleachTTL: 23, -// data: { -// links: ["a8:40:41:1c:85:a4", "9c:a2:f4:8c:b8:58"], -// coordinates: { -// lon: "-64.41609", -// lat: "-31.80461", -// }, -// macs: [ -// "02:58:47:1d:27:b6", -// "a8:40:41:1c:85:50", -// "a8:40:41:1d:27:b4", -// "aa:40:41:1d:27:b4", -// "a8:40:41:1c:85:4f", -// ], -// hostname: "rl-tanque-2", -// }, -// author: "rl-tanque-2", -// }, -// "ql-cutieddo": { -// bleachTTL: 28, -// data: { -// links: ["a8:40:41:1c:86:2d", "a0:f3:c1:85:fb:43"], -// coordinates: { -// lon: "-64.43312", -// lat: "-31.80787", -// }, -// macs: [ -// "a8:40:41:1d:f9:2c", -// "a8:40:41:1f:75:c4", -// "aa:40:41:1f:75:c4", -// "a8:40:41:1d:f8:fb", -// "02:ab:46:1f:74:7a", -// "02:cc:4e:1f:74:7a", -// ], -// hostname: "ql-cutieddo", -// }, -// author: "ql-cutieddo", -// }, -// "si-claudio": { -// bleachTTL: 21, -// data: { -// hostname: "si-claudio", -// coordinates: { -// lon: "-64.39444", -// lat: "-31.82071", -// }, -// macs: [ -// "66:70:02:4e:cd:0a", -// "64:70:02:4e:cd:0b", -// "64:70:02:4e:cd:0a", -// "02:ab:46:4e:cd:09", -// ], -// links: ["64:66:b3:87:4e:d1", "a8:40:41:1c:84:16"], -// }, -// author: "si-claudio", -// }, -// "ql-irene": { -// bleachTTL: 25, -// data: { -// links: [ -// "a2:f3:c1:48:cf:ec", -// "64:70:02:4e:cc:e2", -// "64:70:02:4e:cc:e3", -// "a2:f3:c1:48:cf:ed", -// "a8:40:41:1c:86:96", -// ], -// coordinates: { -// lon: "-64.41682", -// lat: "-31.80584", -// }, -// macs: [ -// "02:ab:46:87:4b:37", -// "66:66:b3:87:4b:38", -// "02:58:47:87:4b:37", -// "64:66:b3:87:4b:38", -// "64:66:b3:87:4b:39", -// "62:66:b3:87:4b:38", -// ], -// hostname: "ql-irene", -// }, -// author: "ql-irene", -// }, -// "ql-guillermina": { -// bleachTTL: 27, -// data: { -// links: [ -// "a8:40:41:1c:85:3c", -// "a8:40:41:1d:2a:40", -// "a8:40:41:1f:71:f0", -// "a8:40:41:1c:86:2d", -// "a8:40:41:1d:f9:2c", -// ], -// coordinates: { -// lon: "-64.43312", -// lat: "-31.80740", -// }, -// macs: [ -// "a0:f3:c1:85:fb:43", -// "02:ab:46:85:fb:41", -// "02:58:47:85:fb:41", -// "a0:f3:c1:85:fb:42", -// "a6:f3:c1:85:fb:42", -// "a2:f3:c1:85:fb:42", -// ], -// hostname: "ql-guillermina", -// }, -// author: "ql-guillermina", -// }, -// }, -// }; diff --git a/plugins/lime-plugin-mesh-wide/src/meshWideTypes.tsx b/plugins/lime-plugin-mesh-wide/src/meshWideTypes.tsx index 014bb795..08f3d50d 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWideTypes.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWideTypes.tsx @@ -14,11 +14,15 @@ export type LinkDataTypes = { bat_links_info: IBatManLinkData; }; export type LinkType = keyof LinkDataTypes; -export type ILocatedLink = { - [key: string]: LinkDataTypes[T] & { +export type IBaseLink = { + [linkKey: string]: LinkDataTypes[T]; +}; +export type ILocatedLink = IBaseLink & { + [key: string]: { coordinates: Coordinates; }; }; + export type BaseMacToMacLink = MacToMacLink; /** @@ -60,7 +64,7 @@ export type IBatManLinkData = { * List of Link info retrieved from the API */ export interface ILinks { - [key: string]: Array; + [nodeKey: string]: IBaseLink; } export type IWifiLinks = ILinks<"wifi_links_info">; @@ -172,8 +176,7 @@ export type ILinkErrors = { }; /** - * Type to store the link detail id, created deterministically by the - * two macs of this link + * Type to store the link detail id */ export type MacToMacLinkId = string; From 5094a7255bd919ea0894d3bb3c02cb94ddb5d6c6 Mon Sep 17 00:00:00 2001 From: selankon Date: Sun, 12 May 2024 16:40:39 +0200 Subject: [PATCH 02/22] chore(meshwide): implement reference state using async --- .../FeatureDetail/UpdateNodeInfoBtn.tsx | 3 +- .../src/hooks/useMeshWideDataErrors.tsx | 12 +-- .../lime-plugin-mesh-wide/src/meshWideApi.ts | 52 +++++------ .../src/meshWideQueries.tsx | 89 +++++++++++-------- .../src/meshWideQueriesKeys.tsx | 40 ++++----- 5 files changed, 98 insertions(+), 98 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/UpdateNodeInfoBtn.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/UpdateNodeInfoBtn.tsx index 3d3e80e3..02b330af 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/UpdateNodeInfoBtn.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/UpdateNodeInfoBtn.tsx @@ -45,8 +45,7 @@ const UpdateNodeInfoBtn = ({ completeDataTypeKeys ) as DataTypes[]) { queryCache.invalidateQueries({ - queryKey: - getFromSharedStateKeys.getFromSharedStateAsync(dataType), + queryKey: getFromSharedStateKeys.getFromSharedState(dataType), }); } }, []); diff --git a/plugins/lime-plugin-mesh-wide/src/hooks/useMeshWideDataErrors.tsx b/plugins/lime-plugin-mesh-wide/src/hooks/useMeshWideDataErrors.tsx index da9e137a..bbdfc4f0 100644 --- a/plugins/lime-plugin-mesh-wide/src/hooks/useMeshWideDataErrors.tsx +++ b/plugins/lime-plugin-mesh-wide/src/hooks/useMeshWideDataErrors.tsx @@ -40,42 +40,42 @@ export const useMeshWideDataErrors = () => { const { data: linksReferenceData, error: linksReferenceError } = useMeshWideLinksReference({}); addError( - getFromSharedStateKeys.getFromSharedStateMultiWriter("wifi_links_info"), + getFromSharedStateKeys.getReferenceFromSharedState("wifi_links_info"), linksReferenceError, linksReferenceData ); const { error: linksError } = useMeshWideLinks({}); addError( - getFromSharedStateKeys.getFromSharedStateAsync("wifi_links_info"), + getFromSharedStateKeys.getFromSharedState("wifi_links_info"), linksError ); const { data: batmanReferenceData, error: batmanReferenceError } = useMeshWideBatmanReference({}); addError( - getFromSharedStateKeys.getFromSharedStateMultiWriter("bat_links_info"), + getFromSharedStateKeys.getReferenceFromSharedState("bat_links_info"), batmanReferenceError, batmanReferenceData ); const { error: batmanError } = useMeshWideBatman({}); addError( - getFromSharedStateKeys.getFromSharedStateAsync("bat_links_info"), + getFromSharedStateKeys.getFromSharedState("bat_links_info"), batmanError ); const { data: nodesReferenceData, error: nodesReferenceError } = useMeshWideNodesReference({}); addError( - getFromSharedStateKeys.getFromSharedStateMultiWriter("node_info"), + getFromSharedStateKeys.getReferenceFromSharedState("node_info"), nodesReferenceError, nodesReferenceData ); const { error: nodesError } = useMeshWideNodes({}); addError( - getFromSharedStateKeys.getFromSharedStateAsync("node_info"), + getFromSharedStateKeys.getFromSharedState("node_info"), nodesError ); diff --git a/plugins/lime-plugin-mesh-wide/src/meshWideApi.ts b/plugins/lime-plugin-mesh-wide/src/meshWideApi.ts index 682de569..8f026ed0 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWideApi.ts +++ b/plugins/lime-plugin-mesh-wide/src/meshWideApi.ts @@ -1,10 +1,7 @@ import { QueryKey } from "@tanstack/react-query"; import { callToRemoteNode } from "plugins/lime-plugin-mesh-wide-upgrade/src/utils/api"; -import { - getFromSharedStateKeys, - publishAllFromSharedStateAsyncKey, -} from "plugins/lime-plugin-mesh-wide/src/meshWideQueriesKeys"; +import { getFromSharedStateKeys } from "plugins/lime-plugin-mesh-wide/src/meshWideQueriesKeys"; import { DataTypeMap, DataTypes, @@ -12,48 +9,43 @@ import { completeDataTypeKeys, } from "plugins/lime-plugin-mesh-wide/src/meshWideTypes"; -import api from "utils/uhttpd.service"; +import { UhttpdService, default as defaultApi } from "utils/uhttpd.service"; export const doSharedStateApiCall = async ( - queryKey: QueryKey + queryKey: QueryKey, + ip?: string ) => { - const res = (await api.call(...queryKey)) as SharedStateReturnType< - DataTypeMap[T] - >; - if (res.error !== 0 && res.error !== 404) { - throw Error(`Shared state error: ${res.error}`); + const doCall = async (api: UhttpdService = defaultApi) => { + const res = (await api.call(...queryKey)) as SharedStateReturnType< + DataTypeMap[T] + >; + // Don't count 404 as an error, it means not found + if (res.error !== 0 && res.error !== 404) { + throw Error(`Shared state error: ${res.error}`); + } + return res.data; + }; + if (ip) { + return await callToRemoteNode({ + ip, + apiCall: (customApi) => doCall(customApi), + }); } - return res.data; + return await doCall(); }; /** * Sync all data types from shared state from remote node */ -interface ISyncWithIpProps { - ip: string; -} - -export async function publishOnRemoteNode({ ip }: ISyncWithIpProps) { - return await callToRemoteNode({ - ip, - apiCall: (customApi) => - customApi - .call(...publishAllFromSharedStateAsyncKey, {}) - .then(() => true), - }); -} - -export async function syncDataType({ +async function syncDataType({ dataType, ip, }: { dataType: DataTypes; ip: string; }) { - const queryKey = getFromSharedStateKeys.syncFromSharedStateAsync(dataType, [ - ip, - ]); + const queryKey = getFromSharedStateKeys.syncFromSharedState(dataType, [ip]); return doSharedStateApiCall(queryKey); } diff --git a/plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx b/plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx index f1d57c9a..aa86658a 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx @@ -2,14 +2,12 @@ import { useMutation, useQuery } from "@tanstack/react-query"; import { doSharedStateApiCall, - publishOnRemoteNode, syncAllDataTypes, } from "plugins/lime-plugin-mesh-wide/src/meshWideApi"; import { getMeshWideConfig } from "plugins/lime-plugin-mesh-wide/src/meshWideMocks"; import { getFromSharedStateKeys, - publishAllFromSharedStateAsyncKey, - syncFromSharedStateAsyncKey, + syncFromSharedStateKey, } from "plugins/lime-plugin-mesh-wide/src/meshWideQueriesKeys"; import { DataTypes, @@ -27,7 +25,7 @@ const refetchInterval = 60000; export function useMeshWideLinksReference(params) { const dataType: DataTypes = "wifi_links_info"; const queryKey = - getFromSharedStateKeys.getFromSharedStateMultiWriter(dataType); + getFromSharedStateKeys.getReferenceFromSharedState(dataType); return useQuery( queryKey, () => doSharedStateApiCall(queryKey), @@ -40,7 +38,7 @@ export function useMeshWideLinksReference(params) { export function useMeshWideLinks(params) { const dataType: DataTypes = "wifi_links_info"; - const queryKey = getFromSharedStateKeys.getFromSharedStateAsync(dataType); + const queryKey = getFromSharedStateKeys.getFromSharedState(dataType); return useQuery( queryKey, () => doSharedStateApiCall(queryKey), @@ -54,7 +52,7 @@ export function useMeshWideLinks(params) { export function useMeshWideBatmanReference(params) { const dataType: DataTypes = "bat_links_info"; const queryKey = - getFromSharedStateKeys.getFromSharedStateMultiWriter(dataType); + getFromSharedStateKeys.getReferenceFromSharedState(dataType); return useQuery( queryKey, () => doSharedStateApiCall(queryKey), @@ -67,7 +65,7 @@ export function useMeshWideBatmanReference(params) { export function useMeshWideBatman(params) { const dataType: DataTypes = "bat_links_info"; - const queryKey = getFromSharedStateKeys.getFromSharedStateAsync(dataType); + const queryKey = getFromSharedStateKeys.getFromSharedState(dataType); return useQuery( queryKey, () => doSharedStateApiCall(queryKey), @@ -81,7 +79,7 @@ export function useMeshWideBatman(params) { export function useMeshWideNodesReference(params) { const dataType: DataTypes = "node_info"; const queryKey = - getFromSharedStateKeys.getFromSharedStateMultiWriter(dataType); + getFromSharedStateKeys.getReferenceFromSharedState(dataType); return useQuery( queryKey, () => doSharedStateApiCall(queryKey), @@ -94,7 +92,7 @@ export function useMeshWideNodesReference(params) { export function useMeshWideNodes(params) { const dataType: DataTypes = "node_info"; - const queryKey = getFromSharedStateKeys.getFromSharedStateAsync(dataType); + const queryKey = getFromSharedStateKeys.getFromSharedState(dataType); return useQuery( queryKey, () => doSharedStateApiCall(queryKey), @@ -112,48 +110,63 @@ export function useMeshWideNodes(params) { * to unify criterias and add a confirmation modal */ -export const useSetNodeInfoReferenceState = (params) => { +interface IShatedStateRemoteQueryProps { + ip: string; + hostname?: string; + params?: any; +} + +export const useSetNodeInfoReferenceState = ({ + ip, + hostname, + params, +}: IShatedStateRemoteQueryProps) => { const type = "node_info"; const { data } = useMeshWideNodes({}); - const queryKey = getFromSharedStateKeys.insertIntoSharedStateKey( - type, - data - ); + const queryKey = getFromSharedStateKeys.insertIntoReferenceState(type, { + [hostname]: data[hostname], + }); return useMutation( queryKey, - () => doSharedStateApiCall(queryKey), + () => doSharedStateApiCall(queryKey, ip), { ...params, } ); }; -export const useSetWifiLinksInfoReferenceState = (params) => { +export const useSetWifiLinksInfoReferenceState = ({ + ip, + hostname, + params, +}: IShatedStateRemoteQueryProps) => { const type = "wifi_links_info"; const { data } = useMeshWideLinks({}); - const queryKey = getFromSharedStateKeys.insertIntoSharedStateKey( - type, - data - ); + const queryKey = getFromSharedStateKeys.insertIntoReferenceState(type, { + [hostname]: data[hostname], + }); return useMutation( queryKey, - () => doSharedStateApiCall(queryKey), + () => doSharedStateApiCall(queryKey, ip), { ...params, } ); }; -export const useSetBatmanLinksInfoReferenceState = (params) => { +export const useSetBatmanLinksInfoReferenceState = ({ + ip, + hostname, + params, +}: IShatedStateRemoteQueryProps) => { const type = "bat_links_info"; const { data } = useMeshWideBatman({}); - const queryKey = getFromSharedStateKeys.insertIntoSharedStateKey( - type, - data - ); + const queryKey = getFromSharedStateKeys.insertIntoReferenceState(type, { + [hostname]: data[hostname], + }); return useMutation( queryKey, - () => doSharedStateApiCall(queryKey), + () => doSharedStateApiCall(queryKey, ip), { ...params, } @@ -166,13 +179,16 @@ export const useSetBatmanLinksInfoReferenceState = (params) => { export const usePublishOnRemoteNode = ({ ip, + hostname, ...opts -}: { - ip: string; - opts?: any; -}) => { - return useMutation(publishOnRemoteNode, { - mutationKey: [publishAllFromSharedStateAsyncKey, ip], +}: IShatedStateRemoteQueryProps) => { + return useMutation({ + mutationFn: ({ ip }) => + doSharedStateApiCall( + getFromSharedStateKeys.publishAllFromSharedState(), + ip + ), + mutationKey: [getFromSharedStateKeys.publishAllFromSharedState(), ip], ...opts, }); }; @@ -180,12 +196,9 @@ export const usePublishOnRemoteNode = ({ export const useSyncDataTypes = ({ ip, ...opts -}: { - ip: string; - opts?: any; -}) => { +}: IShatedStateRemoteQueryProps) => { return useMutation(syncAllDataTypes, { - mutationKey: [syncFromSharedStateAsyncKey, ip], + mutationKey: [syncFromSharedStateKey, ip], ...opts, }); }; diff --git a/plugins/lime-plugin-mesh-wide/src/meshWideQueriesKeys.tsx b/plugins/lime-plugin-mesh-wide/src/meshWideQueriesKeys.tsx index dc8138fc..ce9d7597 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWideQueriesKeys.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWideQueriesKeys.tsx @@ -3,37 +3,33 @@ import { DataTypes, } from "plugins/lime-plugin-mesh-wide/src/meshWideTypes"; -export const getFromSharedStateMultiWriterKey = [ - "shared-state", - "getFromSharedStateMultiWriter", -]; -export const getFromSharedStateAsyncKey = ["shared-state-async", "get"]; -export const syncFromSharedStateAsyncKey = ["shared-state-async", "sync"]; -export const publishAllFromSharedStateAsyncKey = [ +export const getFromSharedStateKey = ["shared-state-async", "get"]; +export const insertIntoSharedStateKey = ["shared-state-async", "insert"]; +export const syncFromSharedStateKey = ["shared-state-async", "sync"]; +export const publishAllFromSharedStateKey = [ "shared-state-async", "publish_all", ]; -export const insertIntoSharedStateKey = [ - "shared-state", - "insertIntoSharedStateMultiWriter", -]; - export const getFromSharedStateKeys = { - getFromSharedStateAsync: (dataType: DataTypes) => [ - ...getFromSharedStateAsyncKey, + getFromSharedState: (dataType: DataTypes) => [ + ...getFromSharedStateKey, { data_type: dataType }, ], - syncFromSharedStateAsync: ( + getReferenceFromSharedState: (dataType: DataTypes) => [ + ...getFromSharedStateKey, + { data_type: `${dataType}_ref` }, + ], + syncFromSharedState: ( dataType: T, peers_ip: string[] - ) => [...syncFromSharedStateAsyncKey, { data_type: dataType, peers_ip }], - getFromSharedStateMultiWriter: (dataType: DataTypes) => [ - ...getFromSharedStateMultiWriterKey, - { data_type: dataType }, - ], - insertIntoSharedStateKey: ( + ) => [...syncFromSharedStateKey, { data_type: dataType, peers_ip }], + insertIntoReferenceState: ( dataType: T, data: DataTypeMap[T] - ) => [...insertIntoSharedStateKey, { data_type: dataType, json: data }], + ) => [ + ...insertIntoSharedStateKey, + { data_type: `${dataType}_ref`, json: data }, + ], + publishAllFromSharedState: () => [...publishAllFromSharedStateKey, {}], }; From 47a88b373f54c39554e9630fc8e66735ce7abfa2 Mon Sep 17 00:00:00 2001 From: selankon Date: Sun, 12 May 2024 17:11:24 +0200 Subject: [PATCH 03/22] chore(meshwide): disable set reference state from errors types --- .../FeatureDetail/ShowErrorsDetail.tsx | 25 ++++++------------- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/ShowErrorsDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/ShowErrorsDetail.tsx index 50e72733..47ff61d6 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/ShowErrorsDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/ShowErrorsDetail.tsx @@ -1,23 +1,7 @@ import { Trans } from "@lingui/macro"; -import { Button } from "components/buttons/button"; - -import { useSetReferenceState } from "plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/SetReferenceStateBtn"; import { Row } from "plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index"; -import { - DataTypes, - ErrorsDetails, -} from "plugins/lime-plugin-mesh-wide/src/meshWideTypes"; - -const SetDataTypeBtn = ({ dataType }: { dataType: T }) => { - const { mutate, btnText } = useSetReferenceState(dataType); - return ( -
-
{dataType}
- -
- ); -}; +import { ErrorsDetails } from "plugins/lime-plugin-mesh-wide/src/meshWideTypes"; export const ShowErrorsDetail = ({ errors }: { errors: ErrorsDetails }) => { return ( @@ -70,7 +54,12 @@ export const ShowErrorsDetail = ({ errors }: { errors: ErrorsDetails }) => { ); } return ( - +
+ + Reference state is not set for{" "} + {dataType} + +
); })} From 50c69b61d9e3efe3e955097ca60636483804a2e1 Mon Sep 17 00:00:00 2001 From: selankon Date: Sun, 12 May 2024 19:37:39 +0200 Subject: [PATCH 04/22] chore(components): update toast default duration --- .../src/components/FeatureDetail/UpdateNodeInfoBtn.tsx | 1 - .../src/components/configPage/ConfigSection.tsx | 3 --- .../src/components/configPage/MeshStatus.tsx | 1 - .../src/components/configPage/OptionForm.tsx | 2 -- src/components/toast/index.tsx | 2 +- 5 files changed, 1 insertion(+), 8 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/UpdateNodeInfoBtn.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/UpdateNodeInfoBtn.tsx index 02b330af..1d8f833f 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/UpdateNodeInfoBtn.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/UpdateNodeInfoBtn.tsx @@ -62,7 +62,6 @@ const UpdateNodeInfoBtn = ({ Error connecting with {nodeName}, is node up? ), - duration: 5000, }); throw e; }) diff --git a/plugins/lime-plugin-mesh-wide/src/components/configPage/ConfigSection.tsx b/plugins/lime-plugin-mesh-wide/src/components/configPage/ConfigSection.tsx index 66609042..95f64665 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/configPage/ConfigSection.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/configPage/ConfigSection.tsx @@ -48,7 +48,6 @@ export const SectionEditOrDelete = ({ name }) => { Edited {name} - {new Date().toDateString()} ), - duration: 5000, onAction: () => { console.log("Undo action"); }, @@ -66,7 +65,6 @@ export const SectionEditOrDelete = ({ name }) => { Deleted {name} - {new Date().toDateString()} ), - duration: 5000, onAction: () => { console.log("Undo action"); }, @@ -96,7 +94,6 @@ export const AddNewSectionBtn = () => { {new Date().toDateString()} ), - duration: 5000, }); }); }} diff --git a/plugins/lime-plugin-mesh-wide/src/components/configPage/MeshStatus.tsx b/plugins/lime-plugin-mesh-wide/src/components/configPage/MeshStatus.tsx index 7dc84e84..361e2081 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/configPage/MeshStatus.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/configPage/MeshStatus.tsx @@ -19,7 +19,6 @@ export const MeshStatus = () => { ), - duration: 5000, }); }} > diff --git a/plugins/lime-plugin-mesh-wide/src/components/configPage/OptionForm.tsx b/plugins/lime-plugin-mesh-wide/src/components/configPage/OptionForm.tsx index af75fbcd..7f93c1dc 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/configPage/OptionForm.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/configPage/OptionForm.tsx @@ -100,7 +100,6 @@ export const OptionContainer = ({ Deleted {keyString} ), - duration: 5000, onAction: () => { console.log("Undo action"); }, @@ -122,7 +121,6 @@ export const OptionContainer = ({ toggleIsEditing(); showToast({ text: Edited {keyString}, - duration: 5000, }); }); }} diff --git a/src/components/toast/index.tsx b/src/components/toast/index.tsx index 102a67c4..995d9cc6 100644 --- a/src/components/toast/index.tsx +++ b/src/components/toast/index.tsx @@ -32,7 +32,7 @@ const Toast = ({ onHide, onAction, actionText = "Undo", - duration, + duration = 5000, }: IToastProps) => { const [showToast, setShowToast] = useState(true); const _onAction = () => { From 3ee252effd83516ac2acfacdf8e04946ae6aea2c Mon Sep 17 00:00:00 2001 From: selankon Date: Sun, 12 May 2024 19:43:29 +0200 Subject: [PATCH 05/22] chore(meshwide): implement set reference state --- .../components/FeatureDetail/LinkDetail.tsx | 66 ++++++++++- .../components/FeatureDetail/NodeDetail.tsx | 51 ++++++++- .../FeatureDetail/SetReferenceStateBtn.tsx | 69 ------------ .../src/components/configPage/modals.tsx | 71 +++++++++++- .../src/hooks/useLocatedLinks.tsx | 21 ++-- .../src/lib/links/PointToPointLink.ts | 20 ++-- .../src/lib/links/getLinksCoordinates.ts | 4 +- .../src/meshWideQueries.tsx | 103 +++++++++++------- 8 files changed, 260 insertions(+), 145 deletions(-) delete mode 100644 plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/SetReferenceStateBtn.tsx diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx index 7436f2eb..bbf3d051 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx @@ -1,17 +1,20 @@ import { Trans } from "@lingui/macro"; import { useState } from "preact/hooks"; +import { useCallback } from "react"; import { Warning } from "components/icons/status"; import Tabs from "components/tabs"; +import { useToast } from "components/toast/toastProvider"; import { StatusAndButton } from "plugins/lime-plugin-mesh-wide/src/components/Components"; -import { useSetReferenceState } from "plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/SetReferenceStateBtn"; +import { useSetLinkReferenceStateModal } from "plugins/lime-plugin-mesh-wide/src/components/configPage/modals"; import { getQueryByLinkType, usePointToPointErrors, } from "plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks"; import { MacToMacLink } from "plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink"; import { readableBytes } from "plugins/lime-plugin-mesh-wide/src/lib/utils"; +import { useSetLinkReferenceState } from "plugins/lime-plugin-mesh-wide/src/meshWideQueries"; import { BaseMacToMacLink, BatmanLinkErrorCodes, @@ -221,6 +224,8 @@ export const LinkReferenceStatus = ({ reference }: LinkMapFeature) => { type: reference.type, }); + const isDown = !errors.linkUp; + // Check if there are errors of global reference state to shown const { reference: fetchDataReference } = getQueryByLinkType( reference.type @@ -232,8 +237,63 @@ export const LinkReferenceStatus = ({ reference }: LinkMapFeature) => { referenceError = true; } + const { toggleModal, confirmModal, isModalOpen } = + useSetLinkReferenceStateModal(); + const { showToast } = useToast(); + // Mutation to update the reference state - const { mutate, btnText } = useSetReferenceState(reference.type); + const nodesToUpdate = reference.nodes.reduce((acc, node) => { + acc[node.ipv4] = node.hostname; + return acc; + }, {}); + const { callMutations } = useSetLinkReferenceState({ + linkType: reference.type, + linkToUpdate: reference, + isDown, + nodesToUpdate, + params: { + onSuccess: () => { + showToast({ + text: New reference state set!, + }); + }, + onError: () => { + showToast({ + text: Error setting new reference state!, + }); + }, + onSettled: () => { + if (isModalOpen) toggleModal(); + }, + }, + }); + + const setReferenceState = useCallback(async () => { + confirmModal( + reference.type, + Object.values(nodesToUpdate), + isDown, + async () => { + await callMutations(); + } + ); + }, [callMutations, confirmModal, isDown, nodesToUpdate, reference.type]); + + let btnText = ( + + Set reference state for this +
{reference.type} link +
+ ); + if (isDown) { + btnText = ( + + Delete this {reference.type} link +
+ from reference state +
+ ); + } let errorMessage = Same status as in the reference state; if (referenceError) { @@ -252,7 +312,7 @@ export const LinkReferenceStatus = ({ reference }: LinkMapFeature) => { {errorMessage} diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx index 0357bc4f..d7ddde77 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx @@ -1,16 +1,22 @@ import { Trans } from "@lingui/macro"; +import { useCallback } from "react"; + +import { useToast } from "components/toast/toastProvider"; import { StatusAndButton } from "plugins/lime-plugin-mesh-wide/src/components/Components"; import RemoteRebootBtn from "plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/RebootNodeBtn"; -import { useSetReferenceState } from "plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/SetReferenceStateBtn"; import UpdateNodeInfoBtn from "plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/UpdateNodeInfoBtn"; import { Row, TitleAndText, } from "plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/index"; +import { useSetNoeInfoReferenceStateModal } from "plugins/lime-plugin-mesh-wide/src/components/configPage/modals"; import { useSingleNodeErrors } from "plugins/lime-plugin-mesh-wide/src/hooks/useSingleNodeErrors"; import { getArrayDifference } from "plugins/lime-plugin-mesh-wide/src/lib/utils"; -import { useMeshWideNodesReference } from "plugins/lime-plugin-mesh-wide/src/meshWideQueries"; +import { + useMeshWideNodesReference, + useSetNodeInfoReferenceState, +} from "plugins/lime-plugin-mesh-wide/src/meshWideQueries"; import { NodeErrorCodes, NodeMapFeature, @@ -111,12 +117,49 @@ export const NodeReferenceStatus = ({ actual, reference }: NodeMapFeature) => { reference, }); + const hostname = isDown ? reference.hostname : actual.hostname; + const ip = isDown ? reference.ipv4 : actual.ipv4; + // Check if there are errors of global reference state to shown const { data: meshWideNodesReference, isError: isReferenceError } = useMeshWideNodesReference({}); + const { toggleModal, confirmModal, isModalOpen } = + useSetNoeInfoReferenceStateModal(); + const { showToast } = useToast(); + // Mutation to update the reference state - const { mutate, btnText } = useSetReferenceState("node_info"); + const { mutateAsync } = useSetNodeInfoReferenceState({ + ip, + hostname, + isDown, + params: { + onSuccess: () => { + showToast({ + text: New reference state set!, + }); + }, + onError: () => { + showToast({ + text: Error setting new reference state!, + }); + }, + onSettled: () => { + if (isModalOpen) toggleModal(); + }, + }, + }); + + const setReferenceState = useCallback(async () => { + confirmModal(hostname, isDown, async () => { + await mutateAsync(); + }); + }, [confirmModal, hostname, isDown, mutateAsync]); + + let btnText = Set reference state for this node; + if (isDown) { + btnText = Delete this this node from reference state; + } let referenceError = false; if ( @@ -144,7 +187,7 @@ export const NodeReferenceStatus = ({ actual, reference }: NodeMapFeature) => { {errorMessage} diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/SetReferenceStateBtn.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/SetReferenceStateBtn.tsx deleted file mode 100644 index fda44759..00000000 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/SetReferenceStateBtn.tsx +++ /dev/null @@ -1,69 +0,0 @@ -import { Trans } from "@lingui/macro"; -import { useCallback } from "react"; - -import { useToast } from "components/toast/toastProvider"; - -import { useSetReferenceStateModal } from "plugins/lime-plugin-mesh-wide/src/components/configPage/modals"; -import { - useSetBatmanLinksInfoReferenceState, - useSetNodeInfoReferenceState, - useSetWifiLinksInfoReferenceState, -} from "plugins/lime-plugin-mesh-wide/src/meshWideQueries"; -import { DataTypes } from "plugins/lime-plugin-mesh-wide/src/meshWideTypes"; - -const toastDuration = 5000; - -export const useSetReferenceState = (dataType: T) => { - const { toggleModal, confirmModal, isModalOpen } = - useSetReferenceStateModal(); - const { showToast } = useToast(); - - const mutationOpts = { - onSuccess: () => { - showToast({ - text: New reference state set!, - duration: toastDuration, - }); - }, - onError: () => { - showToast({ - text: Error setting new reference state!, - duration: toastDuration, - }); - }, - onSettled: () => { - if (isModalOpen) toggleModal(); - }, - }; - - const { mutateAsync: nodesMutation } = - useSetNodeInfoReferenceState(mutationOpts); - const { mutateAsync: wifiMutation } = - useSetWifiLinksInfoReferenceState(mutationOpts); - const { mutateAsync: batmanMutation } = - useSetBatmanLinksInfoReferenceState(mutationOpts); - - const btnText = Set {dataType} reference state; - - const mutate = useCallback(async () => { - switch (dataType) { - case "node_info": - await confirmModal(dataType, async () => { - await nodesMutation(); - }); - break; - case "wifi_links_info": - confirmModal(dataType, async () => { - await wifiMutation(); - }); - break; - case "bat_links_info": - confirmModal(dataType, async () => { - await batmanMutation(); - }); - break; - } - }, [batmanMutation, confirmModal, dataType, nodesMutation, wifiMutation]); - - return { mutate, btnText }; -}; diff --git a/plugins/lime-plugin-mesh-wide/src/components/configPage/modals.tsx b/plugins/lime-plugin-mesh-wide/src/components/configPage/modals.tsx index e0f2f40b..c4ce68c7 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/configPage/modals.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/configPage/modals.tsx @@ -85,18 +85,77 @@ export const useAddNewSectionModal = () => { return { actionModal, toggleModal }; }; -export const useSetReferenceStateModal = () => { +export const useSetNoeInfoReferenceStateModal = () => { const { toggleModal, setModalState, isModalOpen } = useModal(); const confirmModal = useCallback( - (dataType: DataTypes, cb: () => Promise) => { + (nodeName: string, isDown: boolean, cb: () => Promise) => { + let title = Set reference state for {nodeName}; + let content = Set the reference state for this node.; + if (isDown) { + title = ( + Remove {nodeName} from the reference state + ); + content = ( + + This node seems down, remove them from the reference + state? + + ); + } setModalState({ - title: Set reference state for {dataType}, - content: ( + title, + content, + successCb: cb, + successBtnText: Continue, + }); + toggleModal(); + }, + [setModalState, toggleModal] + ); + return { confirmModal, toggleModal, isModalOpen }; +}; + +export const useSetLinkReferenceStateModal = () => { + const { toggleModal, setModalState, isModalOpen } = useModal(); + + const confirmModal = useCallback( + ( + dataType: DataTypes, + nodes: string[], + isDown: boolean, + cb: () => Promise + ) => { + let title = ( + Set reference state for this {dataType} link? + ); + let content = ( + This will set the reference state of this link: + ); + if (isDown) { + title = ( + + Remove this {dataType} from the reference state + + ); + content = ( - Are you sure you want to set this reference state for{" "} - {dataType} + This link seems down, remove them from the reference + state? + ); + } + setModalState({ + title, + content: ( +
+ {content} +
+
+
{nodes[0]}
+
{nodes[1]}
+
+
), successCb: cb, successBtnText: Continue, diff --git a/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx b/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx index 4be5cb17..12894ec9 100644 --- a/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx +++ b/plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks.tsx @@ -35,16 +35,19 @@ interface getQueryByLinkTypeReturnType { export const getQueryByLinkType = ( type: T ): getQueryByLinkTypeReturnType => { - if (type === "bat_links_info") { - return { - state: useMeshWideBatman, - reference: useMeshWideBatmanReference, - } as getQueryByLinkTypeReturnType; + switch (type) { + case "bat_links_info": + return { + state: useMeshWideBatman, + reference: useMeshWideBatmanReference, + } as getQueryByLinkTypeReturnType; + case "wifi_links_info": + default: + return { + state: useMeshWideLinks, + reference: useMeshWideLinksReference, + } as getQueryByLinkTypeReturnType; } - return { - state: useMeshWideLinks, - reference: useMeshWideLinksReference, - } as getQueryByLinkTypeReturnType; }; interface IUselocatedLinks { diff --git a/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts b/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts index 067c458f..dae62fd9 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts @@ -2,6 +2,7 @@ import { BaseMacToMacLink, Coordinates, ILocatedLink, + INodeInfo, LinkDataTypes, LinkType, MacToMacLinkId, @@ -15,11 +16,15 @@ import { */ export class PontToPointLink { private _links: BaseMacToMacLink[] = []; + private _nodes: INodeInfo[] = []; public readonly id: PointToPointLinkId; public readonly coordinates: Coordinates[] = []; - constructor(coord1: Coordinates, coord2: Coordinates) { + constructor(node1: INodeInfo, node2: INodeInfo) { + const coord1 = node1.coordinates; + const coord2 = node2.coordinates; this.id = PontToPointLink.generateId(coord1, coord2); + this.nodes.push(node1, node2); this.coordinates.push(coord1, coord2); } @@ -50,19 +55,14 @@ export class PontToPointLink { return false; } - get names(): string[] { - return [ - ...this._links.reduce((acc, link) => { - Object.keys(link).forEach((key) => acc.add(key)); - return acc; - }, new Set()), - ] as string[]; - } - get links() { return this._links; } + get nodes() { + return this._nodes; + } + /** * Generate a deterministic unique id based on the coordinates of a node. * @param coord1 diff --git a/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts b/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts index e620c716..8736f9ec 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts @@ -55,8 +55,8 @@ export const mergeLinksAndCoordinates = ( // If this point to point link no exists, instantiate it if (!result[linkKey]) { result[linkKey] = new PontToPointLink( - nodes[linkNodeName].coordinates, - nodes[dstNodeName!].coordinates + nodes[linkNodeName], + nodes[dstNodeName] ); } // If the link PontToPointLink already exists and the link is already added, ignore it diff --git a/plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx b/plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx index aa86658a..9c8ddc3a 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx @@ -1,5 +1,8 @@ import { useMutation, useQuery } from "@tanstack/react-query"; +import { meshUpgradeQueryKeys } from "plugins/lime-plugin-mesh-wide-upgrade/src/meshUpgradeQueriesKeys"; +import { getQueryByLinkType } from "plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks"; +import { PontToPointLink } from "plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink"; import { doSharedStateApiCall, syncAllDataTypes, @@ -15,9 +18,11 @@ import { IMeshWideConfig, INodes, IWifiLinks, + LinkType, SelectedMapFeature, } from "plugins/lime-plugin-mesh-wide/src/meshWideTypes"; +import { useMeshWideSyncCall } from "utils/meshWideSyncCall"; import { useSharedData } from "utils/useSharedData"; const refetchInterval = 60000; @@ -110,21 +115,28 @@ export function useMeshWideNodes(params) { * to unify criterias and add a confirmation modal */ -interface IShatedStateRemoteQueryProps { +interface ISharedStateRemoteQueryProps { ip: string; - hostname?: string; params?: any; } +type ISharedStateSetReferenceQueryProps = { + isDown: boolean; + hostname?: string; +} & ISharedStateRemoteQueryProps; + export const useSetNodeInfoReferenceState = ({ ip, hostname, + isDown, params, -}: IShatedStateRemoteQueryProps) => { +}: ISharedStateSetReferenceQueryProps) => { const type = "node_info"; const { data } = useMeshWideNodes({}); + // Ignore the types here because it to delete a node you have to pass an empty object + // @ts-ignore const queryKey = getFromSharedStateKeys.insertIntoReferenceState(type, { - [hostname]: data[hostname], + [hostname]: isDown ? null : data[hostname], }); return useMutation( queryKey, @@ -135,42 +147,50 @@ export const useSetNodeInfoReferenceState = ({ ); }; -export const useSetWifiLinksInfoReferenceState = ({ - ip, - hostname, - params, -}: IShatedStateRemoteQueryProps) => { - const type = "wifi_links_info"; - const { data } = useMeshWideLinks({}); - const queryKey = getFromSharedStateKeys.insertIntoReferenceState(type, { - [hostname]: data[hostname], - }); - return useMutation( - queryKey, - () => doSharedStateApiCall(queryKey, ip), - { - ...params, - } - ); -}; +interface IUseSetLinkReferenceState { + linkType: LinkType; + linkToUpdate: PontToPointLink; + nodesToUpdate: { [ip: string]: string }; // { ip: hostname } + params: any; + isDown: boolean; +} -export const useSetBatmanLinksInfoReferenceState = ({ - ip, - hostname, +export const useSetLinkReferenceState = ({ + linkType, + linkToUpdate, + isDown, + nodesToUpdate, params, -}: IShatedStateRemoteQueryProps) => { - const type = "bat_links_info"; - const { data } = useMeshWideBatman({}); - const queryKey = getFromSharedStateKeys.insertIntoReferenceState(type, { - [hostname]: data[hostname], +}: IUseSetLinkReferenceState) => { + const { state, reference } = getQueryByLinkType(linkType); + const { data } = state({}); + const { data: referenceData } = reference({}); + + return useMeshWideSyncCall({ + mutationKey: meshUpgradeQueryKeys.remoteConfirmUpgrade(), + mutationFn: ({ ip }) => { + const hostname = nodesToUpdate[ip]; + const referenceLinks = referenceData[hostname]; + for (const mactomac of linkToUpdate.links) { + if (isDown) { + delete referenceLinks[mactomac.id]; + continue; + } + referenceLinks[mactomac.id] = data[hostname][mactomac.id]; + } + const queryKey = getFromSharedStateKeys.insertIntoReferenceState( + linkType, + // For some reason I have to ignore the types here because it not infers properly. + // Using the same code but for a specific link type, it works. + // For some reason with the use of getQueryByLinkType it doesn't work. + // @ts-ignore + { [hostname]: referenceLinks } + ); + return doSharedStateApiCall(queryKey, ip); + }, + ips: Object.keys(nodesToUpdate), + options: params, }); - return useMutation( - queryKey, - () => doSharedStateApiCall(queryKey, ip), - { - ...params, - } - ); }; /** @@ -179,9 +199,8 @@ export const useSetBatmanLinksInfoReferenceState = ({ export const usePublishOnRemoteNode = ({ ip, - hostname, ...opts -}: IShatedStateRemoteQueryProps) => { +}: ISharedStateRemoteQueryProps) => { return useMutation({ mutationFn: ({ ip }) => doSharedStateApiCall( @@ -195,11 +214,11 @@ export const usePublishOnRemoteNode = ({ export const useSyncDataTypes = ({ ip, - ...opts -}: IShatedStateRemoteQueryProps) => { + params, +}: ISharedStateRemoteQueryProps) => { return useMutation(syncAllDataTypes, { mutationKey: [syncFromSharedStateKey, ip], - ...opts, + ...params, }); }; From ba051e8ad0e85292d14372b058f4e7e9aaa3cbab Mon Sep 17 00:00:00 2001 From: selankon Date: Mon, 13 May 2024 09:46:26 +0200 Subject: [PATCH 06/22] chore(meshwide): implement modal key --- .../src/components/FeatureDetail/RebootNodeBtn.tsx | 12 +++++++----- .../src/components/configPage/modals.tsx | 4 ++-- src/components/Modal/Modal.tsx | 11 ++++++++--- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/RebootNodeBtn.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/RebootNodeBtn.tsx index 8704c8b3..b3f0b2b1 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/RebootNodeBtn.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/RebootNodeBtn.tsx @@ -35,11 +35,13 @@ const useRemoteReboot = (opts?) => { }; const useRebootNodeModal = ({ node }: { node: INodeInfo }) => { - const { toggleModal, setModalState, isModalOpen } = useModal(); + const modalKey = "rebootNodeModal"; + const { toggleModal, setModalState, isModalOpen, openModalKey } = + useModal(); const [password, setPassword] = useState(""); const { mutate, isLoading, error } = useRemoteReboot({ onSuccess: () => { - toggleModal(); + toggleModal(modalKey); }, }); @@ -91,15 +93,15 @@ const useRebootNodeModal = ({ node }: { node: INodeInfo }) => { const rebootModal = useCallback(() => { updateModalState(); - toggleModal(); + toggleModal(modalKey); }, [toggleModal, updateModalState]); // Update modal state with mutation result useEffect(() => { - if (isModalOpen) { + if (isModalOpen && openModalKey === modalKey) { updateModalState(); } - }, [isLoading, error, isModalOpen, updateModalState]); + }, [isLoading, error, isModalOpen, updateModalState, openModalKey]); return { rebootModal, toggleModal, isModalOpen }; }; diff --git a/plugins/lime-plugin-mesh-wide/src/components/configPage/modals.tsx b/plugins/lime-plugin-mesh-wide/src/components/configPage/modals.tsx index c4ce68c7..06b28f91 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/configPage/modals.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/configPage/modals.tsx @@ -32,7 +32,7 @@ const useActionModal = ( }); toggleModal(); }, - [setModalState, toggleModal] + [actionName, btnText, setModalState, title, toggleModal] ); return { actionModal, toggleModal }; }; @@ -80,7 +80,7 @@ export const useAddNewSectionModal = () => { }); toggleModal(); }, - [setModalState, toggleModal] + [handleSubmit, register, setModalState, toggleModal] ); return { actionModal, toggleModal }; }; diff --git a/src/components/Modal/Modal.tsx b/src/components/Modal/Modal.tsx index bc067e60..3a4e854b 100644 --- a/src/components/Modal/Modal.tsx +++ b/src/components/Modal/Modal.tsx @@ -8,7 +8,8 @@ import Divider from "components/divider"; interface ModalContextProps { isModalOpen: boolean; - toggleModal: () => void; + openModalKey?: string | null; + toggleModal: (key?: string) => void; setModalState: (state?: ModalState) => void; isLoading: boolean; } @@ -28,6 +29,7 @@ interface ModalState { const ModalContext = createContext({ isModalOpen: false, + openModalKey: null, toggleModal: () => {}, setModalState: () => {}, isLoading: false, @@ -45,6 +47,7 @@ export type ModalActions = "success" | "delete"; export const UseModalProvider = ({ children }) => { const [isModalOpen, setModalOpen] = useState(false); + const [openModalKey, setOpenModalKey] = useState(null); const [isLoading, setIsLoading] = useState(false); const [modalState, setModalState] = useState({ @@ -57,9 +60,10 @@ export const UseModalProvider = ({ children }) => { deleteBtnText: Cancel, }); - const toggleModal = useCallback(() => { + const toggleModal = useCallback((key?: string) => { setModalOpen((prevIsModalOpen) => !prevIsModalOpen); - }, [isModalOpen]); + setOpenModalKey(key ?? null); + }, []); const runCb = useCallback( async (cb: CallbackFn) => { @@ -83,6 +87,7 @@ export const UseModalProvider = ({ children }) => { toggleModal, setModalState, isLoading, + openModalKey, }} > {children} From 46f95623f1af8f8ed197d09aaecc25fd0b86ec47 Mon Sep 17 00:00:00 2001 From: selankon Date: Mon, 13 May 2024 11:15:17 +0200 Subject: [PATCH 07/22] chore(meshwide): use correct link keys --- .../src/lib/links/PointToPointLink.ts | 18 +++--------------- .../src/lib/links/getLinksCoordinates.ts | 19 +++++++++---------- 2 files changed, 12 insertions(+), 25 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts b/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts index dae62fd9..853afd50 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink.ts @@ -38,21 +38,9 @@ export class PontToPointLink { * @param mac1 * @param mac2 */ - linkExists(mac1: string, mac2: string) { - for (const link of this._links) { - // Just needed to check the first node of the link object becouse the other will have the same macs but reversed - const node = link.data[Object.keys(link.data)[0]]; - if ( - node && - (node.dst_mac.toLowerCase() === mac1.toLowerCase() || - node.src_mac.toLowerCase() === mac1.toLowerCase()) && - (node.dst_mac.toLowerCase() === mac2.toLowerCase() || - node.src_mac.toLowerCase() === mac2.toLowerCase()) - ) { - return true; - } - } - return false; + linkExists(linkKey: string) { + const link = this._links.find((link) => link.id === linkKey); + return !!link; } get links() { diff --git a/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts b/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts index 8736f9ec..0ec6cf97 100644 --- a/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/links/getLinksCoordinates.ts @@ -47,31 +47,28 @@ export const mergeLinksAndCoordinates = ( nodes[linkNodeName] ) { // Generate a unique id of the point to point link based on the coordinates to check if already exists - const linkKey = PontToPointLink.generateId( + const geoLinkKey = PontToPointLink.generateId( nodes[linkNodeName].coordinates, nodes[dstNodeName].coordinates ); // If this point to point link no exists, instantiate it - if (!result[linkKey]) { - result[linkKey] = new PontToPointLink( + if (!result[geoLinkKey]) { + result[geoLinkKey] = new PontToPointLink( nodes[linkNodeName], nodes[dstNodeName] ); } // If the link PontToPointLink already exists and the link is already added, ignore it else if ( - result[linkKey].linkExists( - linkData.src_mac, - linkData.dst_mac - ) || + result[geoLinkKey].linkExists(linkKey) || !links[dstNodeName] ) { continue; } // Find destination link info from shared state - const destPointData = links[dstNodeName][linkKey]; + const destLinkData = links[dstNodeName][linkKey]; const entry = { [linkNodeName]: { @@ -79,12 +76,14 @@ export const mergeLinksAndCoordinates = ( coordinates: nodes[linkNodeName].coordinates, }, [dstNodeName]: { - ...destPointData, + ...destLinkData, coordinates: nodes[dstNodeName].coordinates, }, } as ILocatedLink; - result[linkKey].addLink(new MacToMacLink(linkKey, entry, type)); + result[geoLinkKey].addLink( + new MacToMacLink(linkKey, entry, type) + ); } } } From 1c39d33e9ae758ebb3aa772a10249588894be992 Mon Sep 17 00:00:00 2001 From: selankon Date: Mon, 13 May 2024 11:35:54 +0200 Subject: [PATCH 08/22] chore(meshwide): implement connection error toast --- .../FeatureDetail/RebootNodeBtn.tsx | 5 +++++ .../src/meshWideQueries.tsx | 12 +++++++++++ src/components/toast/toasts.tsx | 20 +++++++++++++++++++ 3 files changed, 37 insertions(+) create mode 100644 src/components/toast/toasts.tsx diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/RebootNodeBtn.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/RebootNodeBtn.tsx index b3f0b2b1..c35db8f4 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/RebootNodeBtn.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/RebootNodeBtn.tsx @@ -7,6 +7,7 @@ import { useModal } from "components/Modal/Modal"; import { Button } from "components/buttons/button"; import { ErrorMsg } from "components/form"; import Loading from "components/loading"; +import { useErrrorConnectionToast } from "components/toast/toasts"; import { callToRemoteNode } from "plugins/lime-plugin-mesh-wide-upgrade/src/utils/api"; import { PowerIcon } from "plugins/lime-plugin-mesh-wide/src/icons/power"; @@ -28,8 +29,12 @@ export async function remoteReboot({ ip, password }: IRemoteRebotProps) { } const useRemoteReboot = (opts?) => { + const { show } = useErrrorConnectionToast(); return useMutation((props: IRemoteRebotProps) => remoteReboot(props), { mutationKey: ["system", "reboot"], + onError: (error, variables) => { + show(variables.ip); + }, ...opts, }); }; diff --git a/plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx b/plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx index 9c8ddc3a..e00b8307 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx @@ -1,5 +1,7 @@ import { useMutation, useQuery } from "@tanstack/react-query"; +import { useErrrorConnectionToast } from "components/toast/toasts"; + import { meshUpgradeQueryKeys } from "plugins/lime-plugin-mesh-wide-upgrade/src/meshUpgradeQueriesKeys"; import { getQueryByLinkType } from "plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks"; import { PontToPointLink } from "plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink"; @@ -133,6 +135,8 @@ export const useSetNodeInfoReferenceState = ({ }: ISharedStateSetReferenceQueryProps) => { const type = "node_info"; const { data } = useMeshWideNodes({}); + const { show } = useErrrorConnectionToast(); + // Ignore the types here because it to delete a node you have to pass an empty object // @ts-ignore const queryKey = getFromSharedStateKeys.insertIntoReferenceState(type, { @@ -142,6 +146,9 @@ export const useSetNodeInfoReferenceState = ({ queryKey, () => doSharedStateApiCall(queryKey, ip), { + onError: () => { + show(hostname); + }, ...params, } ); @@ -201,6 +208,8 @@ export const usePublishOnRemoteNode = ({ ip, ...opts }: ISharedStateRemoteQueryProps) => { + const { show } = useErrrorConnectionToast(); + return useMutation({ mutationFn: ({ ip }) => doSharedStateApiCall( @@ -208,6 +217,9 @@ export const usePublishOnRemoteNode = ({ ip ), mutationKey: [getFromSharedStateKeys.publishAllFromSharedState(), ip], + onError: () => { + show(ip); + }, ...opts, }); }; diff --git a/src/components/toast/toasts.tsx b/src/components/toast/toasts.tsx new file mode 100644 index 00000000..86161a33 --- /dev/null +++ b/src/components/toast/toasts.tsx @@ -0,0 +1,20 @@ +import { Trans } from "@lingui/macro"; +import { useCallback } from "react"; + +import { useToast } from "components/toast/toastProvider"; + +// Toast to inform cannot connect to a node +export const useErrrorConnectionToast = () => { + const { showToast } = useToast(); + const show = useCallback( + (nodeInfo: string) => { + showToast({ + text: ( + Error connecting with {nodeInfo}, is node up? + ), + }); + }, + [showToast] + ); + return { show }; +}; From 42eb3dc8044deb2dc12198d6f89e185467d7eefa Mon Sep 17 00:00:00 2001 From: selankon Date: Mon, 13 May 2024 12:53:48 +0200 Subject: [PATCH 09/22] chore(components): fix isLoading state onError --- src/components/buttons/button.tsx | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/components/buttons/button.tsx b/src/components/buttons/button.tsx index 319a674c..b92e8fde 100644 --- a/src/components/buttons/button.tsx +++ b/src/components/buttons/button.tsx @@ -1,3 +1,4 @@ +import { useState } from "preact/hooks"; import React, { useCallback } from "react"; export interface ButtonProps { @@ -21,7 +22,7 @@ export const Button = ({ ...props }: ButtonProps) => { // button internal state to set loading state - const [isLoading, setIsLoading] = React.useState(false); + const [innerIsLoading, setInnerIsLoading] = useState(false); let sizeClasses = "", colorClasses = ""; @@ -37,9 +38,9 @@ export const Button = ({ break; } - color = disabled || isLoading ? "disabled" : color; + const _color = disabled || innerIsLoading ? "disabled" : color; - switch (color) { + switch (_color) { case "secondary": colorClasses = outline ? "border-2 border-button-secondary text-button-secondary hover:bg-button-secondary hover:text-white" @@ -74,13 +75,17 @@ export const Button = ({ // useCallback for button click const handleClick = useCallback( async (e) => { - if (isLoading || disabled) return; - setIsLoading(true); - await onClick(e); - setIsLoading(false); + if (innerIsLoading || disabled) return; + setInnerIsLoading(true); + try { + await onClick(e); + } finally { + setInnerIsLoading(false); + } }, - [disabled, isLoading, onClick] + [disabled, innerIsLoading, onClick] ); + const Btn = () => (
Date: Mon, 13 May 2024 12:54:26 +0200 Subject: [PATCH 10/22] chore(meshwide): split sync to node logic --- .../FeatureDetail/UpdateNodeInfoBtn.tsx | 86 +++---------------- .../src/hooks/useSyncWithNode.tsx | 78 +++++++++++++++++ 2 files changed, 89 insertions(+), 75 deletions(-) create mode 100644 plugins/lime-plugin-mesh-wide/src/hooks/useSyncWithNode.tsx diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/UpdateNodeInfoBtn.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/UpdateNodeInfoBtn.tsx index 1d8f833f..3f3fd41c 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/UpdateNodeInfoBtn.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/UpdateNodeInfoBtn.tsx @@ -1,27 +1,11 @@ -import { Trans } from "@lingui/macro"; -import { useEffect, useState } from "preact/hooks"; -import { useCallback } from "react"; +import { useEffect } from "preact/hooks"; import { Button } from "components/buttons/button"; import { RefreshIcon } from "components/icons/teenny/refresh"; -import { useToast } from "components/toast/toastProvider"; -import { - usePublishOnRemoteNode, - useSyncDataTypes, -} from "plugins/lime-plugin-mesh-wide/src/meshWideQueries"; -import { getFromSharedStateKeys } from "plugins/lime-plugin-mesh-wide/src/meshWideQueriesKeys"; -import { - DataTypes, - completeDataTypeKeys, -} from "plugins/lime-plugin-mesh-wide/src/meshWideTypes"; - -import queryCache from "utils/queryCache"; - -interface INodeInfoProps { - ip: string; - nodeName: string; -} +import useSyncWithNode, { + ISyncWithNodeProps, +} from "plugins/lime-plugin-mesh-wide/src/hooks/useSyncWithNode"; const UpdateNodeInfoBtn = ({ ip, @@ -29,58 +13,8 @@ const UpdateNodeInfoBtn = ({ updateOnMount = true, }: { updateOnMount?: boolean; -} & INodeInfoProps) => { - const [isLoading, setIsLoading] = useState(false); - const { showToast } = useToast(); - - const { mutateAsync: localNodeSync } = useSyncDataTypes({ - ip, - }); - const { mutateAsync: publishOnRemoteNode } = usePublishOnRemoteNode({ - ip, - }); - - const invalidateQueries = useCallback(() => { - for (const dataType of Object.keys( - completeDataTypeKeys - ) as DataTypes[]) { - queryCache.invalidateQueries({ - queryKey: getFromSharedStateKeys.getFromSharedState(dataType), - }); - } - }, []); - - // useCallback to sync the node data - const syncNode = useCallback(async () => { - if (isLoading) return; - setIsLoading(true); - publishOnRemoteNode({ ip }) - .catch((e) => { - showToast({ - text: ( - - Error connecting with {nodeName}, is node up? - - ), - }); - throw e; - }) - .then(async () => { - await localNodeSync({ ip }); - await invalidateQueries(); - }) - .finally(() => { - setIsLoading(false); - }); - }, [ - invalidateQueries, - ip, - isLoading, - localNodeSync, - nodeName, - publishOnRemoteNode, - showToast, - ]); +} & ISyncWithNodeProps) => { + const { syncNode, isLoading } = useSyncWithNode({ ip, nodeName }); // Use effect to sync the node data on mount useEffect(() => { @@ -88,18 +22,20 @@ const UpdateNodeInfoBtn = ({ (async () => { await syncNode(); })(); + // Avoid executing the effect on updateOnMount change // eslint-disable-next-line react-hooks/exhaustive-deps }, [ip]); return (
@@ -127,6 +129,7 @@ export const NodeReferenceStatus = ({ actual, reference }: NodeMapFeature) => { const { toggleModal, confirmModal, isModalOpen } = useSetNoeInfoReferenceStateModal(); const { showToast } = useToast(); + const { syncNode } = useSyncWithNode({ ip, nodeName: hostname }); // Mutation to update the reference state const { mutateAsync } = useSetNodeInfoReferenceState({ @@ -134,7 +137,8 @@ export const NodeReferenceStatus = ({ actual, reference }: NodeMapFeature) => { hostname, isDown, params: { - onSuccess: () => { + onSuccess: async () => { + await syncNode(); showToast({ text: New reference state set!, }); From 589900423295756d6113642cce28f60617cfa792 Mon Sep 17 00:00:00 2001 From: selankon Date: Mon, 13 May 2024 18:28:52 +0200 Subject: [PATCH 13/22] chore(meshwide): implement channel --- .../src/components/FeatureDetail/LinkDetail.tsx | 3 +++ plugins/lime-plugin-mesh-wide/src/meshWideTypes.tsx | 1 + 2 files changed, 4 insertions(+) diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx index bbf3d051..79b994fc 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/LinkDetail.tsx @@ -102,6 +102,9 @@ const WifiDetail = ({ > {node?.chains?.toString() ?? "0/0"} + Channel}> + {node?.channel?.toString() ?? "0"} + TxRate}> diff --git a/plugins/lime-plugin-mesh-wide/src/meshWideTypes.tsx b/plugins/lime-plugin-mesh-wide/src/meshWideTypes.tsx index 08f3d50d..c4fa7ef4 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWideTypes.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWideTypes.tsx @@ -49,6 +49,7 @@ export type IWifiLinkData = { chains: number[]; signal: number; rx_rate: number; + channel: number; } & MacPair; /** From 0d96b9e93db92f2a3488ccb5c64eaaf11144c4fd Mon Sep 17 00:00:00 2001 From: selankon Date: Mon, 13 May 2024 18:29:24 +0200 Subject: [PATCH 14/22] chore(meshwide): add new node to mocks --- plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx b/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx index 5cf4e78f..7f28314a 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx @@ -71,6 +71,9 @@ export const nodesReferenceState: INodes = { board: "", hostname: "", }, +}; + +const newNode = { segundo: { bleachTTL: 12, author: "segundo", @@ -365,7 +368,7 @@ export const nodes = (): INodes => { // This delete an entire node delete newState[nodeName]; - return newState; + return { ...newState, ...newNode }; }; export const getMeshWideConfig = async () => meshWideConfig; From 29011456252174e85a9e1e85cd0eda41b474663c Mon Sep 17 00:00:00 2001 From: selankon Date: Mon, 13 May 2024 18:51:01 +0200 Subject: [PATCH 15/22] chore(meshwide): change representation of new nodes --- .../src/components/Map/LinkLine.tsx | 18 +++++++++++++----- .../src/components/Map/NodeMarker.tsx | 9 ++++++--- .../src/components/Map/style.less | 16 ++++++++++++++++ 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx index 7d1b44b8..caff4c07 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx @@ -1,5 +1,6 @@ +import { Trans } from "@lingui/macro"; import L from "leaflet"; -import { Polyline } from "react-leaflet"; +import { Polyline, Tooltip } from "react-leaflet"; import { useLocatedLinks } from "plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks"; import { PontToPointLink } from "plugins/lime-plugin-mesh-wide/src/lib/links/PointToPointLink"; @@ -16,9 +17,9 @@ export const LinkLine = ({ referenceLink, actualLink }: ILinkLineProps) => { const linkToShow = referenceLink ?? actualLink; const linkId = linkToShow.id; - let isNewNode = false; + let isNewLink = true; if (!referenceLink) { - isNewNode = true; + isNewLink = true; } const type = linkToShow.type; @@ -45,9 +46,10 @@ export const LinkLine = ({ referenceLink, actualLink }: ILinkLineProps) => { const getPathOpts = (isSelected) => { return { color: hasError ? "#eb7575" : "#76bd7d", + stroke: true, weight: isSelected ? 7 : 5, opacity: isSelected ? 1 : 0.8, - dashArray: isNewNode || !linkUp ? "7 10" : null, // Show dash array also when is a new node + dashArray: isNewLink ? "1,6" : !linkUp ? "7 10" : null, // Show dot line when new and dashed line when link is down }; }; @@ -71,7 +73,13 @@ export const LinkLine = ({ referenceLink, actualLink }: ILinkLineProps) => { l.setStyle(getPathOpts(isSelected)); }, }} - /> + > + {isNewLink && ( + + New link + + )} + ); }; diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/NodeMarker.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map/NodeMarker.tsx index e04ca9f8..19c5aa42 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map/NodeMarker.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/NodeMarker.tsx @@ -31,8 +31,7 @@ const NodeMarker = ({ selectedMapFeature?.id === name && style.selectedMarker } ${hasErrors ? style.errorMarker : style.syncedMarker} - ${isDown && style.notUpMarker} - ${isNewNode && style.newNodeMarker}`; + ${isDown && style.notUpMarker}`; // If node no reference is set, is a new node const nodeToShow = reference ?? actual; @@ -44,7 +43,11 @@ const NodeMarker = ({ className: style.leafletDivCustomIcon, iconAnchor: [0, 24], popupAnchor: [0, -36], - html: ``, + html: ` `, })} eventHandlers={{ click: (e) => { diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/style.less b/plugins/lime-plugin-mesh-wide/src/components/Map/style.less index 23662c5a..c6618fe1 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map/style.less +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/style.less @@ -2,6 +2,11 @@ @warning: #eaab7e; @bad: #eb7575; +.markerContainer { + position: relative; + display: inline-block; +} + //Delete a leaflet strange div .leaflet-div-custom-icon { background: none !important; @@ -67,3 +72,14 @@ .defaultMarker:hover { border: 2px solid black; } + +.badge { + position: absolute; + top: 7px; + right: -3px; + background-color: @warning; + color: white; + border-radius: 50%; + padding: 6px 6px; + font-size: 0.8em; +} From f3583d7b7bab7c4965338969ca096cfa79e3df33 Mon Sep 17 00:00:00 2001 From: selankon Date: Mon, 13 May 2024 18:59:07 +0200 Subject: [PATCH 16/22] chore(meshwide): add channel to mocks --- plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx b/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx index 7f28314a..f9c9959b 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWideMocks.tsx @@ -105,11 +105,13 @@ export const linksReferenceState: IWifiLinks = { tx_rate: 150000, rx_rate: 180000, chains: [-63, -59], + channel: 13, signal: -58, src_mac: "a8:40:41:1d:f9:35", dst_mac: "A0:F3:C1:46:28:97", }, "14CC20DA4EACa840411df935": { + channel: 13, tx_rate: 162000, rx_rate: 240000, chains: [-57, -51], @@ -120,6 +122,7 @@ export const linksReferenceState: IWifiLinks = { }, segundo: { A0F3C1461197a840411df9ff: { + channel: 13, tx_rate: 150000, rx_rate: 180000, chains: [-58, -59], @@ -128,6 +131,7 @@ export const linksReferenceState: IWifiLinks = { dst_mac: "A0:F3:C1:46:11:97", }, "14CC20DA4EACa840411df9aa": { + channel: 13, tx_rate: 162000, rx_rate: 240000, chains: [-52, -51], @@ -138,6 +142,7 @@ export const linksReferenceState: IWifiLinks = { }, "LiMe-da4eaa": { "14cc20da4eabA0F3C1462896": { + channel: 13, tx_rate: 65000, rx_rate: 65000, chains: [-25, -25], @@ -146,6 +151,7 @@ export const linksReferenceState: IWifiLinks = { dst_mac: "A0:F3:C1:46:28:96", }, "14cc20da4eacA0F3C1462897": { + channel: 13, tx_rate: 270000, rx_rate: 150000, chains: [-50, -47], @@ -154,6 +160,7 @@ export const linksReferenceState: IWifiLinks = { dst_mac: "A0:F3:C1:46:28:97", }, "14cc20da4eacA840411DF935": { + channel: 13, tx_rate: 243000, rx_rate: 162000, chains: [-75, -64], @@ -162,6 +169,7 @@ export const linksReferenceState: IWifiLinks = { dst_mac: "A8:40:41:1D:F9:35", }, "14cc20da4eacA840411DF9aa": { + channel: 13, tx_rate: 243000, rx_rate: 162000, chains: [-75, -64], @@ -172,6 +180,7 @@ export const linksReferenceState: IWifiLinks = { }, "LiMe-462895": { "14CC20DA4EABa0f3c1462896": { + channel: 13, tx_rate: 78000, rx_rate: 78000, chains: [-43, -46], @@ -180,6 +189,7 @@ export const linksReferenceState: IWifiLinks = { dst_mac: "14:CC:20:DA:4E:AB", }, "14CC20DA4EACa0f3c1462897": { + channel: 13, tx_rate: 243000, rx_rate: 216000, chains: [-68, -41], @@ -188,6 +198,7 @@ export const linksReferenceState: IWifiLinks = { dst_mac: "14:CC:20:DA:4E:AC", }, A840411DF935a0f3c1462897: { + channel: 13, tx_rate: 240000, rx_rate: 135000, chains: [-77, -65], @@ -196,6 +207,7 @@ export const linksReferenceState: IWifiLinks = { dst_mac: "A8:40:41:1D:F9:35", }, A840411DF9ffa0f3c1461197: { + channel: 13, tx_rate: 240000, rx_rate: 135000, chains: [-64, -65], From 1df8af587ed443289dcabde1673d3bc7401cf722 Mon Sep 17 00:00:00 2001 From: selankon Date: Mon, 13 May 2024 19:20:06 +0200 Subject: [PATCH 17/22] chore(meshwide): prevent show stored errors --- .../src/hooks/useMeshWideDataErrors.tsx | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/hooks/useMeshWideDataErrors.tsx b/plugins/lime-plugin-mesh-wide/src/hooks/useMeshWideDataErrors.tsx index bbdfc4f0..cb6ec9ec 100644 --- a/plugins/lime-plugin-mesh-wide/src/hooks/useMeshWideDataErrors.tsx +++ b/plugins/lime-plugin-mesh-wide/src/hooks/useMeshWideDataErrors.tsx @@ -37,11 +37,14 @@ export const useMeshWideDataErrors = () => { } }; - const { data: linksReferenceData, error: linksReferenceError } = - useMeshWideLinksReference({}); + const { + data: linksReferenceData, + error: linksReferenceError, + isError: linksReferenceIsError, + } = useMeshWideLinksReference({}); addError( getFromSharedStateKeys.getReferenceFromSharedState("wifi_links_info"), - linksReferenceError, + linksReferenceIsError ? linksReferenceError : null, linksReferenceData ); @@ -51,11 +54,14 @@ export const useMeshWideDataErrors = () => { linksError ); - const { data: batmanReferenceData, error: batmanReferenceError } = - useMeshWideBatmanReference({}); + const { + data: batmanReferenceData, + error: batmanReferenceError, + isError: batmanReferenceIsError, + } = useMeshWideBatmanReference({}); addError( getFromSharedStateKeys.getReferenceFromSharedState("bat_links_info"), - batmanReferenceError, + batmanReferenceIsError ? batmanReferenceError : null, batmanReferenceData ); @@ -65,11 +71,14 @@ export const useMeshWideDataErrors = () => { batmanError ); - const { data: nodesReferenceData, error: nodesReferenceError } = - useMeshWideNodesReference({}); + const { + data: nodesReferenceData, + error: nodesReferenceError, + isError: isNodesReferenceError, + } = useMeshWideNodesReference({}); addError( getFromSharedStateKeys.getReferenceFromSharedState("node_info"), - nodesReferenceError, + isNodesReferenceError ? nodesReferenceError : null, nodesReferenceData ); From 2e113414bd62021f8e7a46c584bdadf69543cf20 Mon Sep 17 00:00:00 2001 From: selankon Date: Mon, 13 May 2024 19:20:16 +0200 Subject: [PATCH 18/22] chore(meshwide): increase timer --- .../src/hooks/meshWideUpgradeProvider.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/lime-plugin-mesh-wide-upgrade/src/hooks/meshWideUpgradeProvider.tsx b/plugins/lime-plugin-mesh-wide-upgrade/src/hooks/meshWideUpgradeProvider.tsx index 9692e98f..9814a4b7 100644 --- a/plugins/lime-plugin-mesh-wide-upgrade/src/hooks/meshWideUpgradeProvider.tsx +++ b/plugins/lime-plugin-mesh-wide-upgrade/src/hooks/meshWideUpgradeProvider.tsx @@ -26,7 +26,7 @@ import { getMeshWideError } from "plugins/lime-plugin-mesh-wide-upgrade/src/util import { useSession } from "utils/queries"; import queryCache from "utils/queryCache"; -const NODE_STATUS_REFETCH_INTERVAL = 2000; +const NODE_STATUS_REFETCH_INTERVAL = 5000; interface MeshWideUpgradeContextProps { data?: MeshWideUpgradeInfo; From e94c52034c07d52c3fba9e964c2ef74157f0e230 Mon Sep 17 00:00:00 2001 From: selankon Date: Tue, 14 May 2024 14:51:53 +0200 Subject: [PATCH 19/22] chore(meshwide): fix reference is not set --- plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx b/plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx index e00b8307..00b64fe5 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWideQueries.tsx @@ -177,13 +177,14 @@ export const useSetLinkReferenceState = ({ mutationKey: meshUpgradeQueryKeys.remoteConfirmUpgrade(), mutationFn: ({ ip }) => { const hostname = nodesToUpdate[ip]; - const referenceLinks = referenceData[hostname]; + + const newReferenceLinks = referenceData[hostname] ?? {}; for (const mactomac of linkToUpdate.links) { if (isDown) { - delete referenceLinks[mactomac.id]; + delete newReferenceLinks[mactomac.id]; continue; } - referenceLinks[mactomac.id] = data[hostname][mactomac.id]; + newReferenceLinks[mactomac.id] = data[hostname][mactomac.id]; } const queryKey = getFromSharedStateKeys.insertIntoReferenceState( linkType, @@ -191,7 +192,7 @@ export const useSetLinkReferenceState = ({ // Using the same code but for a specific link type, it works. // For some reason with the use of getQueryByLinkType it doesn't work. // @ts-ignore - { [hostname]: referenceLinks } + { [hostname]: newReferenceLinks } ); return doSharedStateApiCall(queryKey, ip); }, From 7724d8bfe893ffa1504ef63f389a485e4be21848 Mon Sep 17 00:00:00 2001 From: selankon Date: Tue, 14 May 2024 14:55:52 +0200 Subject: [PATCH 20/22] chore(meshwide): fix link is not new --- plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx index caff4c07..d2bb126d 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/LinkLine.tsx @@ -17,7 +17,7 @@ export const LinkLine = ({ referenceLink, actualLink }: ILinkLineProps) => { const linkToShow = referenceLink ?? actualLink; const linkId = linkToShow.id; - let isNewLink = true; + let isNewLink = false; if (!referenceLink) { isNewLink = true; } From 4321aa2182ebf91d186906ff4061a49fef747cf7 Mon Sep 17 00:00:00 2001 From: selankon Date: Thu, 13 Jun 2024 08:59:36 +0200 Subject: [PATCH 21/22] chore(meshwide): add new node label --- .../src/components/Map/NodeMarker.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/Map/NodeMarker.tsx b/plugins/lime-plugin-mesh-wide/src/components/Map/NodeMarker.tsx index 19c5aa42..7f191386 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/Map/NodeMarker.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/Map/NodeMarker.tsx @@ -1,3 +1,4 @@ +import { Trans } from "@lingui/macro"; import L from "leaflet"; import { Marker, Tooltip } from "react-leaflet"; @@ -36,6 +37,8 @@ const NodeMarker = ({ // If node no reference is set, is a new node const nodeToShow = reference ?? actual; + const newNodeTooltip = isNewNode ? (new) : ""; + return ( - {name} + + {name} {newNodeTooltip} + ); }; From 6056c5688ae09044f4cb1c79bd6454b5fc8733eb Mon Sep 17 00:00:00 2001 From: selankon Date: Thu, 13 Jun 2024 09:23:49 +0200 Subject: [PATCH 22/22] chore(meshwide): show actual state on node info --- .../components/FeatureDetail/NodeDetail.tsx | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx index cdf4bf4c..a742a3f6 100644 --- a/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx +++ b/plugins/lime-plugin-mesh-wide/src/components/FeatureDetail/NodeDetail.tsx @@ -26,14 +26,6 @@ import { import { isEmpty } from "utils/utils"; const NodeDetails = ({ actual, reference, name }: NodeMapFeature) => { - // If node no reference is set, is a new node - const nodeToShow = reference ?? actual; - - const uptime = nodeToShow.uptime; - const firmware = nodeToShow.firmware_version; - const ipv6 = nodeToShow.ipv6; - const ipv4 = nodeToShow.ipv4; - const device = nodeToShow.device; const { errors, isDown } = useSingleNodeErrors({ actual, reference, @@ -42,6 +34,12 @@ const NodeDetails = ({ actual, reference, name }: NodeMapFeature) => { if (isDown) { return This node seems down; } + + const uptime = actual.uptime; + const firmware = actual.firmware_version; + const ipv6 = actual.ipv6; + const ipv4 = actual.ipv4; + const device = actual.device; const macs = actual.macs; return ( @@ -50,11 +48,11 @@ const NodeDetails = ({ actual, reference, name }: NodeMapFeature) => {
{name}
- +