@backbay/glia-three 0.2.0-alpha.2
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/package.json +43 -0
- package/src/environment/AuroraLayer/AuroraLayer.stories.tsx +43 -0
- package/src/environment/AuroraLayer/AuroraLayer.tsx +200 -0
- package/src/environment/AuroraLayer/index.ts +2 -0
- package/src/environment/AuroraLayer/types.ts +30 -0
- package/src/environment/EnvironmentLayer/EnvironmentLayer.stories.tsx +262 -0
- package/src/environment/EnvironmentLayer/EnvironmentLayer.tsx +105 -0
- package/src/environment/EnvironmentLayer/index.ts +4 -0
- package/src/environment/EnvironmentLayer/presets.ts +128 -0
- package/src/environment/FogLayer/FogLayer.stories.tsx +83 -0
- package/src/environment/FogLayer/FogLayer.tsx +113 -0
- package/src/environment/FogLayer/index.ts +2 -0
- package/src/environment/FogLayer/types.ts +45 -0
- package/src/environment/VolumetricLight/VolumetricLight.stories.tsx +55 -0
- package/src/environment/VolumetricLight/VolumetricLight.tsx +188 -0
- package/src/environment/VolumetricLight/index.ts +2 -0
- package/src/environment/VolumetricLight/types.ts +33 -0
- package/src/environment/WeatherLayer/WeatherLayer.stories.tsx +348 -0
- package/src/environment/WeatherLayer/WeatherLayer.tsx +266 -0
- package/src/environment/WeatherLayer/cinematicCanvas.tsx +809 -0
- package/src/environment/WeatherLayer/colors.ts +27 -0
- package/src/environment/WeatherLayer/index.ts +4 -0
- package/src/environment/WeatherLayer/leafPresets.ts +12 -0
- package/src/environment/WeatherLayer/particles.ts +227 -0
- package/src/environment/WeatherLayer/types.ts +140 -0
- package/src/environment/index.ts +17 -0
- package/src/environment/shared/index.ts +2 -0
- package/src/environment/shared/noise.ts +10 -0
- package/src/environment/shared/performance.ts +33 -0
- package/src/environment/shared/types.ts +26 -0
- package/src/index.ts +2 -0
- package/src/lib/utils.ts +6 -0
- package/src/lib/vision-types.ts +84 -0
- package/src/three/AgentConsole/AgentConsole.stories.tsx +397 -0
- package/src/three/AgentConsole/AgentConsole.tsx +195 -0
- package/src/three/AgentConsole/ConsoleChat.tsx +237 -0
- package/src/three/AgentConsole/FocusConstellation.tsx +297 -0
- package/src/three/AgentConsole/GlyphAvatar.stories.tsx +110 -0
- package/src/three/AgentConsole/GlyphAvatar.tsx +117 -0
- package/src/three/AgentConsole/QuickActions.tsx +111 -0
- package/src/three/AgentConsole/index.ts +41 -0
- package/src/three/AgentConsole/types.ts +241 -0
- package/src/three/AmbientField/AmbientField.stories.tsx +290 -0
- package/src/three/AmbientField/AmbientField.tsx +307 -0
- package/src/three/AmbientField/BackbayFieldBus.ts +326 -0
- package/src/three/AmbientField/FieldProvider.tsx +83 -0
- package/src/three/AmbientField/index.ts +37 -0
- package/src/three/AmbientField/shaders/constellation.ts +384 -0
- package/src/three/AmbientField/types.ts +174 -0
- package/src/three/AttackGraph/AttackGraph.stories.tsx +144 -0
- package/src/three/AttackGraph/AttackGraph.tsx +325 -0
- package/src/three/AttackGraph/index.ts +19 -0
- package/src/three/AttackGraph/types.ts +97 -0
- package/src/three/AuditTrail/AuditTrail.stories.tsx +567 -0
- package/src/three/AuditTrail/AuditTrail.tsx +644 -0
- package/src/three/AuditTrail/index.ts +33 -0
- package/src/three/AuditTrail/types.ts +192 -0
- package/src/three/CrystallineOrganism/Breadcrumb.tsx +61 -0
- package/src/three/CrystallineOrganism/CrystallineOrganism.stories.tsx +509 -0
- package/src/three/CrystallineOrganism/CrystallineOrganism.tsx +273 -0
- package/src/three/CrystallineOrganism/LatticeEdge.tsx +69 -0
- package/src/three/CrystallineOrganism/OrganismLattice.tsx +159 -0
- package/src/three/CrystallineOrganism/OrganismParticles.tsx +148 -0
- package/src/three/CrystallineOrganism/OrganismShell.tsx +277 -0
- package/src/three/CrystallineOrganism/constants.ts +161 -0
- package/src/three/CrystallineOrganism/index.ts +17 -0
- package/src/three/CrystallineOrganism/layouts/hexGrid.ts +85 -0
- package/src/three/CrystallineOrganism/layouts/index.ts +1 -0
- package/src/three/CrystallineOrganism/types.ts +167 -0
- package/src/three/CrystallineOrganism/useOrganismEmotion.ts +84 -0
- package/src/three/FirewallBarrier/FirewallBarrier.stories.tsx +167 -0
- package/src/three/FirewallBarrier/FirewallBarrier.tsx +259 -0
- package/src/three/FirewallBarrier/index.ts +14 -0
- package/src/three/FirewallBarrier/types.ts +52 -0
- package/src/three/Glyph/GlyphObject.stories.tsx +577 -0
- package/src/three/Glyph/GlyphObject.tsx +422 -0
- package/src/three/Glyph/index.ts +10 -0
- package/src/three/Glyph/types.ts +36 -0
- package/src/three/Glyph/useGlyphController.ts +231 -0
- package/src/three/Glyph/useGlyphEmotion.ts +70 -0
- package/src/three/Graph3D/Graph3D.stories.tsx +269 -0
- package/src/three/Graph3D/Graph3D.tsx +248 -0
- package/src/three/Graph3D/GraphEdge.tsx +79 -0
- package/src/three/Graph3D/GraphNode.tsx +239 -0
- package/src/three/Graph3D/types.ts +66 -0
- package/src/three/Graph3D/utils.ts +204 -0
- package/src/three/IntelFeed/IntelFeed.stories.tsx +168 -0
- package/src/three/IntelFeed/IntelFeed.tsx +284 -0
- package/src/three/IntelFeed/index.ts +14 -0
- package/src/three/IntelFeed/types.ts +56 -0
- package/src/three/MetricsGalaxy/MetricsGalaxy.tsx +484 -0
- package/src/three/MetricsGalaxy/index.ts +6 -0
- package/src/three/MetricsGalaxy/types.ts +26 -0
- package/src/three/NetworkTopology/NetworkTopology.stories.tsx +184 -0
- package/src/three/NetworkTopology/NetworkTopology.tsx +421 -0
- package/src/three/NetworkTopology/index.ts +34 -0
- package/src/three/NetworkTopology/types.ts +128 -0
- package/src/three/ParticleField/ParticleField.stories.tsx +162 -0
- package/src/three/ParticleField/ParticleField.tsx +81 -0
- package/src/three/ParticleField/index.ts +1 -0
- package/src/three/PermissionMatrix/PermissionMatrix.stories.tsx +475 -0
- package/src/three/PermissionMatrix/PermissionMatrix.tsx +380 -0
- package/src/three/PermissionMatrix/index.ts +15 -0
- package/src/three/PermissionMatrix/types.ts +54 -0
- package/src/three/QuantumField/ConstellationField.tsx +238 -0
- package/src/three/QuantumField/FieldBus.ts +349 -0
- package/src/three/QuantumField/FieldLayer.tsx +430 -0
- package/src/three/QuantumField/FieldProvider.tsx +460 -0
- package/src/three/QuantumField/PcbField.tsx +406 -0
- package/src/three/QuantumField/QuantumField.stories.tsx +1155 -0
- package/src/three/QuantumField/TrailRTT.ts +212 -0
- package/src/three/QuantumField/WaterField.tsx +226 -0
- package/src/three/QuantumField/WaterSimRTT.ts +283 -0
- package/src/three/QuantumField/domMapping.ts +185 -0
- package/src/three/QuantumField/index.ts +110 -0
- package/src/three/QuantumField/styles/index.ts +9 -0
- package/src/three/QuantumField/styles/styleA.ts +526 -0
- package/src/three/QuantumField/styles/styleB.ts +1210 -0
- package/src/three/QuantumField/styles/styleC.ts +266 -0
- package/src/three/QuantumField/themes.ts +211 -0
- package/src/three/QuantumField/types.ts +380 -0
- package/src/three/SOCCommandCenter/SOCCommandCenter.stories.tsx +591 -0
- package/src/three/SOCCommandCenter/SOCCommandCenter.tsx +248 -0
- package/src/three/SOCCommandCenter/index.ts +26 -0
- package/src/three/SOCCommandCenter/types.ts +201 -0
- package/src/three/SecurityDashboard/SecurityDashboard.stories.tsx +508 -0
- package/src/three/SecurityDashboard/SecurityDashboard.tsx +507 -0
- package/src/three/SecurityDashboard/index.ts +37 -0
- package/src/three/SecurityDashboard/types.ts +143 -0
- package/src/three/SecurityShield/SecurityShield.stories.tsx +257 -0
- package/src/three/SecurityShield/SecurityShield.tsx +502 -0
- package/src/three/SecurityShield/index.ts +25 -0
- package/src/three/SecurityShield/types.ts +64 -0
- package/src/three/Sentinel/AvatarMode.tsx +578 -0
- package/src/three/Sentinel/AvatarRenderer.tsx +199 -0
- package/src/three/Sentinel/CameraPip.tsx +127 -0
- package/src/three/Sentinel/CardinalItem.tsx +83 -0
- package/src/three/Sentinel/CardinalMenu.tsx +370 -0
- package/src/three/Sentinel/DockedMiniOrb.tsx +146 -0
- package/src/three/Sentinel/RadialSubmenu.tsx +273 -0
- package/src/three/Sentinel/SentinelConversation.tsx +802 -0
- package/src/three/Sentinel/SentinelOrb.tsx +316 -0
- package/src/three/Sentinel/SentinelOverlay.tsx +146 -0
- package/src/three/Sentinel/SentinelProvider.tsx +145 -0
- package/src/three/Sentinel/SentinelTether.tsx +182 -0
- package/src/three/Sentinel/SigilPlaceholder.tsx +176 -0
- package/src/three/Sentinel/VerticalSubmenu.tsx +150 -0
- package/src/three/Sentinel/index.ts +145 -0
- package/src/three/Sentinel/sentinelStore.ts +196 -0
- package/src/three/Sentinel/types.ts +403 -0
- package/src/three/Sentinel/useCameraPermission.ts +153 -0
- package/src/three/Sentinel/useThrowPhysics.ts +220 -0
- package/src/three/SpatialWorkspace/CyntraWorkspace.tsx +84 -0
- package/src/three/SpatialWorkspace/JobCluster.tsx +281 -0
- package/src/three/SpatialWorkspace/NodeGraph.tsx +236 -0
- package/src/three/SpatialWorkspace/ReceiptOrbit.tsx +368 -0
- package/src/three/SpatialWorkspace/SpatialWorkspace.stories.tsx +547 -0
- package/src/three/SpatialWorkspace/SpatialWorkspace.tsx +428 -0
- package/src/three/SpatialWorkspace/TrustRings.tsx +228 -0
- package/src/three/SpatialWorkspace/adapters.ts +353 -0
- package/src/three/SpatialWorkspace/index.ts +85 -0
- package/src/three/SpatialWorkspace/nexusAdapter.ts +182 -0
- package/src/three/SpatialWorkspace/types.ts +389 -0
- package/src/three/ThreatRadar/ThreatRadar.stories.tsx +451 -0
- package/src/three/ThreatRadar/ThreatRadar.tsx +542 -0
- package/src/three/ThreatRadar/index.ts +8 -0
- package/src/three/ThreatRadar/types.ts +90 -0
- package/src/three/ThreeErrorBoundary/ThreeErrorBoundary.tsx +235 -0
- package/src/three/ThreeErrorBoundary/index.ts +5 -0
- package/src/three/index.ts +56 -0
- package/tsconfig.json +20 -0
- package/tsup.config.ts +21 -0
|
@@ -0,0 +1,507 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* SecurityDashboard - Composite 3D security monitoring dashboard
|
|
5
|
+
*
|
|
6
|
+
* Integrates SecurityShield, ThreatRadar, and AuditTrail components
|
|
7
|
+
* into a unified security monitoring view with multiple layout presets.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import * as React from "react";
|
|
11
|
+
import { useFrame } from "@react-three/fiber";
|
|
12
|
+
import { Html, Line } from "@react-three/drei";
|
|
13
|
+
import * as THREE from "three";
|
|
14
|
+
import { SecurityShield } from "../SecurityShield";
|
|
15
|
+
import { ThreatRadar } from "../ThreatRadar";
|
|
16
|
+
import { AuditTrail } from "../AuditTrail";
|
|
17
|
+
import type {
|
|
18
|
+
SecurityDashboardProps,
|
|
19
|
+
SecurityStatus,
|
|
20
|
+
DashboardThreat,
|
|
21
|
+
} from "./types";
|
|
22
|
+
import { LAYOUT_PRESETS, STATUS_THEME_COLORS } from "./types";
|
|
23
|
+
|
|
24
|
+
// -----------------------------------------------------------------------------
|
|
25
|
+
// Connection Lines Sub-component
|
|
26
|
+
// -----------------------------------------------------------------------------
|
|
27
|
+
|
|
28
|
+
interface ConnectionLinesProps {
|
|
29
|
+
shield: [number, number, number];
|
|
30
|
+
radar: [number, number, number];
|
|
31
|
+
audit: [number, number, number];
|
|
32
|
+
color: string;
|
|
33
|
+
animated: boolean;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function ConnectionLines({
|
|
37
|
+
shield,
|
|
38
|
+
radar,
|
|
39
|
+
audit,
|
|
40
|
+
color,
|
|
41
|
+
animated,
|
|
42
|
+
}: ConnectionLinesProps) {
|
|
43
|
+
const lineRef1 = React.useRef<THREE.Line>(null);
|
|
44
|
+
const lineRef2 = React.useRef<THREE.Line>(null);
|
|
45
|
+
const [dashOffset, setDashOffset] = React.useState(0);
|
|
46
|
+
|
|
47
|
+
useFrame((_, delta) => {
|
|
48
|
+
if (animated) {
|
|
49
|
+
setDashOffset((prev) => (prev + delta * 0.5) % 1);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// Generate curved path points using quadratic bezier
|
|
54
|
+
const generateCurve = (
|
|
55
|
+
start: [number, number, number],
|
|
56
|
+
end: [number, number, number],
|
|
57
|
+
segments: number = 20
|
|
58
|
+
): [number, number, number][] => {
|
|
59
|
+
const points: [number, number, number][] = [];
|
|
60
|
+
const midY = Math.max(start[1], end[1]) + 0.5;
|
|
61
|
+
const midX = (start[0] + end[0]) / 2;
|
|
62
|
+
const midZ = (start[2] + end[2]) / 2;
|
|
63
|
+
|
|
64
|
+
for (let i = 0; i <= segments; i++) {
|
|
65
|
+
const t = i / segments;
|
|
66
|
+
const t2 = t * t;
|
|
67
|
+
const mt = 1 - t;
|
|
68
|
+
const mt2 = mt * mt;
|
|
69
|
+
|
|
70
|
+
// Quadratic bezier
|
|
71
|
+
const x = mt2 * start[0] + 2 * mt * t * midX + t2 * end[0];
|
|
72
|
+
const y = mt2 * start[1] + 2 * mt * t * midY + t2 * end[1];
|
|
73
|
+
const z = mt2 * start[2] + 2 * mt * t * midZ + t2 * end[2];
|
|
74
|
+
|
|
75
|
+
points.push([x, y, z]);
|
|
76
|
+
}
|
|
77
|
+
return points;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const shieldToRadar = generateCurve(shield, radar);
|
|
81
|
+
const shieldToAudit = generateCurve(shield, audit);
|
|
82
|
+
|
|
83
|
+
return (
|
|
84
|
+
<group>
|
|
85
|
+
{/* Shield to Radar connection */}
|
|
86
|
+
<Line
|
|
87
|
+
points={shieldToRadar}
|
|
88
|
+
color={color}
|
|
89
|
+
lineWidth={1.5}
|
|
90
|
+
transparent
|
|
91
|
+
opacity={0.25}
|
|
92
|
+
dashed
|
|
93
|
+
dashScale={10}
|
|
94
|
+
dashSize={0.3}
|
|
95
|
+
dashOffset={dashOffset}
|
|
96
|
+
/>
|
|
97
|
+
<Line
|
|
98
|
+
points={shieldToRadar}
|
|
99
|
+
color={color}
|
|
100
|
+
lineWidth={4}
|
|
101
|
+
transparent
|
|
102
|
+
opacity={0.05}
|
|
103
|
+
/>
|
|
104
|
+
|
|
105
|
+
{/* Shield to Audit connection */}
|
|
106
|
+
<Line
|
|
107
|
+
points={shieldToAudit}
|
|
108
|
+
color={color}
|
|
109
|
+
lineWidth={1.5}
|
|
110
|
+
transparent
|
|
111
|
+
opacity={0.25}
|
|
112
|
+
dashed
|
|
113
|
+
dashScale={10}
|
|
114
|
+
dashSize={0.3}
|
|
115
|
+
dashOffset={-dashOffset}
|
|
116
|
+
/>
|
|
117
|
+
<Line
|
|
118
|
+
points={shieldToAudit}
|
|
119
|
+
color={color}
|
|
120
|
+
lineWidth={4}
|
|
121
|
+
transparent
|
|
122
|
+
opacity={0.05}
|
|
123
|
+
/>
|
|
124
|
+
|
|
125
|
+
{/* Connection nodes at endpoints */}
|
|
126
|
+
{[shield, radar, audit].map((pos, i) => (
|
|
127
|
+
<mesh key={i} position={pos}>
|
|
128
|
+
<sphereGeometry args={[0.06, 12, 12]} />
|
|
129
|
+
<meshBasicMaterial
|
|
130
|
+
color={color}
|
|
131
|
+
transparent
|
|
132
|
+
opacity={0.4}
|
|
133
|
+
/>
|
|
134
|
+
</mesh>
|
|
135
|
+
))}
|
|
136
|
+
</group>
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// -----------------------------------------------------------------------------
|
|
141
|
+
// Status HUD Sub-component
|
|
142
|
+
// -----------------------------------------------------------------------------
|
|
143
|
+
|
|
144
|
+
interface StatusHUDProps {
|
|
145
|
+
score: number;
|
|
146
|
+
status: SecurityStatus;
|
|
147
|
+
shieldLevel: number;
|
|
148
|
+
threatCount: number;
|
|
149
|
+
activeThreats: number;
|
|
150
|
+
eventCount: number;
|
|
151
|
+
errorCount: number;
|
|
152
|
+
position: [number, number, number];
|
|
153
|
+
theme: SecurityDashboardProps["theme"];
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function StatusHUD({
|
|
157
|
+
score,
|
|
158
|
+
status,
|
|
159
|
+
shieldLevel,
|
|
160
|
+
threatCount,
|
|
161
|
+
activeThreats,
|
|
162
|
+
eventCount,
|
|
163
|
+
errorCount,
|
|
164
|
+
position,
|
|
165
|
+
theme = "cyber",
|
|
166
|
+
}: StatusHUDProps) {
|
|
167
|
+
const statusColor = STATUS_THEME_COLORS[status];
|
|
168
|
+
|
|
169
|
+
const themeAccent =
|
|
170
|
+
theme === "matrix"
|
|
171
|
+
? "#00ff66"
|
|
172
|
+
: theme === "terminal"
|
|
173
|
+
? "#ffaa00"
|
|
174
|
+
: theme === "neon"
|
|
175
|
+
? "#ff00ff"
|
|
176
|
+
: theme === "blueprint"
|
|
177
|
+
? "#4aa3ff"
|
|
178
|
+
: "#00ffff";
|
|
179
|
+
|
|
180
|
+
return (
|
|
181
|
+
<Html position={position} center>
|
|
182
|
+
<div
|
|
183
|
+
style={{
|
|
184
|
+
background: "rgba(0, 4, 8, 0.95)",
|
|
185
|
+
border: `2px solid ${statusColor}`,
|
|
186
|
+
borderRadius: "8px",
|
|
187
|
+
padding: "16px 24px",
|
|
188
|
+
fontFamily: "'JetBrains Mono', 'SF Mono', monospace",
|
|
189
|
+
minWidth: "200px",
|
|
190
|
+
boxShadow: `0 0 30px ${statusColor}40, inset 0 0 20px ${statusColor}15`,
|
|
191
|
+
}}
|
|
192
|
+
>
|
|
193
|
+
{/* Status Header */}
|
|
194
|
+
<div
|
|
195
|
+
style={{
|
|
196
|
+
textAlign: "center",
|
|
197
|
+
marginBottom: "12px",
|
|
198
|
+
paddingBottom: "10px",
|
|
199
|
+
borderBottom: `1px solid ${statusColor}50`,
|
|
200
|
+
}}
|
|
201
|
+
>
|
|
202
|
+
<div
|
|
203
|
+
style={{
|
|
204
|
+
fontSize: "24px",
|
|
205
|
+
fontWeight: 700,
|
|
206
|
+
color: statusColor,
|
|
207
|
+
letterSpacing: "3px",
|
|
208
|
+
textShadow: `0 0 10px ${statusColor}`,
|
|
209
|
+
}}
|
|
210
|
+
>
|
|
211
|
+
{status}
|
|
212
|
+
</div>
|
|
213
|
+
<div
|
|
214
|
+
style={{
|
|
215
|
+
fontSize: "14px",
|
|
216
|
+
color: "#ffffff",
|
|
217
|
+
marginTop: "4px",
|
|
218
|
+
}}
|
|
219
|
+
>
|
|
220
|
+
Security Score:{" "}
|
|
221
|
+
<span style={{ fontWeight: 700, color: statusColor }}>
|
|
222
|
+
{score}%
|
|
223
|
+
</span>
|
|
224
|
+
</div>
|
|
225
|
+
</div>
|
|
226
|
+
|
|
227
|
+
{/* Metrics Grid */}
|
|
228
|
+
<div
|
|
229
|
+
style={{
|
|
230
|
+
display: "grid",
|
|
231
|
+
gridTemplateColumns: "1fr 1fr",
|
|
232
|
+
gap: "8px 16px",
|
|
233
|
+
fontSize: "11px",
|
|
234
|
+
}}
|
|
235
|
+
>
|
|
236
|
+
<div style={{ color: "#888" }}>Shield:</div>
|
|
237
|
+
<div style={{ color: themeAccent, fontWeight: 600, textAlign: "right" }}>
|
|
238
|
+
{Math.round(shieldLevel * 100)}%
|
|
239
|
+
</div>
|
|
240
|
+
|
|
241
|
+
<div style={{ color: "#888" }}>Threats:</div>
|
|
242
|
+
<div
|
|
243
|
+
style={{
|
|
244
|
+
color: threatCount > 0 ? "#ff6644" : themeAccent,
|
|
245
|
+
fontWeight: 600,
|
|
246
|
+
textAlign: "right",
|
|
247
|
+
}}
|
|
248
|
+
>
|
|
249
|
+
{threatCount}
|
|
250
|
+
</div>
|
|
251
|
+
|
|
252
|
+
<div style={{ color: "#888" }}>Active:</div>
|
|
253
|
+
<div
|
|
254
|
+
style={{
|
|
255
|
+
color: activeThreats > 0 ? "#ff3344" : themeAccent,
|
|
256
|
+
fontWeight: 600,
|
|
257
|
+
textAlign: "right",
|
|
258
|
+
}}
|
|
259
|
+
>
|
|
260
|
+
{activeThreats}
|
|
261
|
+
</div>
|
|
262
|
+
|
|
263
|
+
<div style={{ color: "#888" }}>Events:</div>
|
|
264
|
+
<div style={{ color: "#ffffff", fontWeight: 600, textAlign: "right" }}>
|
|
265
|
+
{eventCount}
|
|
266
|
+
</div>
|
|
267
|
+
|
|
268
|
+
<div style={{ color: "#888" }}>Errors:</div>
|
|
269
|
+
<div
|
|
270
|
+
style={{
|
|
271
|
+
color: errorCount > 0 ? "#ff4444" : themeAccent,
|
|
272
|
+
fontWeight: 600,
|
|
273
|
+
textAlign: "right",
|
|
274
|
+
}}
|
|
275
|
+
>
|
|
276
|
+
{errorCount}
|
|
277
|
+
</div>
|
|
278
|
+
</div>
|
|
279
|
+
|
|
280
|
+
{/* Score Bar */}
|
|
281
|
+
<div
|
|
282
|
+
style={{
|
|
283
|
+
marginTop: "12px",
|
|
284
|
+
paddingTop: "10px",
|
|
285
|
+
borderTop: `1px solid ${statusColor}30`,
|
|
286
|
+
}}
|
|
287
|
+
>
|
|
288
|
+
<div
|
|
289
|
+
style={{
|
|
290
|
+
height: "6px",
|
|
291
|
+
background: "#1a1a2e",
|
|
292
|
+
borderRadius: "3px",
|
|
293
|
+
overflow: "hidden",
|
|
294
|
+
}}
|
|
295
|
+
>
|
|
296
|
+
<div
|
|
297
|
+
style={{
|
|
298
|
+
height: "100%",
|
|
299
|
+
width: `${score}%`,
|
|
300
|
+
background: `linear-gradient(90deg, ${statusColor}80, ${statusColor})`,
|
|
301
|
+
borderRadius: "3px",
|
|
302
|
+
transition: "width 0.3s ease",
|
|
303
|
+
boxShadow: `0 0 8px ${statusColor}`,
|
|
304
|
+
}}
|
|
305
|
+
/>
|
|
306
|
+
</div>
|
|
307
|
+
</div>
|
|
308
|
+
</div>
|
|
309
|
+
</Html>
|
|
310
|
+
);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// -----------------------------------------------------------------------------
|
|
314
|
+
// Main SecurityDashboard Component
|
|
315
|
+
// -----------------------------------------------------------------------------
|
|
316
|
+
|
|
317
|
+
export function SecurityDashboard({
|
|
318
|
+
shield,
|
|
319
|
+
threats,
|
|
320
|
+
auditEvents,
|
|
321
|
+
layout = "command",
|
|
322
|
+
position = [0, 0, 0],
|
|
323
|
+
animated = true,
|
|
324
|
+
onShieldClick,
|
|
325
|
+
onThreatClick,
|
|
326
|
+
onEventClick,
|
|
327
|
+
showConnections = true,
|
|
328
|
+
showStatusHUD = true,
|
|
329
|
+
theme = "cyber",
|
|
330
|
+
}: SecurityDashboardProps) {
|
|
331
|
+
const layoutConfig = LAYOUT_PRESETS[layout];
|
|
332
|
+
|
|
333
|
+
// Calculate overall security score
|
|
334
|
+
const securityScore = React.useMemo(() => {
|
|
335
|
+
// Base score from shield level
|
|
336
|
+
const shieldScore = shield.level * 40;
|
|
337
|
+
|
|
338
|
+
// Penalty for active threats
|
|
339
|
+
const activeThreats = threats.filter((t) => t.active);
|
|
340
|
+
const threatPenalty = activeThreats.length * 8;
|
|
341
|
+
|
|
342
|
+
// Penalty for high severity threats
|
|
343
|
+
const severeThreatPenalty =
|
|
344
|
+
threats.filter((t) => t.severity > 0.7).length * 5;
|
|
345
|
+
|
|
346
|
+
// Penalty for errors/critical events
|
|
347
|
+
const errorEvents = auditEvents.filter(
|
|
348
|
+
(e) => e.severity === "error" || e.severity === "critical"
|
|
349
|
+
);
|
|
350
|
+
const errorPenalty = errorEvents.length * 3;
|
|
351
|
+
|
|
352
|
+
// Penalty for failed events
|
|
353
|
+
const failedEvents = auditEvents.filter((e) => !e.success);
|
|
354
|
+
const failedPenalty = failedEvents.length * 2;
|
|
355
|
+
|
|
356
|
+
// Calculate final score
|
|
357
|
+
const baseScore = 60 + shieldScore;
|
|
358
|
+
const penalties =
|
|
359
|
+
threatPenalty + severeThreatPenalty + errorPenalty + failedPenalty;
|
|
360
|
+
|
|
361
|
+
return Math.max(0, Math.min(100, Math.round(baseScore - penalties)));
|
|
362
|
+
}, [shield, threats, auditEvents]);
|
|
363
|
+
|
|
364
|
+
// Determine overall status
|
|
365
|
+
const overallStatus: SecurityStatus = React.useMemo(() => {
|
|
366
|
+
if (shield.status === "offline") return "OFFLINE";
|
|
367
|
+
if (securityScore >= 75) return "SECURE";
|
|
368
|
+
if (securityScore >= 40) return "WARNING";
|
|
369
|
+
return "CRITICAL";
|
|
370
|
+
}, [securityScore, shield.status]);
|
|
371
|
+
|
|
372
|
+
const statusColor = STATUS_THEME_COLORS[overallStatus];
|
|
373
|
+
|
|
374
|
+
// Count metrics
|
|
375
|
+
const activeThreats = threats.filter((t) => t.active).length;
|
|
376
|
+
const errorCount = auditEvents.filter(
|
|
377
|
+
(e) => e.severity === "error" || e.severity === "critical"
|
|
378
|
+
).length;
|
|
379
|
+
|
|
380
|
+
// Convert dashboard threats to radar format
|
|
381
|
+
const radarThreats = React.useMemo(() => {
|
|
382
|
+
return threats.map((t) => ({
|
|
383
|
+
...t,
|
|
384
|
+
detectedAt: Date.now(),
|
|
385
|
+
}));
|
|
386
|
+
}, [threats]);
|
|
387
|
+
|
|
388
|
+
// Map audit trail theme
|
|
389
|
+
const auditTheme = theme;
|
|
390
|
+
|
|
391
|
+
return (
|
|
392
|
+
<group position={position}>
|
|
393
|
+
{/* SecurityShield */}
|
|
394
|
+
<SecurityShield
|
|
395
|
+
level={shield.level}
|
|
396
|
+
status={shield.status}
|
|
397
|
+
threatsBlocked={shield.threatsBlocked}
|
|
398
|
+
position={layoutConfig.shield.position}
|
|
399
|
+
radius={layoutConfig.shield.radius}
|
|
400
|
+
onClick={onShieldClick}
|
|
401
|
+
showStats={layout !== "compact"}
|
|
402
|
+
animationSpeed={animated ? 1 : 0}
|
|
403
|
+
/>
|
|
404
|
+
|
|
405
|
+
{/* ThreatRadar */}
|
|
406
|
+
<ThreatRadar
|
|
407
|
+
threats={radarThreats}
|
|
408
|
+
position={layoutConfig.radar.position}
|
|
409
|
+
radius={layoutConfig.radar.radius}
|
|
410
|
+
scanSpeed={animated ? 0.5 : 0}
|
|
411
|
+
onThreatClick={onThreatClick as (threat: any) => void}
|
|
412
|
+
showLabels={layout !== "compact"}
|
|
413
|
+
showStats={layout !== "compact"}
|
|
414
|
+
sweepColor={
|
|
415
|
+
theme === "matrix"
|
|
416
|
+
? "#00ff66"
|
|
417
|
+
: theme === "terminal"
|
|
418
|
+
? "#ffaa00"
|
|
419
|
+
: theme === "neon"
|
|
420
|
+
? "#ff00ff"
|
|
421
|
+
: theme === "blueprint"
|
|
422
|
+
? "#4aa3ff"
|
|
423
|
+
: "#00ff66"
|
|
424
|
+
}
|
|
425
|
+
gridColor={
|
|
426
|
+
theme === "matrix"
|
|
427
|
+
? "#00ff44"
|
|
428
|
+
: theme === "terminal"
|
|
429
|
+
? "#ff8800"
|
|
430
|
+
: theme === "neon"
|
|
431
|
+
? "#ff44ff"
|
|
432
|
+
: "#00ff44"
|
|
433
|
+
}
|
|
434
|
+
/>
|
|
435
|
+
|
|
436
|
+
{/* AuditTrail */}
|
|
437
|
+
<AuditTrail
|
|
438
|
+
events={auditEvents}
|
|
439
|
+
position={layoutConfig.audit.position}
|
|
440
|
+
length={layoutConfig.audit.length}
|
|
441
|
+
orientation={layoutConfig.audit.orientation}
|
|
442
|
+
onEventClick={onEventClick}
|
|
443
|
+
maxEvents={layout === "compact" ? 10 : 15}
|
|
444
|
+
theme={auditTheme}
|
|
445
|
+
showSummary={layout !== "compact"}
|
|
446
|
+
enableParticles={animated}
|
|
447
|
+
/>
|
|
448
|
+
|
|
449
|
+
{/* Central Status HUD */}
|
|
450
|
+
{showStatusHUD && (
|
|
451
|
+
<StatusHUD
|
|
452
|
+
score={securityScore}
|
|
453
|
+
status={overallStatus}
|
|
454
|
+
shieldLevel={shield.level}
|
|
455
|
+
threatCount={threats.length}
|
|
456
|
+
activeThreats={activeThreats}
|
|
457
|
+
eventCount={auditEvents.length}
|
|
458
|
+
errorCount={errorCount}
|
|
459
|
+
position={layoutConfig.statusHUD.position}
|
|
460
|
+
theme={theme}
|
|
461
|
+
/>
|
|
462
|
+
)}
|
|
463
|
+
|
|
464
|
+
{/* Connecting lines between components */}
|
|
465
|
+
{showConnections && layout === "command" && (
|
|
466
|
+
<ConnectionLines
|
|
467
|
+
shield={layoutConfig.shield.position}
|
|
468
|
+
radar={layoutConfig.radar.position}
|
|
469
|
+
audit={layoutConfig.audit.position}
|
|
470
|
+
color={statusColor}
|
|
471
|
+
animated={animated}
|
|
472
|
+
/>
|
|
473
|
+
)}
|
|
474
|
+
|
|
475
|
+
{/* Ambient glow base */}
|
|
476
|
+
<mesh
|
|
477
|
+
position={[0, -0.5, 0]}
|
|
478
|
+
rotation={[-Math.PI / 2, 0, 0]}
|
|
479
|
+
>
|
|
480
|
+
<circleGeometry args={[layout === "compact" ? 4 : 8, 64]} />
|
|
481
|
+
<meshBasicMaterial
|
|
482
|
+
color={statusColor}
|
|
483
|
+
transparent
|
|
484
|
+
opacity={0.03}
|
|
485
|
+
side={THREE.DoubleSide}
|
|
486
|
+
blending={THREE.AdditiveBlending}
|
|
487
|
+
depthWrite={false}
|
|
488
|
+
/>
|
|
489
|
+
</mesh>
|
|
490
|
+
|
|
491
|
+
{/* Grid floor */}
|
|
492
|
+
<gridHelper
|
|
493
|
+
args={[
|
|
494
|
+
layout === "compact" ? 8 : 16,
|
|
495
|
+
layout === "compact" ? 16 : 32,
|
|
496
|
+
statusColor,
|
|
497
|
+
"#111122",
|
|
498
|
+
]}
|
|
499
|
+
position={[0, -0.5, 0]}
|
|
500
|
+
material-opacity={0.15}
|
|
501
|
+
material-transparent={true}
|
|
502
|
+
/>
|
|
503
|
+
</group>
|
|
504
|
+
);
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
SecurityDashboard.displayName = "SecurityDashboard";
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SecurityDashboard - Composite 3D security monitoring dashboard
|
|
3
|
+
*
|
|
4
|
+
* Integrates SecurityShield, ThreatRadar, and AuditTrail into a unified
|
|
5
|
+
* security monitoring view with multiple layout presets.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```tsx
|
|
9
|
+
* import { SecurityDashboard } from "@backbay/glia/primitives/three/SecurityDashboard";
|
|
10
|
+
*
|
|
11
|
+
* <SecurityDashboard
|
|
12
|
+
* shield={{ level: 0.85, status: 'active', threatsBlocked: 5 }}
|
|
13
|
+
* threats={[
|
|
14
|
+
* { id: '1', angle: 0.5, distance: 0.6, severity: 0.8, type: 'malware', active: true }
|
|
15
|
+
* ]}
|
|
16
|
+
* auditEvents={[
|
|
17
|
+
* { id: '1', timestamp: new Date(), type: 'login', severity: 'info', ... }
|
|
18
|
+
* ]}
|
|
19
|
+
* layout="command"
|
|
20
|
+
* onShieldClick={() => console.log('Shield clicked')}
|
|
21
|
+
* onThreatClick={(threat) => console.log('Threat:', threat)}
|
|
22
|
+
* onEventClick={(event) => console.log('Event:', event)}
|
|
23
|
+
* />
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
export { SecurityDashboard } from "./SecurityDashboard";
|
|
28
|
+
export type {
|
|
29
|
+
SecurityDashboardProps,
|
|
30
|
+
ShieldConfig,
|
|
31
|
+
DashboardThreat,
|
|
32
|
+
DashboardAuditEvent,
|
|
33
|
+
DashboardLayout,
|
|
34
|
+
LayoutConfig,
|
|
35
|
+
SecurityStatus,
|
|
36
|
+
} from "./types";
|
|
37
|
+
export { LAYOUT_PRESETS, STATUS_THEME_COLORS } from "./types";
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SecurityDashboard Types
|
|
3
|
+
*
|
|
4
|
+
* Type definitions for the composite 3D security dashboard component
|
|
5
|
+
* that integrates SecurityShield, ThreatRadar, and AuditTrail.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { ShieldStatus } from "../SecurityShield";
|
|
9
|
+
import type { Threat, ThreatType } from "../ThreatRadar";
|
|
10
|
+
import type { AuditEvent } from "../AuditTrail";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Shield configuration for the dashboard
|
|
14
|
+
*/
|
|
15
|
+
export interface ShieldConfig {
|
|
16
|
+
/** Protection level 0-1 */
|
|
17
|
+
level: number;
|
|
18
|
+
/** Current shield status */
|
|
19
|
+
status: ShieldStatus;
|
|
20
|
+
/** Number of threats blocked */
|
|
21
|
+
threatsBlocked: number;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Dashboard threat (extends base Threat type for dashboard context)
|
|
26
|
+
*/
|
|
27
|
+
export interface DashboardThreat {
|
|
28
|
+
/** Unique identifier */
|
|
29
|
+
id: string;
|
|
30
|
+
/** Angle in radians (0-2pi) */
|
|
31
|
+
angle: number;
|
|
32
|
+
/** Distance from center (0-1) */
|
|
33
|
+
distance: number;
|
|
34
|
+
/** Severity level (0-1) */
|
|
35
|
+
severity: number;
|
|
36
|
+
/** Threat classification */
|
|
37
|
+
type: ThreatType;
|
|
38
|
+
/** Whether threat is actively attacking */
|
|
39
|
+
active: boolean;
|
|
40
|
+
/** Optional label */
|
|
41
|
+
label?: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Dashboard audit event
|
|
46
|
+
*/
|
|
47
|
+
export type DashboardAuditEvent = AuditEvent;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Layout preset names
|
|
51
|
+
*/
|
|
52
|
+
export type DashboardLayout = "command" | "monitoring" | "compact";
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Props for the SecurityDashboard component
|
|
56
|
+
*/
|
|
57
|
+
export interface SecurityDashboardProps {
|
|
58
|
+
/** Shield configuration */
|
|
59
|
+
shield: ShieldConfig;
|
|
60
|
+
/** Threats for the radar display */
|
|
61
|
+
threats: DashboardThreat[];
|
|
62
|
+
/** Audit events for the trail */
|
|
63
|
+
auditEvents: DashboardAuditEvent[];
|
|
64
|
+
/** Layout preset (default: 'command') */
|
|
65
|
+
layout?: DashboardLayout;
|
|
66
|
+
/** Overall position in 3D space */
|
|
67
|
+
position?: [number, number, number];
|
|
68
|
+
/** Enable animations (default: true) */
|
|
69
|
+
animated?: boolean;
|
|
70
|
+
/** Click handler for the shield */
|
|
71
|
+
onShieldClick?: () => void;
|
|
72
|
+
/** Click handler for threats */
|
|
73
|
+
onThreatClick?: (threat: DashboardThreat) => void;
|
|
74
|
+
/** Click handler for audit events */
|
|
75
|
+
onEventClick?: (event: DashboardAuditEvent) => void;
|
|
76
|
+
/** Show connecting lines between components (default: true in command layout) */
|
|
77
|
+
showConnections?: boolean;
|
|
78
|
+
/** Show central status HUD (default: true) */
|
|
79
|
+
showStatusHUD?: boolean;
|
|
80
|
+
/** Color theme */
|
|
81
|
+
theme?: "cyber" | "matrix" | "terminal" | "neon" | "blueprint";
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Internal layout configuration for component positioning
|
|
86
|
+
*/
|
|
87
|
+
export interface LayoutConfig {
|
|
88
|
+
shield: {
|
|
89
|
+
position: [number, number, number];
|
|
90
|
+
radius: number;
|
|
91
|
+
};
|
|
92
|
+
radar: {
|
|
93
|
+
position: [number, number, number];
|
|
94
|
+
radius: number;
|
|
95
|
+
};
|
|
96
|
+
audit: {
|
|
97
|
+
position: [number, number, number];
|
|
98
|
+
length: number;
|
|
99
|
+
orientation: "horizontal" | "vertical";
|
|
100
|
+
};
|
|
101
|
+
statusHUD: {
|
|
102
|
+
position: [number, number, number];
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Layout presets for different dashboard configurations
|
|
108
|
+
*/
|
|
109
|
+
export const LAYOUT_PRESETS: Record<DashboardLayout, LayoutConfig> = {
|
|
110
|
+
command: {
|
|
111
|
+
shield: { position: [0, 1.5, -3], radius: 2 },
|
|
112
|
+
radar: { position: [-4.5, 0, 0], radius: 2.5 },
|
|
113
|
+
audit: { position: [4.5, 0, 0], length: 6, orientation: "vertical" },
|
|
114
|
+
statusHUD: { position: [0, 4.5, -2] },
|
|
115
|
+
},
|
|
116
|
+
monitoring: {
|
|
117
|
+
shield: { position: [-6, 0, 0], radius: 1.5 },
|
|
118
|
+
radar: { position: [0, 0, 0], radius: 3 },
|
|
119
|
+
audit: { position: [6, 0, 0], length: 5, orientation: "vertical" },
|
|
120
|
+
statusHUD: { position: [0, 3.5, 0] },
|
|
121
|
+
},
|
|
122
|
+
compact: {
|
|
123
|
+
shield: { position: [0, 3.5, 0], radius: 1.2 },
|
|
124
|
+
radar: { position: [0, 0, 0], radius: 1.8 },
|
|
125
|
+
audit: { position: [0, -3, 0], length: 5, orientation: "horizontal" },
|
|
126
|
+
statusHUD: { position: [0, 5.5, 0] },
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Security status levels
|
|
132
|
+
*/
|
|
133
|
+
export type SecurityStatus = "SECURE" | "WARNING" | "CRITICAL" | "OFFLINE";
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Theme color configuration
|
|
137
|
+
*/
|
|
138
|
+
export const STATUS_THEME_COLORS: Record<SecurityStatus, string> = {
|
|
139
|
+
SECURE: "#00ff88",
|
|
140
|
+
WARNING: "#ffaa00",
|
|
141
|
+
CRITICAL: "#ff4444",
|
|
142
|
+
OFFLINE: "#666666",
|
|
143
|
+
};
|