@matter-server/dashboard 0.7.2-alpha.0-20260601-e778038 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/components/dialogs/node-label-dialog/node-label-dialog.d.ts +28 -0
- package/dist/esm/components/dialogs/node-label-dialog/node-label-dialog.d.ts.map +1 -0
- package/dist/esm/components/dialogs/node-label-dialog/node-label-dialog.js +99 -0
- package/dist/esm/components/dialogs/node-label-dialog/node-label-dialog.js.map +6 -0
- package/dist/esm/components/dialogs/node-label-dialog/show-node-label-dialog.d.ts +8 -0
- package/dist/esm/components/dialogs/node-label-dialog/show-node-label-dialog.d.ts.map +1 -0
- package/dist/esm/components/dialogs/node-label-dialog/show-node-label-dialog.js +16 -0
- package/dist/esm/components/dialogs/node-label-dialog/show-node-label-dialog.js.map +6 -0
- package/dist/esm/components/dialogs/settings/log-level-section.d.ts.map +1 -1
- package/dist/esm/components/dialogs/settings/log-level-section.js +1 -0
- package/dist/esm/components/dialogs/settings/log-level-section.js.map +1 -1
- package/dist/esm/pages/cluster-commands/clusters/basic-information-commands.d.ts.map +1 -1
- package/dist/esm/pages/cluster-commands/clusters/basic-information-commands.js +7 -18
- package/dist/esm/pages/cluster-commands/clusters/basic-information-commands.js.map +1 -1
- package/dist/esm/pages/components/header.d.ts +2 -0
- package/dist/esm/pages/components/header.d.ts.map +1 -1
- package/dist/esm/pages/components/header.js +13 -4
- package/dist/esm/pages/components/header.js.map +1 -1
- package/dist/esm/pages/components/node-details.d.ts +1 -0
- package/dist/esm/pages/components/node-details.d.ts.map +1 -1
- package/dist/esm/pages/components/node-details.js +28 -2
- package/dist/esm/pages/components/node-details.js.map +1 -1
- package/dist/esm/pages/matter-network-view.js +4 -4
- package/dist/esm/pages/matter-network-view.js.map +1 -1
- package/dist/esm/pages/network/thread-graph.d.ts +5 -6
- package/dist/esm/pages/network/thread-graph.d.ts.map +1 -1
- package/dist/esm/pages/network/thread-graph.js +39 -20
- package/dist/esm/pages/network/thread-graph.js.map +1 -1
- package/dist/esm/util/device-icons.d.ts +12 -3
- package/dist/esm/util/device-icons.d.ts.map +1 -1
- package/dist/esm/util/device-icons.js +28 -13
- package/dist/esm/util/device-icons.js.map +1 -1
- package/dist/esm/util/node-label.d.ts +16 -0
- package/dist/esm/util/node-label.d.ts.map +1 -0
- package/dist/esm/util/node-label.js +20 -0
- package/dist/esm/util/node-label.js.map +6 -0
- package/dist/web/index.html +6 -0
- package/dist/web/js/{attribute-write-dialog-BfQ9Xflh.js → attribute-write-dialog-f6XnfRjW.js} +1 -1
- package/dist/web/js/{command-invoke-dialog-Zj6gySV_.js → command-invoke-dialog-jzzpwI81.js} +1 -1
- package/dist/web/js/{commission-node-dialog-BpEVqGkZ.js → commission-node-dialog-B3RBDYQU.js} +5 -5
- package/dist/web/js/{commission-node-existing-4zO8iG_s.js → commission-node-existing-Cf6SG9fC.js} +2 -2
- package/dist/web/js/{commission-node-thread-AHWmXDx1.js → commission-node-thread-BlC2ZhGB.js} +2 -2
- package/dist/web/js/{commission-node-wifi-C07wuota.js → commission-node-wifi-BzeVHU3H.js} +2 -2
- package/dist/web/js/{dialog-box-BVHU0m4j.js → dialog-box-8CugytjX.js} +1 -1
- package/dist/web/js/{fire_event-YKA6y_5c.js → fire_event-B0dFAh3R.js} +1 -1
- package/dist/web/js/main.js +4 -4
- package/dist/web/js/{matter-dashboard-app-DIak2OyX.js → matter-dashboard-app-D7-YX94X.js} +170 -66
- package/dist/web/js/{node-binding-dialog-DILw-ecn.js → node-binding-dialog-Dpjn-GtG.js} +1 -1
- package/dist/web/js/node-label-dialog-B31BzWy6.js +80 -0
- package/dist/web/js/{settings-dialog-CBVhNIXT.js → settings-dialog-Di2Qnh3-.js} +4 -1
- package/package.json +7 -7
- package/src/components/dialogs/node-label-dialog/node-label-dialog.ts +93 -0
- package/src/components/dialogs/node-label-dialog/show-node-label-dialog.ts +15 -0
- package/src/components/dialogs/settings/log-level-section.ts +1 -0
- package/src/pages/cluster-commands/clusters/basic-information-commands.ts +7 -26
- package/src/pages/components/header.ts +15 -4
- package/src/pages/components/node-details.ts +31 -2
- package/src/pages/matter-network-view.ts +4 -4
- package/src/pages/network/thread-graph.ts +46 -22
- package/src/util/device-icons.ts +59 -14
- package/src/util/node-label.ts +22 -0
package/src/util/device-icons.ts
CHANGED
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
mdiCast,
|
|
18
18
|
mdiCctv,
|
|
19
19
|
mdiChip,
|
|
20
|
+
mdiCircleMedium,
|
|
20
21
|
mdiCrown,
|
|
21
22
|
mdiDishwasher,
|
|
22
23
|
mdiDoorbell,
|
|
@@ -41,12 +42,15 @@ import {
|
|
|
41
42
|
mdiRobotVacuum,
|
|
42
43
|
mdiRouter,
|
|
43
44
|
mdiRouterWireless,
|
|
45
|
+
mdiSleep,
|
|
44
46
|
mdiSmokeDetector,
|
|
45
47
|
mdiSnowflakeAlert,
|
|
46
48
|
mdiSolarPower,
|
|
47
49
|
mdiSpeaker,
|
|
48
50
|
mdiSprinkler,
|
|
51
|
+
mdiStar,
|
|
49
52
|
mdiStove,
|
|
53
|
+
mdiSwapHorizontal,
|
|
50
54
|
mdiTelevision,
|
|
51
55
|
mdiThermometer,
|
|
52
56
|
mdiToggleSwitch,
|
|
@@ -304,6 +308,19 @@ const threadRoleToIcon: Record<number, string> = {
|
|
|
304
308
|
6: mdiAccessPoint, // Leader
|
|
305
309
|
};
|
|
306
310
|
|
|
311
|
+
/**
|
|
312
|
+
* Corner badge marking a node's Thread RoutingRole (attr 0/53/1) — a role-rank indicator overlaid on
|
|
313
|
+
* the device icon. The Leader is the rare, high-signal exception (amber crown); routers and end
|
|
314
|
+
* devices use progressively lower-key glyphs. Unassigned/Unspecified and unknown roles get no badge.
|
|
315
|
+
*/
|
|
316
|
+
const THREAD_ROLE_BADGES: Record<number, { iconPath: string; colorVar: string; colorFallback: string }> = {
|
|
317
|
+
2: { iconPath: mdiSleep, colorVar: "--node-color-thread-enddevice", colorFallback: "#90a4ae" }, // Sleepy End Device
|
|
318
|
+
3: { iconPath: mdiCircleMedium, colorVar: "--node-color-thread-enddevice", colorFallback: "#90a4ae" }, // End Device
|
|
319
|
+
4: { iconPath: mdiCircleMedium, colorVar: "--node-color-thread-enddevice", colorFallback: "#90a4ae" }, // REED
|
|
320
|
+
5: { iconPath: mdiSwapHorizontal, colorVar: "--node-color-thread-router", colorFallback: "#1e88e5" }, // Router
|
|
321
|
+
6: { iconPath: mdiCrown, colorVar: "--node-color-thread-leader", colorFallback: "#f9a825" }, // Leader
|
|
322
|
+
};
|
|
323
|
+
|
|
307
324
|
/**
|
|
308
325
|
* Utility device types (per Matter spec) deprioritized when selecting the primary type for icon display.
|
|
309
326
|
* These are commonly reported alongside the actual application type (e.g., a light also reports as
|
|
@@ -454,14 +471,26 @@ export function getNetworkTypeIcon(networkType: string): string {
|
|
|
454
471
|
* @param iconPath - The MDI icon path
|
|
455
472
|
* @param color - The icon color (CSS color string)
|
|
456
473
|
* @param size - The icon size in pixels
|
|
474
|
+
* @param badge - Optional top-right corner badge: an MDI glyph filled white on a colored disc
|
|
457
475
|
* @returns A data URL containing the SVG
|
|
458
476
|
*/
|
|
459
|
-
export function createIconDataUrl(
|
|
477
|
+
export function createIconDataUrl(
|
|
478
|
+
iconPath: string,
|
|
479
|
+
color: string,
|
|
480
|
+
size: number = 48,
|
|
481
|
+
badge?: { iconPath: string; color: string },
|
|
482
|
+
): string {
|
|
460
483
|
// MDI icons use a 24x24 viewBox
|
|
484
|
+
const badgeMarkup =
|
|
485
|
+
badge !== undefined
|
|
486
|
+
? `<circle cx="18" cy="6" r="4" fill="${badge.color}"/>
|
|
487
|
+
<path d="${badge.iconPath}" fill="white" transform="translate(14.64,2.64) scale(0.28)"/>`
|
|
488
|
+
: "";
|
|
461
489
|
const svg = `
|
|
462
490
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="${size}" height="${size}">
|
|
463
491
|
<circle cx="12" cy="12" r="11" fill="white" stroke="${color}" stroke-width="1"/>
|
|
464
492
|
<path d="${iconPath}" fill="${color}" transform="scale(0.6) translate(8,8)"/>
|
|
493
|
+
${badgeMarkup}
|
|
465
494
|
</svg>
|
|
466
495
|
`.trim();
|
|
467
496
|
|
|
@@ -493,7 +522,14 @@ export function createNodeIconDataUrl(
|
|
|
493
522
|
} else {
|
|
494
523
|
color = getDefaultIconColor(); // Theme-aware default
|
|
495
524
|
}
|
|
496
|
-
|
|
525
|
+
// Thread RoutingRole (incl. Leader) applies to any router node, not just BRs. Badge it over the
|
|
526
|
+
// device icon rather than replacing the icon, preserving device identity.
|
|
527
|
+
const roleBadge = threadRole !== undefined ? THREAD_ROLE_BADGES[threadRole] : undefined;
|
|
528
|
+
const badge =
|
|
529
|
+
roleBadge !== undefined
|
|
530
|
+
? { iconPath: roleBadge.iconPath, color: getCssVar(roleBadge.colorVar, roleBadge.colorFallback) }
|
|
531
|
+
: undefined;
|
|
532
|
+
return createIconDataUrl(iconPath, color, 48, badge);
|
|
497
533
|
}
|
|
498
534
|
|
|
499
535
|
/**
|
|
@@ -512,22 +548,31 @@ export function createUnknownDeviceIconDataUrl(isRouter: boolean = false, isSele
|
|
|
512
548
|
|
|
513
549
|
/**
|
|
514
550
|
* Creates an SVG data URL for a Thread Border Router identified via mDNS.
|
|
515
|
-
*
|
|
551
|
+
*
|
|
552
|
+
* Thread Leader (mesh routing role) and Primary BBR (backbone role) are orthogonal: the central
|
|
553
|
+
* glyph reflects the mesh role (crown for leader, router otherwise) while a corner star badge marks
|
|
554
|
+
* the primary BBR. A BR that is both shows both.
|
|
555
|
+
*
|
|
516
556
|
* @param isSelected - Whether the node is selected
|
|
517
557
|
* @param isLeader - Whether this BR is the Thread network leader (from MeshCoP state bitmap)
|
|
558
|
+
* @param isPrimaryBbr - Whether this BR is the primary Backbone Border Router (from MeshCoP state bitmap)
|
|
518
559
|
* @returns A data URL containing the SVG
|
|
519
560
|
*/
|
|
520
|
-
export function createBorderRouterIconDataUrl(
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
561
|
+
export function createBorderRouterIconDataUrl(
|
|
562
|
+
isSelected: boolean = false,
|
|
563
|
+
isLeader: boolean = false,
|
|
564
|
+
isPrimaryBbr: boolean = false,
|
|
565
|
+
): string {
|
|
566
|
+
const glyph = isLeader ? mdiCrown : mdiRouterWireless;
|
|
567
|
+
const color = isSelected
|
|
568
|
+
? getCssVar("--node-color-selected", "#1976d2")
|
|
569
|
+
: isLeader
|
|
570
|
+
? getCssVar("--node-color-thread-leader", "#f9a825")
|
|
571
|
+
: getCssVar("--md-sys-color-primary", "#03a9f4");
|
|
572
|
+
const badge = isPrimaryBbr
|
|
573
|
+
? { iconPath: mdiStar, color: getCssVar("--node-color-primary-bbr", "#00897b") }
|
|
574
|
+
: undefined;
|
|
575
|
+
return createIconDataUrl(glyph, color, 48, badge);
|
|
531
576
|
}
|
|
532
577
|
|
|
533
578
|
/**
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Open Home Foundation
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { MatterClient, MatterNode } from "@matter-server/ws-client";
|
|
8
|
+
|
|
9
|
+
// BasicInformation cluster (0x28 / 40), always on endpoint 0 per Matter specification.
|
|
10
|
+
export const NODE_LABEL_CLUSTER_ID = 0x28;
|
|
11
|
+
export const NODE_LABEL_ATTRIBUTE_ID = 5;
|
|
12
|
+
export const MAX_NODE_LABEL_LENGTH = 32;
|
|
13
|
+
|
|
14
|
+
export const NODE_LABEL_ATTRIBUTE_PATH = `0/${NODE_LABEL_CLUSTER_ID}/${NODE_LABEL_ATTRIBUTE_ID}`;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Write the BasicInformation NodeLabel attribute for a node.
|
|
18
|
+
* Trims surrounding whitespace so the stored value matches what MatterNode.nodeLabel reads back.
|
|
19
|
+
*/
|
|
20
|
+
export function writeNodeLabel(client: MatterClient, node: MatterNode, label: string): Promise<unknown> {
|
|
21
|
+
return client.writeAttribute(node.node_id, NODE_LABEL_ATTRIBUTE_PATH, label.trim());
|
|
22
|
+
}
|