workspace management progress
This commit is contained in:
parent
4ec31764d5
commit
8b5df3827b
@ -19,62 +19,17 @@ export default function LogPanel({ logs, expanded, workspaceMode, onToggleExpand
|
||||
const scrollRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (scrollRef.current && !expanded) {
|
||||
if (scrollRef.current) {
|
||||
scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
|
||||
}
|
||||
}, [logs, expanded]);
|
||||
|
||||
if (expanded) {
|
||||
return (
|
||||
<div className="absolute inset-0 z-10 bg-bg-primary flex flex-col border-t border-border-subtle">
|
||||
<div className="flex items-center justify-between px-4 py-2 bg-bg-tertiary shrink-0 border-b border-border-subtle">
|
||||
<h3 className="text-sm font-semibold text-text-secondary uppercase tracking-wider">
|
||||
Log
|
||||
</h3>
|
||||
<button
|
||||
onClick={onToggleExpand}
|
||||
className="w-6 h-6 flex items-center justify-center text-text-muted hover:text-text-secondary transition-colors"
|
||||
title="Collapse"
|
||||
>
|
||||
▾
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
ref={scrollRef}
|
||||
className="flex-1 overflow-y-auto p-2 font-mono text-xs"
|
||||
>
|
||||
{logs.length === 0 ? (
|
||||
<div className="text-text-muted">No log entries</div>
|
||||
) : (
|
||||
logs.map((entry) => (
|
||||
<div key={entry.id} className="flex gap-2 py-0.5">
|
||||
<span className="text-text-muted shrink-0">
|
||||
{entry.timestamp.toLocaleTimeString()}
|
||||
</span>
|
||||
<span
|
||||
className={`shrink-0 ${
|
||||
entry.level === 'error'
|
||||
? 'text-red-500'
|
||||
: entry.level === 'warn'
|
||||
? 'text-yellow-500'
|
||||
: entry.level === 'info'
|
||||
? 'text-blue-400'
|
||||
: 'text-text-secondary'
|
||||
}`}
|
||||
>
|
||||
[{entry.level.toUpperCase()}]
|
||||
</span>
|
||||
<span className="text-text-primary">{entry.message}</span>
|
||||
</div>
|
||||
))
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}, [logs]);
|
||||
|
||||
return (
|
||||
<div className="h-48 border-t border-border-subtle bg-bg-secondary flex flex-col shrink-0">
|
||||
<div
|
||||
className={`border-t border-border-subtle bg-bg-secondary flex flex-col ${
|
||||
expanded ? 'flex-1' : 'h-48'
|
||||
}`}
|
||||
>
|
||||
<div className="flex items-center justify-between px-4 py-2 bg-bg-tertiary shrink-0">
|
||||
<h3 className="text-sm font-semibold text-text-secondary uppercase tracking-wider">
|
||||
Log
|
||||
@ -82,9 +37,9 @@ export default function LogPanel({ logs, expanded, workspaceMode, onToggleExpand
|
||||
<button
|
||||
onClick={onToggleExpand}
|
||||
className="w-6 h-6 flex items-center justify-center text-text-muted hover:text-text-secondary transition-colors"
|
||||
title="Expand"
|
||||
title={expanded ? 'Collapse' : 'Expand'}
|
||||
>
|
||||
▴
|
||||
{expanded ? '▾' : '▴'}
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
|
||||
@ -223,15 +223,24 @@ export default function ChatSessionView() {
|
||||
const handleWorkspaceModeChange = async (mode: WorkspaceMode) => {
|
||||
if (!session || !project) return;
|
||||
|
||||
const registration = session.drone as any;
|
||||
const success = await socketClient.requestWorkspaceMode(
|
||||
registration,
|
||||
project,
|
||||
session,
|
||||
mode,
|
||||
);
|
||||
if (!success) {
|
||||
showToast(`Cannot switch to ${mode} mode: workspace is not idle`);
|
||||
try {
|
||||
const droneJson = localStorage.getItem('dtp_drone_registration');
|
||||
if (!droneJson) {
|
||||
showToast('No drone registration found');
|
||||
return;
|
||||
}
|
||||
const registration = JSON.parse(droneJson);
|
||||
const success = await socketClient.requestWorkspaceMode(
|
||||
registration,
|
||||
project,
|
||||
session,
|
||||
mode,
|
||||
);
|
||||
if (!success) {
|
||||
showToast(`Cannot switch to ${mode} mode: workspace is not idle`);
|
||||
}
|
||||
} catch (err) {
|
||||
showToast(`Failed to change workspace mode: ${err instanceof Error ? err.message : 'Unknown error'}`);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -703,6 +703,7 @@ export default function ProjectManager({ user }: ProjectManagerProps) {
|
||||
console.error("Failed to lock drone session");
|
||||
return;
|
||||
}
|
||||
localStorage.setItem('dtp_drone_registration', JSON.stringify(selectedDrone));
|
||||
navigate(`/projects/${selectedProject._id}/chat-session/${sessionId}`);
|
||||
} catch (err) {
|
||||
console.error("Failed to open chat session", err);
|
||||
|
||||
@ -37,6 +37,7 @@ export class CodeSession extends SocketSession {
|
||||
super.register();
|
||||
|
||||
this.socket.on("requestSessionLock", this.onRequestSessionLock.bind(this));
|
||||
this.socket.on("requestWorkspaceMode", this.onRequestWorkspaceMode.bind(this));
|
||||
this.socket.on("submitPrompt", this.onSubmitPrompt.bind(this));
|
||||
}
|
||||
|
||||
@ -90,6 +91,43 @@ export class CodeSession extends SocketSession {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the IDE sends a requestWorkspaceMode event to change the drone's
|
||||
* workspace mode.
|
||||
* @param registration the gadget-drone registration
|
||||
* @param project the project
|
||||
* @param chatSession the chat session
|
||||
* @param mode the requested workspace mode
|
||||
* @param cb response callback with success and current mode
|
||||
*/
|
||||
onRequestWorkspaceMode(
|
||||
registration: IDroneRegistration,
|
||||
project: IProject,
|
||||
chatSession: IChatSession,
|
||||
mode: WorkspaceMode,
|
||||
cb: (success: boolean, currentMode: WorkspaceMode) => void,
|
||||
) {
|
||||
if (!this.selectedDrone) {
|
||||
this.log.warn("workspace mode request rejected: no drone selected");
|
||||
return cb(false, this.workspaceMode);
|
||||
}
|
||||
|
||||
const droneSession = SocketService.getDroneSession(this.selectedDrone);
|
||||
droneSession.socket.emit(
|
||||
"requestWorkspaceMode",
|
||||
registration,
|
||||
project,
|
||||
chatSession,
|
||||
mode,
|
||||
(success: boolean, currentMode: WorkspaceMode) => {
|
||||
if (success) {
|
||||
this.workspaceMode = currentMode;
|
||||
}
|
||||
cb(success, currentMode);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the IDE submits a prompt to be processed by the agent.
|
||||
* Creates a ChatTurn document and sends a work order to the selected drone.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user