@matter-server/dashboard 0.3.2 → 0.3.3

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.
Files changed (104) hide show
  1. package/dist/esm/pages/cluster-commands/base-cluster-commands.d.ts +2 -2
  2. package/dist/esm/pages/cluster-commands/base-cluster-commands.d.ts.map +1 -1
  3. package/dist/esm/pages/cluster-commands/base-cluster-commands.js.map +1 -1
  4. package/dist/esm/pages/cluster-commands/clusters/basic-information-commands.d.ts +36 -0
  5. package/dist/esm/pages/cluster-commands/clusters/basic-information-commands.d.ts.map +1 -0
  6. package/dist/esm/pages/cluster-commands/clusters/basic-information-commands.js +159 -0
  7. package/dist/esm/pages/cluster-commands/clusters/basic-information-commands.js.map +6 -0
  8. package/dist/esm/pages/cluster-commands/index.d.ts +1 -0
  9. package/dist/esm/pages/cluster-commands/index.d.ts.map +1 -1
  10. package/dist/esm/pages/cluster-commands/index.js +1 -0
  11. package/dist/esm/pages/cluster-commands/index.js.map +1 -1
  12. package/dist/esm/pages/components/footer.d.ts.map +1 -1
  13. package/dist/esm/pages/components/footer.js +4 -7
  14. package/dist/esm/pages/components/footer.js.map +1 -1
  15. package/dist/esm/pages/components/header.d.ts +5 -0
  16. package/dist/esm/pages/components/header.d.ts.map +1 -1
  17. package/dist/esm/pages/components/header.js +75 -0
  18. package/dist/esm/pages/components/header.js.map +1 -1
  19. package/dist/esm/pages/components/node-details.js +1 -1
  20. package/dist/esm/pages/components/node-details.js.map +1 -1
  21. package/dist/esm/pages/components/server-details.d.ts.map +1 -1
  22. package/dist/esm/pages/components/server-details.js +0 -1
  23. package/dist/esm/pages/components/server-details.js.map +1 -1
  24. package/dist/esm/pages/matter-dashboard-app.d.ts +12 -0
  25. package/dist/esm/pages/matter-dashboard-app.d.ts.map +1 -1
  26. package/dist/esm/pages/matter-dashboard-app.js +84 -4
  27. package/dist/esm/pages/matter-dashboard-app.js.map +1 -1
  28. package/dist/esm/pages/matter-network-view.d.ts +52 -0
  29. package/dist/esm/pages/matter-network-view.d.ts.map +1 -0
  30. package/dist/esm/pages/matter-network-view.js +309 -0
  31. package/dist/esm/pages/matter-network-view.js.map +6 -0
  32. package/dist/esm/pages/matter-node-view.d.ts.map +1 -1
  33. package/dist/esm/pages/matter-node-view.js +70 -1
  34. package/dist/esm/pages/matter-node-view.js.map +1 -1
  35. package/dist/esm/pages/matter-server-view.d.ts +4 -0
  36. package/dist/esm/pages/matter-server-view.d.ts.map +1 -1
  37. package/dist/esm/pages/matter-server-view.js +16 -1
  38. package/dist/esm/pages/matter-server-view.js.map +1 -1
  39. package/dist/esm/pages/network/base-network-graph.d.ts +74 -0
  40. package/dist/esm/pages/network/base-network-graph.d.ts.map +1 -0
  41. package/dist/esm/pages/network/base-network-graph.js +403 -0
  42. package/dist/esm/pages/network/base-network-graph.js.map +6 -0
  43. package/dist/esm/pages/network/device-icons.d.ts +52 -0
  44. package/dist/esm/pages/network/device-icons.d.ts.map +1 -0
  45. package/dist/esm/pages/network/device-icons.js +197 -0
  46. package/dist/esm/pages/network/device-icons.js.map +6 -0
  47. package/dist/esm/pages/network/device-panel.d.ts +31 -0
  48. package/dist/esm/pages/network/device-panel.d.ts.map +1 -0
  49. package/dist/esm/pages/network/device-panel.js +183 -0
  50. package/dist/esm/pages/network/device-panel.js.map +6 -0
  51. package/dist/esm/pages/network/network-details.d.ts +47 -0
  52. package/dist/esm/pages/network/network-details.d.ts.map +1 -0
  53. package/dist/esm/pages/network/network-details.js +686 -0
  54. package/dist/esm/pages/network/network-details.js.map +6 -0
  55. package/dist/esm/pages/network/network-types.d.ts +153 -0
  56. package/dist/esm/pages/network/network-types.d.ts.map +1 -0
  57. package/dist/esm/pages/network/network-types.js +19 -0
  58. package/dist/esm/pages/network/network-types.js.map +6 -0
  59. package/dist/esm/pages/network/network-utils.d.ts +170 -0
  60. package/dist/esm/pages/network/network-utils.d.ts.map +1 -0
  61. package/dist/esm/pages/network/network-utils.js +472 -0
  62. package/dist/esm/pages/network/network-utils.js.map +6 -0
  63. package/dist/esm/pages/network/thread-graph.d.ts +27 -0
  64. package/dist/esm/pages/network/thread-graph.d.ts.map +1 -0
  65. package/dist/esm/pages/network/thread-graph.js +134 -0
  66. package/dist/esm/pages/network/thread-graph.js.map +6 -0
  67. package/dist/esm/pages/network/wifi-graph.d.ts +27 -0
  68. package/dist/esm/pages/network/wifi-graph.d.ts.map +1 -0
  69. package/dist/esm/pages/network/wifi-graph.js +167 -0
  70. package/dist/esm/pages/network/wifi-graph.js.map +6 -0
  71. package/dist/web/js/{commission-node-dialog-CBSDiqRW.js → commission-node-dialog-B1_khzZb.js} +5 -5
  72. package/dist/web/js/{commission-node-existing-TP6s8Tez.js → commission-node-existing-RpdajrwF.js} +2 -5
  73. package/dist/web/js/{commission-node-thread-DOB8pu6x.js → commission-node-thread-5f2itkTG.js} +2 -5
  74. package/dist/web/js/{commission-node-wifi-tzavmk1j.js → commission-node-wifi-DZ_pWqsa.js} +2 -5
  75. package/dist/web/js/{dialog-box-Dknil_Be.js → dialog-box-DEUxM4B1.js} +2 -2
  76. package/dist/web/js/{fire_event-DRpOSjJR.js → fire_event-BczBMT8E.js} +1 -1
  77. package/dist/web/js/{log-level-dialog-TXkma-7Z.js → log-level-dialog-Cr3PfX1X.js} +2 -3
  78. package/dist/web/js/main.js +1 -1
  79. package/dist/web/js/matter-dashboard-app-BuCe_Jxf.js +29990 -0
  80. package/dist/web/js/{node-binding-dialog-D52FCBFP.js → node-binding-dialog-DMiHNDLA.js} +2 -4
  81. package/dist/web/js/{prevent_default-BPgSQsuY.js → prevent_default-D4FX_PIh.js} +2 -42
  82. package/package.json +5 -4
  83. package/src/pages/cluster-commands/base-cluster-commands.ts +2 -2
  84. package/src/pages/cluster-commands/clusters/basic-information-commands.ts +171 -0
  85. package/src/pages/cluster-commands/index.ts +1 -0
  86. package/src/pages/components/footer.ts +4 -7
  87. package/src/pages/components/header.ts +81 -0
  88. package/src/pages/components/node-details.ts +2 -2
  89. package/src/pages/components/server-details.ts +0 -1
  90. package/src/pages/matter-dashboard-app.ts +105 -5
  91. package/src/pages/matter-network-view.ts +325 -0
  92. package/src/pages/matter-node-view.ts +75 -1
  93. package/src/pages/matter-server-view.ts +17 -1
  94. package/src/pages/network/base-network-graph.ts +463 -0
  95. package/src/pages/network/device-icons.ts +283 -0
  96. package/src/pages/network/device-panel.ts +180 -0
  97. package/src/pages/network/network-details.ts +750 -0
  98. package/src/pages/network/network-types.ts +161 -0
  99. package/src/pages/network/network-utils.ts +752 -0
  100. package/src/pages/network/thread-graph.ts +164 -0
  101. package/src/pages/network/wifi-graph.ts +192 -0
  102. package/dist/web/js/matter-dashboard-app-B7GUghkC.js +0 -17254
  103. package/dist/web/js/outlined-text-field-D1DyKQY-.js +0 -968
  104. package/dist/web/js/validator-C735j770.js +0 -1122
