add frontend support for the date formatting option

This commit is contained in:
Gregor Vostrak
2025-05-08 18:00:25 +02:00
committed by Constantin Graf
parent f69bc28316
commit a076bb2fb0
6 changed files with 34 additions and 22 deletions

View File

@@ -43,7 +43,7 @@ const xAxisLabels = computed(() => {
if (props.groupedType === 'week') {
return props?.groupedData?.map((el) => formatWeek(el.key));
}
return props?.groupedData?.map((el) => formatDate(el.key ?? ''));
return props?.groupedData?.map((el) => formatDate(el.key ?? '', organization?.value?.date_format));
});
const accentColor = useCssVar('--theme-color-chart', null, { observe: true });
const labelColor = useCssVar('--color-text-secondary', null, { observe: true });

View File

@@ -9,7 +9,8 @@ import { Calendar } from '@/Components/ui/calendar';
import { CalendarIcon } from 'lucide-vue-next';
import { formatDateLocalized } from '@/packages/ui/src/utils/time';
import { parseDate } from '@internationalized/date';
import { computed } from 'vue';
import { computed, inject, type ComputedRef } from 'vue';
import { type Organization } from '@/packages/api/src';
const model = defineModel<string | null>();
const emit = defineEmits<{
@@ -27,6 +28,8 @@ const handleBlur = () => {
const date = computed(() => {
return model.value ? parseDate(model.value) : undefined;
});
const organization = inject<ComputedRef<Organization>>('organization');
</script>
<template>
@@ -41,7 +44,7 @@ const date = computed(() => {
]"
>
<CalendarIcon class="mr-2 h-4 w-4" />
{{ model ? formatDateLocalized(model) : 'Pick a date' }}
{{ model ? formatDateLocalized(model, organization?.date_format) : 'Pick a date' }}
</Button>
</PopoverTrigger>
<PopoverContent class="w-auto p-0">

View File

@@ -7,8 +7,8 @@ import {
getDayJsInstance,
getLocalizedDayJs,
} from '@/packages/ui/src/utils/time';
import { ref } from 'vue';
import { ref, inject, type ComputedRef } from 'vue';
import { type Organization } from '@/packages/api/src';
const start = defineModel('start', { default: '' });
const end = defineModel('end', { default: '' });
@@ -95,6 +95,8 @@ function setLastYear() {
emit('submit');
open.value = false;
}
const organization = inject<ComputedRef<Organization>>('organization');
</script>
<template>
@@ -108,9 +110,9 @@ function setLastYear() {
class="px-2 py-1 bg-input-background border border-input-border font-medium rounded-lg flex items-center space-x-2">
<CalendarIcon class="w-5"></CalendarIcon>
<div class="text-text-primary">
{{ formatDateLocalized(start) }}
{{ formatDateLocalized(start, organization?.date_format) }}
<span class="px-1.5 text-text-secondary">-</span>
{{ formatDateLocalized(end) }}
{{ formatDateLocalized(end, organization?.date_format) }}
</div>
</button>
</template>

View File

@@ -1,13 +1,13 @@
<script setup lang="ts">
import Dropdown from '@/packages/ui/src/Input/Dropdown.vue';
import { defineProps, ref } from 'vue';
import { defineProps, ref, inject, type ComputedRef } from 'vue';
import {
formatDateLocalized,
formatStartEnd,
} from '@/packages/ui/src/utils/time';
import TimeRangeSelector from '@/packages/ui/src/Input/TimeRangeSelector.vue';
import { twMerge } from 'tailwind-merge';
import { type Organization } from '@/packages/api/src';
defineProps<{
start: string;
end: string | null;
@@ -20,6 +20,9 @@ const emit = defineEmits<{
const open = ref(false);
const triggerElement = ref<HTMLButtonElement | null>(null);
const organization = inject<ComputedRef<Organization>>('organization');
</script>
<template>
@@ -44,7 +47,7 @@ const triggerElement = ref<HTMLButtonElement | null>(null);
">
{{ formatStartEnd(start, end) }}
<span v-if="showDate" class="text-text-tertiary font-medium"
>{{ formatDateLocalized(start) }}
>{{ formatDateLocalized(start, organization?.date_format) }}
</span>
</button>
</template>

View File

@@ -58,7 +58,7 @@ function selectUnselectAll(value: boolean) {
{{ formatWeekday(date) }}
</span>
<span class="font-semibold text-text-secondary">
{{ formatDate(date) }}
{{ formatDate(date, organization?.date_format) }}
</span>
</div>
<div class="text-text-secondary pr-[90px] lg:pr-[92px]">

View File

@@ -13,13 +13,7 @@ import updateLocale from 'dayjs/plugin/updateLocale';
import { computed } from 'vue';
import { formatNumber } from './number';
export type CurrencyFormat =
| 'iso-code-before-with-space'
| 'iso-code-after-with-space'
| 'symbol-before'
| 'symbol-after'
| 'symbol-before-with-space'
| 'symbol-after-with-space';
export type DateFormat =
| 'point-separated-d-m-yyyy'
| 'slash-separated-mm-dd-yyyy'
@@ -27,6 +21,16 @@ export type DateFormat =
| 'hyphen-separated-dd-mm-yyyy'
| 'hyphen-separated-mm-dd-yyyy'
| 'hyphen-separated-yyyy-mm-dd';
const dateFormatMap: Record<DateFormat, string> = {
'point-separated-d-m-yyyy': 'D.M.YYYY',
'slash-separated-mm-dd-yyyy': 'MM/DD/YYYY',
'slash-separated-dd-mm-yyyy': 'DD/MM/YYYY',
'hyphen-separated-dd-mm-yyyy': 'DD-MM-YYYY',
'hyphen-separated-mm-dd-yyyy': 'MM-DD-YYYY',
'hyphen-separated-yyyy-mm-dd': 'YYYY-MM-DD'
};
export type TimeFormat = '12-hours' | '24-hours';
export type IntervalFormat =
| 'decimal'
@@ -123,21 +127,21 @@ export function getLocalizedDateFromTimestamp(timestamp: string) {
* Returns a formatted date.
* @param date - date in the format of 'YYYY-MM-DD'
*/
export function formatDate(date: string): string {
export function formatDate(date: string, format: DateFormat = 'point-separated-d-m-yyyy'): string {
if (date?.includes('+')) {
console.warn(
'Date contains timezone information, use formatDateLocalized instead'
);
}
return getDayJsInstance()(date).format('DD.MM.YYYY');
return getDayJsInstance()(date).format(dateFormatMap[format]);
}
/*
* Returns a formatted date.
* @param date - date in the format of 'YYYY-MM-DD'
*/
export function formatDateLocalized(date: string): string {
return getLocalizedDayJs(date).format('DD.MM.YYYY');
export function formatDateLocalized(date: string, format: DateFormat = 'point-separated-d-m-yyyy'): string {
return getLocalizedDayJs(date).format(dateFormatMap[format]);
}
export function formatDateTimeLocalized(date: string): string {