feat: migrate task jobs to workflow notifications + timeline
This commit is contained in:
@@ -8,14 +8,12 @@ import { AppShell } from '@/components/shell/app-shell';
|
||||
import { Panel } from '@/components/ui/panel';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { StatusPill } from '@/components/ui/status-pill';
|
||||
import { useLinkPrefetch } from '@/hooks/use-link-prefetch';
|
||||
import { useAuthGuard } from '@/hooks/use-auth-guard';
|
||||
import { useTaskPoller } from '@/hooks/use-task-poller';
|
||||
import { deleteWatchlistItem, queueFilingSync, upsertWatchlistItem } from '@/lib/api';
|
||||
import type { Task, WatchlistItem } from '@/lib/types';
|
||||
import type { WatchlistItem } from '@/lib/types';
|
||||
import { queryKeys } from '@/lib/query/keys';
|
||||
import { taskQueryOptions, watchlistQueryOptions } from '@/lib/query/options';
|
||||
import { watchlistQueryOptions } from '@/lib/query/options';
|
||||
|
||||
type FormState = {
|
||||
ticker: string;
|
||||
@@ -31,7 +29,6 @@ export default function WatchlistPage() {
|
||||
const [items, setItems] = useState<WatchlistItem[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [activeTask, setActiveTask] = useState<Task | null>(null);
|
||||
const [form, setForm] = useState<FormState>({ ticker: '', companyName: '', sector: '' });
|
||||
|
||||
const loadWatchlist = useCallback(async () => {
|
||||
@@ -59,17 +56,6 @@ export default function WatchlistPage() {
|
||||
}
|
||||
}, [isPending, isAuthenticated, loadWatchlist]);
|
||||
|
||||
const polledTask = useTaskPoller({
|
||||
taskId: activeTask?.id ?? null,
|
||||
onTerminalState: () => {
|
||||
setActiveTask(null);
|
||||
void queryClient.invalidateQueries({ queryKey: queryKeys.recentTasks(20) });
|
||||
void queryClient.invalidateQueries({ queryKey: ['filings'] });
|
||||
}
|
||||
});
|
||||
|
||||
const liveTask = polledTask ?? activeTask;
|
||||
|
||||
const submit = async (event: React.FormEvent<HTMLFormElement>) => {
|
||||
event.preventDefault();
|
||||
|
||||
@@ -90,10 +76,9 @@ export default function WatchlistPage() {
|
||||
|
||||
const queueSync = async (ticker: string) => {
|
||||
try {
|
||||
const { task } = await queueFilingSync({ ticker, limit: 20 });
|
||||
const latest = await queryClient.fetchQuery(taskQueryOptions(task.id));
|
||||
setActiveTask(latest.task);
|
||||
await queueFilingSync({ ticker, limit: 20 });
|
||||
void queryClient.invalidateQueries({ queryKey: queryKeys.recentTasks(20) });
|
||||
void queryClient.invalidateQueries({ queryKey: ['filings'] });
|
||||
} catch (err) {
|
||||
setError(err instanceof Error ? err.message : `Failed to queue sync for ${ticker}`);
|
||||
}
|
||||
@@ -108,15 +93,6 @@ export default function WatchlistPage() {
|
||||
title="Watchlist"
|
||||
subtitle="Track symbols, company context, and trigger filing ingestion jobs from one surface."
|
||||
>
|
||||
{liveTask ? (
|
||||
<Panel title="Queue Status">
|
||||
<div className="flex items-center justify-between rounded-lg border border-[color:var(--line-weak)] bg-[color:var(--panel-soft)] px-3 py-2">
|
||||
<p className="text-sm text-[color:var(--terminal-bright)]">{liveTask.task_type}</p>
|
||||
<StatusPill status={liveTask.status} />
|
||||
</div>
|
||||
</Panel>
|
||||
) : null}
|
||||
|
||||
<div className="grid grid-cols-1 gap-6 xl:grid-cols-[1.6fr_1fr]">
|
||||
<Panel title="Symbols" subtitle="Your monitored universe.">
|
||||
{error ? <p className="text-sm text-[#ffb5b5]">{error}</p> : null}
|
||||
|
||||
Reference in New Issue
Block a user