@@ -0,0 +1,325 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025-2026 Open Home Foundation
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ import type { MatterClient, MatterNode } from "@matter-server/ws-client";
8
+ import { mdiFitToScreen } from "@mdi/js";
9
+ import { css, html, LitElement } from "lit";
10
+ import { customElement, property, query, state } from "lit/decorators.js";
11
+ import "../components/ha-svg-icon";
12
+ import "./components/footer";
13
+ import "./components/header";
14
+ import type { ActiveView } from "./components/header.js";
15
+ import "./network/device-panel";
16
+ import "./network/network-details";
17
+ import "./network/thread-graph";
18
+ import type { ThreadGraph } from "./network/thread-graph.js";
19
+ import "./network/wifi-graph";
20
+ import type { WiFiGraph } from "./network/wifi-graph.js";
21
+
22
+ declare global {
23
+ interface HTMLElementTagNameMap {
24
+ "matter-network-view": MatterNetworkView;
25
+ }
26
+ }
27
+
28
+ @customElement("matter-network-view")
29
+ class MatterNetworkView extends LitElement {
30
+ public client!: MatterClient;
31
+
32
+ @property({ type: Object })
33
+ public nodes: Record<string, MatterNode> = {};
34
+
35
+ @property()
36
+ public activeView?: ActiveView;
37
+
38
+ @property()
39
+ public networkType: "thread" | "wifi" = "thread";
40
+
41
+ /** Initial selected node ID from URL (string to avoid BigInt precision loss) */
42
+ @property()
43
+ public initialSelectedNodeId: string | null = null;
44
+
45
+ @property({ type: Boolean })
46
+ public hasThreadDevices?: boolean;
47
+
48
+ @property({ type: Boolean })
49
+ public hasWifiDevices?: boolean;
50
+
51
+ @state()
52
+ private _selectedNodeId: number | string | null = null;
53
+
54
+ private _initialSelectionApplied = false;
55
+ private _selectRetryTimer?: ReturnType<typeof setTimeout>;
56
+
57
+ @query("thread-graph")
58
+ private _threadGraph?: ThreadGraph;
59
+
60
+ @query("wifi-graph")
61
+ private _wifiGraph?: WiFiGraph;
62
+
63
+ override willUpdate(changedProperties: Map<string, unknown>): void {
64
+ // Apply initial selection when the property changes
65
+ if (changedProperties.has("initialSelectedNodeId") && this.initialSelectedNodeId !== null) {
66
+ this._selectedNodeId = this.initialSelectedNodeId;
67
+ this._initialSelectionApplied = false;
68
+ }
69
+ }
70
+
71
+ override updated(changedProperties: Map<string, unknown>): void {
72
+ super.updated(changedProperties);
73
+
74
+ // After render, select the node in the graph
75
+ if (!this._initialSelectionApplied && this.initialSelectedNodeId !== null) {
76
+ this._initialSelectionApplied = true;
77
+ // Wait for the graph to be ready, then select and focus
78
+ this._selectNodeWhenReady(this.initialSelectedNodeId);
79
+ }
80
+ }
81
+
82
+ override disconnectedCallback(): void {
83
+ super.disconnectedCallback();
84
+ if (this._selectRetryTimer) {
85
+ clearTimeout(this._selectRetryTimer);
86
+ }
87
+ }
88
+
89
+ /**
90
+ * Tries to select a node in the graph, retrying until the graph is ready.
91
+ */
92
+ private _selectNodeWhenReady(nodeId: string | number, retries: number = 10): void {
93
+ const graph = this.networkType === "thread" ? this._threadGraph : this._wifiGraph;
94
+
95
+ if (graph?.isReady()) {
96
+ graph.selectNode(nodeId);
97
+ } else if (retries > 0) {
98
+ // Graph not ready yet, retry after a short delay
99
+ this._selectRetryTimer = setTimeout(() => this._selectNodeWhenReady(nodeId, retries - 1), 100);
100
+ }
101
+ }
102
+
103
+ private _handleNodeSelected(event: CustomEvent<{ nodeId: number | string | null }>): void {
104
+ this._selectedNodeId = event.detail.nodeId;
105
+ }
106
+
107
+ private _handleDetailsClose(): void {
108
+ this._selectedNodeId = null;
109
+ }
110
+
111
+ private _handleSelectNode(event: CustomEvent<{ nodeId: number | string }>): void {
112
+ const nodeId = event.detail.nodeId;
113
+ this._selectedNodeId = nodeId;
114
+ // Select the node in the graph
115
+ if (this.networkType === "thread") {
116
+ this._threadGraph?.selectNode(nodeId);
117
+ } else {
118
+ this._wifiGraph?.selectNode(nodeId);
119
+ }
120
+ }
121
+
122
+ private _handleFitToScreen(): void {
123
+ if (this.networkType === "thread") {
124
+ this._threadGraph?.fit();
125
+ } else {
126
+ this._wifiGraph?.fit();
127
+ }
128
+ }
129
+
130
+ private _renderThreadView() {
131
+ return html`
132
+ <div class="graph-section">
133
+ <div class="graph-header">
134
+ <h2>Thread Network Mesh</h2>
135
+ <button class="fit-button" @click=${this._handleFitToScreen} title="Fit to screen">
136
+ <ha-svg-icon .path=${mdiFitToScreen}></ha-svg-icon>
137
+ </button>
138
+ </div>
139
+ <thread-graph .nodes=${this.nodes} @node-selected=${this._handleNodeSelected}></thread-graph>
140
+ </div>
141
+ `;
142
+ }
143
+
144
+ private _renderWifiView() {
145
+ return html`
146
+ <div class="graph-section">
147
+ <div class="graph-header">
148
+ <h2>WiFi Network</h2>
149
+ <button class="fit-button" @click=${this._handleFitToScreen} title="Fit to screen">
150
+ <ha-svg-icon .path=${mdiFitToScreen}></ha-svg-icon>
151
+ </button>
152
+ </div>
153
+ <wifi-graph .nodes=${this.nodes} @node-selected=${this._handleNodeSelected}></wifi-graph>
154
+ </div>
155
+ `;
156
+ }
157
+
158
+ override render() {
159
+ const showSidebar = this._selectedNodeId !== null;
160
+ const unknownDevices = this._threadGraph?.unknownDevicesMap ?? new Map();
161
+ const wifiAccessPoints = this._wifiGraph?.wifiAccessPointsMap ?? new Map();
162
+
163
+ return html`
164
+ <dashboard-header
165
+ title="Open Home Foundation Matter Server"
166
+ .client=${this.client}
167
+ .activeView=${this.activeView}
168
+ .hasThreadDevices=${this.hasThreadDevices}
169
+ .hasWifiDevices=${this.hasWifiDevices}
170
+ ></dashboard-header>
171
+
172
+ <div class="content">
173
+ <div class="main-area">
174
+ ${this.networkType === "thread" ? this._renderThreadView() : this._renderWifiView()}
175
+ </div>
176
+
177
+ <aside class="details-sidebar ${showSidebar ? "visible" : ""}">
178
+ <network-details
179
+ .selectedNodeId=${this._selectedNodeId}
180
+ .nodes=${this.nodes}
181
+ .unknownDevices=${unknownDevices}
182
+ .wifiAccessPoints=${wifiAccessPoints}
183
+ @close=${this._handleDetailsClose}
184
+ @select-node=${this._handleSelectNode}
185
+ ></network-details>
186
+ </aside>
187
+ </div>
188
+
189
+ <dashboard-footer></dashboard-footer>
190
+ `;
191
+ }
192
+
193
+ static override styles = css`
194
+ :host {
195
+ display: flex;
196
+ flex-direction: column;
197
+ height: 100vh;
198
+ height: 100dvh; /* dynamic viewport height - fallback above for older browsers */
199
+ overflow: hidden;
200
+ background-color: var(--md-sys-color-background, #fafafa);
201
+ }
202
+
203
+ .content {
204
+ display: flex;
205
+ flex: 1 1 0;
206
+ padding: 8px 16px;
207
+ gap: 8px;
208
+ max-width: 1600px;
209
+ margin: 0 auto;
210
+ width: 100%;
211
+ box-sizing: border-box;
212
+ min-height: 0;
213
+ overflow: hidden;
214
+ }
215
+
216
+ .main-area {
217
+ flex: 1 1 0;
218
+ display: flex;
219
+ flex-direction: column;
220
+ min-width: 0;
221
+ min-height: 0;
222
+ overflow: hidden;
223
+ }
224
+
225
+ .graph-section {
226
+ flex: 1 1 0;
227
+ min-height: 0;
228
+ display: flex;
229
+ flex-direction: column;
230
+ overflow: hidden;
231
+ }
232
+
233
+ .graph-header {
234
+ display: flex;
235
+ align-items: center;
236
+ justify-content: space-between;
237
+ margin-bottom: 4px;
238
+ flex-shrink: 0;
239
+ }
240
+
241
+ .graph-header h2 {
242
+ margin: 0;
243
+ font-size: 1.1rem;
244
+ font-weight: 500;
245
+ color: var(--md-sys-color-on-background, #333);
246
+ }
247
+
248
+ .fit-button {
249
+ background: none;
250
+ border: 1px solid var(--md-sys-color-outline-variant, #ccc);
251
+ border-radius: 4px;
252
+ padding: 6px;
253
+ cursor: pointer;
254
+ display: flex;
255
+ align-items: center;
256
+ justify-content: center;
257
+ transition: background-color 0.2s;
258
+ }
259
+
260
+ .fit-button:hover {
261
+ background-color: var(--md-sys-color-surface-container-high, #e8e8e8);
262
+ }
263
+
264
+ .fit-button ha-svg-icon {
265
+ --icon-primary-color: var(--md-sys-color-on-surface-variant, #666);
266
+ }
267
+
268
+ .graph-section thread-graph,
269
+ .graph-section wifi-graph {
270
+ flex: 1 1 0;
271
+ min-height: 0;
272
+ }
273
+
274
+ .wifi-section {
275
+ display: flex;
276
+ flex-direction: column;
277
+ gap: 16px;
278
+ overflow-y: auto;
279
+ }
280
+
281
+ .wifi-section h2 {
282
+ margin: 0;
283
+ font-size: 1.25rem;
284
+ font-weight: 500;
285
+ color: var(--md-sys-color-on-background, #333);
286
+ }
287
+
288
+ .wifi-section device-panel {
289
+ flex-shrink: 0;
290
+ }
291
+
292
+ .details-sidebar {
293
+ width: 320px;
294
+ flex-shrink: 0;
295
+ display: none;
296
+ min-height: 0;
297
+ overflow-y: auto;
298
+ }
299
+
300
+ .details-sidebar.visible {
301
+ display: block;
302
+ }
303
+
304
+ @media (max-width: 1024px) {
305
+ .content {
306
+ flex-direction: column;
307
+ }
308
+
309
+ .details-sidebar {
310
+ width: 100%;
311
+ max-height: 300px;
312
+ }
313
+
314
+ .details-sidebar.visible {
315
+ display: block;
316
+ }
317
+ }
318
+
319
+ @media (max-width: 600px) {
320
+ .content {
321
+ padding: 8px;
322
+ }
323
+ }
324
+ `;
325
+ }
@@ -9,7 +9,7 @@ import "@material/web/iconbutton/icon-button";
9
9
  import "@material/web/list/list";
