|
|
@ -1,9 +1,10 @@ |
|
|
|
<script lang="ts" setup> |
|
|
|
<script lang="ts" setup> |
|
|
|
import dayjs from 'dayjs' |
|
|
|
import dayjs from 'dayjs' |
|
|
|
|
|
|
|
import type { Row } from '#imports' |
|
|
|
|
|
|
|
|
|
|
|
const emit = defineEmits(['new-record', 'expand-record']) |
|
|
|
const emit = defineEmits(['new-record', 'expand-record']) |
|
|
|
|
|
|
|
|
|
|
|
const { pageDate, selectedDate, formattedData, displayField, calendarRange } = useCalendarViewStoreOrThrow() |
|
|
|
const { selectedDate, formattedData, displayField, calendarRange } = useCalendarViewStoreOrThrow() |
|
|
|
|
|
|
|
|
|
|
|
const isMondayFirst = ref(true) |
|
|
|
const isMondayFirst = ref(true) |
|
|
|
|
|
|
|
|
|
|
@ -15,13 +16,17 @@ const days = computed(() => { |
|
|
|
} |
|
|
|
} |
|
|
|
}) |
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const calendarGridContainer = ref() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const { width: gridContainerWidth, height: gridContainerHeight } = useElementSize(calendarGridContainer) |
|
|
|
|
|
|
|
|
|
|
|
const isDayInPagedMonth = (date: Date) => { |
|
|
|
const isDayInPagedMonth = (date: Date) => { |
|
|
|
return date.getMonth() === pageDate.value.getMonth() |
|
|
|
return date.getMonth() === selectedDate.value.getMonth() |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const dates = computed(() => { |
|
|
|
const dates = computed(() => { |
|
|
|
const startOfMonth = dayjs(pageDate.value).startOf('month') |
|
|
|
const startOfMonth = dayjs(selectedDate.value).startOf('month') |
|
|
|
const endOfMonth = dayjs(pageDate.value).endOf('month') |
|
|
|
const endOfMonth = dayjs(selectedDate.value).endOf('month') |
|
|
|
|
|
|
|
|
|
|
|
const firstDayToDisplay = startOfMonth.startOf('week').add(isMondayFirst.value ? 0 : -1, 'day') |
|
|
|
const firstDayToDisplay = startOfMonth.startOf('week').add(isMondayFirst.value ? 0 : -1, 'day') |
|
|
|
const lastDayToDisplay = endOfMonth.endOf('week').add(isMondayFirst.value ? 0 : -1, 'day') |
|
|
|
const lastDayToDisplay = endOfMonth.endOf('week').add(isMondayFirst.value ? 0 : -1, 'day') |
|
|
@ -44,6 +49,71 @@ const dates = computed(() => { |
|
|
|
return weeksArray |
|
|
|
return weeksArray |
|
|
|
}) |
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const recordsToDisplay = computed<Array<Row>>(() => { |
|
|
|
|
|
|
|
if (!dates.value || !calendarRange.value) return [] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const perWidth = gridContainerWidth.value / 7 |
|
|
|
|
|
|
|
const perHeight = gridContainerHeight.value / dates.value.length |
|
|
|
|
|
|
|
const perRecordHeight = '40' |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const recordsInDay: { [key: string]: number } = {} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!calendarRange.value) return [] |
|
|
|
|
|
|
|
const recordsToDisplay: Array<Row> = [] |
|
|
|
|
|
|
|
calendarRange.value.forEach((range) => { |
|
|
|
|
|
|
|
const startCol = range.fk_from_col |
|
|
|
|
|
|
|
const endCol = range.fk_to_col |
|
|
|
|
|
|
|
formattedData.value.forEach((record: Row) => { |
|
|
|
|
|
|
|
if (!endCol && startCol) { |
|
|
|
|
|
|
|
const startDate = dayjs(record.row[startCol.title]) |
|
|
|
|
|
|
|
recordsInDay[startDate.format('YYYY-MM-DD')] = recordsInDay[startDate.format('YYYY-MM-DD')] + 1 || 1 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const weekIndex = dates.value.findIndex((week) => { |
|
|
|
|
|
|
|
return ( |
|
|
|
|
|
|
|
week.findIndex((day) => { |
|
|
|
|
|
|
|
return dayjs(day).isSame(startDate, 'day') |
|
|
|
|
|
|
|
}) !== -1 |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const dayIndex = dates.value[weekIndex].findIndex((day) => { |
|
|
|
|
|
|
|
return dayjs(day).isSame(startDate, 'day') |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const style = { |
|
|
|
|
|
|
|
left: `${dayIndex * perWidth}px`, |
|
|
|
|
|
|
|
width: `${perWidth}px`, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const recordIndex = recordsInDay[startDate.format('YYYY-MM-DD')] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const top = weekIndex * perHeight + 40 + (recordIndex - 1) * perRecordHeight |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const heightRequired = perRecordHeight * recordIndex + 40 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (heightRequired > perHeight) { |
|
|
|
|
|
|
|
style.display = 'none' |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
style.top = `${top}px` |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
recordsToDisplay.push({ |
|
|
|
|
|
|
|
...record, |
|
|
|
|
|
|
|
rowMeta: { |
|
|
|
|
|
|
|
...record.rowMeta, |
|
|
|
|
|
|
|
style, |
|
|
|
|
|
|
|
range, |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
} else if (startCol && endCol) { |
|
|
|
|
|
|
|
// TODO: Handle range |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
console.log(recordsInDay) |
|
|
|
|
|
|
|
return recordsToDisplay |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
const selectDate = (date: Date) => { |
|
|
|
const selectDate = (date: Date) => { |
|
|
|
selectedDate.value = date |
|
|
|
selectedDate.value = date |
|
|
|
} |
|
|
|
} |
|
|
@ -55,7 +125,7 @@ const isDateSelected = (date: Date) => { |
|
|
|
</script> |
|
|
|
</script> |
|
|
|
|
|
|
|
|
|
|
|
<template> |
|
|
|
<template> |
|
|
|
<div v-if="calendarRange" class="h-full"> |
|
|
|
<div v-if="calendarRange" class="h-full relative"> |
|
|
|
<div class="grid grid-cols-7"> |
|
|
|
<div class="grid grid-cols-7"> |
|
|
|
<div |
|
|
|
<div |
|
|
|
v-for="(day, index) in days" |
|
|
|
v-for="(day, index) in days" |
|
|
@ -66,6 +136,7 @@ const isDateSelected = (date: Date) => { |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div |
|
|
|
<div |
|
|
|
|
|
|
|
ref="calendarGridContainer" |
|
|
|
:class="{ |
|
|
|
:class="{ |
|
|
|
'grid-rows-5': dates.length === 5, |
|
|
|
'grid-rows-5': dates.length === 5, |
|
|
|
'grid-rows-6': dates.length === 6, |
|
|
|
'grid-rows-6': dates.length === 6, |
|
|
@ -109,6 +180,24 @@ const isDateSelected = (date: Date) => { |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="absolute inset-0 pointer-events-none mt-8 pb-7.5"> |
|
|
|
|
|
|
|
<div |
|
|
|
|
|
|
|
v-for="(record, recordIndex) in recordsToDisplay" |
|
|
|
|
|
|
|
:key="recordIndex" |
|
|
|
|
|
|
|
:style="record.rowMeta.style" |
|
|
|
|
|
|
|
class="absolute pointer-events-auto" |
|
|
|
|
|
|
|
draggable="true" |
|
|
|
|
|
|
|
@dragover.prevent |
|
|
|
|
|
|
|
> |
|
|
|
|
|
|
|
<LazySmartsheetRow :row="record"> |
|
|
|
|
|
|
|
<LazySmartsheetCalendarRecordCard |
|
|
|
|
|
|
|
:date="record.row[record.rowMeta.range.fk_from_col.title]" |
|
|
|
|
|
|
|
:name="record.row[displayField.title]" |
|
|
|
|
|
|
|
@click="emit('expand-record', record)" |
|
|
|
|
|
|
|
/> |
|
|
|
|
|
|
|
</LazySmartsheetRow> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</template> |
|
|
|
</template> |
|
|
|
|
|
|
|
|
|
|
|