diff --git a/frontend/src/app/pages/Settings/sections/settingsStyles.ts b/frontend/src/app/pages/Settings/sections/settingsStyles.ts index 4eb6c5fd..bb13ca9b 100644 --- a/frontend/src/app/pages/Settings/sections/settingsStyles.ts +++ b/frontend/src/app/pages/Settings/sections/settingsStyles.ts @@ -66,6 +66,7 @@ export function makeSettingsStyles(c: ClaudeTokens) { color: c.text.muted, borderColor: c.border.medium, textTransform: 'none' as const, + whiteSpace: 'nowrap' as const, px: 1.75, py: 0.5, gap: 0.5, diff --git a/frontend/src/app/pages/Workflows/SchedulePopover.tsx b/frontend/src/app/pages/Workflows/SchedulePopover.tsx index c0064f95..856f1dd9 100644 --- a/frontend/src/app/pages/Workflows/SchedulePopover.tsx +++ b/frontend/src/app/pages/Workflows/SchedulePopover.tsx @@ -6,6 +6,7 @@ import IconButton from '@mui/material/IconButton'; import Tooltip from '@mui/material/Tooltip'; import BookmarkIcon from '@mui/icons-material/BookmarkBorderRounded'; import SearchIcon from '@mui/icons-material/Search'; +import ChatBubbleOutlineIcon from '@mui/icons-material/ChatBubbleOutline'; import CalendarMonthIcon from '@mui/icons-material/CalendarMonthRounded'; import OpenInFullIcon from '@mui/icons-material/OpenInFullRounded'; import ChevronLeftIcon from '@mui/icons-material/ChevronLeft'; @@ -160,27 +161,37 @@ export default function SchedulePopover({ )} - + {historyResults.length === 0 && !historyLoading && ( {historyQuery ? 'No matching chats' : 'No chat history yet'} )} - {historyResults.map((entry) => { + {historyResults.map((entry, idx) => { const hasWorkflow = Boolean(workflowIconMap[entry.id]); + const bucket = dayBucket(entry.closed_at); + const prevBucket = idx > 0 ? dayBucket(historyResults[idx - 1].closed_at) : null; return ( - onHistorySelect(entry.id)} sx={{ display: 'flex', alignItems: 'center', gap: 1, px: 1.5, py: 0.9, cursor: 'pointer', '&:hover': { bgcolor: c.bg.elevated } }}> - {entry.name} - {/* Only annotate chats that became saved workflows. - A small workflow glyph reads as a tag, where the - old single-letter chip read as a random initial. */} - {hasWorkflow && ( - - - - - + + {bucket !== prevBucket && ( + {bucket} )} - {relTime(entry.closed_at)} - + onHistorySelect(entry.id)} sx={{ display: 'flex', alignItems: 'center', gap: 1, px: 1, py: 0.8, cursor: 'pointer', borderRadius: `${c.radius.md}px`, '&:hover': { bgcolor: c.bg.elevated } }}> + + + + {entry.name} + {/* Only annotate chats that became saved workflows. + A small workflow glyph reads as a tag, where the + old single-letter chip read as a random initial. */} + {hasWorkflow && ( + + + + + + )} + {relTime(entry.closed_at)} + + ); })} @@ -266,6 +277,18 @@ function ModeChip({ label, icon, active, onClick }: { label: string; icon: React ); } +function dayBucket(iso: string | null): string { + if (!iso) return 'Earlier'; + const then = new Date(iso); + const now = new Date(); + const startOfDay = (d: Date): number => new Date(d.getFullYear(), d.getMonth(), d.getDate()).getTime(); + const dayDiff = Math.round((startOfDay(now) - startOfDay(then)) / 86400000); + if (dayDiff <= 0) return 'Today'; + if (dayDiff === 1) return 'Yesterday'; + if (dayDiff < 7) return 'This week'; + return 'Earlier'; +} + function relTime(iso: string | null): string { if (!iso) return ''; const sec = Math.floor((Date.now() - new Date(iso).getTime()) / 1000); diff --git a/frontend/src/app/pages/Workflows/app/LeftRail.tsx b/frontend/src/app/pages/Workflows/app/LeftRail.tsx index 11625702..db1a07c5 100644 --- a/frontend/src/app/pages/Workflows/app/LeftRail.tsx +++ b/frontend/src/app/pages/Workflows/app/LeftRail.tsx @@ -135,7 +135,10 @@ const LeftRail: React.FC<{ nav: AppNav }> = ({ nav }) => { ); })} {filtered.length === 0 && ( -
No workflows yet.
+
+
No workflows yet.
+
Schedule anything an agent can do, or ask a chat to watch a folder or site for you.
+
)}