Browse Source

feat(nc-gui): month view dat & date time field

pull/7611/head
DarkPhoenix2704 8 months ago
parent
commit
23560dcfd2
  1. 1
      packages/nc-gui/components/smartsheet/calendar/DayView.vue
  2. 141
      packages/nc-gui/components/smartsheet/calendar/MonthView.vue
  3. 3
      packages/nc-gui/components/smartsheet/calendar/WeekView.vue
  4. 1
      packages/nc-gui/lib/types.ts

1
packages/nc-gui/components/smartsheet/calendar/DayView.vue

@ -315,7 +315,6 @@ const dropEvent = (event: DragEvent) => {
> >
<LazySmartsheetRow :row="record"> <LazySmartsheetRow :row="record">
<LazySmartsheetCalendarRecordCard <LazySmartsheetCalendarRecordCard
:key="rowIndex"
:date="dayjs(record.row[record.rowMeta.range.fk_from_col.title]).format('H:mm')" :date="dayjs(record.row[record.rowMeta.range.fk_from_col.title]).format('H:mm')"
:name="record.row[displayField.title]" :name="record.row[displayField.title]"
:position="getRecordPosition(record)" :position="getRecordPosition(record)"

141
packages/nc-gui/components/smartsheet/calendar/MonthView.vue

@ -1,10 +1,11 @@
<script lang="ts" setup> <script lang="ts" setup>
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { UITypes } from 'nocodb-sdk'
import type { Row } from '#imports' import type { Row } from '#imports'
const emit = defineEmits(['new-record', 'expand-record']) const emit = defineEmits(['new-record', 'expand-record'])
const { selectedDate, formattedData, displayField, calendarRange } = useCalendarViewStoreOrThrow() const { selectedDate, formattedData, displayField, calendarRange, calDataType } = useCalendarViewStoreOrThrow()
const isMondayFirst = ref(true) const isMondayFirst = ref(true)
@ -65,7 +66,9 @@ const recordsToDisplay = computed<{
const perWidth = gridContainerWidth.value / 7 const perWidth = gridContainerWidth.value / 7
const perHeight = gridContainerHeight.value / dates.value.length const perHeight = gridContainerHeight.value / dates.value.length
const perRecordHeight = '40' const perRecordHeight = 40
const spaceBetweenRecords = 35
const recordsInDay: { const recordsInDay: {
[key: string]: { [key: string]: {
@ -76,14 +79,31 @@ const recordsToDisplay = computed<{
} = {} } = {}
if (!calendarRange.value) return [] if (!calendarRange.value) return []
const recordsToDisplay: Array<Row> = [] const recordsToDisplay: Array<Row> = []
calendarRange.value.forEach((range) => { calendarRange.value.forEach((range) => {
const startCol = range.fk_from_col const startCol = range.fk_from_col
const endCol = range.fk_to_col const endCol = range.fk_to_col
formattedData.value.forEach((record: Row) => {
const sortedFormattedData = [...formattedData.value].sort((a, b) => {
if (startCol && endCol) {
const startA = dayjs(a.row[startCol.title])
const endA = dayjs(a.row[endCol.title])
const startB = dayjs(b.row[startCol.title])
const endB = dayjs(b.row[endCol.title])
return endB.diff(startB) - endA.diff(startA)
} else {
const startA = dayjs(a.row[startCol.title])
const startB = dayjs(b.row[startCol.title])
return startB.diff(startA)
}
})
sortedFormattedData.forEach((record: Row) => {
if (!endCol && startCol) { if (!endCol && startCol) {
const startDate = dayjs(record.row[startCol.title]) const startDate = dayjs(record.row[startCol.title])
const dateKey = startDate.format('YYYY-MM-DD') const dateKey = startDate.format('YYYY-MM-DD')
if (!recordsInDay[dateKey]) { if (!recordsInDay[dateKey]) {
@ -91,28 +111,21 @@ const recordsToDisplay = computed<{
} }
recordsInDay[dateKey].count++ recordsInDay[dateKey].count++
const weekIndex = dates.value.findIndex((week) => { const weekIndex = dates.value.findIndex((week) => week.some((day) => dayjs(day).isSame(startDate, 'day')))
return (
week.findIndex((day) => {
return dayjs(day).isSame(startDate, 'day')
}) !== -1
)
})
const dayIndex = dates.value[weekIndex].findIndex((day) => { const dayIndex = dates.value[weekIndex].findIndex((day) => {
return dayjs(day).isSame(startDate, 'day') return dayjs(day).isSame(startDate, 'day')
}) })
const style = { const style: Partial<CSSStyleDeclaration> = {
left: `${dayIndex * perWidth}px`, left: `${dayIndex * perWidth}px`,
width: `${perWidth}px`, width: `${perWidth}px`,
} }
const recordIndex = recordsInDay[dateKey].count const recordIndex = recordsInDay[dateKey].count
const top = weekIndex * perHeight + 42 + (recordIndex - 1) * perRecordHeight const top = weekIndex * perHeight + spaceBetweenRecords + (recordIndex - 1) * perRecordHeight
const heightRequired = perRecordHeight * recordIndex + spaceBetweenRecords
const heightRequired = perRecordHeight * recordIndex + 42
if (heightRequired > perHeight) { if (heightRequired > perHeight) {
style.display = 'none' style.display = 'none'
@ -127,11 +140,96 @@ const recordsToDisplay = computed<{
rowMeta: { rowMeta: {
...record.rowMeta, ...record.rowMeta,
style, style,
position: 'rounded',
range, range,
}, },
}) })
} else if (startCol && endCol) { } else if (startCol && endCol) {
// TODO: Handle range const startDate = dayjs(record.row[startCol.title])
const endDate = dayjs(record.row[endCol.title])
let currentWeekStart = startDate.startOf('week')
while (currentWeekStart.isBefore(endDate)) {
const currentWeekEnd = currentWeekStart.endOf('week')
const recordStart = currentWeekStart.isBefore(startDate) ? startDate : currentWeekStart
const recordEnd = currentWeekEnd.isAfter(endDate) ? endDate : currentWeekEnd
let day = recordStart.clone()
while (day.isBefore(recordEnd) || day.isSame(recordEnd, 'day')) {
const dateKey = day.format('YYYY-MM-DD')
if (!recordsInDay[dateKey]) {
recordsInDay[dateKey] = { overflow: false, count: 0, overflowCount: 0 }
}
recordsInDay[dateKey].count++
day = day.add(1, 'day')
}
const weekIndex = dates.value.findIndex((week) => {
return (
week.findIndex((day) => {
return dayjs(day).isSame(recordStart, 'day')
}) !== -1
)
})
let maxRecordCount = 0
for (let i = 0; i < dates.value[weekIndex].length; i++) {
const day = dates.value[weekIndex][i]
const dateKey = dayjs(day).format('YYYY-MM-DD')
if (!recordsInDay[dateKey]) continue
const recordIndex = recordsInDay[dateKey].count
maxRecordCount = Math.max(maxRecordCount, recordIndex)
}
const startDayIndex = dates.value[weekIndex].findIndex((day) => dayjs(day).isSame(recordStart, 'day'))
const endDayIndex = dates.value[weekIndex].findIndex((day) => dayjs(day).isSame(recordEnd, 'day'))
const style: Partial<CSSStyleDeclaration> = {
left: `${startDayIndex * perWidth}px`,
width: `${(endDayIndex - startDayIndex + 1) * perWidth}px`,
}
const top = weekIndex * perHeight + spaceBetweenRecords + (maxRecordCount - 1) * perRecordHeight
const heightRequired = perRecordHeight * maxRecordCount + spaceBetweenRecords
let position = 'rounded' as const
if (startDate.isSame(currentWeekStart, 'week') && endDate.isSame(currentWeekEnd, 'week')) {
position = 'rounded' as const
} else if (startDate.isSame(currentWeekStart, 'week')) {
position = 'leftRounded' as const
} else if (endDate.isSame(currentWeekEnd, 'week')) {
position = 'rightRounded' as const
} else {
position = 'none' as const
}
if (heightRequired > perHeight) {
style.display = 'none'
for (let i = startDayIndex; i <= endDayIndex; i++) {
const day = dates.value[weekIndex][i]
const dateKey = dayjs(day).format('YYYY-MM-DD')
if (!recordsInDay[dateKey]) continue
recordsInDay[dateKey].overflow = true
recordsInDay[dateKey].overflowCount++
}
} else {
style.top = `${top}px`
}
recordsToDisplay.push({
...record,
rowMeta: {
...record.rowMeta,
position,
style,
range,
},
})
currentWeekStart = currentWeekStart.add(1, 'week')
}
} }
}) })
}) })
@ -209,7 +307,7 @@ const isDateSelected = (date: Date) => {
recordsToDisplay.count[dayjs(day).format('YYYY-MM-DD')] && recordsToDisplay.count[dayjs(day).format('YYYY-MM-DD')] &&
recordsToDisplay.count[dayjs(day).format('YYYY-MM-DD')]?.overflow recordsToDisplay.count[dayjs(day).format('YYYY-MM-DD')]?.overflow
" "
class="text-xs absolute bottom-2 text-center inset-x-0 text-gray-500" class="text-xs absolute bottom-1 text-center inset-x-0 text-gray-500"
> >
+ {{ recordsToDisplay.count[dayjs(day).format('YYYY-MM-DD')]?.overflowCount }} more + {{ recordsToDisplay.count[dayjs(day).format('YYYY-MM-DD')]?.overflowCount }} more
</div> </div>
@ -220,15 +318,20 @@ const isDateSelected = (date: Date) => {
<div <div
v-for="(record, recordIndex) in recordsToDisplay.records" v-for="(record, recordIndex) in recordsToDisplay.records"
:key="recordIndex" :key="recordIndex"
:style="record.rowMeta.style" :style="record.rowMeta.style as Partial<CSSStyleValue>"
class="absolute pointer-events-auto" class="absolute pointer-events-auto"
draggable="true" draggable="true"
@dragover.prevent @dragover.prevent
> >
<LazySmartsheetRow :row="record"> <LazySmartsheetRow :row="record">
<LazySmartsheetCalendarRecordCard <LazySmartsheetCalendarRecordCard
:date="record.row[record.rowMeta.range.fk_from_col.title]" :date="
calDataType === UITypes.DateTime
? dayjs(record.row[record.rowMeta.range?.fk_from_col.title]).format('YYYY-MM-DD HH:mm')
: dayjs(record.row[record.rowMeta.range?.fk_from_col.title]).format('YYYY-MM-DD')
"
:name="record.row[displayField.title]" :name="record.row[displayField.title]"
:position="record.rowMeta.position"
@click="emit('expand-record', record)" @click="emit('expand-record', record)"
/> />
</LazySmartsheetRow> </LazySmartsheetRow>

3
packages/nc-gui/components/smartsheet/calendar/WeekView.vue

@ -82,6 +82,9 @@ const findFirstSuitableColumn = (recordsInDay: any, startDayIndex: number, spanD
let isColumnSuitable = true let isColumnSuitable = true
for (let i = 0; i < spanDays; i++) { for (let i = 0; i < spanDays; i++) {
const dayIndex = startDayIndex + i const dayIndex = startDayIndex + i
if (!recordsInDay[dayIndex]) {
recordsInDay[dayIndex] = {}
}
if (recordsInDay[dayIndex][column]) { if (recordsInDay[dayIndex][column]) {
isColumnSuitable = false isColumnSuitable = false
break break

1
packages/nc-gui/lib/types.ts

@ -69,6 +69,7 @@ interface Row {
fk_from_col: ColumnType fk_from_col: ColumnType
fk_to_col: ColumnType | null fk_to_col: ColumnType | null
} }
position?: 'leftRounded' | 'rightRounded' | 'rounded' | 'none' | 'spanning'
} }
} }

Loading…
Cancel
Save