@friggframework/devtools 2.0.0--canary.398.7664c46.0 → 2.0.0--canary.400.bed3308.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/frigg-cli/.eslintrc.js +141 -0
- package/frigg-cli/__tests__/jest.config.js +102 -0
- package/frigg-cli/__tests__/unit/commands/build.test.js +483 -0
- package/frigg-cli/__tests__/unit/commands/install.test.js +418 -0
- package/frigg-cli/__tests__/unit/commands/ui.test.js +592 -0
- package/frigg-cli/__tests__/utils/command-tester.js +170 -0
- package/frigg-cli/__tests__/utils/mock-factory.js +270 -0
- package/frigg-cli/__tests__/utils/test-fixtures.js +463 -0
- package/frigg-cli/__tests__/utils/test-setup.js +286 -0
- package/frigg-cli/build-command/index.js +15 -2
- package/frigg-cli/deploy-command/index.js +15 -2
- package/frigg-cli/generate-command/__tests__/generate-command.test.js +312 -0
- package/frigg-cli/generate-command/azure-generator.js +43 -0
- package/frigg-cli/generate-command/gcp-generator.js +47 -0
- package/frigg-cli/generate-command/index.js +350 -0
- package/frigg-cli/generate-command/terraform-generator.js +555 -0
- package/frigg-cli/index.js +66 -4
- package/frigg-cli/install-command/index.js +15 -2
- package/frigg-cli/package.json +75 -0
- package/frigg-cli/start-command/index.js +17 -2
- package/frigg-cli/ui-command/index.js +167 -0
- package/frigg-cli/utils/app-resolver.js +319 -0
- package/frigg-cli/utils/backend-path.js +38 -0
- package/frigg-cli/utils/process-manager.js +199 -0
- package/frigg-cli/utils/repo-detection.js +405 -0
- package/infrastructure/AWS-IAM-CREDENTIAL-NEEDS.md +43 -19
- package/infrastructure/IAM-POLICY-TEMPLATES.md +1 -1
- package/infrastructure/frigg-deployment-iam-stack.yaml +16 -2
- package/infrastructure/iam-generator.js +129 -6
- package/infrastructure/iam-policy-basic.json +29 -5
- package/infrastructure/iam-policy-full.json +28 -5
- package/infrastructure/serverless-template.js +209 -3
- package/infrastructure/serverless-template.test.js +12 -0
- package/management-ui/.eslintrc.js +22 -0
- package/management-ui/README.md +203 -0
- package/management-ui/components.json +21 -0
- package/management-ui/{dist/index.html → index.html} +1 -2
- package/management-ui/merge-conflict-cleaner.py +371 -0
- package/management-ui/package-lock.json +10997 -0
- package/management-ui/package.json +76 -0
- package/management-ui/postcss.config.js +6 -0
- package/management-ui/server/api/backend.js +256 -0
- package/management-ui/server/api/cli.js +315 -0
- package/management-ui/server/api/codegen.js +663 -0
- package/management-ui/server/api/connections.js +857 -0
- package/management-ui/server/api/discovery.js +185 -0
- package/management-ui/server/api/environment/index.js +1 -0
- package/management-ui/server/api/environment/router.js +378 -0
- package/management-ui/server/api/environment.js +328 -0
- package/management-ui/server/api/integrations.js +479 -0
- package/management-ui/server/api/logs.js +248 -0
- package/management-ui/server/api/monitoring.js +282 -0
- package/management-ui/server/api/open-ide.js +31 -0
- package/management-ui/server/api/project.js +553 -0
- package/management-ui/server/api/users/sessions.js +371 -0
- package/management-ui/server/api/users/simulation.js +254 -0
- package/management-ui/server/api/users.js +362 -0
- package/management-ui/server/api-contract.md +275 -0
- package/management-ui/server/index.js +428 -0
- package/management-ui/server/middleware/errorHandler.js +70 -0
- package/management-ui/server/middleware/security.js +32 -0
- package/management-ui/server/processManager.js +296 -0
- package/management-ui/server/server.js +188 -0
- package/management-ui/server/services/aws-monitor.js +413 -0
- package/management-ui/server/services/npm-registry.js +347 -0
- package/management-ui/server/services/template-engine.js +538 -0
- package/management-ui/server/utils/cliIntegration.js +220 -0
- package/management-ui/server/utils/environment/auditLogger.js +471 -0
- package/management-ui/server/utils/environment/awsParameterStore.js +264 -0
- package/management-ui/server/utils/environment/encryption.js +278 -0
- package/management-ui/server/utils/environment/envFileManager.js +286 -0
- package/management-ui/server/utils/import-commonjs.js +28 -0
- package/management-ui/server/utils/response.js +83 -0
- package/management-ui/server/websocket/handler.js +325 -0
- package/management-ui/src/App.jsx +51 -0
- package/management-ui/src/components/AppRouter.jsx +65 -0
- package/management-ui/src/components/Button.jsx +2 -0
- package/management-ui/src/components/Card.jsx +9 -0
- package/management-ui/src/components/EnvironmentCompare.jsx +400 -0
- package/management-ui/src/components/EnvironmentEditor.jsx +372 -0
- package/management-ui/src/components/EnvironmentImportExport.jsx +469 -0
- package/management-ui/src/components/EnvironmentSchema.jsx +491 -0
- package/management-ui/src/components/EnvironmentSecurity.jsx +463 -0
- package/management-ui/src/components/ErrorBoundary.jsx +73 -0
- package/management-ui/src/components/IntegrationCard.jsx +199 -0
- package/management-ui/src/components/IntegrationCardEnhanced.jsx +490 -0
- package/management-ui/src/components/IntegrationExplorer.jsx +379 -0
- package/management-ui/src/components/IntegrationStatus.jsx +235 -0
- package/management-ui/src/components/Layout.jsx +250 -0
- package/management-ui/src/components/LoadingSpinner.jsx +45 -0
- package/management-ui/src/components/RepositoryPicker.jsx +248 -0
- package/management-ui/src/components/SessionMonitor.jsx +255 -0
- package/management-ui/src/components/StatusBadge.jsx +70 -0
- package/management-ui/src/components/UserContextSwitcher.jsx +154 -0
- package/management-ui/src/components/UserSimulation.jsx +299 -0
- package/management-ui/src/components/Welcome.jsx +434 -0
- package/management-ui/src/components/codegen/APIEndpointGenerator.jsx +637 -0
- package/management-ui/src/components/codegen/APIModuleSelector.jsx +227 -0
- package/management-ui/src/components/codegen/CodeGenerationWizard.jsx +247 -0
- package/management-ui/src/components/codegen/CodePreviewEditor.jsx +316 -0
- package/management-ui/src/components/codegen/DynamicModuleForm.jsx +271 -0
- package/management-ui/src/components/codegen/FormBuilder.jsx +737 -0
- package/management-ui/src/components/codegen/IntegrationGenerator.jsx +855 -0
- package/management-ui/src/components/codegen/ProjectScaffoldWizard.jsx +797 -0
- package/management-ui/src/components/codegen/SchemaBuilder.jsx +303 -0
- package/management-ui/src/components/codegen/TemplateSelector.jsx +586 -0
- package/management-ui/src/components/codegen/index.js +10 -0
- package/management-ui/src/components/connections/ConnectionConfigForm.jsx +362 -0
- package/management-ui/src/components/connections/ConnectionHealthMonitor.jsx +182 -0
- package/management-ui/src/components/connections/ConnectionTester.jsx +200 -0
- package/management-ui/src/components/connections/EntityRelationshipMapper.jsx +292 -0
- package/management-ui/src/components/connections/OAuthFlow.jsx +204 -0
- package/management-ui/src/components/connections/index.js +5 -0
- package/management-ui/src/components/index.js +21 -0
- package/management-ui/src/components/monitoring/APIGatewayMetrics.jsx +222 -0
- package/management-ui/src/components/monitoring/LambdaMetrics.jsx +169 -0
- package/management-ui/src/components/monitoring/MetricsChart.jsx +197 -0
- package/management-ui/src/components/monitoring/MonitoringDashboard.jsx +393 -0
- package/management-ui/src/components/monitoring/SQSMetrics.jsx +246 -0
- package/management-ui/src/components/monitoring/index.js +6 -0
- package/management-ui/src/components/monitoring/monitoring.css +218 -0
- package/management-ui/src/components/theme-provider.jsx +52 -0
- package/management-ui/src/components/theme-toggle.jsx +39 -0
- package/management-ui/src/components/ui/badge.tsx +36 -0
- package/management-ui/src/components/ui/button.test.jsx +56 -0
- package/management-ui/src/components/ui/button.tsx +57 -0
- package/management-ui/src/components/ui/card.tsx +76 -0
- package/management-ui/src/components/ui/dropdown-menu.tsx +199 -0
- package/management-ui/src/components/ui/select.tsx +157 -0
- package/management-ui/src/components/ui/skeleton.jsx +15 -0
- package/management-ui/src/hooks/useFrigg.jsx +387 -0
- package/management-ui/src/hooks/useSocket.jsx +58 -0
- package/management-ui/src/index.css +194 -0
- package/management-ui/src/lib/utils.ts +6 -0
- package/management-ui/src/main.jsx +10 -0
- package/management-ui/src/pages/CodeGeneration.jsx +14 -0
- package/management-ui/src/pages/Connections.jsx +252 -0
- package/management-ui/src/pages/ConnectionsEnhanced.jsx +427 -0
- package/management-ui/src/pages/Dashboard.jsx +311 -0
- package/management-ui/src/pages/Environment.jsx +314 -0
- package/management-ui/src/pages/IntegrationConfigure.jsx +544 -0
- package/management-ui/src/pages/IntegrationDiscovery.jsx +479 -0
- package/management-ui/src/pages/IntegrationTest.jsx +494 -0
- package/management-ui/src/pages/Integrations.jsx +254 -0
- package/management-ui/src/pages/Monitoring.jsx +17 -0
- package/management-ui/src/pages/Simulation.jsx +155 -0
- package/management-ui/src/pages/Users.jsx +492 -0
- package/management-ui/src/services/api.js +41 -0
- package/management-ui/src/services/apiModuleService.js +193 -0
- package/management-ui/src/services/websocket-handlers.js +120 -0
- package/management-ui/src/test/api/project.test.js +273 -0
- package/management-ui/src/test/components/Welcome.test.jsx +378 -0
- package/management-ui/src/test/mocks/server.js +178 -0
- package/management-ui/src/test/setup.js +61 -0
- package/management-ui/src/test/utils/test-utils.jsx +134 -0
- package/management-ui/src/utils/repository.js +98 -0
- package/management-ui/src/utils/repository.test.js +118 -0
- package/management-ui/src/workflows/phase2-integration-workflows.js +884 -0
- package/management-ui/tailwind.config.js +63 -0
- package/management-ui/tsconfig.json +37 -0
- package/management-ui/tsconfig.node.json +10 -0
- package/management-ui/vite.config.js +26 -0
- package/management-ui/vitest.config.js +38 -0
- package/package.json +5 -5
- package/management-ui/dist/assets/index-CbM64Oba.js +0 -1221
- package/management-ui/dist/assets/index-CkvseXTC.css +0 -1
- /package/management-ui/{dist/assets/FriggLogo-B7Xx8ZW1.svg → src/assets/FriggLogo.svg} +0 -0
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
import { EventEmitter } from 'events'
|
|
2
|
+
|
|
3
|
+
class WebSocketHandler extends EventEmitter {
|
|
4
|
+
constructor() {
|
|
5
|
+
super();
|
|
6
|
+
this.clients = new Map();
|
|
7
|
+
this.subscriptions = new Map();
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
setupWebSocket(wss) {
|
|
11
|
+
wss.on('connection', (ws, req) => {
|
|
12
|
+
const clientId = this.generateClientId();
|
|
13
|
+
|
|
14
|
+
console.log(`New WebSocket connection: ${clientId}`);
|
|
15
|
+
|
|
16
|
+
// Store client connection
|
|
17
|
+
this.clients.set(clientId, {
|
|
18
|
+
ws,
|
|
19
|
+
subscriptions: new Set(),
|
|
20
|
+
connectedAt: new Date()
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
// Send welcome message
|
|
24
|
+
this.sendToClient(clientId, {
|
|
25
|
+
type: 'connection',
|
|
26
|
+
data: {
|
|
27
|
+
clientId,
|
|
28
|
+
message: 'Connected to Frigg Management Server',
|
|
29
|
+
timestamp: new Date().toISOString()
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// Handle incoming messages
|
|
34
|
+
ws.on('message', (message) => {
|
|
35
|
+
try {
|
|
36
|
+
const data = JSON.parse(message.toString());
|
|
37
|
+
this.handleMessage(clientId, data);
|
|
38
|
+
} catch (error) {
|
|
39
|
+
console.error('Invalid WebSocket message:', error);
|
|
40
|
+
this.sendToClient(clientId, {
|
|
41
|
+
type: 'error',
|
|
42
|
+
data: {
|
|
43
|
+
message: 'Invalid message format',
|
|
44
|
+
timestamp: new Date().toISOString()
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
// Handle client disconnect
|
|
51
|
+
ws.on('close', () => {
|
|
52
|
+
console.log(`Client disconnected: ${clientId}`);
|
|
53
|
+
this.handleDisconnect(clientId);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// Handle errors
|
|
57
|
+
ws.on('error', (error) => {
|
|
58
|
+
console.error(`WebSocket error for client ${clientId}:`, error);
|
|
59
|
+
this.handleDisconnect(clientId);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// Ping to keep connection alive
|
|
63
|
+
const pingInterval = setInterval(() => {
|
|
64
|
+
if (ws.readyState === ws.OPEN) {
|
|
65
|
+
ws.ping();
|
|
66
|
+
} else {
|
|
67
|
+
clearInterval(pingInterval);
|
|
68
|
+
}
|
|
69
|
+
}, 30000);
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
handleMessage(clientId, message) {
|
|
74
|
+
const { type, data } = message;
|
|
75
|
+
|
|
76
|
+
switch (type) {
|
|
77
|
+
case 'subscribe':
|
|
78
|
+
this.handleSubscribe(clientId, data);
|
|
79
|
+
break;
|
|
80
|
+
case 'unsubscribe':
|
|
81
|
+
this.handleUnsubscribe(clientId, data);
|
|
82
|
+
break;
|
|
83
|
+
case 'ping':
|
|
84
|
+
this.sendToClient(clientId, { type: 'pong', data: { timestamp: new Date().toISOString() } });
|
|
85
|
+
break;
|
|
86
|
+
default:
|
|
87
|
+
// Emit custom events for other components to handle
|
|
88
|
+
this.emit(type, { clientId, data });
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
handleSubscribe(clientId, data) {
|
|
93
|
+
const { topics } = data;
|
|
94
|
+
const client = this.clients.get(clientId);
|
|
95
|
+
|
|
96
|
+
if (!client) return;
|
|
97
|
+
|
|
98
|
+
topics.forEach(topic => {
|
|
99
|
+
client.subscriptions.add(topic);
|
|
100
|
+
|
|
101
|
+
if (!this.subscriptions.has(topic)) {
|
|
102
|
+
this.subscriptions.set(topic, new Set());
|
|
103
|
+
}
|
|
104
|
+
this.subscriptions.get(topic).add(clientId);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
this.sendToClient(clientId, {
|
|
108
|
+
type: 'subscribed',
|
|
109
|
+
data: {
|
|
110
|
+
topics,
|
|
111
|
+
timestamp: new Date().toISOString()
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
handleUnsubscribe(clientId, data) {
|
|
117
|
+
const { topics } = data;
|
|
118
|
+
const client = this.clients.get(clientId);
|
|
119
|
+
|
|
120
|
+
if (!client) return;
|
|
121
|
+
|
|
122
|
+
topics.forEach(topic => {
|
|
123
|
+
client.subscriptions.delete(topic);
|
|
124
|
+
|
|
125
|
+
const topicSubscribers = this.subscriptions.get(topic);
|
|
126
|
+
if (topicSubscribers) {
|
|
127
|
+
topicSubscribers.delete(clientId);
|
|
128
|
+
if (topicSubscribers.size === 0) {
|
|
129
|
+
this.subscriptions.delete(topic);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
this.sendToClient(clientId, {
|
|
135
|
+
type: 'unsubscribed',
|
|
136
|
+
data: {
|
|
137
|
+
topics,
|
|
138
|
+
timestamp: new Date().toISOString()
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
handleDisconnect(clientId) {
|
|
144
|
+
const client = this.clients.get(clientId);
|
|
145
|
+
|
|
146
|
+
if (!client) return;
|
|
147
|
+
|
|
148
|
+
// Remove from all topic subscriptions
|
|
149
|
+
client.subscriptions.forEach(topic => {
|
|
150
|
+
const topicSubscribers = this.subscriptions.get(topic);
|
|
151
|
+
if (topicSubscribers) {
|
|
152
|
+
topicSubscribers.delete(clientId);
|
|
153
|
+
if (topicSubscribers.size === 0) {
|
|
154
|
+
this.subscriptions.delete(topic);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
// Remove client
|
|
160
|
+
this.clients.delete(clientId);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
sendToClient(clientId, message) {
|
|
164
|
+
const client = this.clients.get(clientId);
|
|
165
|
+
|
|
166
|
+
if (client && client.ws.readyState === client.ws.OPEN) {
|
|
167
|
+
client.ws.send(JSON.stringify(message));
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
broadcast(topic, message) {
|
|
172
|
+
const subscribers = this.subscriptions.get(topic);
|
|
173
|
+
|
|
174
|
+
if (!subscribers) return;
|
|
175
|
+
|
|
176
|
+
const broadcastMessage = {
|
|
177
|
+
type: 'broadcast',
|
|
178
|
+
topic,
|
|
179
|
+
data: message,
|
|
180
|
+
timestamp: new Date().toISOString()
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
subscribers.forEach(clientId => {
|
|
184
|
+
this.sendToClient(clientId, broadcastMessage);
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
broadcastToAll(message) {
|
|
189
|
+
const broadcastMessage = {
|
|
190
|
+
type: 'broadcast',
|
|
191
|
+
data: message,
|
|
192
|
+
timestamp: new Date().toISOString()
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
this.clients.forEach((client, clientId) => {
|
|
196
|
+
this.sendToClient(clientId, broadcastMessage);
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
generateClientId() {
|
|
201
|
+
return `client_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// Create singleton instance
|
|
206
|
+
const wsHandler = new WebSocketHandler()
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Setup WebSocket handling for Socket.IO server
|
|
210
|
+
* @param {Server} io - Socket.IO server instance
|
|
211
|
+
*/
|
|
212
|
+
function setupWebSocket(io) {
|
|
213
|
+
io.on('connection', (socket) => {
|
|
214
|
+
const clientId = wsHandler.generateClientId()
|
|
215
|
+
|
|
216
|
+
console.log(`New WebSocket connection: ${clientId}`)
|
|
217
|
+
|
|
218
|
+
// Store client connection
|
|
219
|
+
wsHandler.clients.set(clientId, {
|
|
220
|
+
socket,
|
|
221
|
+
subscriptions: new Set(),
|
|
222
|
+
connectedAt: new Date()
|
|
223
|
+
})
|
|
224
|
+
|
|
225
|
+
// Send welcome message
|
|
226
|
+
socket.emit('connection', {
|
|
227
|
+
clientId,
|
|
228
|
+
message: 'Connected to Frigg Management Server',
|
|
229
|
+
timestamp: new Date().toISOString()
|
|
230
|
+
})
|
|
231
|
+
|
|
232
|
+
// Handle incoming messages
|
|
233
|
+
socket.on('message', (data) => {
|
|
234
|
+
try {
|
|
235
|
+
wsHandler.handleMessage(clientId, data)
|
|
236
|
+
} catch (error) {
|
|
237
|
+
console.error('Invalid WebSocket message:', error)
|
|
238
|
+
socket.emit('error', {
|
|
239
|
+
message: 'Invalid message format',
|
|
240
|
+
timestamp: new Date().toISOString()
|
|
241
|
+
})
|
|
242
|
+
}
|
|
243
|
+
})
|
|
244
|
+
|
|
245
|
+
// Handle subscriptions
|
|
246
|
+
socket.on('subscribe', (data) => {
|
|
247
|
+
wsHandler.handleSubscribe(clientId, data)
|
|
248
|
+
})
|
|
249
|
+
|
|
250
|
+
socket.on('unsubscribe', (data) => {
|
|
251
|
+
wsHandler.handleUnsubscribe(clientId, data)
|
|
252
|
+
})
|
|
253
|
+
|
|
254
|
+
// Handle ping
|
|
255
|
+
socket.on('ping', () => {
|
|
256
|
+
socket.emit('pong', { timestamp: new Date().toISOString() })
|
|
257
|
+
})
|
|
258
|
+
|
|
259
|
+
// Handle client disconnect
|
|
260
|
+
socket.on('disconnect', () => {
|
|
261
|
+
console.log(`Client disconnected: ${clientId}`)
|
|
262
|
+
wsHandler.handleDisconnect(clientId)
|
|
263
|
+
})
|
|
264
|
+
|
|
265
|
+
// Handle errors
|
|
266
|
+
socket.on('error', (error) => {
|
|
267
|
+
console.error(`WebSocket error for client ${clientId}:`, error)
|
|
268
|
+
wsHandler.handleDisconnect(clientId)
|
|
269
|
+
})
|
|
270
|
+
|
|
271
|
+
// Keep-alive ping
|
|
272
|
+
const pingInterval = setInterval(() => {
|
|
273
|
+
if (socket.connected) {
|
|
274
|
+
socket.emit('ping', { timestamp: new Date().toISOString() })
|
|
275
|
+
} else {
|
|
276
|
+
clearInterval(pingInterval)
|
|
277
|
+
}
|
|
278
|
+
}, 30000)
|
|
279
|
+
})
|
|
280
|
+
|
|
281
|
+
// Store io instance for broadcasting
|
|
282
|
+
wsHandler.io = io
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// Enhanced handler methods
|
|
286
|
+
WebSocketHandler.prototype.sendToClient = function(clientId, message) {
|
|
287
|
+
const client = this.clients.get(clientId)
|
|
288
|
+
|
|
289
|
+
if (client && client.socket.connected) {
|
|
290
|
+
client.socket.emit('message', message)
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
WebSocketHandler.prototype.broadcast = function(topic, message) {
|
|
295
|
+
const subscribers = this.subscriptions.get(topic)
|
|
296
|
+
|
|
297
|
+
if (!subscribers) {
|
|
298
|
+
// If no specific subscribers, broadcast to all connected clients
|
|
299
|
+
this.broadcastToAll({ topic, ...message })
|
|
300
|
+
return
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
const broadcastMessage = {
|
|
304
|
+
type: 'broadcast',
|
|
305
|
+
topic,
|
|
306
|
+
data: message,
|
|
307
|
+
timestamp: new Date().toISOString()
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
subscribers.forEach(clientId => {
|
|
311
|
+
this.sendToClient(clientId, broadcastMessage)
|
|
312
|
+
})
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
WebSocketHandler.prototype.broadcastToAll = function(message) {
|
|
316
|
+
if (this.io) {
|
|
317
|
+
this.io.emit('broadcast', {
|
|
318
|
+
data: message,
|
|
319
|
+
timestamp: new Date().toISOString()
|
|
320
|
+
})
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// Export setup function and handler instance
|
|
325
|
+
export { setupWebSocket, wsHandler }
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom'
|
|
3
|
+
import Layout from './components/Layout'
|
|
4
|
+
import Dashboard from './pages/Dashboard'
|
|
5
|
+
import Integrations from './pages/Integrations'
|
|
6
|
+
import IntegrationDiscovery from './pages/IntegrationDiscovery'
|
|
7
|
+
import IntegrationConfigure from './pages/IntegrationConfigure'
|
|
8
|
+
import IntegrationTest from './pages/IntegrationTest'
|
|
9
|
+
import Environment from './pages/Environment'
|
|
10
|
+
import Users from './pages/Users'
|
|
11
|
+
import ConnectionsEnhanced from './pages/ConnectionsEnhanced'
|
|
12
|
+
import Simulation from './pages/Simulation'
|
|
13
|
+
import Monitoring from './pages/Monitoring'
|
|
14
|
+
import CodeGeneration from './pages/CodeGeneration'
|
|
15
|
+
import ErrorBoundary from './components/ErrorBoundary'
|
|
16
|
+
import { SocketProvider } from './hooks/useSocket'
|
|
17
|
+
import { FriggProvider } from './hooks/useFrigg'
|
|
18
|
+
import { ThemeProvider } from './components/theme-provider'
|
|
19
|
+
|
|
20
|
+
function App() {
|
|
21
|
+
return (
|
|
22
|
+
<ErrorBoundary>
|
|
23
|
+
<ThemeProvider defaultTheme="system">
|
|
24
|
+
<SocketProvider>
|
|
25
|
+
<FriggProvider>
|
|
26
|
+
<Router>
|
|
27
|
+
<Routes>
|
|
28
|
+
<Route path="/" element={<Layout />}>
|
|
29
|
+
<Route index element={<Navigate to="/dashboard" replace />} />
|
|
30
|
+
<Route path="dashboard" element={<Dashboard />} />
|
|
31
|
+
<Route path="integrations" element={<Integrations />} />
|
|
32
|
+
<Route path="integrations/discover" element={<IntegrationDiscovery />} />
|
|
33
|
+
<Route path="integrations/:integrationName/configure" element={<IntegrationConfigure />} />
|
|
34
|
+
<Route path="integrations/:integrationName/test" element={<IntegrationTest />} />
|
|
35
|
+
<Route path="environment" element={<Environment />} />
|
|
36
|
+
<Route path="users" element={<Users />} />
|
|
37
|
+
<Route path="connections" element={<ConnectionsEnhanced />} />
|
|
38
|
+
<Route path="simulation" element={<Simulation />} />
|
|
39
|
+
<Route path="monitoring" element={<Monitoring />} />
|
|
40
|
+
<Route path="code-generation" element={<CodeGeneration />} />
|
|
41
|
+
</Route>
|
|
42
|
+
</Routes>
|
|
43
|
+
</Router>
|
|
44
|
+
</FriggProvider>
|
|
45
|
+
</SocketProvider>
|
|
46
|
+
</ThemeProvider>
|
|
47
|
+
</ErrorBoundary>
|
|
48
|
+
)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export default App
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { Routes, Route, Navigate, useLocation } from 'react-router-dom'
|
|
3
|
+
import { useFrigg } from '../hooks/useFrigg'
|
|
4
|
+
import Layout from './Layout'
|
|
5
|
+
import Welcome from './Welcome'
|
|
6
|
+
import Dashboard from '../pages/Dashboard'
|
|
7
|
+
import Integrations from '../pages/Integrations'
|
|
8
|
+
import IntegrationDiscovery from '../pages/IntegrationDiscovery'
|
|
9
|
+
import IntegrationConfigure from '../pages/IntegrationConfigure'
|
|
10
|
+
import IntegrationTest from '../pages/IntegrationTest'
|
|
11
|
+
import Environment from '../pages/Environment'
|
|
12
|
+
import Users from '../pages/Users'
|
|
13
|
+
import ConnectionsEnhanced from '../pages/ConnectionsEnhanced'
|
|
14
|
+
import Simulation from '../pages/Simulation'
|
|
15
|
+
import Monitoring from '../pages/Monitoring'
|
|
16
|
+
import CodeGeneration from '../pages/CodeGeneration'
|
|
17
|
+
|
|
18
|
+
export default function AppRouter() {
|
|
19
|
+
const { currentRepository, isLoading } = useFrigg()
|
|
20
|
+
const location = useLocation()
|
|
21
|
+
|
|
22
|
+
// Show loading screen while initializing
|
|
23
|
+
if (isLoading) {
|
|
24
|
+
return (
|
|
25
|
+
<div className="min-h-screen bg-background flex items-center justify-center">
|
|
26
|
+
<div className="text-center">
|
|
27
|
+
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-primary mx-auto mb-4"></div>
|
|
28
|
+
<p className="text-muted-foreground">Initializing Frigg Management UI...</p>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Always show welcome screen if no repository is selected
|
|
35
|
+
if (!currentRepository) {
|
|
36
|
+
return <Welcome />
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// If we have a repository and we're still on welcome (shouldn't happen with new flow)
|
|
40
|
+
// or we're on root, redirect to dashboard
|
|
41
|
+
if (currentRepository && (location.pathname === '/welcome' || location.pathname === '/')) {
|
|
42
|
+
return <Navigate to="/dashboard" replace />
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Normal routing with Layout for all other cases
|
|
46
|
+
return (
|
|
47
|
+
<Layout>
|
|
48
|
+
<Routes>
|
|
49
|
+
<Route path="/welcome" element={<Welcome />} />
|
|
50
|
+
<Route path="/" element={<Navigate to="/dashboard" />} />
|
|
51
|
+
<Route path="/dashboard" element={<Dashboard />} />
|
|
52
|
+
<Route path="/integrations" element={<Integrations />} />
|
|
53
|
+
<Route path="/integrations/discover" element={<IntegrationDiscovery />} />
|
|
54
|
+
<Route path="/integrations/:integrationName/configure" element={<IntegrationConfigure />} />
|
|
55
|
+
<Route path="/integrations/:integrationName/test" element={<IntegrationTest />} />
|
|
56
|
+
<Route path="/environment" element={<Environment />} />
|
|
57
|
+
<Route path="/users" element={<Users />} />
|
|
58
|
+
<Route path="/connections" element={<ConnectionsEnhanced />} />
|
|
59
|
+
<Route path="/simulation" element={<Simulation />} />
|
|
60
|
+
<Route path="/monitoring" element={<Monitoring />} />
|
|
61
|
+
<Route path="/code-generation" element={<CodeGeneration />} />
|
|
62
|
+
</Routes>
|
|
63
|
+
</Layout>
|
|
64
|
+
)
|
|
65
|
+
}
|