initial commit

This commit is contained in:
2026-02-10 11:04:44 +01:00
commit 5979fa3374
57 changed files with 19344 additions and 0 deletions

View File

@@ -0,0 +1,155 @@
.panel {
height: 200px;
display: flex;
flex-direction: column;
background-color: var(--vscode-panel-background);
border-top: 1px solid var(--vscode-panel-border);
}
.panel-header {
display: flex;
align-items: center;
justify-content: space-between;
height: 35px;
padding: 0 8px;
background-color: var(--vscode-sideBar-background);
border-bottom: 1px solid var(--vscode-panel-border);
}
.panel-tabs {
display: flex;
gap: 2px;
}
.panel-tab {
padding: 6px 12px;
font-size: 12px;
color: var(--vscode-tab-inactiveForeground);
cursor: pointer;
border-bottom: 2px solid transparent;
}
.panel-tab:hover {
color: var(--vscode-tab-activeForeground);
}
.panel-tab.active {
color: var(--vscode-tab-activeForeground);
border-bottom-color: var(--vscode-focusBorder);
}
.panel-close {
background: transparent;
border: none;
color: var(--vscode-descriptionForeground);
font-size: 18px;
width: 24px;
height: 24px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
border-radius: 4px;
padding: 0;
}
.panel-close:hover {
background-color: var(--vscode-list-hoverBackground);
color: var(--vscode-editor-foreground);
}
.panel-content {
flex: 1;
overflow-y: auto;
padding: 8px;
}
.panel-empty {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
color: var(--vscode-descriptionForeground);
font-size: 12px;
}
.task-list {
display: flex;
flex-direction: column;
gap: 4px;
}
.task-item {
display: flex;
align-items: center;
gap: 8px;
padding: 6px 8px;
background-color: var(--vscode-sideBar-background);
border-radius: 4px;
font-size: 12px;
}
.task-status {
width: 16px;
display: flex;
align-items: center;
justify-content: center;
}
.task-spinner {
width: 12px;
height: 12px;
border: 2px solid var(--vscode-descriptionForeground);
border-top-color: var(--vscode-focusBorder);
border-radius: 50%;
animation: spin 0.8s linear infinite;
}
.task-check {
color: var(--vscode-testing-iconPassed);
font-weight: bold;
}
.task-error {
color: var(--vscode-notificationsErrorIcon-foreground);
font-weight: bold;
}
.task-pending {
color: var(--vscode-descriptionForeground);
}
.task-info {
flex: 1;
min-width: 0;
}
.task-message {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.task-progress-bar {
height: 3px;
background-color: var(--vscode-input-background);
border-radius: 2px;
margin-top: 4px;
overflow: hidden;
}
.task-progress-fill {
height: 100%;
background-color: var(--vscode-focusBorder);
transition: width 0.2s ease;
}
.task-cancel {
padding: 2px 8px;
font-size: 11px;
background-color: var(--vscode-button-secondaryBackground);
}
@keyframes spin {
to { transform: rotate(360deg); }
}

View File

@@ -0,0 +1,69 @@
import React from 'react';
import { useAppStore } from '../../store';
import './Panel.css';
export const Panel: React.FC = () => {
const { panelVisible, tasks } = useAppStore();
if (!panelVisible) {
return null;
}
const recentTasks = tasks.slice(-10).reverse();
return (
<div className="panel">
<div className="panel-header">
<div className="panel-tabs">
<div className="panel-tab active">Tasks</div>
<div className="panel-tab">Output</div>
<div className="panel-tab">Sync Log</div>
</div>
<button
className="panel-close"
onClick={() => useAppStore.getState().togglePanel()}
title="Close Panel"
>
×
</button>
</div>
<div className="panel-content">
{recentTasks.length === 0 ? (
<div className="panel-empty">No recent tasks</div>
) : (
<div className="task-list">
{recentTasks.map(task => (
<div key={task.taskId} className={`task-item status-${task.status}`}>
<div className="task-status">
{task.status === 'running' && <span className="task-spinner" />}
{task.status === 'completed' && <span className="task-check"></span>}
{task.status === 'failed' && <span className="task-error"></span>}
{task.status === 'pending' && <span className="task-pending"></span>}
</div>
<div className="task-info">
<div className="task-message">{task.message}</div>
{task.status === 'running' && (
<div className="task-progress-bar">
<div
className="task-progress-fill"
style={{ width: `${task.progress}%` }}
/>
</div>
)}
</div>
{task.status === 'running' && (
<button
className="task-cancel"
onClick={() => window.electronAPI?.tasks.cancel(task.taskId)}
>
Cancel
</button>
)}
</div>
))}
</div>
)}
</div>
</div>
);
};

View File

@@ -0,0 +1 @@
export { Panel } from './Panel';