10
10
  import "@material/web/list/list-item";
11
11
  import { MatterClient, MatterNode } from "@matter-server/ws-client";
12
- import { mdiChevronRight } from "@mdi/js";
12
+ import { mdiChevronRight, mdiGraphOutline } from "@mdi/js";
13
13
  import { LitElement, css, html } from "lit";
14
14
  import { customElement, property } from "lit/decorators.js";
15
15
  import { guard } from "lit/directives/guard.js";
@@ -17,6 +17,7 @@ import "../components/ha-svg-icon";
17
17
  import "./components/header";
18
18
  import "./components/node-details";
19
19
  import { getEndpointDeviceTypes } from "./matter-endpoint-view.js";
20
+ import { getNetworkType } from "./network/network-utils.js";
20
21
 
21
22
  declare global {
22
23
  interface HTMLElementTagNameMap {
@@ -46,6 +47,13 @@ class MatterNodeView extends LitElement {
46
47
  `;
47
48
  }
48
49
 
50
+ const networkType = getNetworkType(this.node);
51
+ // Show graph button for Thread, WiFi, and Ethernet (Ethernet devices are shown in WiFi graph)
52
+ const showGraphButton = networkType === "thread" || networkType === "wifi" || networkType === "ethernet";
53
+ // Ethernet devices go to WiFi graph since they're displayed there
54
+ const graphViewType = networkType === "ethernet" ? "wifi" : networkType;
55
+ const graphUrl = showGraphButton ? `#${graphViewType}/${this.node.node_id}` : null;
56
+
49
57
  return html`
50
58
  <dashboard-header
51
59
  .title=${"Node " + this.node.node_id}
@@ -55,6 +63,17 @@ class MatterNodeView extends LitElement {
55
63
 
56
64
  <!-- node details section -->
57
65
  <div class="container">
66
+ <div class="node-title-bar">
67
+ <h2>Node ${this.node.node_id}</h2>
68
+ ${showGraphButton
69
+ ? html`
70
+ <a href=${graphUrl} class="show-in-graph-button" title="Show in ${graphViewType} graph">
71
+ <ha-svg-icon .path=${mdiGraphOutline}></ha-svg-icon>
72
+ <span class="button-text">Show in graph</span>
73
+ </a>
74
+ `
75
+ : ""}
76
+ </div>
58
77
  <node-details .node=${this.node} .client=${this.client}></node-details>
59
78
  </div>
60
79
 
@@ -122,5 +141,60 @@ class MatterNodeView extends LitElement {
122
141
  font-weight: bold;
123
142
  font-size: 0.8em;
124
143
  }
144
+
145
+ .node-title-bar {
146
+ display: flex;
147
+ align-items: center;
148
+ gap: 16px;
149
+ margin-bottom: 16px;
150
+ }
151
+
152
+ .node-title-bar h2 {
153
+ margin: 0;
154
+ font-size: 1.25rem;
155
+ font-weight: 500;
156
+ color: var(--md-sys-color-on-background, #333);
157
+ }
158
+
159
+ .show-in-graph-button {
160
+ display: inline-flex;
161
+ align-items: center;
162
+ gap: 6px;
163
+ padding: 6px 12px;
164
+ background-color: var(--md-sys-color-primary);
165
+ color: var(--md-sys-color-on-primary);
166
+ text-decoration: none;
167
+ border-radius: 4px;
168
+ font-size: 0.8rem;
169
+ font-weight: 500;
170
+ transition: opacity 0.2s;
171
+ white-space: nowrap;
172
+ }
173
+
174
+ .show-in-graph-button:hover {
175
+ opacity: 0.9;
176
+ }
177
+
178
+ .show-in-graph-button ha-svg-icon {
179
+ --icon-primary-color: var(--md-sys-color-on-primary);
180
+ width: 16px;
181
+ height: 16px;
182
+ }
183
+
184
+ @media (max-width: 768px) {
185
+ .show-in-graph-button {
186
+ display: none;
187
+ }
188
+ }
189
+
190
+ @media (max-width: 480px) {
191
+ .show-in-graph-button .button-text {
192
+ display: none;
193
+ }
194
+
195
+ .show-in-graph-button {
196
+ padding: 6px;
197
+ }
198
+ }
125
199
  `;
126
200
  }
@@ -16,6 +16,7 @@ import "../components/ha-svg-icon";
16
16
  import { formatNodeAddress } from "../util/format_hex.js";
17
17
  import "./components/footer";
18
18
  import "./components/header";
19
+ import type { ActiveView } from "./components/header.js";
19
20
  import "./components/server-details";
20
21
 
21
22
  declare global {
@@ -31,6 +32,15 @@ class MatterServerView extends LitElement {
31
32
  @property()
32
33
  public nodes!: MatterClient["nodes"];
33
34
 
35
+ @property()
36
+ public activeView?: ActiveView;
37
+
38
+ @property({ type: Boolean })
39
+ public hasThreadDevices?: boolean;
40
+
41
+ @property({ type: Boolean })
42
+ public hasWifiDevices?: boolean;
43
+
34
44
  private _cachedNodes?: MatterClient["nodes"];
35
45
  private _cachedNodeEntries?: [string, MatterNode][];
36
46
 
@@ -46,7 +56,13 @@ class MatterServerView extends LitElement {
46
56
  const nodes = this.getNodeEntries(this.nodes);
47
57
 
48
58
  return html`
49
- <dashboard-header title="Open Home Foundation Matter Server" .client=${this.client}></dashboard-header>
59
+ <dashboard-header
60
+ title="Open Home Foundation Matter Server"
61
+ .client=${this.client}
62
+ .activeView=${this.activeView}
63
+ .hasThreadDevices=${this.hasThreadDevices}
64
+ .hasWifiDevices=${this.hasWifiDevices}
65
+ ></dashboard-header>
50
66
 
51
67
  <!-- server details section -->
52
68
  <div class="container">