Files
kandev/apps/web/components/task/chat/context-items/lazy-plan-preview.tsx
T
Carlos Florêncio f4d1dfd3a7 feat: better context files (#222)
feat: context files
2026-02-14 20:13:11 +00:00

66 lines
1.9 KiB
TypeScript

'use client';
import { useEffect } from 'react';
import { useAppStore, useAppStoreApi } from '@/components/state-provider';
import { getTaskPlan } from '@/lib/api/domains/plan-api';
type LazyPlanPreviewProps = {
taskId: string | null;
};
export function LazyPlanPreview({ taskId }: LazyPlanPreviewProps) {
const plan = useAppStore((state) =>
taskId ? state.taskPlans.byTaskId[taskId] ?? null : null
);
const loaded = useAppStore((state) =>
taskId ? state.taskPlans.loadedByTaskId[taskId] ?? false : false
);
const loading = useAppStore((state) =>
taskId ? state.taskPlans.loadingByTaskId[taskId] ?? false : false
);
const storeApi = useAppStoreApi();
useEffect(() => {
if (!taskId || loaded || loading) return;
const { setTaskPlanLoading } = storeApi.getState();
setTaskPlanLoading(taskId, true);
getTaskPlan(taskId).then((result) => {
storeApi.getState().setTaskPlan(taskId, result);
}).catch(() => {
storeApi.getState().setTaskPlanLoading(taskId, false);
});
}, [taskId, loaded, loading, storeApi]);
if (!taskId) {
return <div className="text-xs text-muted-foreground">No task selected</div>;
}
if (loading || !loaded) {
return (
<div className="space-y-1.5">
<div className="text-muted-foreground text-xs font-medium">Plan</div>
<div className="h-3 w-3/4 bg-muted animate-pulse rounded" />
<div className="h-3 w-1/2 bg-muted animate-pulse rounded" />
</div>
);
}
if (!plan?.content) {
return <div className="text-xs text-muted-foreground">Plan is empty</div>;
}
const preview = plan.content.length > 2000 ? plan.content.slice(0, 2000) + '...' : plan.content;
return (
<div className="space-y-1.5">
<div className="text-muted-foreground text-xs font-medium">Plan</div>
<pre className="text-[10px] leading-tight font-mono whitespace-pre-wrap break-all">
{preview}
</pre>
</div>
);
}