diff --git a/web/src/components/ui/toast.tsx b/web/src/components/ui/toast.tsx index 3d41450..5ccb925 100644 --- a/web/src/components/ui/toast.tsx +++ b/web/src/components/ui/toast.tsx @@ -32,21 +32,34 @@ export const toast = { // Param is `item`, not `toast`, so it doesn't shadow the module's `toast` export. function ToastItem({ item }: { item: Toast }) { const dismiss = useToastStore((s) => s.dismiss) + const isError = item.tone === 'error' useEffect(() => { + // Error toasts are the primary report that a mutation failed, so they do NOT + // auto-dismiss — a user who looked away at second 4 would otherwise lose the + // only notice, with nothing to retrieve (#85). Info toasts still time out. + if (isError) return const t = setTimeout(() => dismiss(item.id), 4000) return () => clearTimeout(t) - }, [item.id, dismiss]) + }, [item.id, dismiss, isError]) return (
- {item.message} + {item.message} +
) } diff --git a/web/src/editor/JournalPanel.tsx b/web/src/editor/JournalPanel.tsx index d37c193..15d7b2d 100644 --- a/web/src/editor/JournalPanel.tsx +++ b/web/src/editor/JournalPanel.tsx @@ -42,7 +42,15 @@ export function JournalPanel({ scopeObjectId: number | null onScopeChange: (id: number | null) => void }) { - const filter = scopeObjectId != null ? { objectId: scopeObjectId } : {} + // Date-range narrowing (#85): the backend and JournalFilter already supported + // from/to; they just had no UI. Empty inputs don't filter. + const [from, setFrom] = useState('') + const [to, setTo] = useState('') + const filter = { + ...(scopeObjectId != null ? { objectId: scopeObjectId } : {}), + ...(from ? { from } : {}), + ...(to ? { to } : {}), + } const journal = useJournal(gardenId, filter) const entries = journal.data?.pages.flatMap((p) => p.entries) ?? [] const scopedObject = objects.find((o) => o.id === scopeObjectId) ?? null @@ -70,6 +78,41 @@ export function JournalPanel({ )} +
+ + + {(from || to) && ( + + )} +
+ {canEdit && ( +

{garden.name}