From 7dc7fbbbe2dfbd55adfad1f11d40cdf4805105f1 Mon Sep 17 00:00:00 2001 From: fahed Date: Wed, 4 Mar 2026 23:54:32 +0300 Subject: [PATCH] fix: RTL support for timelines and header dropdown - InteractiveTimeline: dir="ltr" on scroll area, i18n for all strings - ArtefactVersionTimeline: text-start, ms-11 logical properties - Header dropdown: end-0 instead of right-0, text-start on menu items - Added 11 new timeline i18n keys (en + ar) Co-Authored-By: Claude Opus 4.6 --- .../components/ArtefactVersionTimeline.jsx | 4 +- client/src/components/Header.jsx | 8 +-- client/src/components/InteractiveTimeline.jsx | 50 ++++++++++--------- client/src/i18n/ar.json | 13 ++++- client/src/i18n/en.json | 13 ++++- 5 files changed, 56 insertions(+), 32 deletions(-) diff --git a/client/src/components/ArtefactVersionTimeline.jsx b/client/src/components/ArtefactVersionTimeline.jsx index 9f715d0..479fce9 100644 --- a/client/src/components/ArtefactVersionTimeline.jsx +++ b/client/src/components/ArtefactVersionTimeline.jsx @@ -19,7 +19,7 @@ export default function ArtefactVersionTimeline({ versions, activeVersionId, onS {showDropdown && ( -
+
{/* User info */}

{user?.name}

@@ -153,7 +153,7 @@ export default function Header() { setShowDropdown(false) window.location.href = '/users' }} - className="w-full flex items-center gap-3 px-4 py-2.5 hover:bg-surface-secondary transition-colors text-left" + className="w-full flex items-center gap-3 px-4 py-2.5 hover:bg-surface-secondary transition-colors text-start" > User Management @@ -162,7 +162,7 @@ export default function Header() { ))}
@@ -266,28 +268,28 @@ export default function InteractiveTimeline({ items = [], mapItem, onDateChange,
{/* Timeline */} -
+
{/* Day header */}
-
- Item +
+ {t('timeline.item')}
{days.map((day, i) => { @@ -336,7 +338,7 @@ export default function InteractiveTimeline({ items = [], mapItem, onDateChange, > {/* Label column */}
{isExpanded ? ( @@ -351,7 +353,7 @@ export default function InteractiveTimeline({ items = [], mapItem, onDateChange, }} className={`w-5 h-5 rounded-full border-2 border-white shadow-sm shrink-0 hover:scale-110 transition-transform ${!item.color ? (STATUS_COLORS[item.status] || 'bg-gray-400') : ''}`} style={item.color ? { backgroundColor: item.color } : undefined} - title="Change color" + title={t('timeline.changeColor')} /> )} {item.thumbnailUrl ? ( @@ -387,7 +389,7 @@ export default function InteractiveTimeline({ items = [], mapItem, onDateChange, }} className={`w-4 h-4 rounded-full border-2 border-white shadow-sm shrink-0 hover:scale-110 transition-transform ${!item.color ? (STATUS_COLORS[item.status] || 'bg-gray-400') : ''}`} style={item.color ? { backgroundColor: item.color } : undefined} - title="Change color" + title={t('timeline.changeColor')} /> )} {item.thumbnailUrl ? ( @@ -414,7 +416,7 @@ export default function InteractiveTimeline({ items = [], mapItem, onDateChange, > {idx === 0 && (
- Today + {t('timeline.today')}
)}
@@ -477,7 +479,7 @@ export default function InteractiveTimeline({ items = [], mapItem, onDateChange, )} {width > 120 && item.status && ( - + {item.status.replace(/_/g, ' ')} )} @@ -493,7 +495,7 @@ export default function InteractiveTimeline({ items = [], mapItem, onDateChange, {tag} ))} {width > 140 && item.startDate && item.endDate && ( - + {format(item.startDate, 'MMM d')} – {format(item.endDate, 'MMM d')} )} @@ -557,7 +559,7 @@ export default function InteractiveTimeline({ items = [], mapItem, onDateChange, }} className="w-full text-[10px] text-text-tertiary hover:text-text-primary text-center py-1 hover:bg-surface-tertiary rounded transition-colors" > - Reset to default + {t('timeline.resetColor')}
)} @@ -576,21 +578,21 @@ export default function InteractiveTimeline({ items = [], mapItem, onDateChange,
{tooltip.item.label}
{tooltip.item.startDate && ( -
Start: {format(tooltip.item.startDate, 'MMM d, yyyy')}
+
{t('timeline.startDate')}: {format(tooltip.item.startDate, 'MMM d, yyyy')}
)} {tooltip.item.endDate && ( -
End: {format(tooltip.item.endDate, 'MMM d, yyyy')}
+
{t('timeline.endDate')}: {format(tooltip.item.endDate, 'MMM d, yyyy')}
)} {tooltip.item.assigneeName && ( -
Assignee: {tooltip.item.assigneeName}
+
{t('timeline.assignee')}: {tooltip.item.assigneeName}
)} {tooltip.item.status && ( -
Status: {tooltip.item.status.replace(/_/g, ' ')}
+
{t('timeline.status')}: {tooltip.item.status.replace(/_/g, ' ')}
)}
{!readOnly && onDateChange && (
- Drag to move · Drag edges to resize + {t('timeline.dragToMove')} · {t('timeline.dragToResize')}
)}
diff --git a/client/src/i18n/ar.json b/client/src/i18n/ar.json index 8e29ed0..630dbc9 100644 --- a/client/src/i18n/ar.json +++ b/client/src/i18n/ar.json @@ -351,13 +351,24 @@ "timeline.day": "يوم", "timeline.week": "أسبوع", "timeline.today": "اليوم", - "timeline.startDate": "تاريخ البدء", + "timeline.startDate": "البداية", + "timeline.endDate": "النهاية", + "timeline.assignee": "المُكلّف", + "timeline.status": "الحالة", "timeline.dragToMove": "اسحب للنقل", "timeline.dragToResize": "اسحب الحواف لتغيير الحجم", "timeline.noItems": "لا توجد عناصر للعرض", "timeline.addItems": "أضف عناصر بتواريخ لعرض الجدول الزمني", "timeline.tracks": "المسارات", "timeline.timeline": "الجدول الزمني", + "timeline.item": "العنصر", + "timeline.month": "شهر", + "timeline.compact": "مضغوط", + "timeline.expand": "موسّع", + "timeline.resetColor": "إعادة إلى الافتراضي", + "timeline.changeColor": "تغيير اللون", + "timeline.compactBars": "أشرطة مضغوطة", + "timeline.expandedBars": "أشرطة موسّعة", "posts.details": "التفاصيل", "posts.platformsLinks": "المنصات والروابط", "posts.discussion": "النقاش", diff --git a/client/src/i18n/en.json b/client/src/i18n/en.json index cac5151..6835a5b 100644 --- a/client/src/i18n/en.json +++ b/client/src/i18n/en.json @@ -351,13 +351,24 @@ "timeline.day": "Day", "timeline.week": "Week", "timeline.today": "Today", - "timeline.startDate": "Start Date", + "timeline.startDate": "Start", + "timeline.endDate": "End", + "timeline.assignee": "Assignee", + "timeline.status": "Status", "timeline.dragToMove": "Drag to move", "timeline.dragToResize": "Drag edges to resize", "timeline.noItems": "No items to display", "timeline.addItems": "Add items with dates to see the timeline", "timeline.tracks": "Tracks", "timeline.timeline": "Timeline", + "timeline.item": "Item", + "timeline.month": "Month", + "timeline.compact": "Compact", + "timeline.expand": "Expand", + "timeline.resetColor": "Reset to default", + "timeline.changeColor": "Change color", + "timeline.compactBars": "Compact bars", + "timeline.expandedBars": "Expanded bars", "posts.details": "Details", "posts.platformsLinks": "Platforms & Links", "posts.discussion": "Discussion",