This commit is contained in:
IGNY8 VPS (Salman)
2025-12-04 22:43:25 +00:00
parent 1521f3ff8c
commit 8b895dbdc7
18 changed files with 1569 additions and 172 deletions

View File

@@ -54,6 +54,7 @@ const AutomationPage: React.FC = () => {
const [pipelineOverview, setPipelineOverview] = useState<PipelineStage[]>([]);
const [metrics, setMetrics] = useState<any>(null);
const [showConfigModal, setShowConfigModal] = useState(false);
const [showProcessingCard, setShowProcessingCard] = useState<boolean>(true);
const [loading, setLoading] = useState(true);
const [estimate, setEstimate] = useState<{ estimated_credits: number; current_balance: number; sufficient: boolean } | null>(null);
@@ -147,6 +148,10 @@ const AutomationPage: React.FC = () => {
setCurrentRun(runData.run);
setEstimate(estimateData);
setPipelineOverview(pipelineData.stages);
// show processing card when there's a current run
if (runData.run) {
setShowProcessingCard(true);
}
} catch (error: any) {
toast.error('Failed to load automation data');
console.error(error);
@@ -160,6 +165,8 @@ const AutomationPage: React.FC = () => {
try {
const data = await automationService.getCurrentRun(activeSite.id);
setCurrentRun(data.run);
// ensure processing card is visible when a run exists
if (data.run) setShowProcessingCard(true);
} catch (error) {
console.error('Failed to poll current run', error);
}
@@ -251,22 +258,27 @@ const AutomationPage: React.FC = () => {
};
const handlePause = async () => {
if (!currentRun) return;
if (!currentRun || !activeSite) return;
try {
await automationService.pause(currentRun.run_id);
await automationService.pause(activeSite.id, currentRun.run_id);
toast.success('Automation paused');
loadCurrentRun();
// refresh run and pipeline/metrics
await loadCurrentRun();
await loadPipelineOverview();
await loadMetrics();
} catch (error) {
toast.error('Failed to pause automation');
}
};
const handleResume = async () => {
if (!currentRun) return;
if (!currentRun || !activeSite) return;
try {
await automationService.resume(currentRun.run_id);
await automationService.resume(activeSite.id, currentRun.run_id);
toast.success('Automation resumed');
loadCurrentRun();
await loadCurrentRun();
await loadPipelineOverview();
await loadMetrics();
} catch (error) {
toast.error('Failed to resume automation');
}
@@ -278,8 +290,13 @@ const AutomationPage: React.FC = () => {
await automationService.updateConfig(activeSite.id, newConfig);
toast.success('Configuration saved');
setShowConfigModal(false);
loadData();
// Optimistically update config locally and refresh data
setConfig((prev) => ({ ...(prev as AutomationConfig), ...newConfig } as AutomationConfig));
await loadPipelineOverview();
await loadMetrics();
await loadCurrentRun();
} catch (error) {
console.error('Failed to save config:', error);
toast.error('Failed to save configuration');
}
};
@@ -665,18 +682,21 @@ const AutomationPage: React.FC = () => {
</div>
{/* Current Processing Card - Shows real-time automation progress */}
{currentRun && (currentRun.status === 'running' || currentRun.status === 'paused') && activeSite && (
{currentRun && showProcessingCard && activeSite && (
<CurrentProcessingCard
runId={currentRun.run_id}
siteId={activeSite.id}
currentRun={currentRun}
onUpdate={() => {
// Refresh current run status
loadCurrentRun();
pipelineOverview={pipelineOverview}
onUpdate={async () => {
// Refresh current run status, pipeline overview and metrics (no full page reload)
await loadCurrentRun();
await loadPipelineOverview();
await loadMetrics();
}}
onClose={() => {
// Card will remain in DOM but user acknowledged it
// Can add state here to minimize it if needed
// hide the processing card until next run
setShowProcessingCard(false);
}}
/>
)}
@@ -692,7 +712,8 @@ const AutomationPage: React.FC = () => {
const isComplete = currentRun && currentRun.current_stage > stage.number;
const result = currentRun ? (currentRun[`stage_${stage.number}_result` as keyof AutomationRun] as any) : null;
const processed = result ? Object.values(result).reduce((sum: number, val) => typeof val === 'number' ? sum + val : sum, 0) : 0;
const progressPercent = stage.pending > 0 ? Math.round((processed / (processed + stage.pending)) * 100) : 0;
const total = (stage.pending ?? 0) + processed;
const progressPercent = total > 0 ? Math.round((processed / total) * 100) : 0;
return (
<div
@@ -787,7 +808,8 @@ const AutomationPage: React.FC = () => {
const isComplete = currentRun && currentRun.current_stage > stage.number;
const result = currentRun ? (currentRun[`stage_${stage.number}_result` as keyof AutomationRun] as any) : null;
const processed = result ? Object.values(result).reduce((sum: number, val) => typeof val === 'number' ? sum + val : sum, 0) : 0;
const progressPercent = stage.pending > 0 ? Math.round((processed / (processed + stage.pending)) * 100) : 0;
const total = (stage.pending ?? 0) + processed;
const progressPercent = total > 0 ? Math.round((processed / total) * 100) : 0;
return (
<div