@mp70/react-networks 0.1.0-alpha → 0.1.1-alpha

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/README.md CHANGED
@@ -1,7 +1,7 @@
1
- # @react-networks/network-diagrams
1
+ # @mp70/react-networks
2
2
 
3
- [![npm version](https://badge.fury.io/js/%40react-networks%2Fnetwork-diagrams.svg)](https://badge.fury.io/js/%40react-networks%2Fnetwork-diagrams)
4
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
3
+ [![npm version](https://badge.fury.io/js/%40mp70%2Freact-networks.svg)](https://badge.fury.io/js/%40mp70%2Freact-networks)
4
+ [![License: AGPL v3](https://img.shields.io/badge/License-AGPLv3-blue.svg)](https://www.gnu.org/licenses/agpl-3.0)
5
5
  [![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-%230074c1.svg)](http://www.typescriptlang.org/)
6
6
 
7
7
  A production-ready React library for creating interactive network diagrams with support for rack management, fiber networks, and power distribution. Built on React Flow with TypeScript support.
@@ -14,7 +14,7 @@ A production-ready React library for creating interactive network diagrams with
14
14
  - **⚡ Power Distribution**: Vertical PDU support with power connections
15
15
  - **👁️ View Switching**: Front/rear view switching for devices and racks
16
16
  - **📐 Rack Alignment**: Align rack bottoms to the same horizontal plane
17
- - **🔗 NetBox Integration**: Built-in support for NetBox data import/export
17
+ - **🔗 Inventory Integration**: Built-in helpers to import/export generic inventory/CMDB data
18
18
  - **🎨 Customizable**: Extensive styling and theming options
19
19
  - **📱 Responsive**: Works on desktop and mobile devices
20
20
  - **🔧 TypeScript**: Full TypeScript support with comprehensive type definitions
@@ -24,19 +24,19 @@ A production-ready React library for creating interactive network diagrams with
24
24
  ### Installation
25
25
 
26
26
  ```bash
27
- npm install @react-networks/network-diagrams react react-dom reactflow
27
+ npm install @mp70/react-networks react react-dom reactflow
28
28
  # or
29
- yarn add @react-networks/network-diagrams react react-dom reactflow
29
+ yarn add @mp70/react-networks react react-dom reactflow
30
30
  # or
31
- pnpm add @react-networks/network-diagrams react react-dom reactflow
31
+ pnpm add @mp70/react-networks react react-dom reactflow
32
32
  ```
33
33
 
34
34
  ### Basic Usage
35
35
 
36
36
  ```tsx
37
37
  import React from 'react';
38
- import { NetworkDiagram, NetworkNode, NetworkEdge } from '@react-networks/network-diagrams';
39
- import '@react-networks/network-diagrams/index.css';
38
+ import { NetworkDiagram, NetworkNode, NetworkEdge } from '@mp70/react-networks';
39
+ import '@mp70/react-networks/index.css';
40
40
 
41
41
  const nodes: NetworkNode[] = [
42
42
  {
@@ -144,7 +144,7 @@ type NetworkEdgeType = 'fiber' | 'ethernet' | 'power';
144
144
  ### Rack Configuration
145
145
 
146
146
  ```tsx
147
- import { RackConfig, buildNodesFromRackConfig, Width } from '@react-networks/network-diagrams';
147
+ import { RackConfig, buildNodesFromRackConfig, Width } from '@mp70/react-networks';
148
148
 
149
149
  const rackSchema: RackConfig[] = [
150
150
  {
@@ -190,24 +190,24 @@ const rackSchema: RackConfig[] = [
190
190
  const nodes = buildNodesFromRackConfig(rackSchema);
191
191
  ```
192
192
 
193
- ### NetBox Integration
193
+ ### Inventory Integration
194
194
 
195
195
  ```tsx
196
- import { netboxToNetworkDiagram } from '@react-networks/network-diagrams';
196
+ import { inventoryToNetworkDiagram } from '@mp70/react-networks';
197
197
 
198
- const netboxData = {
199
- racks: [...], // NetBox rack data
200
- devices: [...], // NetBox device data
201
- cables: [...] // NetBox cable data
198
+ const inventoryData = {
199
+ racks: [...],
200
+ devices: [...],
201
+ cables: [...]
202
202
  };
203
203
 
204
- const { nodes, edges } = netboxToNetworkDiagram(netboxData);
204
+ const { nodes, edges } = inventoryToNetworkDiagram(inventoryData);
205
205
  ```
206
206
 
207
207
  ### Custom Styling
208
208
 
209
209
  ```tsx
210
- import '@react-networks/network-diagrams/index.css';
210
+ import '@mp70/react-networks/index.css';
211
211
 
212
212
  // Override CSS variables
213
213
  .network-diagram {
@@ -312,7 +312,7 @@ We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) f
312
312
 
313
313
  ## 📄 License
314
314
 
315
- MIT License - see [LICENSE](LICENSE) for details.
315
+ Dual-licensed under AGPL-3.0 or Commercial. See [LICENSE](LICENSE) for details.
316
316
 
317
317
  ## 🆘 Support
318
318
 
@@ -324,7 +324,7 @@ MIT License - see [LICENSE](LICENSE) for details.
324
324
  ## 🙏 Acknowledgments
325
325
 
326
326
  - [React Flow](https://reactflow.dev) for the excellent diagram foundation
327
- - [NetBox](https://netbox.dev) for network infrastructure management inspiration
327
+ - Network inventory/CMDB projects for inspiration
328
328
  - The open source community for feedback and contributions
329
329
 
330
330
  ---
package/dist/index.css CHANGED
@@ -20,4 +20,73 @@
20
20
  z-index: 500 !important;
21
21
  }
22
22
 
23
+ /* React Flow theming */
24
+ .react-flow-dark {
25
+ --react-flow-background: #1a1a1a;
26
+ --react-flow-text: #ffffff;
27
+ --react-flow-border: #404040;
28
+ --react-flow-controls-bg: #2d2d2d;
29
+ --react-flow-controls-border: #404040;
30
+ --react-flow-minimap-bg: #2d2d2d;
31
+ --react-flow-minimap-border: #404040;
32
+ }
33
+
34
+ .react-flow-light {
35
+ --react-flow-background: #ffffff;
36
+ --react-flow-text: #1a1a1a;
37
+ --react-flow-border: #e9ecef;
38
+ --react-flow-controls-bg: #f8f9fa;
39
+ --react-flow-controls-border: #e9ecef;
40
+ --react-flow-minimap-bg: #f8f9fa;
41
+ --react-flow-minimap-border: #e9ecef;
42
+ }
43
+
44
+ /* Apply ReactFlow theming */
45
+ .react-flow-dark .react-flow__background {
46
+ background-color: var(--react-flow-background);
47
+ }
48
+
49
+ .react-flow-light .react-flow__background {
50
+ background-color: var(--react-flow-background);
51
+ }
52
+
53
+ .react-flow-dark .react-flow__controls {
54
+ background-color: var(--react-flow-controls-bg);
55
+ border-color: var(--react-flow-controls-border);
56
+ }
57
+
58
+ .react-flow-light .react-flow__controls {
59
+ background-color: var(--react-flow-controls-bg);
60
+ border-color: var(--react-flow-controls-border);
61
+ }
62
+
63
+ .react-flow-dark .react-flow__minimap {
64
+ background-color: var(--react-flow-minimap-bg);
65
+ border-color: var(--react-flow-minimap-border);
66
+ }
67
+
68
+ .react-flow-light .react-flow__minimap {
69
+ background-color: var(--react-flow-minimap-bg);
70
+ border-color: var(--react-flow-minimap-border);
71
+ }
72
+
73
+ .react-flow-dark .react-flow__controls-button {
74
+ background-color: var(--react-flow-controls-bg);
75
+ color: var(--react-flow-text);
76
+ border-color: var(--react-flow-controls-border);
77
+ }
78
+
79
+ .react-flow-light .react-flow__controls-button {
80
+ background-color: var(--react-flow-controls-bg);
81
+ color: var(--react-flow-text);
82
+ border-color: var(--react-flow-controls-border);
83
+ }
84
+
85
+ .react-flow-dark .react-flow__controls-button:hover {
86
+ background-color: #4b5563;
87
+ }
88
+
89
+ .react-flow-light .react-flow__controls-button:hover {
90
+ background-color: #e9ecef;
91
+ }
23
92
 
package/dist/index.d.mts CHANGED
@@ -1,151 +1,6 @@
1
1
  import React$1 from 'react';
2
2
  import { NodeProps, EdgeProps } from 'reactflow';
3
3
 
4
- interface NetBoxDevice {
5
- id: number;
6
- name: string;
7
- device_type: {
8
- id: number;
9
- model: string;
10
- manufacturer: {
11
- name: string;
12
- };
13
- };
14
- device_role: {
15
- name: string;
16
- color: string;
17
- };
18
- site: {
19
- name: string;
20
- };
21
- rack: {
22
- id: number;
23
- name: string;
24
- } | null;
25
- position: number | null;
26
- face: 'front' | 'rear' | null;
27
- status: {
28
- label: string;
29
- value: string;
30
- color: string;
31
- };
32
- primary_ip4?: {
33
- address: string;
34
- };
35
- primary_ip6?: {
36
- address: string;
37
- };
38
- interfaces: NetBoxInterface[];
39
- }
40
- interface NetBoxInterface {
41
- id: number;
42
- name: string;
43
- type: {
44
- label: string;
45
- value: string;
46
- };
47
- enabled: boolean;
48
- mac_address: string | null;
49
- mtu: number | null;
50
- connected_endpoint_type: string | null;
51
- connected_endpoint: {
52
- device: {
53
- name: string;
54
- };
55
- name: string;
56
- } | null;
57
- cable: {
58
- id: number;
59
- label: string;
60
- type: string;
61
- color: string;
62
- } | null;
63
- }
64
- interface NetBoxRack {
65
- id: number;
66
- name: string;
67
- site: {
68
- name: string;
69
- };
70
- group: {
71
- name: string;
72
- } | null;
73
- tenant: {
74
- name: string;
75
- } | null;
76
- role: {
77
- name: string;
78
- color: string;
79
- } | null;
80
- status: {
81
- label: string;
82
- value: string;
83
- color: string;
84
- };
85
- facility_id: string | null;
86
- serial: string | null;
87
- asset_tag: string | null;
88
- type: {
89
- label: string;
90
- value: string;
91
- };
92
- width: {
93
- label: string;
94
- value: number;
95
- };
96
- u_height: number;
97
- desc_units: boolean;
98
- outer_width: number | null;
99
- outer_depth: number | null;
100
- weight: number | null;
101
- max_weight: number | null;
102
- weight_unit: string;
103
- mounting_depth: number | null;
104
- devices: NetBoxDevice[];
105
- }
106
- interface NetBoxCable {
107
- id: number;
108
- label: string;
109
- type: {
110
- label: string;
111
- value: string;
112
- };
113
- status: {
114
- label: string;
115
- value: string;
116
- color: string;
117
- };
118
- color: string;
119
- length: number | null;
120
- length_unit: string;
121
- termination_a_type: string;
122
- termination_a: {
123
- device: {
124
- name: string;
125
- };
126
- name: string;
127
- };
128
- termination_b_type: string;
129
- termination_b: {
130
- device: {
131
- name: string;
132
- };
133
- name: string;
134
- };
135
- }
136
- interface NetBoxConnection {
137
- id: string;
138
- source: {
139
- device: string;
140
- interface: string;
141
- };
142
- target: {
143
- device: string;
144
- interface: string;
145
- };
146
- cable: NetBoxCable;
147
- }
148
-
149
4
  /**
150
5
  * Rack device width configuration
151
6
  * @public
@@ -200,6 +55,11 @@ type DeviceView = 'front' | 'rear';
200
55
  * @public
201
56
  */
202
57
  type PowerSide = 'left' | 'right';
58
+ /**
59
+ * U numbering direction for racks
60
+ * @public
61
+ */
62
+ type UNumberingDirection = 'bottom-up' | 'top-down';
203
63
  /**
204
64
  * Network node data structure
205
65
  * @public
@@ -254,6 +114,10 @@ interface NetworkNode {
254
114
  heightCm?: number;
255
115
  /** Number of AC power ports */
256
116
  powerPorts?: number;
117
+ /** U numbering direction for rack nodes */
118
+ uNumberingDirection?: UNumberingDirection;
119
+ /** Custom header text for rack nodes */
120
+ customHeaderText?: string;
257
121
  /** Additional custom properties */
258
122
  [key: string]: any;
259
123
  };
@@ -315,6 +179,10 @@ interface RackConfig {
315
179
  };
316
180
  /** Rack height in U units */
317
181
  units: number;
182
+ /** U numbering direction (default: 'bottom-up') */
183
+ uNumberingDirection?: UNumberingDirection;
184
+ /** Custom header text for rack */
185
+ customHeaderText?: string;
318
186
  /** Devices mounted in the rack */
319
187
  devices: RackDevice[];
320
188
  }
@@ -374,7 +242,6 @@ interface FiberCable {
374
242
  to: string;
375
243
  };
376
244
  }
377
-
378
245
  /**
379
246
  * Network diagram component props
380
247
  * @public
@@ -396,8 +263,8 @@ interface NetworkDiagramProps {
396
263
  store?: any;
397
264
  /** Enable debug mode */
398
265
  debug?: boolean;
399
- /** Callback when a node is clicked */
400
- onNodeClick?: (node: NetworkNode) => void;
266
+ /** Callback when a node is clicked or selection changes (null when deselected) */
267
+ onNodeClick?: (node: NetworkNode | null) => void;
401
268
  /** Callback when an edge is clicked */
402
269
  onEdgeClick?: (edge: NetworkEdge) => void;
403
270
  /** Callback when device view changes */
@@ -410,23 +277,24 @@ interface NetworkDiagramProps {
410
277
  style?: React.CSSProperties;
411
278
  /** If true, vertically align rack bottoms to the same baseline */
412
279
  alignRacksToBottom?: boolean;
413
- }
414
- /**
415
- * NetBox integration props
416
- * @public
417
- */
418
- interface NetBoxNetworkDiagramProps extends NetworkDiagramProps {
419
- /** NetBox data for integration */
420
- netboxData?: {
421
- /** NetBox racks */
422
- racks: NetBoxRack[];
423
- /** NetBox devices */
424
- devices: NetBoxDevice[];
425
- /** NetBox cables */
426
- cables: NetBoxCable[];
427
- };
428
- /** Callback when NetBox data is updated */
429
- onNetBoxUpdate?: (data: any) => void;
280
+ /** Color mode for the diagram */
281
+ colorMode?: 'light' | 'dark' | 'system';
282
+ /** Callback when React Flow instance is initialized */
283
+ onInit?: (instance: any) => void;
284
+ /** Callback to get React Flow methods for save/restore */
285
+ onFlowMethods?: (methods: {
286
+ toObject: () => any;
287
+ setViewport: (viewport: any) => void;
288
+ toImage: (options?: any) => Promise<string>;
289
+ }) => void;
290
+ /** Show download button */
291
+ showDownloadButton?: boolean;
292
+ /** Download button position */
293
+ downloadButtonPosition?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';
294
+ /** Custom download button text */
295
+ downloadButtonText?: string;
296
+ /** Download button styling options */
297
+ downloadButtonStyle?: React.CSSProperties;
430
298
  }
431
299
 
432
300
  declare const NetworkDiagram: React$1.FC<NetworkDiagramProps>;
@@ -434,6 +302,7 @@ declare const NetworkDiagram: React$1.FC<NetworkDiagramProps>;
434
302
  interface RackNodeProps extends NodeProps<NetworkNode['data']> {
435
303
  onViewChange?: (nodeId: string, view: 'front' | 'rear') => void;
436
304
  onRackFaceChange?: (rackId: string, face: 'front' | 'rear') => void;
305
+ isDragOver?: boolean;
437
306
  }
438
307
  declare const RackNode: React$1.FC<RackNodeProps>;
439
308
 
@@ -447,35 +316,111 @@ declare const DeviceNode: React$1.FC<NodeProps<NetworkNode['data']>>;
447
316
 
448
317
  declare const VerticalPDU: React$1.FC<NodeProps<NetworkNode['data']>>;
449
318
 
319
+ interface InventoryRackDTO {
320
+ id: string | number;
321
+ name: string;
322
+ status?: {
323
+ value?: string;
324
+ } | string;
325
+ u_height?: number;
326
+ units?: number;
327
+ facility_id?: string | number;
328
+ serial?: string;
329
+ asset_tag?: string;
330
+ site?: {
331
+ name?: string;
332
+ } | string;
333
+ role?: {
334
+ name?: string;
335
+ } | string;
336
+ tenant?: {
337
+ name?: string;
338
+ } | string;
339
+ }
340
+ interface InventoryDeviceDTO {
341
+ id: string | number;
342
+ name: string;
343
+ status?: {
344
+ value?: string;
345
+ } | string;
346
+ device_type?: {
347
+ u_height?: number;
348
+ model?: string;
349
+ manufacturer?: {
350
+ name?: string;
351
+ };
352
+ };
353
+ model?: string;
354
+ manufacturer?: string;
355
+ device_role?: {
356
+ name?: string;
357
+ } | string;
358
+ u_height?: number;
359
+ position?: number;
360
+ face?: 'front' | 'rear';
361
+ rack?: {
362
+ id?: string | number;
363
+ name?: string;
364
+ } | string | number;
365
+ primary_ip4?: {
366
+ address?: string;
367
+ } | string;
368
+ primary_ip6?: {
369
+ address?: string;
370
+ } | string;
371
+ site?: {
372
+ name?: string;
373
+ } | string;
374
+ }
375
+ interface InventoryCableDTO {
376
+ id: string | number;
377
+ type?: {
378
+ label?: string;
379
+ };
380
+ bandwidth?: string;
381
+ length?: number;
382
+ color?: string;
383
+ status?: {
384
+ value?: string;
385
+ } | string;
386
+ termination_a?: {
387
+ device?: {
388
+ id?: string | number;
389
+ } | string | number;
390
+ name?: string;
391
+ } | string;
392
+ termination_b?: {
393
+ device?: {
394
+ id?: string | number;
395
+ } | string | number;
396
+ name?: string;
397
+ } | string;
398
+ }
450
399
  /**
451
- * Convert NetBox rack data to NetworkNode
400
+ * Convert inventory rack data to NetworkNode
452
401
  */
453
- declare const netboxRackToNetworkNode: (rack: NetBoxRack) => NetworkNode;
402
+ declare const inventoryRackToNetworkNode: (rack: InventoryRackDTO) => NetworkNode;
454
403
  /**
455
- * Convert NetBox device data to NetworkNode
404
+ * Convert inventory device data to NetworkNode
456
405
  */
457
- declare const netboxDeviceToNetworkNode: (device: NetBoxDevice) => NetworkNode;
406
+ declare const inventoryDeviceToNetworkNode: (device: InventoryDeviceDTO) => NetworkNode;
458
407
  /**
459
- * Convert NetBox cable data to NetworkEdge
408
+ * Convert inventory cable data to NetworkEdge
460
409
  */
461
- declare const netboxCableToNetworkEdge: (cable: NetBoxCable) => NetworkEdge;
410
+ declare const inventoryCableToNetworkEdge: (cable: InventoryCableDTO) => NetworkEdge;
462
411
  /**
463
- * Convert NetBox data to network diagram format
412
+ * Convert inventory data to network diagram format
464
413
  */
465
- declare const netboxToNetworkDiagram: (data: {
466
- racks: NetBoxRack[];
467
- devices: NetBoxDevice[];
468
- cables: NetBoxCable[];
414
+ declare const inventoryToNetworkDiagram: (data: {
415
+ racks: InventoryRackDTO[];
416
+ devices: InventoryDeviceDTO[];
417
+ cables: InventoryCableDTO[];
469
418
  }) => {
470
419
  nodes: NetworkNode[];
471
420
  edges: NetworkEdge[];
472
421
  };
473
422
  /**
474
- * Calculate U position for devices in a rack
475
- */
476
- declare const calculateUPositions: (devices: NetBoxDevice[], rackHeight: number) => Map<number, number>;
477
- /**
478
- * Generate layout positions for nodes
423
+ * Generate simple layout positions for nodes array
479
424
  */
480
425
  declare const generateLayout: (nodes: NetworkNode[]) => NetworkNode[];
481
426
 
@@ -501,7 +446,7 @@ declare const findNextAvailableUPosition: (rack: NetworkNode, device: NetworkNod
501
446
  /**
502
447
  * Calculate device position based on U position within a rack
503
448
  */
504
- declare const calculateDevicePositionFromU: (rack: NetworkNode, uPosition: number) => {
449
+ declare const calculateDevicePositionFromU: (rack: NetworkNode, uPosition: number, deviceHeight?: number) => {
505
450
  x: number;
506
451
  y: number;
507
452
  };
@@ -646,6 +591,8 @@ interface NetworkDiagramStore {
646
591
  subscribe: (listener: (state: NetworkDiagramState) => void) => () => void;
647
592
  selectEdgeZIndex: (edge: NetworkEdge) => number;
648
593
  validateConnection: (params: ValidateConnectionParams) => ValidationResult;
594
+ selectNodeById: (id: string) => NetworkNode | undefined;
595
+ selectConnectedEdges: (nodeId: string) => NetworkEdge[];
649
596
  }
650
597
  declare function createNetworkDiagramStore(initial?: Partial<NetworkDiagramState>, options?: NetworkDiagramOptions): NetworkDiagramStore;
651
598
 
@@ -653,4 +600,4 @@ declare function useNetworkDiagram(store: NetworkDiagramStore): NetworkDiagramSt
653
600
  declare function useNodes(store: NetworkDiagramStore): NetworkNode[];
654
601
  declare function useEdges(store: NetworkDiagramStore): NetworkEdge[];
655
602
 
656
- export { DeviceNode, DevicePlacementError, type DevicePlacementValidation, type FiberCable, FiberEdge, FiberNode, type NetBoxCable, type NetBoxConnection, type NetBoxDevice, type NetBoxInterface, type NetBoxNetworkDiagramProps, type NetBoxRack, NetworkDiagram, type NetworkDiagramProps, type NetworkEdge, type NetworkNode, POWER_CONNECTORS, PowerEdge, type RackConfig, type RackDevice, RackNode, type RackSchemaOptions, VerticalPDU, Width, addDeviceToRack, buildNodesFromRackConfig, calculateDevicePositionFromU, calculateUPositions, createNetworkDiagramStore, createRackConfigFromNodes, findNextAvailableUPosition, generateLayout, getConnectorConfig, getDeviceConnectorType, getPDUPortType, getPowerPortStyle, isHighPowerConnector, isUPositionAvailable, netboxCableToNetworkEdge, netboxDeviceToNetworkNode, netboxRackToNetworkNode, netboxToNetworkDiagram, removeDeviceFromRack, snapToUPosition, updateDeviceUPosition$1 as updateDeviceUPosition, updateDeviceUPosition as updateDeviceUPositionInSchema, useEdges as useDiagramEdges, useNodes as useDiagramNodes, useNetworkDiagram, validateAndSnapDevice, validateRackDevicePlacements };
603
+ export { DeviceNode, DevicePlacementError, type DevicePlacementValidation, type FiberCable, FiberEdge, FiberNode, NetworkDiagram, type NetworkDiagramProps, type NetworkEdge, type NetworkNode, POWER_CONNECTORS, PowerEdge, type RackConfig, type RackDevice, RackNode, type RackSchemaOptions, VerticalPDU, Width, addDeviceToRack, buildNodesFromRackConfig, calculateDevicePositionFromU, createNetworkDiagramStore, createRackConfigFromNodes, findNextAvailableUPosition, generateLayout, getConnectorConfig, getDeviceConnectorType, getPDUPortType, getPowerPortStyle, inventoryCableToNetworkEdge, inventoryDeviceToNetworkNode, inventoryRackToNetworkNode, inventoryToNetworkDiagram, isHighPowerConnector, isUPositionAvailable, removeDeviceFromRack, snapToUPosition, updateDeviceUPosition$1 as updateDeviceUPosition, updateDeviceUPosition as updateDeviceUPositionInSchema, useEdges as useDiagramEdges, useNodes as useDiagramNodes, useNetworkDiagram, validateAndSnapDevice, validateRackDevicePlacements };