diff --git a/client/src/mobile/components/MDayPager.tsx b/client/src/mobile/components/MDayPager.tsx index fc0fffc5b..b40d80478 100644 --- a/client/src/mobile/components/MDayPager.tsx +++ b/client/src/mobile/components/MDayPager.tsx @@ -27,8 +27,11 @@ const SETTLE_MS = 90; /** How close to a page edge counts as resting on it. */ const REST_PX = 2; +/** Anything with an id pages: trip days, a leave year's months, the plan's years. */ +export type PagerItem = Pick; + export interface MDayPagerProps { - days: Day[]; + days: PagerItem[]; selectedDayId: number | null; onSelectDay: (dayId: number) => void; /** Draws one day. Pages other than the current one are inert and hidden @@ -38,6 +41,12 @@ export interface MDayPagerProps { locked?: boolean; /** Live-region text after a swipe lands on a day. */ describeDay: (index: number, total: number) => string; + /** + * In the page's flow instead of filling a positioned parent: the strip takes + * the height of its tallest page, for content that sits in a scrolling column + * (Vacay's month editor and year grid) rather than over the whole screen. + */ + inFlow?: boolean; } interface Page { @@ -49,7 +58,7 @@ interface Page { /** The window of pages around the selection. A selection that points at no * day (the whole-trip view, or a day deleted remotely) still gets its page, * with the first day next to it as a way back. */ -export function pagesFor(days: Day[], selectedDayId: number | null): Page[] { +export function pagesFor(days: PagerItem[], selectedDayId: number | null): Page[] { const i = days.findIndex((d) => d.id === selectedDayId); if (i < 0) { const first = days[0]; @@ -74,6 +83,7 @@ export default function MDayPager({ renderDay, locked = false, describeDay, + inFlow = false, }: MDayPagerProps) { const stripRef = useRef(null); const [announcement, setAnnouncement] = useState(''); @@ -177,7 +187,7 @@ export default function MDayPager({
{pages.map((page) => (
{renderDay(page.dayId, page.active)}
diff --git a/client/src/mobile/screens/vacay/MVacay.tsx b/client/src/mobile/screens/vacay/MVacay.tsx index 455d4d9e1..c751a4783 100644 --- a/client/src/mobile/screens/vacay/MVacay.tsx +++ b/client/src/mobile/screens/vacay/MVacay.tsx @@ -1,8 +1,9 @@ -import { Building2, ChevronLeft, ChevronRight, Eye, Minus, PenLine, Pencil, Plus, Settings2, Share2, ShieldCheck, Trash2, Unlink, UserPlus } from 'lucide-react' +import { Building2, Check, ChevronDown, ChevronLeft, ChevronRight, Eye, EyeOff, Minus, PenLine, Pencil, Plus, Settings2, Share2, ShieldCheck, Trash2, Unlink, UserPlus } from 'lucide-react' import type { LucideIcon } from 'lucide-react' import MSheet from '../../components/MSheet' import MIconBtn from '../../components/MIconBtn' import MProgress from '../../components/MProgress' +import MDayPager from '../../components/MDayPager' import { useTranslation } from '../../../i18n' import { useMVacay } from './useMVacay' import MVacayMonth from './MVacayMonth' @@ -12,6 +13,11 @@ import MVacayShareSheet from './MVacayShareSheet' import { FALLBACK_PERSON_COLOR } from './vacayDayModel' import { fmtDays } from '../../../components/Vacay/vacayFormat' +/** The company-holiday tint the calendar cells use (vacayDayModel). */ +const COMPANY_COLOR = '#F5D9A6' // theme-lint-disable: the cells' fixed company-day tint +const GLASS_PILL_BUTTON = 'inline-flex h-8 flex-none items-center gap-2 rounded-full border border-[color:var(--m-gbr)] bg-[color:var(--m-glass)] px-3 text-[0.75rem] font-bold text-m-ink backdrop-blur-[24px] backdrop-saturate-[1.7] transition-transform active:scale-[.97]' +const SHEET_ROW = 'flex items-center gap-3 rounded-[16px] border border-[color:var(--m-gbr)] bg-[color:var(--m-glass)] px-4 py-3 text-start text-[0.875rem] font-bold transition-transform active:scale-[.98]' + const WEEKDAY_KEYS_MONDAY = ['vacay.mon', 'vacay.tue', 'vacay.wed', 'vacay.thu', 'vacay.fri', 'vacay.sat', 'vacay.sun'] as const const WEEKDAY_KEYS_SUNDAY = ['vacay.sun', 'vacay.mon', 'vacay.tue', 'vacay.wed', 'vacay.thu', 'vacay.fri', 'vacay.sat'] as const @@ -41,6 +47,14 @@ export default function MVacay() { ? (stat.remaining < 0 ? 'var(--m-st-danger)' : 'var(--m-st-pending)') : v.selectedColor const weekdayKeys = v.weekStart === 0 ? WEEKDAY_KEYS_SUNDAY : WEEKDAY_KEYS_MONDAY + // People to pick between: fused members, or shared calendars to show or hide. + const peopleChoosable = v.users.length > 1 || v.incomingShares.length > 0 + const legendItems = [ + ...(v.companyHolidaysEnabled ? [{ key: 'company', color: COMPANY_COLOR, label: t('mobileVacay.companyLegend') }] : []), + ...(v.holidaysEnabled ? (v.plan?.holiday_calendars ?? []).map(cal => ({ key: `cal-${cal.id}`, color: cal.color, label: cal.label || cal.region })) : []), + ] + const yearPages = v.years.map(year => ({ id: year })) + const monthPages = v.months.map((_, slot) => ({ id: slot })) return ( // h-dvh, not h-full: the shell stopped providing a definite height (#1809). @@ -121,56 +135,64 @@ export default function MVacay() {
)} - {/* Person + legend chips */} -
- {v.users.map(u => { - const color = u.color || FALLBACK_PERSON_COLOR - const active = u.id === v.selectedUserId - return ( + {/* Who the calendar is for, and what its colours mean: two compact pills + instead of a row of chips. Only the people are a choice; the legend is + explanation, so it waits behind its own pill. */} + {(peopleChoosable || legendItems.length > 0) && ( +
+ {peopleChoosable && ( - ) - })} - {/* Shared read-only calendars: tap toggles that person's ring overlay. */} - {v.incomingShares.map(s => ( - - ))} - {v.companyHolidaysEnabled && ( - - )} - {v.holidaysEnabled && (v.plan?.holiday_calendars ?? []).map(cal => ( - - ))} -
+ )} + {legendItems.length > 0 && ( + + )} +
+ )} {/* Year grid */} + {/* Swipe between the plan's years, like pages. The neighbouring year + draws its calendar at once; its entries arrive once it lands. */} {!edit && ( + String(v.years[i] ?? '')} + renderDay={pageYear => (
{/* Twelve months from the window start (#737) — Jan–Dec on a calendar year, Jul–Jun once the leave year is shifted. */} - {v.months.map(({ year, month }, slot) => ( + {v.monthsFor(pageYear ?? v.selectedYear).map(({ year, month }, slot) => (
{/* The month name is the comfortable way into the editor: the mini cells below it are ~21px on a phone, precise enough to navigate @@ -196,6 +218,8 @@ export default function MVacay() {
))}
+ )} + /> )} {/* Edit view: month quick nav + single month */} @@ -219,12 +243,23 @@ export default function MVacay() { ))} + {/* Swipe between the months of the window, like pages. */} + v.monthNameLongFor(i)} + renderDay={pageSlot => { + const slot = pageSlot ?? v.monthSlot + const m = v.months[slot] ?? v.activeMonth + return (
- {v.monthNameLong} + {v.monthNameLongFor(slot)} @@ -235,8 +270,8 @@ export default function MVacay() { ))}
+ ) + }} + /> )} @@ -338,6 +376,66 @@ export default function MVacay() { v.setSheet(null)} /> v.setSheet(null)} /> v.setSheet(null)} /> + v.setSheet(null)} variant="bottom" ariaLabel={t('mobileVacay.people')}> +
+
{t('mobileVacay.people')}
+
+ {v.users.map(u => { + const color = u.color || FALLBACK_PERSON_COLOR + const active = u.id === v.selectedUserId + return ( + + ) + })} +
+ {/* Shared read-only calendars: a tap shows or hides that person's ring overlay. */} + {v.incomingShares.length > 0 && ( + <> +
{t('vacay.sharedCalendars')}
+
+ {v.incomingShares.map(sh => ( + + ))} +
+ + )} +
+
+ v.setSheet(null)} variant="bottom" ariaLabel={t('mobileVacay.legend')}> +
+
{t('mobileVacay.legend')}
+
+ {legendItems.map(item => ( +
+ + {item.label} +
+ ))} +
+
+
- - {label} - - ) -} /** Forced Fusion-request card — stays open until accepted or declined. */ function MVacayIncomingInvite({ invites, onAccept, onDecline }: { diff --git a/client/src/mobile/screens/vacay/useMVacay.ts b/client/src/mobile/screens/vacay/useMVacay.ts index 8f7e5bea7..5026b051a 100644 --- a/client/src/mobile/screens/vacay/useMVacay.ts +++ b/client/src/mobile/screens/vacay/useMVacay.ts @@ -14,7 +14,7 @@ import { export type MVacayView = 'grid' | 'edit' export type MVacayMode = VacayMode -export type MVacaySheet = 'invite' | 'settings' | 'share' | null +export type MVacaySheet = 'invite' | 'settings' | 'share' | 'people' | 'legend' | null /** * Screen state of the mobile Vacay experience. Data loading, WebSocket sync @@ -96,6 +96,14 @@ export function useMVacay() { [locale, activeMonth], ) + // The pagers draw the neighbours of the open month and year too: the long name + // of any slot of the window, and the twelve months of any year. + const monthNameLongFor = useCallback((slot: number) => { + const m = months[slot] ?? months[0] + return new Intl.DateTimeFormat(locale, { month: 'long' }).format(new Date(m.year, m.month, 1)) + }, [locale, months]) + const monthsFor = useCallback((year: number) => windowMonths(year, yearSettings), [yearSettings]) + const selectedUser = users.find(u => u.id === selectedUserId) const selectedColor = selectedUser?.color || FALLBACK_PERSON_COLOR const selectedStat = stats.find(s => s.user_id === selectedUserId) @@ -156,6 +164,12 @@ export function useMVacay() { else { await handleAddPrevYear(); setSelectedYear(selectedYear - 1) } }, [years, selectedYear, setSelectedYear, handleAddPrevYear]) + // A swipe only moves between years the plan already has; creating one stays + // with the arrows, where it is a deliberate step. + const selectYear = useCallback((year: number) => { + if (years.includes(year)) setSelectedYear(year) + }, [years, setSelectedYear]) + const nextYear = useCallback(async () => { const idx = years.indexOf(selectedYear) if (idx >= 0 && idx < years.length - 1) setSelectedYear(years[idx + 1]) @@ -172,7 +186,7 @@ export function useMVacay() { const tripDotColor = users.find(u => u.id === currentUser?.id)?.color || 'var(--m-st-info)' return { - loading, plan, selectedYear, + loading, plan, selectedYear, years, selectYear, monthsFor, monthNameLongFor, users, isFused, currentUser, incomingInvites, acceptInvite, declineInvite, incomingShares, toggleShareHidden, diff --git a/client/tests/unit/mobile/vacay/MVacay.test.tsx b/client/tests/unit/mobile/vacay/MVacay.test.tsx index 0f8ccb968..ae7bfe9bb 100644 --- a/client/tests/unit/mobile/vacay/MVacay.test.tsx +++ b/client/tests/unit/mobile/vacay/MVacay.test.tsx @@ -45,6 +45,14 @@ const dayCtx: DayVisualContext = { }; const MONTHS_SHORT = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; +const MONTHS_LONG = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']; + +// The paging itself is MDayPager's, tested there. This draws only the current +// page, so the year grid and the month editor under test are the ones on screen. +vi.mock('../../../../src/mobile/components/MDayPager', () => ({ + default: (props: { selectedDayId: number | null; renderDay: (id: number | null, active: boolean) => unknown }) => + props.renderDay(props.selectedDayId, true), +})); /** The screen flips the modifier flags with an updater, so the mock has to run it. */ function boolSetter() { @@ -58,6 +66,10 @@ function buildV(over: Record = {}): Record { loading: false, plan: { id: 1, holiday_calendars: [] }, selectedYear: 2026, + years: [2026], + selectYear: vi.fn((_year: number) => undefined), + monthsFor: (_year: number) => Array.from({ length: 12 }, (_, m) => ({ year: 2026, month: m })), + monthNameLongFor: (slot: number) => MONTHS_LONG[slot], users: [ { id: 1, username: 'alice', color: '#3b82f6' }, { id: 2, username: 'bob', color: null }, @@ -218,19 +230,30 @@ describe('MVacay', () => { expect(screen.queryByRole('button', { name: 'Increase allowance' })).not.toBeInTheDocument(); }); - it('FE-MOB-MVACSCR-010: person chips select their member and fall back on the shared color', () => { + it('FE-MOB-MVACSCR-010: the people pill opens the people sheet, where a member is picked', () => { render(); - - const bobChip = screen.getByRole('button', { name: 'bob' }); - const swatch = bobChip.querySelector('span') as HTMLElement; - expect(swatch.style.background).toBe('rgb(99, 102, 241)'); - - fireEvent.click(bobChip); - expect(mocks.v.selectPerson).toHaveBeenCalledWith(2); + fireEvent.click(screen.getByRole('button', { name: /People/ })); + expect(mocks.v.setSheet).toHaveBeenCalledWith('people'); }); - it('FE-MOB-MVACSCR-011: shared chips toggle their overlay and report their state', () => { + it('FE-MOB-MVACSCR-010b: in the people sheet a member is picked, falling back on the shared color', async () => { + mocks.v = buildV({ sheet: 'people' }); + render(); + + const sheet = await screen.findByRole('dialog', { name: 'People' }); + const bobRow = within(sheet).getByRole('button', { name: 'bob' }); + const swatch = bobRow.querySelector('span') as HTMLElement; + expect(swatch.style.background).toBe('rgb(99, 102, 241)'); + expect(within(sheet).getByRole('button', { name: 'alice' })).toHaveAttribute('aria-pressed', 'true'); + + fireEvent.click(bobRow); + expect(mocks.v.selectPerson).toHaveBeenCalledWith(2); + expect(mocks.v.setSheet).toHaveBeenLastCalledWith(null); + }); + + it('FE-MOB-MVACSCR-011: shared calendars toggle their overlay from the people sheet and report their state', async () => { mocks.v = buildV({ + sheet: 'people', incomingShares: [ { id: 7, owner_id: 3, username: 'carol', color: '#f59e0b', hidden: false }, { id: 8, owner_id: 4, username: 'dan', color: '#10b981', hidden: true }, @@ -238,8 +261,9 @@ describe('MVacay', () => { }); render(); - const carol = screen.getByRole('button', { name: 'carol' }); - const dan = screen.getByRole('button', { name: 'dan' }); + const sheet = await screen.findByRole('dialog', { name: 'People' }); + const carol = within(sheet).getByRole('button', { name: 'carol' }); + const dan = within(sheet).getByRole('button', { name: 'dan' }); expect(carol).toHaveAttribute('aria-pressed', 'true'); expect(dan).toHaveAttribute('aria-pressed', 'false'); @@ -249,8 +273,14 @@ describe('MVacay', () => { expect(mocks.v.toggleShareHidden).toHaveBeenNthCalledWith(2, 8, false); }); - it('FE-MOB-MVACSCR-012: shows the company legend and every enabled holiday calendar', () => { - mocks.v = buildV({ + it('FE-MOB-MVACSCR-011b: a single member with nothing shared gets no people pill', () => { + mocks.v = buildV({ users: [{ id: 1, username: 'alice', color: '#3b82f6' }] }); + render(); + expect(screen.queryByRole('button', { name: /People/ })).not.toBeInTheDocument(); + }); + + it('FE-MOB-MVACSCR-012: the legend waits behind its pill and lists the company days and every holiday calendar', async () => { + const holidays = { holidaysEnabled: true, plan: { id: 1, @@ -259,12 +289,21 @@ describe('MVacay', () => { { id: 2, region: 'NL', label: null, color: '#bbf7d0' }, ], }, - }); - render(); + }; + mocks.v = buildV(holidays); + const { unmount } = render(); + // Not on screen until asked for. + expect(screen.queryByText('Germany')).not.toBeInTheDocument(); + fireEvent.click(screen.getByRole('button', { name: /Legend/ })); + expect(mocks.v.setSheet).toHaveBeenCalledWith('legend'); + unmount(); - expect(screen.getByText('Company days')).toBeInTheDocument(); - expect(screen.getByText('Germany')).toBeInTheDocument(); - expect(screen.getByText('NL')).toBeInTheDocument(); + mocks.v = buildV({ ...holidays, sheet: 'legend' }); + render(); + const sheet = await screen.findByRole('dialog', { name: 'Legend' }); + expect(within(sheet).getByText('Company days')).toBeInTheDocument(); + expect(within(sheet).getByText('Germany')).toBeInTheDocument(); + expect(within(sheet).getByText('NL')).toBeInTheDocument(); }); it('FE-MOB-MVACSCR-013: the year grid shows twelve month cards and reports day taps', () => { @@ -315,7 +354,7 @@ describe('MVacay', () => { mocks.v = buildV({ view: 'edit' }); render(); - // The person chip row carries the same name; the mode switch comes last. + // The mode switch carries the selected person's name. const person = screen.getAllByRole('button', { name: 'alice' }); fireEvent.click(person[person.length - 1]); expect(mocks.v.setMode).toHaveBeenLastCalledWith('vacation'); diff --git a/client/tests/unit/mobile/vacay/useMVacay.test.tsx b/client/tests/unit/mobile/vacay/useMVacay.test.tsx index 8e166b177..cdad4612e 100644 --- a/client/tests/unit/mobile/vacay/useMVacay.test.tsx +++ b/client/tests/unit/mobile/vacay/useMVacay.test.tsx @@ -250,6 +250,19 @@ describe('useMVacay', () => { expect(result.current.monthSlot).toBe(11); }); + it('FE-MOB-MVAC-012b: a swipe selects only years the plan has, and names any slot and any year', async () => { + const setSelectedYear = vi.fn((_year: number) => undefined); + mocks.vacay = buildVacay({ years: [2025, 2026], setSelectedYear }); + const { result } = await mount(); + + act(() => { result.current.selectYear(2025); }); + act(() => { result.current.selectYear(2031); }); + expect(setSelectedYear.mock.calls).toEqual([[2025]]); + + expect(result.current.monthsFor(2025)[0]).toEqual({ year: 2025, month: 0 }); + expect(result.current.monthNameLongFor(0)).toMatch(/jan/i); + }); + it('FE-MOB-MVAC-013: only a fused plan allows selecting another member', async () => { const { result } = await mount(); diff --git a/shared/src/i18n/ar/mobileVacay.ts b/shared/src/i18n/ar/mobileVacay.ts index aaebeb9ff..0329c4966 100644 --- a/shared/src/i18n/ar/mobileVacay.ts +++ b/shared/src/i18n/ar/mobileVacay.ts @@ -24,6 +24,8 @@ const mobileVacay: TranslationStrings = { 'mobileVacay.companyLegend': 'أيام الشركة', 'mobileVacay.editCalendar': 'تحرير التقويم', 'mobileVacay.viewYear': 'عرض السنة', + 'mobileVacay.people': 'الأشخاص', + 'mobileVacay.legend': 'المفتاح', }; export default mobileVacay; diff --git a/shared/src/i18n/az/mobileVacay.ts b/shared/src/i18n/az/mobileVacay.ts index 249261164..33d6ef107 100644 --- a/shared/src/i18n/az/mobileVacay.ts +++ b/shared/src/i18n/az/mobileVacay.ts @@ -16,6 +16,8 @@ const mobileVacay: TranslationStrings = { 'mobileVacay.companyLegend': 'Şirkət günləri', 'mobileVacay.editCalendar': 'Təqvimi redaktə et', 'mobileVacay.viewYear': 'İlə bax', + 'mobileVacay.people': 'İnsanlar', + 'mobileVacay.legend': 'İzahat', }; export default mobileVacay; diff --git a/shared/src/i18n/br/mobileVacay.ts b/shared/src/i18n/br/mobileVacay.ts index ed69348ce..3271db235 100644 --- a/shared/src/i18n/br/mobileVacay.ts +++ b/shared/src/i18n/br/mobileVacay.ts @@ -16,6 +16,8 @@ const mobileVacay: TranslationStrings = { 'mobileVacay.companyLegend': 'Férias coletivas', 'mobileVacay.editCalendar': 'Editar calendário', 'mobileVacay.viewYear': 'Ver ano', + 'mobileVacay.people': 'Pessoas', + 'mobileVacay.legend': 'Legenda', }; export default mobileVacay; diff --git a/shared/src/i18n/ca/mobileVacay.ts b/shared/src/i18n/ca/mobileVacay.ts index 4961b99cd..6aa28db1a 100644 --- a/shared/src/i18n/ca/mobileVacay.ts +++ b/shared/src/i18n/ca/mobileVacay.ts @@ -16,6 +16,8 @@ const mobileVacay: TranslationStrings = { 'mobileVacay.companyLegend': "Dies d'empresa", 'mobileVacay.editCalendar': 'Edita el calendari', 'mobileVacay.viewYear': "Mostra l'any", + 'mobileVacay.people': 'Persones', + 'mobileVacay.legend': 'Llegenda', }; export default mobileVacay; diff --git a/shared/src/i18n/cs/mobileVacay.ts b/shared/src/i18n/cs/mobileVacay.ts index a3232de99..83e62e370 100644 --- a/shared/src/i18n/cs/mobileVacay.ts +++ b/shared/src/i18n/cs/mobileVacay.ts @@ -18,6 +18,8 @@ const mobileVacay: TranslationStrings = { 'mobileVacay.companyLegend': 'Firemní dny', 'mobileVacay.editCalendar': 'Upravit kalendář', 'mobileVacay.viewYear': 'Zobrazit rok', + 'mobileVacay.people': 'Lidé', + 'mobileVacay.legend': 'Legenda', }; export default mobileVacay; diff --git a/shared/src/i18n/de/mobileVacay.ts b/shared/src/i18n/de/mobileVacay.ts index fd054e67c..03c0c7f07 100644 --- a/shared/src/i18n/de/mobileVacay.ts +++ b/shared/src/i18n/de/mobileVacay.ts @@ -16,6 +16,8 @@ const mobileVacay: TranslationStrings = { 'mobileVacay.companyLegend': 'Betriebsferien', 'mobileVacay.editCalendar': 'Kalender bearbeiten', 'mobileVacay.viewYear': 'Jahr ansehen', + 'mobileVacay.people': 'Personen', + 'mobileVacay.legend': 'Legende', }; export default mobileVacay; diff --git a/shared/src/i18n/en/mobileVacay.ts b/shared/src/i18n/en/mobileVacay.ts index b2565fc77..1841709db 100644 --- a/shared/src/i18n/en/mobileVacay.ts +++ b/shared/src/i18n/en/mobileVacay.ts @@ -16,6 +16,8 @@ const mobileVacay: TranslationStrings = { 'mobileVacay.companyLegend': 'Company days', 'mobileVacay.editCalendar': 'Edit calendar', 'mobileVacay.viewYear': 'View year', + 'mobileVacay.people': 'People', + 'mobileVacay.legend': 'Legend', }; export default mobileVacay; diff --git a/shared/src/i18n/es/mobileVacay.ts b/shared/src/i18n/es/mobileVacay.ts index 933391afc..267c3c4bc 100644 --- a/shared/src/i18n/es/mobileVacay.ts +++ b/shared/src/i18n/es/mobileVacay.ts @@ -16,6 +16,8 @@ const mobileVacay: TranslationStrings = { 'mobileVacay.companyLegend': 'Días de empresa', 'mobileVacay.editCalendar': 'Editar calendario', 'mobileVacay.viewYear': 'Ver año', + 'mobileVacay.people': 'Personas', + 'mobileVacay.legend': 'Leyenda', }; export default mobileVacay; diff --git a/shared/src/i18n/et/mobileVacay.ts b/shared/src/i18n/et/mobileVacay.ts index d341518ca..cf8b8fd40 100644 --- a/shared/src/i18n/et/mobileVacay.ts +++ b/shared/src/i18n/et/mobileVacay.ts @@ -16,6 +16,8 @@ const mobileVacay: TranslationStrings = { 'mobileVacay.companyLegend': 'Ettevõtte puhkepäevad', 'mobileVacay.editCalendar': 'Muuda kalendrit', 'mobileVacay.viewYear': 'Vaata aastat', + 'mobileVacay.people': 'Inimesed', + 'mobileVacay.legend': 'Legend', // same-as-en }; export default mobileVacay; diff --git a/shared/src/i18n/fr/mobileVacay.ts b/shared/src/i18n/fr/mobileVacay.ts index 0bc4cabce..919d2ad91 100644 --- a/shared/src/i18n/fr/mobileVacay.ts +++ b/shared/src/i18n/fr/mobileVacay.ts @@ -16,6 +16,8 @@ const mobileVacay: TranslationStrings = { 'mobileVacay.companyLegend': "Congés d'entreprise", 'mobileVacay.editCalendar': 'Modifier le calendrier', 'mobileVacay.viewYear': "Voir l'année", + 'mobileVacay.people': 'Personnes', + 'mobileVacay.legend': 'Légende', }; export default mobileVacay; diff --git a/shared/src/i18n/gr/mobileVacay.ts b/shared/src/i18n/gr/mobileVacay.ts index 7802b19f4..2b6369512 100644 --- a/shared/src/i18n/gr/mobileVacay.ts +++ b/shared/src/i18n/gr/mobileVacay.ts @@ -16,6 +16,8 @@ const mobileVacay: TranslationStrings = { 'mobileVacay.companyLegend': 'Άδεια εταιρείας', 'mobileVacay.editCalendar': 'Επεξεργασία ημερολογίου', 'mobileVacay.viewYear': 'Προβολή έτους', + 'mobileVacay.people': 'Άτομα', + 'mobileVacay.legend': 'Υπόμνημα', }; export default mobileVacay; diff --git a/shared/src/i18n/he/mobileVacay.ts b/shared/src/i18n/he/mobileVacay.ts index 4f2415e43..3bfa97fca 100644 --- a/shared/src/i18n/he/mobileVacay.ts +++ b/shared/src/i18n/he/mobileVacay.ts @@ -18,6 +18,8 @@ const mobileVacay: TranslationStrings = { 'mobileVacay.companyLegend': 'ימי חברה', 'mobileVacay.editCalendar': 'עריכת לוח שנה', 'mobileVacay.viewYear': 'תצוגת שנה', + 'mobileVacay.people': 'אנשים', + 'mobileVacay.legend': 'מקרא', }; export default mobileVacay; diff --git a/shared/src/i18n/hu/mobileVacay.ts b/shared/src/i18n/hu/mobileVacay.ts index 63440a3c1..8c31fc916 100644 --- a/shared/src/i18n/hu/mobileVacay.ts +++ b/shared/src/i18n/hu/mobileVacay.ts @@ -16,6 +16,8 @@ const mobileVacay: TranslationStrings = { 'mobileVacay.companyLegend': 'Céges szabadság', 'mobileVacay.editCalendar': 'Naptár szerkesztése', 'mobileVacay.viewYear': 'Év megtekintése', + 'mobileVacay.people': 'Személyek', + 'mobileVacay.legend': 'Jelmagyarázat', }; export default mobileVacay; diff --git a/shared/src/i18n/id/mobileVacay.ts b/shared/src/i18n/id/mobileVacay.ts index 42e2bc676..503abf46b 100644 --- a/shared/src/i18n/id/mobileVacay.ts +++ b/shared/src/i18n/id/mobileVacay.ts @@ -14,6 +14,8 @@ const mobileVacay: TranslationStrings = { 'mobileVacay.companyLegend': 'Libur perusahaan', 'mobileVacay.editCalendar': 'Edit kalender', 'mobileVacay.viewYear': 'Lihat tahun', + 'mobileVacay.people': 'Orang', + 'mobileVacay.legend': 'Keterangan', }; export default mobileVacay; diff --git a/shared/src/i18n/it/mobileVacay.ts b/shared/src/i18n/it/mobileVacay.ts index 17fcf7bf4..8a6bfae96 100644 --- a/shared/src/i18n/it/mobileVacay.ts +++ b/shared/src/i18n/it/mobileVacay.ts @@ -16,6 +16,8 @@ const mobileVacay: TranslationStrings = { 'mobileVacay.companyLegend': 'Ferie aziendali', 'mobileVacay.editCalendar': 'Modifica calendario', 'mobileVacay.viewYear': 'Visualizza anno', + 'mobileVacay.people': 'Persone', + 'mobileVacay.legend': 'Legenda', }; export default mobileVacay; diff --git a/shared/src/i18n/ja/mobileVacay.ts b/shared/src/i18n/ja/mobileVacay.ts index 62d5d1732..6e0d5ec8c 100644 --- a/shared/src/i18n/ja/mobileVacay.ts +++ b/shared/src/i18n/ja/mobileVacay.ts @@ -14,6 +14,8 @@ const mobileVacay: TranslationStrings = { 'mobileVacay.companyLegend': '会社の休業日', 'mobileVacay.editCalendar': 'カレンダーを編集', 'mobileVacay.viewYear': '年間を表示', + 'mobileVacay.people': 'メンバー', + 'mobileVacay.legend': '凡例', }; export default mobileVacay; diff --git a/shared/src/i18n/ko/mobileVacay.ts b/shared/src/i18n/ko/mobileVacay.ts index 6a48063a0..60777d6b1 100644 --- a/shared/src/i18n/ko/mobileVacay.ts +++ b/shared/src/i18n/ko/mobileVacay.ts @@ -14,6 +14,8 @@ const mobileVacay: TranslationStrings = { 'mobileVacay.companyLegend': '회사 지정 휴무', 'mobileVacay.editCalendar': '캘린더 편집', 'mobileVacay.viewYear': '연간 보기', + 'mobileVacay.people': '사람', + 'mobileVacay.legend': '범례', }; export default mobileVacay; diff --git a/shared/src/i18n/nl/mobileVacay.ts b/shared/src/i18n/nl/mobileVacay.ts index 67135af90..739ebce19 100644 --- a/shared/src/i18n/nl/mobileVacay.ts +++ b/shared/src/i18n/nl/mobileVacay.ts @@ -16,6 +16,8 @@ const mobileVacay: TranslationStrings = { 'mobileVacay.companyLegend': 'Bedrijfsverlof', 'mobileVacay.editCalendar': 'Kalender bewerken', 'mobileVacay.viewYear': 'Jaar bekijken', + 'mobileVacay.people': 'Personen', + 'mobileVacay.legend': 'Legenda', }; export default mobileVacay; diff --git a/shared/src/i18n/pl/mobileVacay.ts b/shared/src/i18n/pl/mobileVacay.ts index b98b36d47..b3f061683 100644 --- a/shared/src/i18n/pl/mobileVacay.ts +++ b/shared/src/i18n/pl/mobileVacay.ts @@ -20,6 +20,8 @@ const mobileVacay: TranslationStrings = { 'mobileVacay.companyLegend': 'Dni firmowe', 'mobileVacay.editCalendar': 'Edytuj kalendarz', 'mobileVacay.viewYear': 'Zobacz rok', + 'mobileVacay.people': 'Osoby', + 'mobileVacay.legend': 'Legenda', }; export default mobileVacay; diff --git a/shared/src/i18n/ru/mobileVacay.ts b/shared/src/i18n/ru/mobileVacay.ts index c75599a48..5a7260bfa 100644 --- a/shared/src/i18n/ru/mobileVacay.ts +++ b/shared/src/i18n/ru/mobileVacay.ts @@ -20,6 +20,8 @@ const mobileVacay: TranslationStrings = { 'mobileVacay.companyLegend': 'Корпоративные дни', 'mobileVacay.editCalendar': 'Изменить календарь', 'mobileVacay.viewYear': 'Просмотр года', + 'mobileVacay.people': 'Люди', + 'mobileVacay.legend': 'Легенда', }; export default mobileVacay; diff --git a/shared/src/i18n/sk/mobileVacay.ts b/shared/src/i18n/sk/mobileVacay.ts index 609a16a8c..640bc26cb 100644 --- a/shared/src/i18n/sk/mobileVacay.ts +++ b/shared/src/i18n/sk/mobileVacay.ts @@ -18,6 +18,8 @@ const mobileVacay: TranslationStrings = { 'mobileVacay.companyLegend': 'Firemné dni', 'mobileVacay.editCalendar': 'Upraviť kalendár', 'mobileVacay.viewYear': 'Zobraziť rok', + 'mobileVacay.people': 'Ľudia', + 'mobileVacay.legend': 'Legenda', }; export default mobileVacay; diff --git a/shared/src/i18n/sv/mobileVacay.ts b/shared/src/i18n/sv/mobileVacay.ts index bcb540d87..38a2cc30f 100644 --- a/shared/src/i18n/sv/mobileVacay.ts +++ b/shared/src/i18n/sv/mobileVacay.ts @@ -16,6 +16,8 @@ const mobileVacay: TranslationStrings = { 'mobileVacay.companyLegend': 'Företagsledighet', 'mobileVacay.editCalendar': 'Redigera kalender', 'mobileVacay.viewYear': 'Visa år', + 'mobileVacay.people': 'Personer', + 'mobileVacay.legend': 'Teckenförklaring', }; export default mobileVacay; diff --git a/shared/src/i18n/th/mobileVacay.ts b/shared/src/i18n/th/mobileVacay.ts index 28cef054e..0e3ac0e70 100644 --- a/shared/src/i18n/th/mobileVacay.ts +++ b/shared/src/i18n/th/mobileVacay.ts @@ -14,6 +14,8 @@ const mobileVacay: TranslationStrings = { 'mobileVacay.companyLegend': 'วันของบริษัท', 'mobileVacay.editCalendar': 'แก้ไขปฏิทิน', 'mobileVacay.viewYear': 'ดูปี', + 'mobileVacay.people': 'บุคคล', + 'mobileVacay.legend': 'คำอธิบายสัญลักษณ์', }; export default mobileVacay; diff --git a/shared/src/i18n/tr/mobileVacay.ts b/shared/src/i18n/tr/mobileVacay.ts index a20e491d4..f162e4708 100644 --- a/shared/src/i18n/tr/mobileVacay.ts +++ b/shared/src/i18n/tr/mobileVacay.ts @@ -16,6 +16,8 @@ const mobileVacay: TranslationStrings = { 'mobileVacay.companyLegend': 'Şirket tatili', 'mobileVacay.editCalendar': 'Takvimi düzenle', 'mobileVacay.viewYear': 'Yılı görüntüle', + 'mobileVacay.people': 'Kişiler', + 'mobileVacay.legend': 'Açıklama', }; export default mobileVacay; diff --git a/shared/src/i18n/uk/mobileVacay.ts b/shared/src/i18n/uk/mobileVacay.ts index 02b5ca519..72526230a 100644 --- a/shared/src/i18n/uk/mobileVacay.ts +++ b/shared/src/i18n/uk/mobileVacay.ts @@ -20,6 +20,8 @@ const mobileVacay: TranslationStrings = { 'mobileVacay.companyLegend': 'Корпоративні дні', 'mobileVacay.editCalendar': 'Редагувати календар', 'mobileVacay.viewYear': 'Переглянути рік', + 'mobileVacay.people': 'Люди', + 'mobileVacay.legend': 'Легенда', }; export default mobileVacay; diff --git a/shared/src/i18n/vi/mobileVacay.ts b/shared/src/i18n/vi/mobileVacay.ts index bde6b7f24..97821937f 100644 --- a/shared/src/i18n/vi/mobileVacay.ts +++ b/shared/src/i18n/vi/mobileVacay.ts @@ -14,6 +14,8 @@ const mobileVacay: TranslationStrings = { 'mobileVacay.companyLegend': 'Ngày nghỉ công ty', 'mobileVacay.editCalendar': 'Sửa lịch', 'mobileVacay.viewYear': 'Xem năm', + 'mobileVacay.people': 'Mọi người', + 'mobileVacay.legend': 'Chú thích', }; export default mobileVacay; diff --git a/shared/src/i18n/zh-TW/mobileVacay.ts b/shared/src/i18n/zh-TW/mobileVacay.ts index ed6327a9c..e05176de6 100644 --- a/shared/src/i18n/zh-TW/mobileVacay.ts +++ b/shared/src/i18n/zh-TW/mobileVacay.ts @@ -14,6 +14,8 @@ const mobileVacay: TranslationStrings = { 'mobileVacay.companyLegend': '公司假期', 'mobileVacay.editCalendar': '編輯日曆', 'mobileVacay.viewYear': '檢視年度', + 'mobileVacay.people': '成員', + 'mobileVacay.legend': '圖例', }; export default mobileVacay; diff --git a/shared/src/i18n/zh/mobileVacay.ts b/shared/src/i18n/zh/mobileVacay.ts index a8defcdbd..1236336c0 100644 --- a/shared/src/i18n/zh/mobileVacay.ts +++ b/shared/src/i18n/zh/mobileVacay.ts @@ -14,6 +14,8 @@ const mobileVacay: TranslationStrings = { 'mobileVacay.companyLegend': '公司假期', 'mobileVacay.editCalendar': '编辑日历', 'mobileVacay.viewYear': '查看年度', + 'mobileVacay.people': '成员', + 'mobileVacay.legend': '图例', }; export default mobileVacay;