From cb7bed12ad056fe172730f101edc260ee3c4aec2 Mon Sep 17 00:00:00 2001 From: jycouet Date: Wed, 10 Jan 2024 23:48:39 +0100 Subject: [PATCH] range & fr & reactivity --- .../src/lib/components/DateButton.svelte | 4 +- .../src/lib/components/DatePickerField.svelte | 6 +- .../src/lib/components/DateRange.svelte | 22 +- .../lib/components/DateRangeDisplay.svelte | 7 +- .../src/lib/components/DateRangeField.svelte | 12 +- packages/svelte-ux/src/lib/utils/date.test.ts | 16 ++ packages/svelte-ux/src/lib/utils/date.ts | 259 +++++++++--------- packages/svelte-ux/src/lib/utils/dateRange.ts | 40 ++- .../svelte-ux/src/lib/utils/dictionary.ts | 2 + packages/svelte-ux/src/lib/utils/locale.ts | 2 + packages/svelte-ux/src/routes/+layout.svelte | 4 +- .../docs/components/DateRange/+page.svelte | 7 +- 12 files changed, 209 insertions(+), 172 deletions(-) diff --git a/packages/svelte-ux/src/lib/components/DateButton.svelte b/packages/svelte-ux/src/lib/components/DateButton.svelte index 8c4f6786b..94ac20538 100644 --- a/packages/svelte-ux/src/lib/components/DateButton.svelte +++ b/packages/svelte-ux/src/lib/components/DateButton.svelte @@ -19,7 +19,7 @@ export let fade: boolean = false; export let format = getCustomFormat(periodType); - const { format: format_ux } = getSettings(); + const { format: format_ux, localeSettings } = getSettings(); const settingsClasses = getComponentClasses('DateButton'); function getCustomFormat(periodType: PeriodType) { @@ -32,7 +32,7 @@ } } - const { start, end, isSame } = getDateFuncsByPeriodType(periodType); + const { start, end, isSame } = getDateFuncsByPeriodType($localeSettings, periodType); $: isSelected = selected instanceof Date diff --git a/packages/svelte-ux/src/lib/components/DatePickerField.svelte b/packages/svelte-ux/src/lib/components/DatePickerField.svelte index bc795f9b6..e0a48ca8b 100644 --- a/packages/svelte-ux/src/lib/components/DatePickerField.svelte +++ b/packages/svelte-ux/src/lib/components/DatePickerField.svelte @@ -32,7 +32,7 @@ export let center = false; const settingsClasses = getComponentClasses('DatePickerField'); - const { format } = getSettings(); + const { format, localeSettings } = getSettings(); $: dictionary = $format.settings.dictionary; let open: boolean = false; @@ -83,7 +83,7 @@ class="p-2" on:click={() => { if (value && periodType) { - const { add } = getDateFuncsByPeriodType(periodType); + const { add } = getDateFuncsByPeriodType($localeSettings, periodType); value = add(value, -1); dispatch('change', value); } @@ -121,7 +121,7 @@ class="p-2" on:click={() => { if (value && periodType) { - const { add } = getDateFuncsByPeriodType(periodType); + const { add } = getDateFuncsByPeriodType($localeSettings, periodType); value = add(value, 1); dispatch('change', value); } diff --git a/packages/svelte-ux/src/lib/components/DateRange.svelte b/packages/svelte-ux/src/lib/components/DateRange.svelte index 53458a214..a771a2899 100644 --- a/packages/svelte-ux/src/lib/components/DateRange.svelte +++ b/packages/svelte-ux/src/lib/components/DateRange.svelte @@ -26,8 +26,8 @@ /** Period types to show */ export let periodTypes: PeriodType[] = [ PeriodType.Day, - PeriodType.WeekSun, - PeriodType.BiWeek1Sun, + PeriodType.Week, + PeriodType.BiWeek1, // PeriodType.BiWeek2Sun, PeriodType.Month, PeriodType.Quarter, @@ -37,7 +37,7 @@ export let getPeriodTypePresets = getDateRangePresets; const settingsClasses = getComponentClasses('DateRange'); - const { format } = getSettings(); + const { format, localeSettings } = getSettings(); let selectedPeriodType = selected?.periodType ?? periodTypes[0]; let selectedPreset: string | null = null; @@ -53,7 +53,7 @@ }; }); - $: presetOptions = getPeriodTypePresets(selectedPeriodType).map((preset) => { + $: presetOptions = getPeriodTypePresets($localeSettings, selectedPeriodType).map((preset) => { return { label: preset.label, value: getDateRangeStr(preset.value), @@ -70,7 +70,7 @@ // Apply date-fns function based on type and from/to. let newSelected = { ...selected, periodType: selectedPeriodType }; - const { start, end } = getDateFuncsByPeriodType(selectedPeriodType); + const { start, end } = getDateFuncsByPeriodType($localeSettings, selectedPeriodType); let newActiveDate: typeof activeDate = activeDate === 'from' ? 'to' : 'from'; @@ -95,7 +95,7 @@ // Expand selection range to match period type (day => month, etc) function onPeriodTypeChange(periodType: PeriodType) { - const { start, end } = getDateFuncsByPeriodType(periodType); + const { start, end } = getDateFuncsByPeriodType($localeSettings, periodType); if (selected!.from) { selected!.from = start(selected!.from); } @@ -121,7 +121,9 @@ // Attempt to maintain selected preset if labels match if (selected?.from && selected?.to && selected.periodType) { - const prevPeriodTypePreset = [...getPeriodTypePresets(selected.periodType)].find( + const prevPeriodTypePreset = [ + ...getPeriodTypePresets($localeSettings, selected.periodType), + ].find( (x) => x.value.from && isSameDay(x.value.from, selected!.from!) && @@ -130,9 +132,9 @@ ); if (prevPeriodTypePreset && newPeriodType) { - const newPeriodTypePreset = [...getPeriodTypePresets(newPeriodType)].find( - (x) => x.label === prevPeriodTypePreset.label - ); + const newPeriodTypePreset = [ + ...getPeriodTypePresets($localeSettings, newPeriodType), + ].find((x) => x.label === prevPeriodTypePreset.label); if (newPeriodTypePreset) { newSelected.from = newPeriodTypePreset.value.from; diff --git a/packages/svelte-ux/src/lib/components/DateRangeDisplay.svelte b/packages/svelte-ux/src/lib/components/DateRangeDisplay.svelte index 1a7665ca4..45c2d593e 100644 --- a/packages/svelte-ux/src/lib/components/DateRangeDisplay.svelte +++ b/packages/svelte-ux/src/lib/components/DateRangeDisplay.svelte @@ -5,12 +5,12 @@ export let value: DateRange | null | undefined; - const { format: format_ux } = getSettings(); + const { format: format_ux, localeSettings } = getSettings(); let showToValue = false; $: if (value?.to) { if (value?.from && value?.periodType) { - const { isSame } = getDateFuncsByPeriodType(value.periodType); + const { isSame } = getDateFuncsByPeriodType($localeSettings, value.periodType); switch (value.periodType) { case PeriodType.Day: @@ -39,6 +39,7 @@ case PeriodType.WeekThu: case PeriodType.WeekFri: case PeriodType.WeekSat: + case PeriodType.Week: case PeriodType.BiWeek1Sun: case PeriodType.BiWeek1Mon: @@ -47,6 +48,7 @@ case PeriodType.BiWeek1Thu: case PeriodType.BiWeek1Fri: case PeriodType.BiWeek1Sat: + case PeriodType.BiWeek1: case PeriodType.BiWeek2Sun: case PeriodType.BiWeek2Mon: @@ -55,6 +57,7 @@ case PeriodType.BiWeek2Thu: case PeriodType.BiWeek2Fri: case PeriodType.BiWeek2Sat: + case PeriodType.BiWeek2: periodType = PeriodType.Day; break; diff --git a/packages/svelte-ux/src/lib/components/DateRangeField.svelte b/packages/svelte-ux/src/lib/components/DateRangeField.svelte index 8b783fd17..991571cf9 100644 --- a/packages/svelte-ux/src/lib/components/DateRangeField.svelte +++ b/packages/svelte-ux/src/lib/components/DateRangeField.svelte @@ -14,7 +14,7 @@ import { getSettings } from './settings'; const dispatch = createEventDispatcher(); - const { format } = getSettings(); + const { format, localeSettings } = getSettings(); const _defaultValue: DateRangeType = { from: null, @@ -82,7 +82,10 @@ class="p-2" on:click={() => { if (value && value.from && value.to && value.periodType) { - const { difference, start, end, add } = getDateFuncsByPeriodType(value.periodType); + const { difference, start, end, add } = getDateFuncsByPeriodType( + $localeSettings, + value.periodType + ); const offset = difference(value.from, value.to) - 1; value = { from: start(add(value.from, offset)), @@ -129,7 +132,10 @@ class="p-2" on:click={() => { if (value && value.from && value.to && value.periodType) { - const { difference, start, end, add } = getDateFuncsByPeriodType(value.periodType); + const { difference, start, end, add } = getDateFuncsByPeriodType( + $localeSettings, + value.periodType + ); const offset = difference(value.to, value.from) + 1; value = { from: start(add(value.from, offset)), diff --git a/packages/svelte-ux/src/lib/utils/date.test.ts b/packages/svelte-ux/src/lib/utils/date.test.ts index 3caa232fe..f4e6f4dcc 100644 --- a/packages/svelte-ux/src/lib/utils/date.test.ts +++ b/packages/svelte-ux/src/lib/utils/date.test.ts @@ -6,6 +6,8 @@ import { utcToLocalDate, formatIntl, formatDateWithLocale, + getPeriodTypeByCode, + getPeriodTypeCode, } from './date'; import { formatWithLocale } from '.'; import { createLocaleSettings, defaultLocale } from './locale'; @@ -518,3 +520,17 @@ describe('getWeekStartsOnFromIntl() tokens', () => { expect(val).toBe(DayOfWeek.Monday); }); }); + +describe('getPeriodTypeByCode()', () => { + it('week', () => { + const val = getPeriodTypeByCode('WEEK'); + expect(val).toBe(PeriodType.Week); + }); +}); + +describe('getPeriodTypeCode()', () => { + it('BiWeek1Sat', () => { + const val = getPeriodTypeCode(PeriodType.BiWeek1Sat); + expect(val).toBe('BIWEEK1-SAT'); + }); +}); diff --git a/packages/svelte-ux/src/lib/utils/date.ts b/packages/svelte-ux/src/lib/utils/date.ts index c50ab483c..a547c67bc 100644 --- a/packages/svelte-ux/src/lib/utils/date.ts +++ b/packages/svelte-ux/src/lib/utils/date.ts @@ -57,6 +57,11 @@ export function getPeriodTypeName(periodType: PeriodType) { return getPeriodTypeNameWithLocale(defaultLocale, periodType); } +// util to make sure we have handled all enum cases +function assertNever(x: never): never { + throw new Error(`Unhandled enum case: ${x}`); +} + export function getPeriodTypeNameWithLocale(settings: LocaleSettings, periodType: PeriodType) { const { locale: locale, @@ -141,121 +146,54 @@ export function getPeriodTypeNameWithLocale(settings: LocaleSettings, periodType } } -function assertNever(x: never): never { - throw new Error(`Unhandled enum case: ${x}`); -} - -export function getPeriodTypeCode(periodType: PeriodType) { - switch (periodType) { - case PeriodType.Day: - return 'DAY'; - - case PeriodType.WeekSun: - return 'WEEK-SUN'; - case PeriodType.WeekMon: - return 'WEEK-MON'; - case PeriodType.WeekTue: - return 'WEEK-TUE'; - case PeriodType.WeekWed: - return 'WEEK-WED'; - case PeriodType.WeekThu: - return 'WEEK-THU'; - case PeriodType.WeekFri: - return 'WEEK-FRI'; - case PeriodType.WeekSat: - return 'WEEK-SAT'; - - case PeriodType.Month: - return 'MTH'; - case PeriodType.Quarter: - return 'QTR'; - case PeriodType.CalendarYear: - return 'CY'; - case PeriodType.FiscalYearOctober: - return 'FY-OCT'; - - case PeriodType.BiWeek1Sun: - return 'BIWEEK1-SUN'; - case PeriodType.BiWeek1Mon: - return 'BIWEEK1-MON'; - case PeriodType.BiWeek1Tue: - return 'BIWEEK1-TUE'; - case PeriodType.BiWeek1Wed: - return 'BIWEEK1-WED'; - case PeriodType.BiWeek1Thu: - return 'BIWEEK1-THU'; - case PeriodType.BiWeek1Fri: - return 'BIWEEK1-FRI'; - case PeriodType.BiWeek1Sat: - return 'BIWEEK1-SAT'; - - case PeriodType.BiWeek2Sun: - return 'BIWEEK2-SUN'; - case PeriodType.BiWeek2Mon: - return 'BIWEEK2-MON'; - case PeriodType.BiWeek2Tue: - return 'BIWEEK2-TUE'; - case PeriodType.BiWeek2Wed: - return 'BIWEEK2-WED'; - case PeriodType.BiWeek2Thu: - return 'BIWEEK2-THU'; - case PeriodType.BiWeek2Fri: - return 'BIWEEK2-FRI'; - case PeriodType.BiWeek2Sat: - return 'BIWEEK2-SAT'; - - default: - return 'UNK'; - } +const periodTypeMappings: Record = { + [PeriodType.Custom]: 'CUSTOM', + + [PeriodType.Day]: 'DAY', + [PeriodType.DayTime]: 'DAY-TIME', + [PeriodType.TimeOnly]: 'TIME', + + [PeriodType.WeekSun]: 'WEEK-SUN', + [PeriodType.WeekMon]: 'WEEK-MON', + [PeriodType.WeekTue]: 'WEEK-TUE', + [PeriodType.WeekWed]: 'WEEK-WED', + [PeriodType.WeekThu]: 'WEEK-THU', + [PeriodType.WeekFri]: 'WEEK-FRI', + [PeriodType.WeekSat]: 'WEEK-SAT', + [PeriodType.Week]: 'WEEK', + + [PeriodType.Month]: 'MTH', + [PeriodType.MonthYear]: 'MTH-CY', + [PeriodType.Quarter]: 'QTR', + [PeriodType.CalendarYear]: 'CY', + [PeriodType.FiscalYearOctober]: 'FY-OCT', + + [PeriodType.BiWeek1Sun]: 'BIWEEK1-SUN', + [PeriodType.BiWeek1Mon]: 'BIWEEK1-MON', + [PeriodType.BiWeek1Tue]: 'BIWEEK1-TUE', + [PeriodType.BiWeek1Wed]: 'BIWEEK1-WED', + [PeriodType.BiWeek1Thu]: 'BIWEEK1-THU', + [PeriodType.BiWeek1Fri]: 'BIWEEK1-FRI', + [PeriodType.BiWeek1Sat]: 'BIWEEK1-SAT', + [PeriodType.BiWeek1]: 'BIWEEK1', + + [PeriodType.BiWeek2Sun]: 'BIWEEK2-SUN', + [PeriodType.BiWeek2Mon]: 'BIWEEK2-MON', + [PeriodType.BiWeek2Tue]: 'BIWEEK2-TUE', + [PeriodType.BiWeek2Wed]: 'BIWEEK2-WED', + [PeriodType.BiWeek2Thu]: 'BIWEEK2-THU', + [PeriodType.BiWeek2Fri]: 'BIWEEK2-FRI', + [PeriodType.BiWeek2Sat]: 'BIWEEK2-SAT', + [PeriodType.BiWeek2]: 'BIWEEK2', +}; + +export function getPeriodTypeCode(periodType: PeriodType): string { + return periodTypeMappings[periodType]; } -export function getPeriodTypeByCode(code: string) { - switch (code) { - case 'DAY': - return PeriodType.Day; - - case 'WEEK-SUN': - return PeriodType.WeekSun; - case 'WEEK-MON': - return PeriodType.WeekMon; - case 'WEEK-TUE': - return PeriodType.WeekTue; - case 'WEEK-WED': - return PeriodType.WeekWed; - case 'WEEK-THU': - return PeriodType.WeekThu; - case 'WEEK-FRI': - return PeriodType.WeekFri; - case 'WEEK-SAT': - return PeriodType.WeekSat; - - case 'MTH': - return PeriodType.Month; - case 'QTR': - return PeriodType.Quarter; - case 'CY': - return PeriodType.CalendarYear; - case 'FY-OCT': - return PeriodType.FiscalYearOctober; - - case 'BIWEEK1-SUN': - return PeriodType.BiWeek1Sun; - case 'BIWEEK1-MON': - return PeriodType.BiWeek1Mon; - case 'BIWEEK1-TUE': - return PeriodType.BiWeek1Tue; - case 'BIWEEK1-WED': - return PeriodType.BiWeek1Wed; - case 'BIWEEK1-THU': - return PeriodType.BiWeek1Thu; - case 'BIWEEK1-FRI': - return PeriodType.BiWeek1Fri; - case 'BIWEEK1-SAT': - return PeriodType.BiWeek1Sat; - - default: - return null; - } +export function getPeriodTypeByCode(code: string): PeriodType { + const element = Object.entries(periodTypeMappings).find((c) => c[1] === code); + return parseInt(element?.[0] ?? '1'); } export function getDayOfWeek(periodType: PeriodType) { @@ -277,8 +215,21 @@ export function replaceDayOfWeek(periodType: PeriodType, dayOfWeek: DayOfWeek) { } export function hasDayOfWeek(periodType: PeriodType) { - const periodTypeCode = getPeriodTypeCode(periodType); - return /\-(SUN|MON|TUE|WED|THU|FRI|SAT)/.test(periodTypeCode); + // It's more: is it week related and .Week, .BiWeek1 or .BiWeek2 don't contain a day... + // const periodTypeCode = getPeriodTypeCode(periodType); + // return /\-(SUN|MON|TUE|WED|THU|FRI|SAT)/.test(periodTypeCode); + + if (periodType >= PeriodType.WeekSun && periodType <= PeriodType.Week) { + return true; + } + if (periodType >= PeriodType.BiWeek1Sun && periodType <= PeriodType.BiWeek1) { + return true; + } + if (periodType >= PeriodType.BiWeek2Sun && periodType <= PeriodType.BiWeek2) { + return true; + } + + return false; } export function getMonths(year = new Date().getFullYear()) { @@ -384,7 +335,14 @@ export function endOfBiWeek(date: Date, week: number, startOfWeek: DayOfWeek) { return addDays(startOfBiWeek(date, week, startOfWeek), 13); } -export function getDateFuncsByPeriodType(periodType: PeriodType | null | undefined) { +export function getDateFuncsByPeriodType( + settings: LocaleSettings | undefined, + periodType: PeriodType | null | undefined +) { + if (settings) { + periodType = updatePeriodeTypeWithWeekStartsOn(settings.formats.dates.weekStartsOn, periodType); + } + switch (periodType) { case PeriodType.Day: return { @@ -395,6 +353,7 @@ export function getDateFuncsByPeriodType(periodType: PeriodType | null | undefin isSame: isSameDay, }; + case PeriodType.Week: case PeriodType.WeekSun: return { start: startOfWeek, @@ -492,6 +451,7 @@ export function getDateFuncsByPeriodType(periodType: PeriodType | null | undefin }; // BiWeek 1 + case PeriodType.BiWeek1: case PeriodType.BiWeek1Sun: case PeriodType.BiWeek1Mon: case PeriodType.BiWeek1Tue: @@ -500,6 +460,7 @@ export function getDateFuncsByPeriodType(periodType: PeriodType | null | undefin case PeriodType.BiWeek1Fri: case PeriodType.BiWeek1Sat: // BiWeek 2 + case PeriodType.BiWeek2: case PeriodType.BiWeek2Sun: case PeriodType.BiWeek2Mon: case PeriodType.BiWeek2Tue: @@ -525,7 +486,14 @@ export function getDateFuncsByPeriodType(periodType: PeriodType | null | undefin }; } - default: + // All cases not handled above + case PeriodType.Custom: + case PeriodType.DayTime: + case PeriodType.TimeOnly: + + case PeriodType.MonthYear: + case null: + case undefined: // Default to end of day if periodType == null, etc return { start: startOfDay, @@ -534,6 +502,9 @@ export function getDateFuncsByPeriodType(periodType: PeriodType | null | undefin difference: differenceInDays, isSame: isSameDay, }; + + default: + assertNever(periodType); // This will now report unhandled cases } } @@ -683,26 +654,10 @@ export function formatDate( return formatDateWithLocale(defaultLocale, date, periodType, options); } -export function formatDateWithLocale( - settings: LocaleSettings, - date: Date | string | null | undefined, - periodType: PeriodType, - options: FormatDateOptions = {} -): string { - if (typeof date === 'string') { - date = parseISO(date); - } - - // Handle 'Invalid Date' - // @ts-ignore - Date is a number (see: https://stackoverflow.com/questions/1353684/detecting-an-invalid-date-date-instance-in-javascript) - if (date == null || isNaN(date)) { - return ''; - } - - const weekStartsOn = options.weekStartsOn ?? settings.formats.dates.weekStartsOn; - - const { day, dayTime, timeOnly, week, month, monthsYear, year } = settings.formats.dates.presets; - +export function updatePeriodeTypeWithWeekStartsOn( + weekStartsOn: DayOfWeek, + periodType: PeriodType | null | undefined +) { if (periodType === PeriodType.Week) { periodType = [ PeriodType.WeekSun, @@ -735,6 +690,31 @@ export function formatDateWithLocale( ][weekStartsOn]; } + return periodType; +} + +export function formatDateWithLocale( + settings: LocaleSettings, + date: Date | string | null | undefined, + periodType: PeriodType, + options: FormatDateOptions = {} +): string { + if (typeof date === 'string') { + date = parseISO(date); + } + + // Handle 'Invalid Date' + // @ts-ignore - Date is a number (see: https://stackoverflow.com/questions/1353684/detecting-an-invalid-date-date-instance-in-javascript) + if (date == null || isNaN(date)) { + return ''; + } + + const weekStartsOn = options.weekStartsOn ?? settings.formats.dates.weekStartsOn; + + const { day, dayTime, timeOnly, week, month, monthsYear, year } = settings.formats.dates.presets; + + periodType = updatePeriodeTypeWithWeekStartsOn(weekStartsOn, periodType) ?? periodType; + /** Resolve a preset given the chosen variant */ function rv(preset: DateFormatVariantPreset) { if (options.variant === 'custom') { @@ -759,6 +739,7 @@ export function formatDateWithLocale( case PeriodType.TimeOnly: return formatIntl(settings, date, rv(timeOnly!)!); + case PeriodType.Week: //Should never happen, but to make types happy case PeriodType.WeekSun: return range(settings, date, 0, rv(week!)!); case PeriodType.WeekMon: @@ -793,6 +774,7 @@ export function formatDateWithLocale( const fDate = new Date(getFiscalYear(date), 0, 1); return formatIntl(settings, fDate, rv(year!)!); + case PeriodType.BiWeek1: //Should never happen, but to make types happy case PeriodType.BiWeek1Sun: return range(settings, date, 0, rv(week!)!, 1); case PeriodType.BiWeek1Mon: @@ -808,6 +790,7 @@ export function formatDateWithLocale( case PeriodType.BiWeek1Sat: return range(settings, date, 6, rv(week!)!, 1); + case PeriodType.BiWeek2: //Should never happen, but to make types happy case PeriodType.BiWeek2Sun: return range(settings, date, 0, rv(week!)!, 2); case PeriodType.BiWeek2Mon: @@ -825,6 +808,8 @@ export function formatDateWithLocale( default: return formatISO(date); + // default: + // assertNever(periodType); // This will now report unhandled cases } } diff --git a/packages/svelte-ux/src/lib/utils/dateRange.ts b/packages/svelte-ux/src/lib/utils/dateRange.ts index 4689e462d..b794016a5 100644 --- a/packages/svelte-ux/src/lib/utils/dateRange.ts +++ b/packages/svelte-ux/src/lib/utils/dateRange.ts @@ -1,7 +1,8 @@ import { startOfDay, isLeapYear, isAfter, isBefore, subYears } from 'date-fns'; -import { getDateFuncsByPeriodType } from './date'; +import { getDateFuncsByPeriodType, updatePeriodeTypeWithWeekStartsOn } from './date'; import { PeriodType } from './date_types'; +import type { LocaleSettings } from '.'; export type DateRange = { from: Date | null; @@ -9,19 +10,30 @@ export type DateRange = { periodType?: PeriodType | null; }; -export const dayPresets = getDateRangePresets(PeriodType.Day); -export const biWeekSun1Presets = getDateRangePresets(PeriodType.BiWeek1Sun); -export const biWeekMon1Presets = getDateRangePresets(PeriodType.BiWeek1Mon); -export const monthPresets = getDateRangePresets(PeriodType.Month); -export const quarterPresets = getDateRangePresets(PeriodType.Quarter); -export const fiscalYearPresets = getDateRangePresets(PeriodType.FiscalYearOctober); +// All this is exported, but never used. Is it usefull? +export const dayPresets = getDateRangePresets(undefined, PeriodType.Day); +export const biWeekSun1Presets = getDateRangePresets(undefined, PeriodType.BiWeek1Sun); +export const biWeekMon1Presets = getDateRangePresets(undefined, PeriodType.BiWeek1Mon); +export const monthPresets = getDateRangePresets(undefined, PeriodType.Month); +export const quarterPresets = getDateRangePresets(undefined, PeriodType.Quarter); +export const fiscalYearPresets = getDateRangePresets(undefined, PeriodType.FiscalYearOctober); const now = new Date(); -export function getDateRangePresets(periodType: PeriodType): { label: string; value: DateRange }[] { +export function getDateRangePresets( + settings: LocaleSettings | undefined, + periodType: PeriodType +): { label: string; value: DateRange }[] { let now = new Date(); const today = startOfDay(now); - const { start, end, add } = getDateFuncsByPeriodType(periodType); + + if (settings) { + periodType = + updatePeriodeTypeWithWeekStartsOn(settings.formats.dates.weekStartsOn, periodType) ?? + periodType; + } + + const { start, end, add } = getDateFuncsByPeriodType(settings, periodType); switch (periodType) { case PeriodType.Day: { @@ -29,7 +41,7 @@ export function getDateRangePresets(periodType: PeriodType): { label: string; va return [ { - label: 'Today', // Current Day + label: settings?.dictionary.Date.Today ?? 'Today', // Current Day value: { from: today, to: end(today), @@ -456,14 +468,18 @@ export function getPreviousYearPeriodOffset( export type PeriodComparison = 'prevPeriod' | 'prevYear' | 'fiftyTwoWeeksAgo'; -export function getPeriodComparisonOffset(view: PeriodComparison, period: DateRange | undefined) { +export function getPeriodComparisonOffset( + settings: LocaleSettings, + view: PeriodComparison, + period: DateRange | undefined +) { if (period == null || period.from == null || period.to == null || period.periodType == null) { throw new Error('Period must be defined to calculate offset'); } switch (view) { case 'prevPeriod': - const dateFuncs = getDateFuncsByPeriodType(period.periodType); + const dateFuncs = getDateFuncsByPeriodType(settings, period.periodType); return dateFuncs.difference(period.from, period.to) - 1; // Difference counts full days, need additoinal offset case 'prevYear': diff --git a/packages/svelte-ux/src/lib/utils/dictionary.ts b/packages/svelte-ux/src/lib/utils/dictionary.ts index 015c28d26..2a43d85e4 100644 --- a/packages/svelte-ux/src/lib/utils/dictionary.ts +++ b/packages/svelte-ux/src/lib/utils/dictionary.ts @@ -12,6 +12,8 @@ export type DictionaryMessagesOptions = { Quarter?: string; CalendarYear?: string; FiscalYearOct?: string; + + Today?: string; }; }; diff --git a/packages/svelte-ux/src/lib/utils/locale.ts b/packages/svelte-ux/src/lib/utils/locale.ts index 610ad92f0..416eb12e5 100644 --- a/packages/svelte-ux/src/lib/utils/locale.ts +++ b/packages/svelte-ux/src/lib/utils/locale.ts @@ -94,6 +94,8 @@ const defaultLocaleSettings: LocaleSettings = { Quarter: 'Quarter', CalendarYear: 'Calendar Year', FiscalYearOct: 'Fiscal Year (Oct)', + + Today: 'Today', }, }, formats: { diff --git a/packages/svelte-ux/src/routes/+layout.svelte b/packages/svelte-ux/src/routes/+layout.svelte index 35b68d5b0..642a678ea 100644 --- a/packages/svelte-ux/src/routes/+layout.svelte +++ b/packages/svelte-ux/src/routes/+layout.svelte @@ -31,7 +31,7 @@ $: title = data.pr_id ? `🚧 (pr:${data.pr_id}) - ${baseTitle}` : baseTitle; settings({ - // fallbackLocale: 'fr', + fallbackLocale: 'fr', localeFormats: { fr: createLocaleSettings({ locale: 'fr', @@ -60,6 +60,8 @@ CalendarYear: 'Année', FiscalYearOct: 'Année fiscale (octobre)', BiWeek: 'Bi-hebdomadaire', + + Today: "Aujourd'hui", }, }, }), diff --git a/packages/svelte-ux/src/routes/docs/components/DateRange/+page.svelte b/packages/svelte-ux/src/routes/docs/components/DateRange/+page.svelte index 8e6e6701d..0de67567f 100644 --- a/packages/svelte-ux/src/routes/docs/components/DateRange/+page.svelte +++ b/packages/svelte-ux/src/routes/docs/components/DateRange/+page.svelte @@ -4,6 +4,9 @@ import Preview from '$lib/components/Preview.svelte'; import DateRange from '$lib/components/DateRange.svelte'; import { PeriodType, getDateFuncsByPeriodType } from '$lib/utils/date'; + import { getSettings } from '$lib/components/settings'; + + const { localeSettings } = getSettings(); let selected = { from: new Date('1982-03-01T00:00:00'), @@ -57,8 +60,8 @@ { - const { start, end, add } = getDateFuncsByPeriodType(periodType); + getPeriodTypePresets={(settings, periodType) => { + const { start, end, add } = getDateFuncsByPeriodType($localeSettings, periodType); if (periodType === PeriodType.Day) { const today = startOfDay(new Date());