@friggframework/devtools 2.0.0-next.4 → 2.0.0-next.41
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 +54 -0
- package/frigg-cli/deploy-command/index.js +175 -0
- 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 +332 -0
- package/frigg-cli/generate-command/terraform-generator.js +555 -0
- package/frigg-cli/generate-iam-command.js +115 -0
- package/frigg-cli/index.js +47 -1
- package/frigg-cli/index.test.js +1 -4
- package/frigg-cli/init-command/backend-first-handler.js +756 -0
- package/frigg-cli/init-command/index.js +93 -0
- package/frigg-cli/init-command/template-handler.js +143 -0
- package/frigg-cli/install-command/index.js +1 -4
- package/frigg-cli/package.json +51 -0
- package/frigg-cli/start-command/index.js +30 -4
- package/frigg-cli/start-command/start-command.test.js +155 -0
- package/frigg-cli/test/init-command.test.js +180 -0
- package/frigg-cli/test/npm-registry.test.js +319 -0
- package/frigg-cli/ui-command/index.js +154 -0
- package/frigg-cli/utils/app-resolver.js +319 -0
- package/frigg-cli/utils/backend-path.js +16 -17
- package/frigg-cli/utils/npm-registry.js +167 -0
- package/frigg-cli/utils/process-manager.js +199 -0
- package/frigg-cli/utils/repo-detection.js +405 -0
- package/infrastructure/DEPLOYMENT-INSTRUCTIONS.md +268 -0
- package/infrastructure/GENERATE-IAM-DOCS.md +278 -0
- package/infrastructure/IAM-POLICY-TEMPLATES.md +176 -0
- package/infrastructure/README.md +443 -0
- package/infrastructure/WEBSOCKET-CONFIGURATION.md +105 -0
- package/infrastructure/__tests__/fixtures/mock-aws-resources.js +391 -0
- package/infrastructure/__tests__/helpers/test-utils.js +277 -0
- package/infrastructure/aws-discovery.js +1176 -0
- package/infrastructure/aws-discovery.test.js +1220 -0
- package/infrastructure/build-time-discovery.js +206 -0
- package/infrastructure/build-time-discovery.test.js +378 -0
- package/infrastructure/create-frigg-infrastructure.js +3 -5
- package/infrastructure/env-validator.js +77 -0
- package/infrastructure/frigg-deployment-iam-stack.yaml +401 -0
- package/infrastructure/iam-generator.js +836 -0
- package/infrastructure/iam-generator.test.js +172 -0
- package/infrastructure/iam-policy-basic.json +218 -0
- package/infrastructure/iam-policy-full.json +288 -0
- package/infrastructure/integration.test.js +383 -0
- package/infrastructure/run-discovery.js +110 -0
- package/infrastructure/serverless-template.js +1493 -138
- package/infrastructure/serverless-template.test.js +1804 -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/docs/phase2-integration-guide.md +320 -0
- package/management-ui/index.html +13 -0
- package/management-ui/package-lock.json +16517 -0
- package/management-ui/package.json +76 -0
- package/management-ui/packages/devtools/frigg-cli/ui-command/index.js +302 -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 +876 -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 +1029 -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 +873 -0
- package/management-ui/server/middleware/errorHandler.js +93 -0
- package/management-ui/server/middleware/security.js +32 -0
- package/management-ui/server/processManager.js +296 -0
- package/management-ui/server/server.js +346 -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 +109 -0
- package/management-ui/src/assets/FriggLogo.svg +1 -0
- package/management-ui/src/components/AppRouter.jsx +65 -0
- package/management-ui/src/components/Button.jsx +70 -0
- package/management-ui/src/components/Card.jsx +97 -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 +481 -0
- package/management-ui/src/components/IntegrationCardEnhanced.jsx +770 -0
- package/management-ui/src/components/IntegrationExplorer.jsx +379 -0
- package/management-ui/src/components/IntegrationStatus.jsx +336 -0
- package/management-ui/src/components/Layout.jsx +716 -0
- package/management-ui/src/components/LoadingSpinner.jsx +113 -0
- package/management-ui/src/components/RepositoryPicker.jsx +248 -0
- package/management-ui/src/components/SessionMonitor.jsx +350 -0
- package/management-ui/src/components/StatusBadge.jsx +208 -0
- package/management-ui/src/components/UserContextSwitcher.jsx +212 -0
- package/management-ui/src/components/UserSimulation.jsx +327 -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 +601 -0
- package/management-ui/src/hooks/useSocket.jsx +58 -0
- package/management-ui/src/index.css +193 -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 +633 -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 +669 -0
- package/management-ui/src/pages/IntegrationDiscovery.jsx +567 -0
- package/management-ui/src/pages/IntegrationTest.jsx +742 -0
- package/management-ui/src/pages/Integrations.jsx +253 -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 +20 -9
- package/infrastructure/app-handler-helpers.js +0 -57
- package/infrastructure/backend-utils.js +0 -90
- package/infrastructure/routers/auth.js +0 -26
- package/infrastructure/routers/integration-defined-routers.js +0 -37
- package/infrastructure/routers/middleware/loadUser.js +0 -15
- package/infrastructure/routers/middleware/requireLoggedInUser.js +0 -12
- package/infrastructure/routers/user.js +0 -41
- package/infrastructure/routers/websocket.js +0 -55
- package/infrastructure/workers/integration-defined-workers.js +0 -24
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import React, { useState, useRef, useEffect } from 'react'
|
|
2
|
+
import { User, ChevronDown, UserCircle } from 'lucide-react'
|
|
3
|
+
<<<<<<< HEAD
|
|
4
|
+
<<<<<<< HEAD
|
|
5
|
+
import { cn } from '../lib/utils'
|
|
6
|
+
=======
|
|
7
|
+
<<<<<<< HEAD
|
|
8
|
+
<<<<<<< HEAD
|
|
9
|
+
import { cn } from '../lib/utils'
|
|
10
|
+
=======
|
|
11
|
+
import { cn } from '../utils/cn'
|
|
12
|
+
>>>>>>> 652520a5 (Claude Flow RFC related development)
|
|
13
|
+
=======
|
|
14
|
+
import { cn } from '../lib/utils'
|
|
15
|
+
>>>>>>> f153939e (refactor: clean up CLI help display and remove unused dependencies)
|
|
16
|
+
>>>>>>> 860052b4 (feat: integrate complete management-ui and additional features)
|
|
17
|
+
=======
|
|
18
|
+
import { cn } from '../lib/utils'
|
|
19
|
+
>>>>>>> 7e97f01c (fix: resolve ui-command merge conflicts and update package.json)
|
|
20
|
+
|
|
21
|
+
const UserContextSwitcher = ({ users, currentUser, onUserSwitch }) => {
|
|
22
|
+
const [isOpen, setIsOpen] = useState(false)
|
|
23
|
+
const dropdownRef = useRef(null)
|
|
24
|
+
|
|
25
|
+
// Close dropdown when clicking outside
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
const handleClickOutside = (event) => {
|
|
28
|
+
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
|
|
29
|
+
setIsOpen(false)
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
document.addEventListener('mousedown', handleClickOutside)
|
|
34
|
+
return () => document.removeEventListener('mousedown', handleClickOutside)
|
|
35
|
+
}, [])
|
|
36
|
+
|
|
37
|
+
const handleUserSelect = (user) => {
|
|
38
|
+
onUserSwitch(user)
|
|
39
|
+
setIsOpen(false)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const clearContext = () => {
|
|
43
|
+
onUserSwitch(null)
|
|
44
|
+
setIsOpen(false)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<div className="relative" ref={dropdownRef}>
|
|
49
|
+
<button
|
|
50
|
+
onClick={() => setIsOpen(!isOpen)}
|
|
51
|
+
className={cn(
|
|
52
|
+
"flex items-center space-x-2 px-3 py-2 rounded-md text-sm font-medium transition-colors",
|
|
53
|
+
<<<<<<< HEAD
|
|
54
|
+
<<<<<<< HEAD
|
|
55
|
+
currentUser
|
|
56
|
+
? "bg-blue-100 text-blue-700 hover:bg-blue-200"
|
|
57
|
+
=======
|
|
58
|
+
<<<<<<< HEAD
|
|
59
|
+
currentUser
|
|
60
|
+
? "bg-blue-100 text-blue-700 hover:bg-blue-200"
|
|
61
|
+
=======
|
|
62
|
+
currentUser
|
|
63
|
+
? "bg-blue-100 text-blue-700 hover:bg-blue-200"
|
|
64
|
+
>>>>>>> 652520a5 (Claude Flow RFC related development)
|
|
65
|
+
>>>>>>> 860052b4 (feat: integrate complete management-ui and additional features)
|
|
66
|
+
=======
|
|
67
|
+
currentUser
|
|
68
|
+
? "bg-blue-100 text-blue-700 hover:bg-blue-200"
|
|
69
|
+
>>>>>>> 7e97f01c (fix: resolve ui-command merge conflicts and update package.json)
|
|
70
|
+
: "bg-gray-100 text-gray-700 hover:bg-gray-200"
|
|
71
|
+
)}
|
|
72
|
+
>
|
|
73
|
+
{currentUser ? (
|
|
74
|
+
<>
|
|
75
|
+
<div className="w-6 h-6 rounded-full bg-blue-600 text-white flex items-center justify-center text-xs">
|
|
76
|
+
{currentUser.firstName?.[0]}{currentUser.lastName?.[0]}
|
|
77
|
+
</div>
|
|
78
|
+
<span className="max-w-[150px] truncate">
|
|
79
|
+
{currentUser.firstName} {currentUser.lastName}
|
|
80
|
+
</span>
|
|
81
|
+
</>
|
|
82
|
+
) : (
|
|
83
|
+
<>
|
|
84
|
+
<UserCircle size={20} />
|
|
85
|
+
<span>No User Context</span>
|
|
86
|
+
</>
|
|
87
|
+
)}
|
|
88
|
+
<ChevronDown size={16} className={cn(
|
|
89
|
+
"transition-transform",
|
|
90
|
+
isOpen && "rotate-180"
|
|
91
|
+
)} />
|
|
92
|
+
</button>
|
|
93
|
+
|
|
94
|
+
{/* Dropdown */}
|
|
95
|
+
{isOpen && (
|
|
96
|
+
<div className="absolute right-0 mt-2 w-72 bg-white rounded-lg shadow-lg border border-gray-200 z-50">
|
|
97
|
+
<div className="p-3 border-b border-gray-200">
|
|
98
|
+
<h3 className="text-sm font-semibold text-gray-900">Switch User Context</h3>
|
|
99
|
+
<p className="text-xs text-gray-500 mt-1">
|
|
100
|
+
Simulate integration behavior as different users
|
|
101
|
+
</p>
|
|
102
|
+
</div>
|
|
103
|
+
|
|
104
|
+
<div className="max-h-64 overflow-y-auto">
|
|
105
|
+
{users.length === 0 ? (
|
|
106
|
+
<div className="p-4 text-center text-sm text-gray-500">
|
|
107
|
+
No users available. Create a test user first.
|
|
108
|
+
</div>
|
|
109
|
+
) : (
|
|
110
|
+
<>
|
|
111
|
+
{currentUser && (
|
|
112
|
+
<button
|
|
113
|
+
onClick={clearContext}
|
|
114
|
+
className="w-full text-left px-4 py-3 hover:bg-gray-50 flex items-center space-x-3 border-b border-gray-100"
|
|
115
|
+
>
|
|
116
|
+
<div className="w-8 h-8 rounded-full bg-gray-300 flex items-center justify-center">
|
|
117
|
+
<User size={16} className="text-gray-600" />
|
|
118
|
+
</div>
|
|
119
|
+
<div>
|
|
120
|
+
<p className="text-sm font-medium text-gray-900">Clear Context</p>
|
|
121
|
+
<p className="text-xs text-gray-500">Use default system context</p>
|
|
122
|
+
</div>
|
|
123
|
+
</button>
|
|
124
|
+
)}
|
|
125
|
+
<<<<<<< HEAD
|
|
126
|
+
<<<<<<< HEAD
|
|
127
|
+
|
|
128
|
+
=======
|
|
129
|
+
<<<<<<< HEAD
|
|
130
|
+
|
|
131
|
+
=======
|
|
132
|
+
|
|
133
|
+
>>>>>>> 652520a5 (Claude Flow RFC related development)
|
|
134
|
+
>>>>>>> 860052b4 (feat: integrate complete management-ui and additional features)
|
|
135
|
+
=======
|
|
136
|
+
|
|
137
|
+
>>>>>>> 7e97f01c (fix: resolve ui-command merge conflicts and update package.json)
|
|
138
|
+
{users.map((user) => (
|
|
139
|
+
<button
|
|
140
|
+
key={user.id}
|
|
141
|
+
onClick={() => handleUserSelect(user)}
|
|
142
|
+
className={cn(
|
|
143
|
+
"w-full text-left px-4 py-3 hover:bg-gray-50 flex items-center space-x-3",
|
|
144
|
+
currentUser?.id === user.id && "bg-blue-50"
|
|
145
|
+
)}
|
|
146
|
+
>
|
|
147
|
+
<div className={cn(
|
|
148
|
+
"w-8 h-8 rounded-full flex items-center justify-center text-xs font-medium",
|
|
149
|
+
<<<<<<< HEAD
|
|
150
|
+
<<<<<<< HEAD
|
|
151
|
+
currentUser?.id === user.id
|
|
152
|
+
? "bg-blue-600 text-white"
|
|
153
|
+
=======
|
|
154
|
+
<<<<<<< HEAD
|
|
155
|
+
currentUser?.id === user.id
|
|
156
|
+
? "bg-blue-600 text-white"
|
|
157
|
+
=======
|
|
158
|
+
currentUser?.id === user.id
|
|
159
|
+
? "bg-blue-600 text-white"
|
|
160
|
+
>>>>>>> 652520a5 (Claude Flow RFC related development)
|
|
161
|
+
>>>>>>> 860052b4 (feat: integrate complete management-ui and additional features)
|
|
162
|
+
=======
|
|
163
|
+
currentUser?.id === user.id
|
|
164
|
+
? "bg-blue-600 text-white"
|
|
165
|
+
>>>>>>> 7e97f01c (fix: resolve ui-command merge conflicts and update package.json)
|
|
166
|
+
: "bg-gray-300 text-gray-700"
|
|
167
|
+
)}>
|
|
168
|
+
{user.firstName?.[0]}{user.lastName?.[0]}
|
|
169
|
+
</div>
|
|
170
|
+
<div className="flex-1 min-w-0">
|
|
171
|
+
<p className="text-sm font-medium text-gray-900">
|
|
172
|
+
{user.firstName} {user.lastName}
|
|
173
|
+
</p>
|
|
174
|
+
<p className="text-xs text-gray-500 truncate">{user.email}</p>
|
|
175
|
+
<div className="flex items-center space-x-2 mt-1">
|
|
176
|
+
<span className="text-xs bg-gray-100 text-gray-600 px-2 py-0.5 rounded">
|
|
177
|
+
{user.role}
|
|
178
|
+
</span>
|
|
179
|
+
{user.appOrgId && (
|
|
180
|
+
<span className="text-xs text-gray-500">
|
|
181
|
+
Org: {user.appOrgId}
|
|
182
|
+
</span>
|
|
183
|
+
)}
|
|
184
|
+
</div>
|
|
185
|
+
</div>
|
|
186
|
+
{currentUser?.id === user.id && (
|
|
187
|
+
<div className="text-blue-600">
|
|
188
|
+
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
|
|
189
|
+
<path fillRule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clipRule="evenodd" />
|
|
190
|
+
</svg>
|
|
191
|
+
</div>
|
|
192
|
+
)}
|
|
193
|
+
</button>
|
|
194
|
+
))}
|
|
195
|
+
</>
|
|
196
|
+
)}
|
|
197
|
+
</div>
|
|
198
|
+
|
|
199
|
+
{currentUser && (
|
|
200
|
+
<div className="p-3 bg-gray-50 border-t border-gray-200">
|
|
201
|
+
<p className="text-xs text-gray-600">
|
|
202
|
+
<span className="font-medium">Current context:</span> {currentUser.appUserId || currentUser.email}
|
|
203
|
+
</p>
|
|
204
|
+
</div>
|
|
205
|
+
)}
|
|
206
|
+
</div>
|
|
207
|
+
)}
|
|
208
|
+
</div>
|
|
209
|
+
)
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
export default UserContextSwitcher
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
import React, { useState, useEffect } from 'react'
|
|
2
|
+
import { Play, Square, AlertCircle, CheckCircle, Clock, Zap } from 'lucide-react'
|
|
3
|
+
import { useFrigg } from '../hooks/useFrigg'
|
|
4
|
+
import { useSocket } from '../hooks/useSocket'
|
|
5
|
+
import api from '../services/api'
|
|
6
|
+
<<<<<<< HEAD
|
|
7
|
+
<<<<<<< HEAD
|
|
8
|
+
import { cn } from '../lib/utils'
|
|
9
|
+
=======
|
|
10
|
+
<<<<<<< HEAD
|
|
11
|
+
<<<<<<< HEAD
|
|
12
|
+
import { cn } from '../lib/utils'
|
|
13
|
+
=======
|
|
14
|
+
import { cn } from '../utils/cn'
|
|
15
|
+
>>>>>>> 652520a5 (Claude Flow RFC related development)
|
|
16
|
+
=======
|
|
17
|
+
import { cn } from '../lib/utils'
|
|
18
|
+
>>>>>>> f153939e (refactor: clean up CLI help display and remove unused dependencies)
|
|
19
|
+
>>>>>>> 860052b4 (feat: integrate complete management-ui and additional features)
|
|
20
|
+
=======
|
|
21
|
+
import { cn } from '../lib/utils'
|
|
22
|
+
>>>>>>> 7e97f01c (fix: resolve ui-command merge conflicts and update package.json)
|
|
23
|
+
|
|
24
|
+
const UserSimulation = ({ user, integration }) => {
|
|
25
|
+
const { currentUser } = useFrigg()
|
|
26
|
+
const { on } = useSocket()
|
|
27
|
+
const [isSimulating, setIsSimulating] = useState(false)
|
|
28
|
+
const [session, setSession] = useState(null)
|
|
29
|
+
const [logs, setLogs] = useState([])
|
|
30
|
+
const [selectedAction, setSelectedAction] = useState('list')
|
|
31
|
+
const [actionPayload, setActionPayload] = useState('')
|
|
32
|
+
|
|
33
|
+
const simulationUser = user || currentUser
|
|
34
|
+
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
// Listen for simulation events
|
|
37
|
+
const unsubscribeAuth = on('simulation:auth', (data) => {
|
|
38
|
+
addLog('Authentication', data.session)
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
const unsubscribeAction = on('simulation:action', (data) => {
|
|
42
|
+
addLog('Action Performed', data.actionResult)
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
const unsubscribeWebhook = on('simulation:webhook', (data) => {
|
|
46
|
+
addLog('Webhook Event', data.webhookEvent)
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
return () => {
|
|
50
|
+
unsubscribeAuth && unsubscribeAuth()
|
|
51
|
+
unsubscribeAction && unsubscribeAction()
|
|
52
|
+
unsubscribeWebhook && unsubscribeWebhook()
|
|
53
|
+
}
|
|
54
|
+
}, [on])
|
|
55
|
+
|
|
56
|
+
const addLog = (type, data) => {
|
|
57
|
+
setLogs(prev => [{
|
|
58
|
+
id: Date.now(),
|
|
59
|
+
type,
|
|
60
|
+
data,
|
|
61
|
+
timestamp: new Date().toISOString()
|
|
62
|
+
}, ...prev].slice(0, 50)) // Keep last 50 logs
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const startSimulation = async () => {
|
|
66
|
+
if (!simulationUser || !integration) {
|
|
67
|
+
alert('Please select a user and integration')
|
|
68
|
+
return
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
try {
|
|
72
|
+
setIsSimulating(true)
|
|
73
|
+
const response = await api.post('/api/users/simulation/authenticate', {
|
|
74
|
+
userId: simulationUser.id,
|
|
75
|
+
integrationId: integration.id
|
|
76
|
+
})
|
|
77
|
+
<<<<<<< HEAD
|
|
78
|
+
<<<<<<< HEAD
|
|
79
|
+
|
|
80
|
+
=======
|
|
81
|
+
<<<<<<< HEAD
|
|
82
|
+
|
|
83
|
+
=======
|
|
84
|
+
|
|
85
|
+
>>>>>>> 652520a5 (Claude Flow RFC related development)
|
|
86
|
+
>>>>>>> 860052b4 (feat: integrate complete management-ui and additional features)
|
|
87
|
+
=======
|
|
88
|
+
|
|
89
|
+
>>>>>>> 7e97f01c (fix: resolve ui-command merge conflicts and update package.json)
|
|
90
|
+
setSession(response.data.session)
|
|
91
|
+
addLog('Session Started', response.data.session)
|
|
92
|
+
} catch (error) {
|
|
93
|
+
console.error('Failed to start simulation:', error)
|
|
94
|
+
alert('Failed to start simulation')
|
|
95
|
+
setIsSimulating(false)
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const stopSimulation = async () => {
|
|
100
|
+
if (!session) return
|
|
101
|
+
|
|
102
|
+
try {
|
|
103
|
+
await api.delete(`/api/users/simulation/sessions/${session.sessionId}`)
|
|
104
|
+
setSession(null)
|
|
105
|
+
setIsSimulating(false)
|
|
106
|
+
addLog('Session Ended', { sessionId: session.sessionId })
|
|
107
|
+
} catch (error) {
|
|
108
|
+
console.error('Failed to stop simulation:', error)
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const performAction = async () => {
|
|
113
|
+
if (!session) return
|
|
114
|
+
|
|
115
|
+
try {
|
|
116
|
+
let payload = {}
|
|
117
|
+
if (actionPayload) {
|
|
118
|
+
try {
|
|
119
|
+
payload = JSON.parse(actionPayload)
|
|
120
|
+
} catch {
|
|
121
|
+
payload = { data: actionPayload }
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const response = await api.post('/api/users/simulation/action', {
|
|
126
|
+
sessionId: session.sessionId,
|
|
127
|
+
action: selectedAction,
|
|
128
|
+
payload
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
addLog('Action Result', response.data.actionResult)
|
|
132
|
+
} catch (error) {
|
|
133
|
+
console.error('Failed to perform action:', error)
|
|
134
|
+
alert('Failed to perform action')
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const simulateWebhook = async () => {
|
|
139
|
+
if (!simulationUser || !integration) return
|
|
140
|
+
|
|
141
|
+
try {
|
|
142
|
+
const response = await api.post('/api/users/simulation/webhook', {
|
|
143
|
+
userId: simulationUser.id,
|
|
144
|
+
integrationId: integration.id,
|
|
145
|
+
event: 'data.updated',
|
|
146
|
+
data: {
|
|
147
|
+
id: 'webhook_item_' + Date.now(),
|
|
148
|
+
changes: ['field1', 'field2'],
|
|
149
|
+
timestamp: new Date().toISOString()
|
|
150
|
+
}
|
|
151
|
+
})
|
|
152
|
+
|
|
153
|
+
addLog('Webhook Simulated', response.data.webhookEvent)
|
|
154
|
+
} catch (error) {
|
|
155
|
+
console.error('Failed to simulate webhook:', error)
|
|
156
|
+
alert('Failed to simulate webhook')
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const commonActions = [
|
|
161
|
+
{ value: 'list', label: 'List Items' },
|
|
162
|
+
{ value: 'create', label: 'Create Item' },
|
|
163
|
+
{ value: 'update', label: 'Update Item' },
|
|
164
|
+
{ value: 'delete', label: 'Delete Item' },
|
|
165
|
+
{ value: 'sync', label: 'Sync Data' }
|
|
166
|
+
]
|
|
167
|
+
|
|
168
|
+
return (
|
|
169
|
+
<div className="bg-white rounded-lg shadow p-6">
|
|
170
|
+
<div className="mb-6">
|
|
171
|
+
<h3 className="text-lg font-semibold text-gray-900 mb-2">User Simulation</h3>
|
|
172
|
+
<p className="text-sm text-gray-600">
|
|
173
|
+
Simulate user interactions with integrations for testing
|
|
174
|
+
</p>
|
|
175
|
+
</div>
|
|
176
|
+
|
|
177
|
+
{/* Simulation Controls */}
|
|
178
|
+
<div className="space-y-4 mb-6">
|
|
179
|
+
<div className="flex items-center justify-between p-4 bg-gray-50 rounded-lg">
|
|
180
|
+
<div>
|
|
181
|
+
<p className="text-sm font-medium text-gray-900">
|
|
182
|
+
{simulationUser ? `${simulationUser.firstName} ${simulationUser.lastName}` : 'No user selected'}
|
|
183
|
+
</p>
|
|
184
|
+
<p className="text-xs text-gray-500">
|
|
185
|
+
{integration ? integration.name : 'No integration selected'}
|
|
186
|
+
</p>
|
|
187
|
+
</div>
|
|
188
|
+
<div className="flex items-center space-x-2">
|
|
189
|
+
{!isSimulating ? (
|
|
190
|
+
<button
|
|
191
|
+
onClick={startSimulation}
|
|
192
|
+
disabled={!simulationUser || !integration}
|
|
193
|
+
className={cn(
|
|
194
|
+
"flex items-center space-x-2 px-4 py-2 rounded-md transition-colors",
|
|
195
|
+
simulationUser && integration
|
|
196
|
+
? "bg-green-600 text-white hover:bg-green-700"
|
|
197
|
+
: "bg-gray-300 text-gray-500 cursor-not-allowed"
|
|
198
|
+
)}
|
|
199
|
+
>
|
|
200
|
+
<Play size={16} />
|
|
201
|
+
<span>Start Simulation</span>
|
|
202
|
+
</button>
|
|
203
|
+
) : (
|
|
204
|
+
<button
|
|
205
|
+
onClick={stopSimulation}
|
|
206
|
+
className="flex items-center space-x-2 px-4 py-2 bg-red-600 text-white rounded-md hover:bg-red-700"
|
|
207
|
+
>
|
|
208
|
+
<Square size={16} />
|
|
209
|
+
<span>Stop Simulation</span>
|
|
210
|
+
</button>
|
|
211
|
+
)}
|
|
212
|
+
</div>
|
|
213
|
+
</div>
|
|
214
|
+
|
|
215
|
+
{session && (
|
|
216
|
+
<div className="p-4 bg-blue-50 border border-blue-200 rounded-lg">
|
|
217
|
+
<div className="flex items-start space-x-3">
|
|
218
|
+
<CheckCircle className="text-blue-600 mt-0.5" size={20} />
|
|
219
|
+
<div className="flex-1">
|
|
220
|
+
<p className="text-sm font-medium text-blue-900">Session Active</p>
|
|
221
|
+
<p className="text-xs text-blue-700 mt-1">
|
|
222
|
+
Session ID: {session.sessionId}
|
|
223
|
+
</p>
|
|
224
|
+
<p className="text-xs text-blue-700">
|
|
225
|
+
Expires: {new Date(session.expiresAt).toLocaleTimeString()}
|
|
226
|
+
</p>
|
|
227
|
+
</div>
|
|
228
|
+
</div>
|
|
229
|
+
</div>
|
|
230
|
+
)}
|
|
231
|
+
</div>
|
|
232
|
+
|
|
233
|
+
{/* Action Simulator */}
|
|
234
|
+
{isSimulating && session && (
|
|
235
|
+
<div className="space-y-4 mb-6">
|
|
236
|
+
<div className="p-4 border border-gray-200 rounded-lg">
|
|
237
|
+
<h4 className="text-sm font-medium text-gray-900 mb-3">Simulate Action</h4>
|
|
238
|
+
<div className="space-y-3">
|
|
239
|
+
<div>
|
|
240
|
+
<label className="block text-xs font-medium text-gray-700 mb-1">
|
|
241
|
+
Action Type
|
|
242
|
+
</label>
|
|
243
|
+
<select
|
|
244
|
+
value={selectedAction}
|
|
245
|
+
onChange={(e) => setSelectedAction(e.target.value)}
|
|
246
|
+
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:border-blue-500"
|
|
247
|
+
>
|
|
248
|
+
{commonActions.map(action => (
|
|
249
|
+
<option key={action.value} value={action.value}>
|
|
250
|
+
{action.label}
|
|
251
|
+
</option>
|
|
252
|
+
))}
|
|
253
|
+
</select>
|
|
254
|
+
</div>
|
|
255
|
+
<div>
|
|
256
|
+
<label className="block text-xs font-medium text-gray-700 mb-1">
|
|
257
|
+
Payload (JSON)
|
|
258
|
+
</label>
|
|
259
|
+
<textarea
|
|
260
|
+
value={actionPayload}
|
|
261
|
+
onChange={(e) => setActionPayload(e.target.value)}
|
|
262
|
+
placeholder='{"name": "Test Item"}'
|
|
263
|
+
className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:border-blue-500 font-mono text-xs"
|
|
264
|
+
rows={3}
|
|
265
|
+
/>
|
|
266
|
+
</div>
|
|
267
|
+
<div className="flex space-x-2">
|
|
268
|
+
<button
|
|
269
|
+
onClick={performAction}
|
|
270
|
+
className="flex items-center space-x-2 px-3 py-1.5 bg-blue-600 text-white text-sm rounded-md hover:bg-blue-700"
|
|
271
|
+
>
|
|
272
|
+
<Zap size={14} />
|
|
273
|
+
<span>Execute Action</span>
|
|
274
|
+
</button>
|
|
275
|
+
<button
|
|
276
|
+
onClick={simulateWebhook}
|
|
277
|
+
className="flex items-center space-x-2 px-3 py-1.5 bg-purple-600 text-white text-sm rounded-md hover:bg-purple-700"
|
|
278
|
+
>
|
|
279
|
+
<AlertCircle size={14} />
|
|
280
|
+
<span>Trigger Webhook</span>
|
|
281
|
+
</button>
|
|
282
|
+
</div>
|
|
283
|
+
</div>
|
|
284
|
+
</div>
|
|
285
|
+
</div>
|
|
286
|
+
)}
|
|
287
|
+
|
|
288
|
+
{/* Activity Logs */}
|
|
289
|
+
<div>
|
|
290
|
+
<h4 className="text-sm font-medium text-gray-900 mb-3">Activity Log</h4>
|
|
291
|
+
<div className="space-y-2 max-h-64 overflow-y-auto">
|
|
292
|
+
{logs.length === 0 ? (
|
|
293
|
+
<p className="text-sm text-gray-500 text-center py-4">
|
|
294
|
+
No activity yet. Start a simulation to see logs.
|
|
295
|
+
</p>
|
|
296
|
+
) : (
|
|
297
|
+
logs.map(log => (
|
|
298
|
+
<div
|
|
299
|
+
key={log.id}
|
|
300
|
+
className="p-3 bg-gray-50 rounded-md border border-gray-200"
|
|
301
|
+
>
|
|
302
|
+
<div className="flex items-start justify-between">
|
|
303
|
+
<div className="flex items-center space-x-2">
|
|
304
|
+
<Clock size={14} className="text-gray-500" />
|
|
305
|
+
<span className="text-xs font-medium text-gray-900">
|
|
306
|
+
{log.type}
|
|
307
|
+
</span>
|
|
308
|
+
</div>
|
|
309
|
+
<span className="text-xs text-gray-500">
|
|
310
|
+
{new Date(log.timestamp).toLocaleTimeString()}
|
|
311
|
+
</span>
|
|
312
|
+
</div>
|
|
313
|
+
<div className="mt-1">
|
|
314
|
+
<pre className="text-xs text-gray-600 font-mono overflow-x-auto">
|
|
315
|
+
{JSON.stringify(log.data, null, 2)}
|
|
316
|
+
</pre>
|
|
317
|
+
</div>
|
|
318
|
+
</div>
|
|
319
|
+
))
|
|
320
|
+
)}
|
|
321
|
+
</div>
|
|
322
|
+
</div>
|
|
323
|
+
</div>
|
|
324
|
+
)
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
export default UserSimulation
|