From ea6d0ee6784fe18ad7e7dfca7416621e8f3b788a Mon Sep 17 00:00:00 2001 From: Sebastian Sanitz Date: Mon, 28 Sep 2026 23:42:30 +0200 Subject: [PATCH 1/2] fix(calendar): size the week view all-day area from the visible week The all-day/tasks area in the week view took its height from (allDayRowCount + taskRowCount) across every loaded day. Since free scrolling loads 37 to 180 days, one crowded day anywhere in that range blew the header up to 250+ px for every week and pushed the time grid down; tasks were also stacked below the global all-day row count, leaving a gap on days without all-day events. - Stack each day's tasks directly below that day's all-day events. - Size the area from the days in view only: track the first visible day by date (so columns prepended while loading do not shift it) plus the number of visible columns (7 on desktop, by width on mobile). - Cap the area at 3 rows with an expand/collapse toggle when a visible day has more entries. Tests cover per-day task stacking, the 3-row cap and toggle, an empty week next to a crowded one, and the area growing when scrolling into it. Co-Authored-By: Claude Opus 5.5 --- .../calendar-week-view-all-day-cap.test.tsx | 188 ++++++++++++++++++ components/calendar/calendar-week-view.tsx | 154 +++++++++----- 2 files changed, 293 insertions(+), 49 deletions(-) create mode 100644 components/calendar/__tests__/calendar-week-view-all-day-cap.test.tsx diff --git a/components/calendar/__tests__/calendar-week-view-all-day-cap.test.tsx b/components/calendar/__tests__/calendar-week-view-all-day-cap.test.tsx new file mode 100644 index 000000000..1fc4014fd --- /dev/null +++ b/components/calendar/__tests__/calendar-week-view-all-day-cap.test.tsx @@ -0,0 +1,188 @@ +import { render, screen, fireEvent, cleanup } from '@testing-library/react'; +import { describe, it, expect, vi, afterEach } from 'vitest'; +import { CalendarWeekView } from '../calendar-week-view'; +import type { CalendarEvent, Calendar, CalendarTask } from '@/lib/jmap/types'; + +const calendars = [{ id: 'cal-1', name: 'Work', color: '#123456' }] as unknown as Calendar[]; + +function makeTask(id: string, due: string, overrides: Partial = {}): CalendarTask { + return { + id, + '@type': 'Task', + uid: id, + title: 'Task ' + id, + description: '', + due, + start: null, + duration: null, + timeZone: null, + showWithoutTime: true, + progress: 'needs-action', + priority: 0, + privacy: 'public', + keywords: null, + categories: null, + color: null, + created: null, + updated: '2026-09-01T00:00:00Z', + recurrenceRules: null, + alerts: null, + relatedTo: null, + calendarIds: { 'cal-1': true }, + ...overrides, + }; +} + +function makeAllDayEvent(id: string, start: string): CalendarEvent { + return { + id, + '@type': 'Event', + uid: id, + title: 'Event ' + id, + start, + duration: 'P1D', + showWithoutTime: true, + calendarIds: { 'cal-1': true }, + } as unknown as CalendarEvent; +} + +type Props = React.ComponentProps; + +function renderView(overrides: Partial = {}) { + const props: Props = { + focus: { date: new Date(2026, 8, 9), nonce: 0 }, + windowKey: 'week:2026-09-07', + // Monday 7 Sep to Sunday 13 Sep 2026 + rangeStart: new Date(2026, 8, 7), + rangeEnd: new Date(2026, 8, 13), + selectedDate: new Date(2026, 8, 9), + events: [], + calendars, + onSelectDate: vi.fn(), + onSelectEvent: vi.fn(), + onCreateAtTime: vi.fn(), + ...overrides, + }; + return { props, ...render() }; +} + +function chipSlot(taskId: string): HTMLElement { + const chip = document.querySelector(`[data-calendar-task="${taskId}"]`); + if (!chip?.parentElement) throw new Error(`no chip for ${taskId}`); + return chip.parentElement; +} + +describe('CalendarWeekView all-day and tasks height cap', () => { + afterEach(() => { + cleanup(); + }); + + it('stacks tasks directly below events of their own day instead of global allDayRowCount', () => { + // Monday 2026-09-07 has 2 all-day events + // Tuesday 2026-09-08 has NO events, but 1 task + renderView({ + events: [ + makeAllDayEvent('e1', '2026-09-07'), + makeAllDayEvent('e2', '2026-09-07'), + ], + tasks: [ + makeTask('t-tue', '2026-09-08'), + ], + }); + + // Tuesday's task must start at row 0 (top: 2px), NOT pushed down to row 2 (top: 50px) + const tueSlot = chipSlot('t-tue'); + expect(tueSlot.style.top).toBe('2px'); + }); + + it('caps all-day height to default max rows (3 rows = 76px) and provides an expand toggle when crowded', () => { + // Monday 2026-09-07 has 5 tasks (rows 0..4) + renderView({ + tasks: [ + makeTask('t1', '2026-09-07'), + makeTask('t2', '2026-09-07'), + makeTask('t3', '2026-09-07'), + makeTask('t4', '2026-09-07'), + makeTask('t5', '2026-09-07'), + ], + }); + + const toggle = screen.getByRole('button', { name: /all-day-expand/i }); + expect(toggle).toBeInTheDocument(); + expect(toggle).toHaveAttribute('aria-expanded', 'false'); + + // Default height is capped to 3 rows (3 * 24 + 4 = 76px) + const allDayGrid = document.querySelector('[data-testid="all-day-grid"]'); + expect(allDayGrid).toBeInTheDocument(); + expect(allDayGrid?.style.height).toBe('76px'); + + // Click toggle to expand + fireEvent.click(toggle); + expect(toggle).toHaveAttribute('aria-expanded', 'true'); + expect(allDayGrid?.style.height).toBe('124px'); // 5 * 24 + 4 + }); + + it('sizes the all-day area from the visible week, not from other loaded weeks (#1293)', () => { + // Three weeks loaded (free scrolling), the focused first week is empty; + // a crowded day two weeks later must not add height or a toggle here. + renderView({ + rangeStart: new Date(2026, 8, 7), + rangeEnd: new Date(2026, 8, 27), + windowKey: 'week:2026-09-07:3w', + events: [ + makeAllDayEvent('e1', '2026-09-23'), + makeAllDayEvent('e2', '2026-09-23'), + makeAllDayEvent('e3', '2026-09-23'), + makeAllDayEvent('e4', '2026-09-23'), + ], + }); + + expect(screen.queryByRole('button', { name: /all-day-expand/i })).toBeNull(); + expect(document.querySelector('[data-testid="all-day-grid"]')).toBeNull(); + }); + + it('still sizes the all-day area from entries in the visible week (#1293)', () => { + renderView({ + rangeStart: new Date(2026, 8, 7), + rangeEnd: new Date(2026, 8, 27), + windowKey: 'week:2026-09-07:3w', + events: [ + makeAllDayEvent('e1', '2026-09-08'), + makeAllDayEvent('e2', '2026-09-23'), + makeAllDayEvent('e3', '2026-09-23'), + makeAllDayEvent('e4', '2026-09-23'), + ], + }); + + const allDayGrid = document.querySelector('[data-testid="all-day-grid"]'); + expect(allDayGrid?.style.height).toBe('28px'); + expect(screen.queryByRole('button', { name: /all-day-expand/i })).toBeNull(); + }); + + it('resizes the all-day area when scrolling to a crowded week (#1293)', async () => { + renderView({ + rangeStart: new Date(2026, 8, 7), + rangeEnd: new Date(2026, 8, 27), + windowKey: 'week:2026-09-07:3w', + events: [ + makeAllDayEvent('e1', '2026-09-23'), + makeAllDayEvent('e2', '2026-09-23'), + makeAllDayEvent('e3', '2026-09-23'), + makeAllDayEvent('e4', '2026-09-23'), + ], + }); + expect(document.querySelector('[data-testid="all-day-grid"]')).toBeNull(); + + // Scroll the strip to Monday 21 Sep: 14 columns of the measured width + const strip = document.querySelector('[role="grid"]')!; + const columns = document.querySelector('[style*="grid-template-columns"]')!; + const colWidth = parseInt(/(\d+)px/.exec(columns.style.gridTemplateColumns)![1], 10); + strip.scrollLeft = 14 * colWidth; + fireEvent.scroll(strip); + await new Promise((r) => requestAnimationFrame(() => r(null))); + + const allDayGrid = await screen.findByTestId('all-day-grid'); + expect(allDayGrid.style.height).toBe('76px'); + expect(screen.getByRole('button', { name: /all-day-expand/i })).toBeInTheDocument(); + }); +}); diff --git a/components/calendar/calendar-week-view.tsx b/components/calendar/calendar-week-view.tsx index 733bb2a5d..e41b0a197 100644 --- a/components/calendar/calendar-week-view.tsx +++ b/components/calendar/calendar-week-view.tsx @@ -100,15 +100,22 @@ export function CalendarWeekView({ return Math.max(MIN_COL_WIDTH, Math.floor((root.clientWidth - gutterWidth) / 7)); }, [isMobile, gutterWidth]); const [colWidth, setColWidth] = useState(MOBILE_COL_WIDTH); + const [viewportWidth, setViewportWidth] = useState(0); + // First day in view, reported by the scroll handler below (#1293) + const [visibleDayKey, setVisibleDayKey] = useState(null); useLayoutEffect(() => { const root = rootRef.current; if (!root) return; - setColWidth(measureColWidth(root)); + const measure = () => { + setColWidth(measureColWidth(root)); + setViewportWidth(Math.max(0, root.clientWidth - gutterWidth)); + }; + measure(); if (typeof ResizeObserver === "undefined") return; - const observer = new ResizeObserver(() => setColWidth(measureColWidth(root))); + const observer = new ResizeObserver(measure); observer.observe(root); return () => observer.disconnect(); - }, [measureColWidth]); + }, [measureColWidth, gutterWidth]); // Every scroll offset is computed with the column width that is rendered. // When that width changes (first measurement, resize) keep the same day at @@ -177,26 +184,55 @@ export function CalendarWeekView({ return packWeekSegments([...explicitAllDay, ...timedFullDay]); }, [events, days]); - const allDayRowCount = useMemo(() => { - return allDaySegments.reduce((maxRows, segment) => Math.max(maxRows, segment.row + 1), 0); - }, [allDaySegments]); - const tasksByDay = useMemo(() => groupTasksByDueDay(tasks), [tasks]); - // Max tasks on any single loaded day - const taskRowCount = useMemo(() => { + // Tasks stack under the events of their own day rather than globally (#1107, #1270) + const dayEventRows = useMemo(() => { + return days.map((_, dayIndex) => + allDaySegments.reduce( + (rows, segment) => + dayIndex >= segment.startIndex && dayIndex < segment.startIndex + segment.span + ? Math.max(rows, segment.row + 1) + : rows, + 0, + ) + ); + }, [days, allDaySegments]); + + // The strip holds weeks to months of days (#759), but the all-day area is + // sized from the columns in view: a crowded day in another week must not + // add empty rows or an expand toggle here (#1293). The first visible day is + // tracked by date, so columns prepended while loading do not shift it. + const visibleStartIndex = useMemo(() => { + const tracked = visibleDayKey ? days.findIndex((d) => dayKey(d) === visibleDayKey) : -1; + if (tracked >= 0) return tracked; + const target = isMobile ? focus.date : startOfWeek(focus.date, { weekStartsOn: weekStart }); + return Math.max(0, Math.min(days.length - 1, differenceInCalendarDays(target, rangeStart))); + }, [visibleDayKey, days, isMobile, focus.date, weekStart, rangeStart]); + const visibleColumns = isMobile ? Math.max(1, Math.ceil(viewportWidth / colWidth)) : 7; + + // Max combined rows (events + tasks) across the visible days + const maxContentRows = useMemo(() => { let max = 0; - for (const day of days) { - const key = format(day, "yyyy-MM-dd"); - const count = tasksByDay.get(key)?.length ?? 0; - if (count > max) max = count; + const end = Math.min(days.length, visibleStartIndex + visibleColumns); + for (let i = visibleStartIndex; i < end; i++) { + const key = format(days[i], "yyyy-MM-dd"); + const taskCount = tasksByDay.get(key)?.length ?? 0; + const total = dayEventRows[i] + taskCount; + if (total > max) max = total; } return max; - }, [tasksByDay, days]); + }, [days, dayEventRows, tasksByDay, visibleStartIndex, visibleColumns]); const hasAllDay = useMemo(() => { - return allDaySegments.length > 0 || taskRowCount > 0; - }, [allDaySegments, taskRowCount]); + return maxContentRows > 0; + }, [maxContentRows]); + + const DEFAULT_ALL_DAY_MAX_ROWS = 3; + const [isAllDayExpanded, setIsAllDayExpanded] = useState(false); + const isExpandable = maxContentRows > DEFAULT_ALL_DAY_MAX_ROWS; + const visibleRows = isAllDayExpanded ? maxContentRows : Math.min(DEFAULT_ALL_DAY_MAX_ROWS, maxContentRows); + const allDayHeight = Math.max(28, visibleRows * 24 + 4); useEffect(() => { if (rootRef.current) { @@ -258,6 +294,7 @@ export function CalendarWeekView({ const key = dayKey(day); if (key === visibleKeyRef.current) return; visibleKeyRef.current = key; + setVisibleDayKey(key); onVisibleDateChange?.(day); }); }, [colWidth, colCount, days, onVisibleDateChange]); @@ -323,14 +360,34 @@ export function CalendarWeekView({ {hasAllDay && (
- {t("events.all_day")} + {t("events.all_day")} + {isExpandable && ( + + )}
{days.map((day) => (
- {/* Task chips in all-day area */} - {taskRowCount > 0 && ( -
- {days.map((day, dayIndex) => { - const key = format(day, "yyyy-MM-dd"); - const dayTasks = tasksByDay.get(key) || []; - return dayTasks.map((task, taskIndex) => ( -
- task.calendarIds[c.id])} - onToggleComplete={onToggleTaskComplete} - onSelect={onSelectTask} - /> -
- )); - })} -
- )} + {/* Task chips in all-day area, stacked under events of their day (#1107, #1270) */} +
+ {days.map((day, dayIndex) => { + const key = format(day, "yyyy-MM-dd"); + const dayTasks = tasksByDay.get(key) || []; + const baseRow = dayEventRows[dayIndex]; + return dayTasks.map((task, taskIndex) => ( +
+ task.calendarIds[c.id])} + onToggleComplete={onToggleTaskComplete} + onSelect={onSelectTask} + /> +
+ )); + })} +
)} From 695cc7303fa4010ba7552d818ca59aa64e15349b Mon Sep 17 00:00:00 2001 From: Sebastian Sanitz Date: Tue, 29 Sep 2026 00:08:15 +0200 Subject: [PATCH 2/2] fix(calendar): add translations for the all-day expand toggle The expand/collapse toggle referenced calendar.events.show_more and show_less, which were missing from every locale (translations test failed), and passed a defaultMessage option next-intl does not support. Add both keys to all 27 locales, reusing each locale's existing email_composer.show_less wording, and drop the unsupported option. Co-Authored-By: Claude Opus 5.5 --- components/calendar/calendar-week-view.tsx | 2 +- locales/ar/common.json | 2 ++ locales/ca/common.json | 2 ++ locales/cs/common.json | 2 ++ locales/da/common.json | 2 ++ locales/de/common.json | 2 ++ locales/en/common.json | 2 ++ locales/es/common.json | 2 ++ locales/fa/common.json | 2 ++ locales/fr/common.json | 2 ++ locales/he/common.json | 2 ++ locales/hu/common.json | 2 ++ locales/it/common.json | 2 ++ locales/ja/common.json | 2 ++ locales/ko/common.json | 2 ++ locales/lv/common.json | 2 ++ locales/mn/common.json | 2 ++ locales/nb/common.json | 2 ++ locales/nl/common.json | 2 ++ locales/pl/common.json | 2 ++ locales/pt/common.json | 2 ++ locales/ro/common.json | 2 ++ locales/ru/common.json | 2 ++ locales/sk/common.json | 2 ++ locales/tr/common.json | 2 ++ locales/uk/common.json | 2 ++ locales/zh-TW/common.json | 2 ++ locales/zh/common.json | 2 ++ 28 files changed, 55 insertions(+), 1 deletion(-) diff --git a/components/calendar/calendar-week-view.tsx b/components/calendar/calendar-week-view.tsx index e41b0a197..9060c7482 100644 --- a/components/calendar/calendar-week-view.tsx +++ b/components/calendar/calendar-week-view.tsx @@ -371,7 +371,7 @@ export function CalendarWeekView({ aria-expanded={isAllDayExpanded} onClick={() => setIsAllDayExpanded((prev) => !prev)} className="self-end mt-auto text-[10px] text-muted-foreground hover:text-foreground flex items-center gap-0.5 rounded px-1 py-0.5 hover:bg-muted transition-colors cursor-pointer" - title={isAllDayExpanded ? t("events.show_less", { defaultMessage: "Weniger anzeigen" }) : t("events.show_more", { defaultMessage: "Mehr anzeigen" })} + title={isAllDayExpanded ? t("events.show_less") : t("events.show_more")} > {isAllDayExpanded ? ( ▲ diff --git a/locales/ar/common.json b/locales/ar/common.json index 40edbe4a4..a954d571c 100644 --- a/locales/ar/common.json +++ b/locales/ar/common.json @@ -2849,6 +2849,8 @@ "no_events": "لا توجد أحداث", "all_day": "طوال اليوم", "more": "+{count} أخرى", + "show_more": "إظهار المزيد", + "show_less": "إظهار أقل", "no_title": "(بلا عنوان)", "resize": "تغيير حجم الحدث", "duplicate": "تكرار", diff --git a/locales/ca/common.json b/locales/ca/common.json index d6ab95b44..84c55a008 100644 --- a/locales/ca/common.json +++ b/locales/ca/common.json @@ -2849,6 +2849,8 @@ "no_events": "Cap esdeveniment", "all_day": "Tot el dia", "more": "+{count} més", + "show_more": "Mostra'n més", + "show_less": "Mostra'n menys", "no_title": "(Sense títol)", "resize": "Redimensiona l'esdeveniment", "duplicate": "Duplica", diff --git a/locales/cs/common.json b/locales/cs/common.json index c3d7d2516..300d6e3b8 100644 --- a/locales/cs/common.json +++ b/locales/cs/common.json @@ -2849,6 +2849,8 @@ "no_events": "Žádné události", "all_day": "Celý den", "more": "+{count} dalších", + "show_more": "Zobrazit více", + "show_less": "Zobrazit méně", "no_title": "(Bez názvu)", "resize": "Změnit velikost události", "duplicate": "Duplikovat", diff --git a/locales/da/common.json b/locales/da/common.json index 9bdaf8200..690c52a66 100644 --- a/locales/da/common.json +++ b/locales/da/common.json @@ -2849,6 +2849,8 @@ "no_events": "Ingen begivenheder", "all_day": "Hele dagen", "more": "+{count} mere", + "show_more": "Vis mere", + "show_less": "Vis mindre", "no_title": "(Ingen titel)", "resize": "Tilpas størrelse på begivenhed", "duplicate": "Duplikér", diff --git a/locales/de/common.json b/locales/de/common.json index 32a34dce9..3d33205f1 100644 --- a/locales/de/common.json +++ b/locales/de/common.json @@ -2849,6 +2849,8 @@ "no_events": "Keine Termine", "all_day": "Ganztägig", "more": "+{count} weitere", + "show_more": "Mehr anzeigen", + "show_less": "Weniger anzeigen", "no_title": "(Kein Titel)", "resize": "Termingröße ändern", "duplicate": "Duplizieren", diff --git a/locales/en/common.json b/locales/en/common.json index 6351deb09..0cb51cbe3 100644 --- a/locales/en/common.json +++ b/locales/en/common.json @@ -2849,6 +2849,8 @@ "no_events": "No events", "all_day": "All day", "more": "+{count} more", + "show_more": "Show more", + "show_less": "Show less", "no_title": "(No title)", "resize": "Resize event", "duplicate": "Duplicate", diff --git a/locales/es/common.json b/locales/es/common.json index 19277a354..949331491 100644 --- a/locales/es/common.json +++ b/locales/es/common.json @@ -2849,6 +2849,8 @@ "no_events": "Sin eventos", "all_day": "Todo el día", "more": "+{count} más", + "show_more": "Mostrar más", + "show_less": "Mostrar menos", "no_title": "(Sin título)", "resize": "Redimensionar evento", "duplicate": "Duplicar", diff --git a/locales/fa/common.json b/locales/fa/common.json index e04947863..9f26e7a35 100644 --- a/locales/fa/common.json +++ b/locales/fa/common.json @@ -2849,6 +2849,8 @@ "no_events": "رویدادی نیست", "all_day": "تمام روز", "more": "+{count} بیشتر", + "show_more": "نمایش بیشتر", + "show_less": "نمایش کمتر", "no_title": "(بدون عنوان)", "resize": "تغییر اندازه رویداد", "duplicate": "کپی", diff --git a/locales/fr/common.json b/locales/fr/common.json index cb3a83a84..dccd929c9 100644 --- a/locales/fr/common.json +++ b/locales/fr/common.json @@ -2849,6 +2849,8 @@ "no_events": "Aucun événement", "all_day": "Toute la journée", "more": "+{count} de plus", + "show_more": "Afficher plus", + "show_less": "Afficher moins", "no_title": "(Sans titre)", "resize": "Redimensionner l'événement", "duplicate": "Dupliquer", diff --git a/locales/he/common.json b/locales/he/common.json index facbf4196..04f1dc3be 100644 --- a/locales/he/common.json +++ b/locales/he/common.json @@ -2773,6 +2773,8 @@ "no_events": "אין אירועים", "all_day": "כל היום", "more": "+{count}נוספים", + "show_more": "הצג עוד", + "show_less": "הצג פחות", "no_title": "(ללא כותרת)", "resize": "שנה את גודל האירוע", "duplicate": "שכפול", diff --git a/locales/hu/common.json b/locales/hu/common.json index 918cbb841..64da73cff 100644 --- a/locales/hu/common.json +++ b/locales/hu/common.json @@ -2849,6 +2849,8 @@ "no_events": "Nincs esemény", "all_day": "Egész napos", "more": "+{count} további", + "show_more": "Több mutatása", + "show_less": "Kevesebb mutatása", "no_title": "(Nincs cím)", "resize": "Esemény átméretezése", "duplicate": "Duplikálás", diff --git a/locales/it/common.json b/locales/it/common.json index bda0dbe9e..54e7132ee 100644 --- a/locales/it/common.json +++ b/locales/it/common.json @@ -2849,6 +2849,8 @@ "no_events": "Nessun evento", "all_day": "Tutto il giorno", "more": "+{count} altri", + "show_more": "Mostra di più", + "show_less": "Mostra meno", "no_title": "(Senza titolo)", "resize": "Ridimensiona evento", "duplicate": "Duplica", diff --git a/locales/ja/common.json b/locales/ja/common.json index c8c24d96e..a473054a2 100644 --- a/locales/ja/common.json +++ b/locales/ja/common.json @@ -2849,6 +2849,8 @@ "no_events": "予定なし", "all_day": "終日", "more": "他{count}件", + "show_more": "展開する", + "show_less": "折りたたむ", "no_title": "(タイトルなし)", "resize": "イベントのサイズ変更", "duplicate": "複製", diff --git a/locales/ko/common.json b/locales/ko/common.json index 980ce19d1..b3e4baf31 100644 --- a/locales/ko/common.json +++ b/locales/ko/common.json @@ -2849,6 +2849,8 @@ "no_events": "일정이 없어요", "all_day": "하루 종일", "more": "+{count}개 더보기", + "show_more": "더 보기", + "show_less": "간략히 보기", "no_title": "(제목 없음)", "resize": "일정 크기 조절", "duplicate": "복제", diff --git a/locales/lv/common.json b/locales/lv/common.json index f3ab666f1..91ea61457 100644 --- a/locales/lv/common.json +++ b/locales/lv/common.json @@ -2848,6 +2848,8 @@ "no_events": "Nav pasākumu", "all_day": "Visa diena", "more": "vēl {count}", + "show_more": "Rādīt vairāk", + "show_less": "Rādīt mazāk", "no_title": "(Bez virsraksta)", "resize": "Mainīt pasākuma laiku", "duplicate": "Dublēt", diff --git a/locales/mn/common.json b/locales/mn/common.json index 7181171d0..c9d3761e0 100644 --- a/locales/mn/common.json +++ b/locales/mn/common.json @@ -2849,6 +2849,8 @@ "no_events": "Үйл явдал байхгүй", "all_day": "Бүтэн өдөр", "more": "+{count} дэлгэрэнгүй", + "show_more": "Илүү харуулах", + "show_less": "Бага харуулах", "no_title": "(Гарчиггүй)", "resize": "Үйл явдлын хэмжээг өөрчлөх", "duplicate": "Давхардсан", diff --git a/locales/nb/common.json b/locales/nb/common.json index c859c67c0..d971fa244 100644 --- a/locales/nb/common.json +++ b/locales/nb/common.json @@ -2849,6 +2849,8 @@ "no_events": "Ingen hendelser", "all_day": "Hele dagen", "more": "+{count} til", + "show_more": "Vis flere", + "show_less": "Vis færre", "no_title": "(Ingen tittel)", "resize": "Endre størrelsen på hendelsen", "duplicate": "Dupliser", diff --git a/locales/nl/common.json b/locales/nl/common.json index 72110bb08..3b1e617ab 100644 --- a/locales/nl/common.json +++ b/locales/nl/common.json @@ -2849,6 +2849,8 @@ "no_events": "Geen evenementen", "all_day": "Hele dag", "more": "+{count} meer", + "show_more": "Meer tonen", + "show_less": "Minder tonen", "no_title": "(Geen titel)", "resize": "Evenement formaat wijzigen", "duplicate": "Dupliceren", diff --git a/locales/pl/common.json b/locales/pl/common.json index 35adb3a71..0e55d7013 100644 --- a/locales/pl/common.json +++ b/locales/pl/common.json @@ -2849,6 +2849,8 @@ "no_events": "Brak wydarzeń", "all_day": "Cały dzień", "more": "+{count} więcej", + "show_more": "Pokaż więcej", + "show_less": "Pokaż mniej", "no_title": "(Bez tytułu)", "resize": "Zmień rozmiar wydarzenia", "duplicate": "Duplikuj", diff --git a/locales/pt/common.json b/locales/pt/common.json index d32107790..b87d44369 100644 --- a/locales/pt/common.json +++ b/locales/pt/common.json @@ -2849,6 +2849,8 @@ "no_events": "Nenhum evento", "all_day": "Dia inteiro", "more": "+{count} mais", + "show_more": "Mostrar mais", + "show_less": "Mostrar menos", "no_title": "(Sem título)", "resize": "Redimensionar evento", "duplicate": "Duplicar", diff --git a/locales/ro/common.json b/locales/ro/common.json index dbfb3d78f..bbc6d407e 100644 --- a/locales/ro/common.json +++ b/locales/ro/common.json @@ -2849,6 +2849,8 @@ "no_events": "Fără evenimente", "all_day": "Toată ziua", "more": "+{count} mai multe", + "show_more": "Afișați mai mult", + "show_less": "Afișați mai puțin", "no_title": "(Fără titlu)", "resize": "Eveniment de redimensionare", "duplicate": "Duplicare", diff --git a/locales/ru/common.json b/locales/ru/common.json index 6c5be0f5a..51720d0e0 100644 --- a/locales/ru/common.json +++ b/locales/ru/common.json @@ -2849,6 +2849,8 @@ "no_events": "Нет событий", "all_day": "Весь день", "more": "ещё {count}", + "show_more": "Развернуть", + "show_less": "Свернуть", "no_title": "(Без названия)", "resize": "Изменить размер события", "duplicate": "Дублировать", diff --git a/locales/sk/common.json b/locales/sk/common.json index 7234cbf76..b88f5a60f 100644 --- a/locales/sk/common.json +++ b/locales/sk/common.json @@ -2849,6 +2849,8 @@ "no_events": "Žiadne udalosti", "all_day": "Celý deň", "more": "+{count} ďalších", + "show_more": "Zobraziť viac", + "show_less": "Zobraziť menej", "no_title": "(Bez názvu)", "resize": "Zmeniť veľkosť udalosti", "duplicate": "Duplikovať", diff --git a/locales/tr/common.json b/locales/tr/common.json index 0cdabeaab..0b784e362 100644 --- a/locales/tr/common.json +++ b/locales/tr/common.json @@ -2849,6 +2849,8 @@ "no_events": "Etkinlik yok", "all_day": "Tüm gün", "more": "+{count} daha", + "show_more": "Daha fazla göster", + "show_less": "Daha az göster", "no_title": "(Başlık yok)", "resize": "Etkinliği yeniden boyutlandır", "duplicate": "Çoğalt", diff --git a/locales/uk/common.json b/locales/uk/common.json index e34a75da5..e03ca789e 100644 --- a/locales/uk/common.json +++ b/locales/uk/common.json @@ -2849,6 +2849,8 @@ "no_events": "Подій немає", "all_day": "Весь день", "more": "+ ще {count}", + "show_more": "Показувати більше", + "show_less": "Показувати менше", "no_title": "(Без назви)", "resize": "Змінити розмір події", "duplicate": "дублікат", diff --git a/locales/zh-TW/common.json b/locales/zh-TW/common.json index ae3679bba..4d345334b 100644 --- a/locales/zh-TW/common.json +++ b/locales/zh-TW/common.json @@ -2849,6 +2849,8 @@ "no_events": "沒有活動", "all_day": "全天", "more": "另有 {count} 個", + "show_more": "顯示更多", + "show_less": "顯示較少", "no_title": "(無標題)", "resize": "調整活動大小", "duplicate": "建立副本", diff --git a/locales/zh/common.json b/locales/zh/common.json index 196c79310..07287e69a 100644 --- a/locales/zh/common.json +++ b/locales/zh/common.json @@ -2849,6 +2849,8 @@ "no_events": "没有活动", "all_day": "全天", "more": "+{count} 更多", + "show_more": "展开", + "show_less": "收起", "no_title": "(无标题)", "resize": "调整事件大小", "duplicate": "复制",