refactor: restructure to monorepo with apps and packages directories - Move companion app to apps/companion with electron-vite - Move domain/application/infrastructure to packages/ - Fix ELECTRON_RUN_AS_NODE env var issue for VS Code terminal - Remove legacy esbuild bundler (replaced by electron-vite) - Update workspace scripts in root package.json
This commit is contained in:
110
apps/companion/renderer/App.tsx
Normal file
110
apps/companion/renderer/App.tsx
Normal file
@@ -0,0 +1,110 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { SessionCreationForm } from './components/SessionCreationForm';
|
||||
import { SessionProgressMonitor } from './components/SessionProgressMonitor';
|
||||
import type { HostedSessionConfig } from '../../../packages/domain/entities/HostedSessionConfig';
|
||||
|
||||
interface SessionProgress {
|
||||
sessionId: string;
|
||||
currentStep: number;
|
||||
state: string;
|
||||
completedSteps: number[];
|
||||
hasError: boolean;
|
||||
errorMessage: string | null;
|
||||
}
|
||||
|
||||
export function App() {
|
||||
const [sessionId, setSessionId] = useState<string | null>(null);
|
||||
const [progress, setProgress] = useState<SessionProgress | null>(null);
|
||||
const [isRunning, setIsRunning] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (window.electronAPI) {
|
||||
window.electronAPI.onSessionProgress((newProgress: SessionProgress) => {
|
||||
setProgress(newProgress);
|
||||
if (newProgress.state === 'COMPLETED' ||
|
||||
newProgress.state === 'FAILED' ||
|
||||
newProgress.state === 'STOPPED_AT_STEP_18') {
|
||||
setIsRunning(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
|
||||
const handleStartAutomation = async (config: HostedSessionConfig) => {
|
||||
setIsRunning(true);
|
||||
const result = await window.electronAPI.startAutomation(config);
|
||||
|
||||
if (result.success && result.sessionId) {
|
||||
setSessionId(result.sessionId);
|
||||
} else {
|
||||
setIsRunning(false);
|
||||
alert(`Failed to start automation: ${result.error}`);
|
||||
}
|
||||
};
|
||||
|
||||
const handleStopAutomation = async () => {
|
||||
if (sessionId) {
|
||||
const result = await window.electronAPI.stopAutomation(sessionId);
|
||||
if (result.success) {
|
||||
setIsRunning(false);
|
||||
setProgress(prev => prev ? { ...prev, state: 'STOPPED', hasError: false, errorMessage: 'User stopped automation' } : null);
|
||||
} else {
|
||||
alert(`Failed to stop automation: ${result.error}`);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
minHeight: '100vh',
|
||||
backgroundColor: '#1a1a1a'
|
||||
}}>
|
||||
<div style={{
|
||||
flex: 1,
|
||||
padding: '2rem',
|
||||
borderRight: '1px solid #333'
|
||||
}}>
|
||||
<h1 style={{ marginBottom: '2rem', color: '#fff' }}>
|
||||
GridPilot Companion
|
||||
</h1>
|
||||
<p style={{ marginBottom: '2rem', color: '#aaa' }}>
|
||||
Hosted Session Automation POC
|
||||
</p>
|
||||
<SessionCreationForm
|
||||
onSubmit={handleStartAutomation}
|
||||
disabled={isRunning}
|
||||
/>
|
||||
{isRunning && (
|
||||
<button
|
||||
onClick={handleStopAutomation}
|
||||
style={{
|
||||
marginTop: '1rem',
|
||||
padding: '0.75rem 1.5rem',
|
||||
backgroundColor: '#dc3545',
|
||||
color: '#fff',
|
||||
border: 'none',
|
||||
borderRadius: '4px',
|
||||
cursor: 'pointer',
|
||||
fontSize: '1rem',
|
||||
fontWeight: 'bold'
|
||||
}}
|
||||
>
|
||||
Stop Automation
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
<div style={{
|
||||
flex: 1,
|
||||
padding: '2rem',
|
||||
backgroundColor: '#0d0d0d'
|
||||
}}>
|
||||
<SessionProgressMonitor
|
||||
sessionId={sessionId}
|
||||
progress={progress}
|
||||
isRunning={isRunning}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user