Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions ui/src/app/api/jobs/stop-all/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { NextResponse } from 'next/server';
import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

export async function POST() {
try {
// Find all jobs with status 'running'
const runningJobs = await prisma.job.findMany({
where: { status: 'running' },
select: { id: true, name: true }
});

if (runningJobs.length === 0) {
return NextResponse.json({
message: 'No running jobs found',
count: 0
});
}

// Update all running jobs to stopped status
const result = await prisma.job.updateMany({
where: { status: 'running' },
data: {
status: 'stopped',
stop: true,
info: 'Stopped via debug panel'
}
});

return NextResponse.json({
message: `Successfully stopped ${result.count} job${result.count === 1 ? '' : 's'}`,
count: result.count,
stoppedJobs: runningJobs.map(job => ({ id: job.id, name: job.name }))
});

} catch (error) {
console.error('Error stopping all running jobs:', error);
return NextResponse.json(
{ error: 'Failed to stop all running jobs' },
{ status: 500 }
);
}
}
58 changes: 58 additions & 0 deletions ui/src/app/settings/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { apiClient } from '@/utils/api';
export default function Settings() {
const { settings, setSettings } = useSettings();
const [status, setStatus] = useState<'idle' | 'saving' | 'success' | 'error'>('idle');
const [debugStatus, setDebugStatus] = useState<'idle' | 'stopping' | 'success' | 'error'>('idle');
const [debugMessage, setDebugMessage] = useState<string>('');

const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
Expand All @@ -32,6 +34,28 @@ export default function Settings() {
setSettings(prev => ({ ...prev, [name]: value }));
};

const handleStopAllJobs = async () => {
setDebugStatus('stopping');
setDebugMessage('');

try {
const response = await apiClient.post('/api/jobs/stop-all');
const data = response.data;

setDebugStatus('success');
setDebugMessage(data.message);
} catch (error: any) {
console.error('Error stopping all running jobs:', error);
setDebugStatus('error');
setDebugMessage(error.response?.data?.error || 'Failed to stop running jobs');
} finally {
setTimeout(() => {
setDebugStatus('idle');
setDebugMessage('');
}, 5000);
}
};

return (
<>
<TopBar>
Expand Down Expand Up @@ -123,6 +147,40 @@ export default function Settings() {
{status === 'success' && <p className="text-green-500 text-center">Settings saved successfully!</p>}
{status === 'error' && <p className="text-red-500 text-center">Error saving settings. Please try again.</p>}
</form>

{/* Debug Section */}
<div className="mt-12 pt-8 border-t border-gray-700">
<h2 className="text-lg font-semibold text-red-400 mb-4">Debug Tools</h2>
<div className="bg-gray-800 p-4 rounded-lg border border-red-600">
<div className="flex flex-col space-y-4">
<div>
<h3 className="text-sm font-medium text-red-300 mb-2">Force Stop All Running Jobs</h3>
<p className="text-gray-400 text-sm mb-3">
This will immediately change the status of all running jobs to "stopped" in the database.
Use this only if jobs appear stuck in running state.
</p>
<button
type="button"
onClick={handleStopAllJobs}
disabled={debugStatus === 'stopping'}
className="px-4 py-2 bg-red-700 hover:bg-red-600 text-white rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
>
{debugStatus === 'stopping' ? 'Stopping Jobs...' : 'Stop All Running Jobs'}
</button>
</div>

{debugMessage && (
<div className={`p-3 rounded-lg text-sm ${
debugStatus === 'success'
? 'bg-green-900 text-green-300 border border-green-700'
: 'bg-red-900 text-red-300 border border-red-700'
}`}>
{debugMessage}
</div>
)}
</div>
</div>
</div>
</MainContent>
</>
);
Expand Down