fix(mood): truncate long notes in the entries table

A long free-text note forced the mood entries table into horizontal
scroll. Cap the note column width, clamp the note to two lines, and
surface the full text on hover through a tooltip. The complete note
stays editable in the entry sheet.
This commit is contained in:
Marc-André Bombeck committed 2026-06-01 22:51:10 +02:00
1 parent 6e61713fc6
commit 3ecfa3a898
2 files changed
+24 -83

No files matched your search

@@ -1,78 +0,0 @@
"use client";
import { formatDateTime } from "@/lib/format";
import { useTranslations } from "@/lib/i18n/context";
import { MOOD_LABEL_KEYS } from "@/lib/mood/labels";
/**
* v1.8.5 (C1) — notes timeline.
*
* Chronological feed of recent mood entries that carry a free-text note,
* each with its score, mood label, note text, and tag chips. Renders the
* note as a plain React text child (no markdown library — the project
* forbids one for XSS reasons).
*/
export interface MoodNoteEntry {
date: string;
loggedAt: string;
score: number;
mood: string | null;
note: string;
tags: string[];
structuredTagLabelKeys: string[];
}
export function MoodNotesTimeline({ notes }: { notes: MoodNoteEntry[] }) {
const { t } = useTranslations();
return (
<ul className="space-y-3" data-slot="mood-notes-timeline">
{notes.map((entry) => {
const moodLabel =
entry.mood && MOOD_LABEL_KEYS[entry.mood]
? t(MOOD_LABEL_KEYS[entry.mood])
: entry.mood;
return (
<li
key={`${entry.loggedAt}-${entry.date}`}
className="border-border/60 border-l-2 pl-3"
>
<div className="text-muted-foreground flex items-center gap-2 text-xs">
<span className="text-foreground font-semibold tabular-nums">
{entry.score}
</span>
{moodLabel && <span>({moodLabel})</span>}
<span>·</span>
<span>{formatDateTime(entry.loggedAt)}</span>
</div>
<p className="text-foreground/90 mt-0.5 text-sm whitespace-pre-wrap">
{entry.note}
</p>
{(entry.structuredTagLabelKeys.length > 0 ||
entry.tags.length > 0) && (
<div className="mt-1 flex flex-wrap gap-1">
{entry.structuredTagLabelKeys.map((labelKey) => (
<span
key={labelKey}
className="bg-muted text-muted-foreground rounded-full px-2 py-0.5 text-[10px]"
>
{t(labelKey)}
</span>
))}
{entry.tags.map((tag) => (
<span
key={tag}
className="border-border/70 text-muted-foreground rounded-full border px-2 py-0.5 text-[10px]"
>
{tag}
</span>
))}
</div>
)}
</li>
);
})}
</ul>
);
}
+24 -5
View File
@@ -32,6 +32,12 @@ import {
} from "@/components/ui/dropdown-menu";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/tooltip";
import { DateTimeInput } from "@/components/ui/date-input";
import { Label } from "@/components/ui/label";
import {
@@ -416,12 +422,25 @@ export function MoodList({ onAddFirst }: MoodListProps = {}) {
)
</span>
</TableCell>
<TableCell className="text-muted-foreground text-sm">
{entry.tags.length > 0 ? entry.tags.join(", ") : "-"}
<TableCell className="text-muted-foreground max-w-[18rem] text-sm">
<span className="block truncate">
{entry.tags.length > 0 ? entry.tags.join(", ") : "-"}
</span>
{entry.note && (
<p className="text-muted-foreground/80 mt-0.5 line-clamp-2 text-xs italic">
{entry.note}
</p>
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<p className="text-muted-foreground/80 mt-0.5 line-clamp-2 cursor-default text-xs italic">
{entry.note}
</p>
</TooltipTrigger>
<TooltipContent className="max-w-xs">
<p className="text-xs whitespace-pre-wrap">
{entry.note}
</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
)}
</TableCell>
<TableCell className="text-muted-foreground text-sm">