Skip to content
Merged
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
1 change: 1 addition & 0 deletions host/client_app/app.tsx
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,6 +6,7 @@ import { bootI18nFromInitialPage, subscribeI18nToNavigation } from './i18n';
import { resolvePage } from './pages';

createInertiaApp({
title: (title) => (title ? `${title} — SimpleModule` : 'SimpleModule'),
resolve: async (name) => {
const page = await resolvePage(name);
return page;
Expand Down
29 changes: 16 additions & 13 deletions host/client_app/pages/Error.tsx
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
import { Link } from '@inertiajs/react';
import { Head, Link } from '@inertiajs/react';
import { keys, useT } from '@simple-module-py/i18n';
import { ErrorScreen } from '@simple-module-py/ui/components/ErrorScreen';
import { Button } from '@simple-module-py/ui/components/ui/button';
Expand DownExpand Up@@ -34,18 +34,21 @@ function ErrorPage({ status, message }: Props) {
const description = message || descriptions[status] || t(keys.host.error.generic_description);

return (
<ErrorScreen hero={status} title={title} description={description} accent={accents[status]}>
<Button asChild className="gap-1.5">
<Link href="/">
<Home className="h-4 w-4" />
{t(keys.host.error.go_home)}
</Link>
</Button>
<Button variant="outline" onClick={() => window.history.back()} className="gap-1.5">
<LifeBuoy className="h-4 w-4" />
{t(keys.host.error.go_back)}
</Button>
</ErrorScreen>
<>
<Head title="Error" />
<ErrorScreen hero={status} title={title} description={description} accent={accents[status]}>
<Button asChild className="gap-1.5">
<Link href="/">
<Home className="h-4 w-4" />
{t(keys.host.error.go_home)}
</Link>
</Button>
<Button variant="outline" onClick={() => window.history.back()} className="gap-1.5">
<LifeBuoy className="h-4 w-4" />
{t(keys.host.error.go_back)}
</Button>
</ErrorScreen>
</>
);
}

Expand Down
2 changes: 2 additions & 0 deletions host/client_app/pages/Landing.tsx
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
import { Head } from '@inertiajs/react';
import { keys, useT } from '@simple-module-py/i18n';
import { Button } from '@simple-module-py/ui/components/ui/button';
import { Card, CardContent } from '@simple-module-py/ui/components/ui/card';
Expand DownExpand Up@@ -66,6 +67,7 @@ function Landing() {

return (
<>
<Head title="Welcome" />
{/* Hero with mesh blobs */}
<section className="relative overflow-hidden">
<div
Expand Down
161 changes: 82 additions & 79 deletions modules/background_tasks/background_tasks/pages/Detail.tsx
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
import { Link, router, usePage } from '@inertiajs/react';
import { Head, Link, router, usePage } from '@inertiajs/react';
import { PageShell } from '@simple-module-py/ui/components/PageShell';
import { Badge } from '@simple-module-py/ui/components/ui/badge';
import { Button } from '@simple-module-py/ui/components/ui/button';
Expand DownExpand Up@@ -89,92 +89,95 @@ function Detail() {
}

return (
<PageShell
title={execution.task_name}
description={`Task execution ${execution.id}`}
actions={
<div className="flex items-center gap-2">
<Button variant="outline" size="sm" asChild>
<Link href={VIEW_BASE}>
<ArrowLeft />
Back to tasks
</Link>
</Button>
{retryable && (
<RetryConfirmDialog
trigger={
<Button size="sm">
<RefreshCcw />
Retry task
</Button>
}
onConfirm={handleRetry}
/>
)}
</div>
}
>
<div className="grid grid-cols-1 lg:grid-cols-3 gap-4">
<Card className="p-4 lg:col-span-1">
<h3 className="font-semibold mb-3">Details</h3>
<dl className="text-sm space-y-2">
<div className="flex justify-between gap-3">
<dt className="text-muted-foreground">Status</dt>
<dd>
<Badge variant={STATUS_BADGE_VARIANT[execution.status]}>
{statusLabel(execution.status)}
</Badge>
</dd>
</div>
<Row label="Queue" value={execution.queue} />
<Row label="Retries" value={String(execution.retries)} />
<Row label="Worker" value={execution.worker || '—'} />
<Row label="Celery id" value={execution.celery_task_id || '—'} mono />
<Row label="Queued at" value={formatTs(execution.queued_at)} />
<Row label="Started at" value={formatTs(execution.started_at)} />
<Row label="Finished at" value={formatTs(execution.finished_at)} />
<Row label="Heartbeat" value={formatTs(execution.heartbeat_at)} />
<Row label="Exception" value={execution.exception_type || '—'} />
{execution.retried_from_id && (
<>
<Head title="Task Detail" />
<PageShell
title={execution.task_name}
description={`Task execution ${execution.id}`}
actions={
<div className="flex items-center gap-2">
<Button variant="outline" size="sm" asChild>
<Link href={VIEW_BASE}>
<ArrowLeft />
Back to tasks
</Link>
</Button>
{retryable && (
<RetryConfirmDialog
trigger={
<Button size="sm">
<RefreshCcw />
Retry task
</Button>
}
onConfirm={handleRetry}
/>
)}
</div>
}
>
<div className="grid grid-cols-1 lg:grid-cols-3 gap-4">
<Card className="p-4 lg:col-span-1">
<h3 className="font-semibold mb-3">Details</h3>
<dl className="text-sm space-y-2">
<div className="flex justify-between gap-3">
<dt className="text-muted-foreground">Retried from</dt>
<dt className="text-muted-foreground">Status</dt>
<dd>
<Link
href={`${VIEW_BASE}/${execution.retried_from_id}`}
className="hover:underline"
>
{execution.retried_from_id.slice(0, 8)}…
</Link>
<Badge variant={STATUS_BADGE_VARIANT[execution.status]}>
{statusLabel(execution.status)}
</Badge>
</dd>
</div>
)}
</dl>
</Card>
<Row label="Queue" value={execution.queue} />
<Row label="Retries" value={String(execution.retries)} />
<Row label="Worker" value={execution.worker || '—'} />
<Row label="Celery id" value={execution.celery_task_id || '—'} mono />
<Row label="Queued at" value={formatTs(execution.queued_at)} />
<Row label="Started at" value={formatTs(execution.started_at)} />
<Row label="Finished at" value={formatTs(execution.finished_at)} />
<Row label="Heartbeat" value={formatTs(execution.heartbeat_at)} />
<Row label="Exception" value={execution.exception_type || '—'} />
{execution.retried_from_id && (
<div className="flex justify-between gap-3">
<dt className="text-muted-foreground">Retried from</dt>
<dd>
<Link
href={`${VIEW_BASE}/${execution.retried_from_id}`}
className="hover:underline"
>
{execution.retried_from_id.slice(0, 8)}…
</Link>
</dd>
</div>
)}
</dl>
</Card>

<div className="lg:col-span-2 flex flex-col gap-4">
<JsonCard title="Arguments">
<JsonBlock value={execution.args} />
</JsonCard>
<JsonCard title="Keyword arguments">
<JsonBlock value={execution.kwargs} />
</JsonCard>
{execution.result !== null && (
<JsonCard title="Result">
<JsonBlock value={execution.result} />
<div className="lg:col-span-2 flex flex-col gap-4">
<JsonCard title="Arguments">
<JsonBlock value={execution.args} />
</JsonCard>
)}
<JsonCard title="Traceback">
{execution.traceback ? (
<pre className="text-xs bg-muted rounded p-3 overflow-x-auto whitespace-pre-wrap">
{execution.traceback}
</pre>
) : (
<p className="text-sm text-muted-foreground">No traceback recorded.</p>
<JsonCard title="Keyword arguments">
<JsonBlock value={execution.kwargs} />
</JsonCard>
{execution.result !== null && (
<JsonCard title="Result">
<JsonBlock value={execution.result} />
</JsonCard>
)}
</JsonCard>
<JsonCard title="Traceback">
{execution.traceback ? (
<pre className="text-xs bg-muted rounded p-3 overflow-x-auto whitespace-pre-wrap">
{execution.traceback}
</pre>
) : (
<p className="text-sm text-muted-foreground">No traceback recorded.</p>
)}
</JsonCard>
</div>
</div>
</div>
</PageShell>
</PageShell>
</>
);
}

Expand Down
Loading
Loading