Tidy the upcoming-meeting alert Details panel

The expanded Details panel had two visible problems pointed out by the user:

1. The "Notes / الملاحظات" block always rendered — including a "No notes
   added." fallback for meetings without notes — adding empty noise the
   user did not want.
2. Attendee names were printed as plain text but the database stores them
   as sanitized rich-text HTML, so they showed up as literal "<p>محمد علي</p>".

Changes:
- Removed the entire Notes block from the DetailsPanel sub-component in
  artifacts/tx-os/src/components/executive-meetings/upcoming-meeting-alert.tsx.
  Dropped the unused StickyNote icon import and the now-unused notesText
  constant.
- Each attendee name is now rendered with the same HTML-stripping pattern
  the popup already uses for the meeting title:
  name.replace(/<[^>]+>/g, "").trim() || name.
- Removed the now-unused i18n keys executiveMeetings.alert.detailsNotes
  and detailsNoNotes from both en.json and ar.json.

Out of scope (per plan): no schema/API changes, no rich-text rendering
of attendee names, no color/toggle changes.

Verification:
- TypeScript: clean.
- e2e (testing skill): a fresh meeting with HTML-tagged attendee names
  was created, the popup expanded, and the test confirmed (a) no Notes
  section / "alert-details-notes" testid present, (b) attendee names
  visible without "<p>", "</p>", "<span>" tags, and (c) the meeting URL
  link still renders.
This commit is contained in:
riyadhafraa
2026-05-01 18:27:34 +00:00
parent b60935ed00
commit 80d6267599
3 changed files with 9 additions and 29 deletions
@@ -34,7 +34,6 @@ import {
Clock,
ExternalLink,
GripVertical,
StickyNote,
Users,
X,
} from "lucide-react";
@@ -1350,7 +1349,6 @@ function DetailsPanel({
groups[key].push(p);
}
const notesText = (meeting.notes ?? "").replace(/<[^>]+>/g, "").trim();
const safeUrl = (() => {
const raw = (meeting.meetingUrl ?? "").trim();
if (!raw) return null;
@@ -1393,26 +1391,6 @@ function DetailsPanel({
</div>
) : null}
<div className="mb-2 flex items-start gap-2">
<StickyNote
className="mt-0.5 h-3.5 w-3.5 shrink-0 opacity-70"
aria-hidden="true"
/>
<div className="min-w-0 flex-1">
<div className="font-semibold opacity-80">
{t("executiveMeetings.alert.detailsNotes")}
</div>
<div
className="whitespace-pre-wrap break-words opacity-90"
data-testid="alert-details-notes"
>
{notesText.length > 0
? notesText
: t("executiveMeetings.alert.detailsNoNotes")}
</div>
</div>
</div>
<div className="flex items-start gap-2">
<Users
className="mt-0.5 h-3.5 w-3.5 shrink-0 opacity-70"
@@ -1442,9 +1420,15 @@ function DetailsPanel({
{t(`executiveMeetings.alert.detailsGroup.${g}`)}
</div>
<ul className="list-disc ps-4 leading-snug">
{list.map((p, idx) => (
<li key={`${g}-${p.id ?? idx}-${p.name}`}>{p.name}</li>
))}
{list.map((p, idx) => {
const cleanName =
p.name.replace(/<[^>]+>/g, "").trim() || p.name;
return (
<li key={`${g}-${p.id ?? idx}-${p.name}`}>
{cleanName}
</li>
);
})}
</ul>
</div>
);
-2
View File
@@ -1068,8 +1068,6 @@
"details": "تفاصيل",
"detailsClose": "إخفاء التفاصيل",
"detailsUrl": "رابط الاجتماع",
"detailsNotes": "الملاحظات",
"detailsNoNotes": "لا توجد ملاحظات.",
"detailsAttendees": "الحضور ({{n}})",
"detailsNoAttendees": "لا يوجد حضور بعد.",
"detailsGroup": {
-2
View File
@@ -986,8 +986,6 @@
"details": "Details",
"detailsClose": "Hide details",
"detailsUrl": "Meeting link",
"detailsNotes": "Notes",
"detailsNoNotes": "No notes added.",
"detailsAttendees": "Attendees ({{n}})",
"detailsNoAttendees": "No attendees yet.",
"detailsGroup": {