mirror of
https://github.com/solidtime-io/solidtime.git
synced 2026-08-08 00:02:15 +01:00
add support for week_start and time_format in calendar
also rename them so that they do not conflict with the datepicker calendar component
This commit is contained in:
@@ -19,6 +19,9 @@ const dateFormat = computed(() => organization?.value?.date_format);
|
||||
|
||||
<template>
|
||||
<div class="fc-day-header-custom">
|
||||
<div class="text-xs text-muted-foreground font-medium">
|
||||
{{ date.toLocaleDateString('en-US', { weekday: 'short' }) }}
|
||||
</div>
|
||||
<span>{{ formatDate(date.toISOString(), dateFormat) }}</span>
|
||||
<span class="block text-xs text-muted-foreground font-medium mt-1">
|
||||
{{ formatHumanReadableDuration(totalSeconds, intervalFormat, numberFormat) }}
|
||||
@@ -4,12 +4,12 @@ import dayGridPlugin from '@fullcalendar/daygrid';
|
||||
import timeGridPlugin from '@fullcalendar/timegrid';
|
||||
import interactionPlugin from '@fullcalendar/interaction';
|
||||
import type { DatesSetArg, EventClickArg, EventDropArg, EventChangeArg } from '@fullcalendar/core';
|
||||
import { computed, ref, watch } from 'vue';
|
||||
import { computed, ref, watch, inject, type ComputedRef } from 'vue';
|
||||
import { getDayJsInstance, getLocalizedDayJs } from '../utils/time';
|
||||
import { getUserTimezone } from '../utils/settings';
|
||||
import { getUserTimezone, getWeekStart } from '../utils/settings';
|
||||
import { LoadingSpinner, TimeEntryCreateModal, TimeEntryEditModal } from '..';
|
||||
import CalendarEventContent from './CalendarEventContent.vue';
|
||||
import CalendarDayHeader from './CalendarDayHeader.vue';
|
||||
import FullCalendarEventContent from './FullCalendarEventContent.vue';
|
||||
import FullCalendarDayHeader from './FullCalendarDayHeader.vue';
|
||||
import type {
|
||||
TimeEntry,
|
||||
Project,
|
||||
@@ -18,6 +18,7 @@ import type {
|
||||
CreateProjectBody,
|
||||
CreateClientBody,
|
||||
Tag,
|
||||
Organization,
|
||||
} from '@/packages/api/src';
|
||||
import type { Dayjs } from 'dayjs';
|
||||
|
||||
@@ -58,6 +59,41 @@ const selectedTimeEntry = ref<TimeEntry | null>(null);
|
||||
|
||||
const calendarRef = ref<InstanceType<typeof FullCalendar> | null>(null);
|
||||
|
||||
// Inject organization data for settings
|
||||
const organization = inject<ComputedRef<Organization>>('organization');
|
||||
|
||||
// Helper function to convert week start to FullCalendar firstDay value
|
||||
const getFirstDay = () => {
|
||||
const weekStart = getWeekStart();
|
||||
const weekStartMap: Record<string, number> = {
|
||||
'sunday': 0,
|
||||
'monday': 1,
|
||||
'tuesday': 2,
|
||||
'wednesday': 3,
|
||||
'thursday': 4,
|
||||
'friday': 5,
|
||||
'saturday': 6,
|
||||
};
|
||||
return weekStartMap[weekStart] ?? 1; // Default to Monday if not found
|
||||
};
|
||||
|
||||
// Helper function to get time format for slot labels
|
||||
const getSlotLabelFormat = () => {
|
||||
const timeFormat = organization?.value?.time_format || '24-hours';
|
||||
if (timeFormat === '12-hours') {
|
||||
return {
|
||||
hour: 'numeric' as const,
|
||||
hour12: true,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
hour: '2-digit' as const,
|
||||
minute: '2-digit' as const,
|
||||
hour12: false,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
// Map API entries to FullCalendar events
|
||||
const events = computed(() => {
|
||||
return props.timeEntries
|
||||
@@ -188,7 +224,9 @@ const calendarOptions = computed(() => ({
|
||||
slotMaxTime: '24:00:00',
|
||||
slotDuration: '00:15:00',
|
||||
slotLabelInterval: '01:00:00',
|
||||
slotLabelFormat: getSlotLabelFormat(),
|
||||
snapDuration: '00:15:00',
|
||||
firstDay: getFirstDay(),
|
||||
allDaySlot: false,
|
||||
nowIndicator: true,
|
||||
selectable: true,
|
||||
@@ -261,7 +299,7 @@ watch(showEditTimeEntryModal, (value) => {
|
||||
:clients="clients" />
|
||||
<FullCalendar ref="calendarRef" class="fullcalendar" :options="calendarOptions">
|
||||
<template #eventContent="arg">
|
||||
<CalendarEventContent
|
||||
<FullCalendarEventContent
|
||||
:title="arg.event.title"
|
||||
:project-name="(arg.event.extendedProps as any).project?.name"
|
||||
:task-name="(arg.event.extendedProps as any).task?.name"
|
||||
@@ -275,7 +313,7 @@ watch(showEditTimeEntryModal, (value) => {
|
||||
:end="arg.event.end as any" />
|
||||
</template>
|
||||
<template #dayHeaderContent="arg">
|
||||
<CalendarDayHeader
|
||||
<FullCalendarDayHeader
|
||||
:date="arg.date"
|
||||
:total-minutes="
|
||||
dailyTotals[getDayJsInstance()(arg.date).format('YYYY-MM-DD')] || 0
|
||||
@@ -29,9 +29,9 @@ import TimeEntryMassActionRow from './TimeEntry/TimeEntryMassActionRow.vue';
|
||||
import TimeEntryCreateModal from './TimeEntry/TimeEntryCreateModal.vue';
|
||||
import TimeEntryEditModal from './TimeEntry/TimeEntryEditModal.vue';
|
||||
import MoreOptionsDropdown from './MoreOptionsDropdown.vue';
|
||||
import CalendarEventContent from './Calendar/CalendarEventContent.vue';
|
||||
import CalendarDayHeader from './Calendar/CalendarDayHeader.vue';
|
||||
import TimeEntryCalendar from './Calendar/TimeEntryCalendar.vue';
|
||||
import FullCalendarEventContent from './FullCalendar/FullCalendarEventContent.vue';
|
||||
import FullCalendarDayHeader from './FullCalendar/FullCalendarDayHeader.vue';
|
||||
import TimeEntryCalendar from './FullCalendar/TimeEntryCalendar.vue';
|
||||
|
||||
export {
|
||||
money,
|
||||
@@ -57,7 +57,7 @@ export {
|
||||
MoreOptionsDropdown,
|
||||
TimeEntryCreateModal,
|
||||
TimeEntryEditModal,
|
||||
CalendarEventContent,
|
||||
CalendarDayHeader,
|
||||
FullCalendarEventContent,
|
||||
FullCalendarDayHeader,
|
||||
TimeEntryCalendar,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user