Browse Source

fix(nc-gui): some edge cases. updated some ui parts

pull/7611/head
DarkPhoenix2704 8 months ago
parent
commit
570ed5616e
  1. 152
      packages/nc-gui/components/smartsheet/calendar/SideMenu.vue
  2. 7
      packages/nc-gui/components/smartsheet/calendar/SideRecordCard.vue
  3. 18
      packages/nc-gui/components/smartsheet/calendar/WeekView.vue
  4. 140
      packages/nc-gui/composables/useCalendarViewStore.ts

152
packages/nc-gui/components/smartsheet/calendar/SideMenu.vue

@ -2,7 +2,7 @@
import type { VNodeRef } from '@vue/runtime-core'
import { UITypes } from 'nocodb-sdk'
import dayjs from 'dayjs'
import { computed, ref } from '#imports'
import { type Row, computed, ref } from '#imports'
const props = defineProps<{
visible: boolean
@ -35,6 +35,124 @@ const {
const sideBarListRef = ref<VNodeRef | null>(null)
const pushToArray = (arr: Array<Row>, record: Row, range) => {
arr.push({
...record,
rowMeta: {
...record.rowMeta,
range,
},
})
}
const renderData = computed<Array<Row>>(() => {
if (!calendarRange.value) return []
const rangedData: Array<Row> = []
calendarRange.value.forEach((range) => {
const fromCol = range.fk_from_col
const toCol = range.fk_to_col
formattedSideBarData.value.forEach((record) => {
if (fromCol && toCol) {
const from = dayjs(record.row[fromCol.title!])
const to = dayjs(record.row[toCol.title!])
if (sideBarFilterOption.value === 'withoutDates') {
if (!from.isValid() || !to.isValid()) {
pushToArray(rangedData, record, range)
}
} else if (sideBarFilterOption.value === 'allRecords') {
pushToArray(rangedData, record, range)
} else if (
sideBarFilterOption.value === 'month' ||
sideBarFilterOption.value === 'year' ||
sideBarFilterOption.value === 'selectedDate' ||
sideBarFilterOption.value === 'week' ||
sideBarFilterOption.value === 'day'
) {
let fromDate: dayjs.Dayjs | null = null
let toDate: dayjs.Dayjs | null = null
switch (sideBarFilterOption.value) {
case 'month':
fromDate = dayjs(selectedMonth.value).startOf('month')
toDate = dayjs(selectedMonth.value).endOf('month')
break
case 'year':
fromDate = dayjs(selectedDate.value).startOf('year')
toDate = dayjs(selectedDate.value).endOf('year')
break
case 'selectedDate':
fromDate = dayjs(selectedDate.value).startOf('day')
toDate = dayjs(selectedDate.value).endOf('day')
break
case 'week':
fromDate = dayjs(selectedDateRange.value.start).startOf('week')
toDate = dayjs(selectedDateRange.value.end).endOf('week')
break
case 'day':
fromDate = dayjs(selectedDate.value).startOf('day')
toDate = dayjs(selectedDate.value).endOf('day')
break
}
if (from && to) {
if (
(from.isSameOrAfter(fromDate) && to.isSameOrBefore(toDate)) ||
(from.isSameOrBefore(fromDate) && to.isSameOrAfter(toDate)) ||
(from.isSameOrBefore(fromDate) && to.isSameOrAfter(fromDate)) ||
(from.isSameOrBefore(toDate) && to.isSameOrAfter(toDate))
) {
pushToArray(rangedData, record, range)
}
}
}
} else if (fromCol) {
const from = dayjs(record.row[fromCol.title!])
if (sideBarFilterOption.value === 'withoutDates') {
if (!from.isValid()) {
pushToArray(rangedData, record, range)
}
} else if (sideBarFilterOption.value === 'allRecords') {
pushToArray(rangedData, record, range)
} else if (sideBarFilterOption.value === 'selectedDate' || sideBarFilterOption.value === 'day') {
if (from.isSame(selectedDate.value, 'day')) {
pushToArray(rangedData, record, range)
}
} else if (
sideBarFilterOption.value === 'week' ||
sideBarFilterOption.value === 'month' ||
sideBarFilterOption.value === 'year'
) {
let fromDate: dayjs.Dayjs
let toDate: dayjs.Dayjs
switch (sideBarFilterOption.value) {
case 'week':
fromDate = dayjs(selectedDateRange.value.start).startOf('week')
toDate = dayjs(selectedDateRange.value.end).endOf('week')
break
case 'month':
fromDate = dayjs(selectedMonth.value).startOf('month')
toDate = dayjs(selectedMonth.value).endOf('month')
break
case 'year':
fromDate = dayjs(selectedDate.value).startOf('year')
toDate = dayjs(selectedDate.value).endOf('year')
break
}
if (from.isSameOrAfter(fromDate) && from.isSameOrBefore(toDate)) {
pushToArray(rangedData, record, range)
}
}
}
})
})
return rangedData
})
const options = computed(() => {
switch (activeCalendarView.value) {
case 'day' as const:
@ -81,6 +199,7 @@ const sideBarListScrollHandle = useDebounceFn(async (e: Event) => {
if (target.clientHeight + target.scrollTop + INFINITY_SCROLL_THRESHOLD >= target.scrollHeight) {
const pageSize = appInfo.value?.defaultLimit ?? 25
const page = Math.ceil(formattedSideBarData.value.length / pageSize)
await loadMoreSidebarData({
offset: page * pageSize,
})
@ -154,28 +273,39 @@ const sideBarListScrollHandle = useDebounceFn(async (e: Event) => {
class="gap-2 flex flex-col nc-scrollbar-md overflow-y-auto nc-calendar-top-height"
@scroll="sideBarListScrollHandle"
>
<div v-if="formattedSideBarData.length === 0 || isSidebarLoading" class="flex h-full items-center justify-center">
<div v-if="renderData.length === 0 || isSidebarLoading" class="flex h-full items-center justify-center">
<GeneralLoader v-if="isSidebarLoading" size="large" />
<div v-else class="text-gray-500">
{{ t('msg.noRecordsFound') }}
</div>
</div>
<template v-else-if="formattedSideBarData.length > 0">
<LazySmartsheetRow v-for="(record, rowIndex) in formattedSideBarData" :key="rowIndex" :row="record">
<template v-else-if="renderData.length > 0">
<LazySmartsheetRow v-for="(record, rowIndex) in renderData" :key="rowIndex" :row="record">
<LazySmartsheetCalendarSideRecordCard
:date="
calDataType === UITypes.DateTime
? dayjs(record.row[calendarRange[0] ? calendarRange[0].fk_from_col.title : '']).format('DD-MM-YYYY HH:mm')
: dayjs(record.row[calendarRange[0] ? calendarRange[0].fk_from_col.title : '']).format('DD-MM-YYYY')
:from-date="
record.rowMeta.range?.fk_from_col
? calDataType === UITypes.Date
? dayjs(record.row[record.rowMeta.range.fk_from_col.title!]).format('DD MMM')
: dayjs(record.row[record.rowMeta.range.fk_from_col.title!]).format('DD MMM•HH:MM A')
: null
"
:invalid="
dayjs(record.row[calendarRange[0] ? calendarRange[0].fk_from_col.title : '']).isAfter(
dayjs(record.row[calendarRange[0] ? calendarRange[0].fk_to_col.title : '']),
record.rowMeta.range!.fk_to_col &&
dayjs(record.row[record.rowMeta.range!.fk_from_col.title!]).isAfter(
dayjs(record.row[record.rowMeta.range!.fk_to_col.title!]),
)
"
:name="record.row[displayField.title]"
:name="record.row[displayField!.title!]"
:to-date="
record.rowMeta.range!.fk_to_col
? calDataType === UITypes.Date
? dayjs(record.row[record.rowMeta.range!.fk_to_col.title!]).format('DD MMM')
: dayjs(record.row[record.rowMeta.range!.fk_to_col.title!]).format('DD MMM•HH:MM A')
: null
"
color="blue"
draggable="true"
@click="emit('expand-record', record)"
/>
</LazySmartsheetRow>

7
packages/nc-gui/components/smartsheet/calendar/SideRecordCard.vue

@ -1,7 +1,8 @@
<script lang="ts" setup>
interface Props {
name: string
date?: string
fromDate?: string
toDate?: string
color?: string
showDate?: boolean
invalid?: boolean
@ -9,7 +10,7 @@ interface Props {
const props = withDefaults(defineProps<Props>(), {
name: '',
date: '',
fromDate: '',
color: 'blue',
showDate: true,
invalid: false,
@ -32,7 +33,7 @@ const props = withDefaults(defineProps<Props>(), {
></span>
<div class="flex flex-col gap-1 ml-3">
<span class="text-sm font-bold text-gray-700">{{ name }}</span>
<span v-if="showDate" class="text-xs text-gray-500">{{ date }}</span>
<span v-if="showDate" class="text-xs text-gray-500">{{ fromDate }} {{ toDate ? ` - ${toDate}` : '' }}</span>
</div>
</div>

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

@ -81,7 +81,16 @@ const calendarData = computed(() => {
}
const startDaysDiff = startDate.diff(selectedDateRange.value.start, 'day')
const spanDays = Math.max(Math.min(endDate.diff(startDate, 'day'), 6) + 1, 1)
let spanDays = Math.max(Math.min(endDate.diff(startDate, 'day'), 6) + 1, 1)
if (endDate.isAfter(startDate, 'month')) {
spanDays = 7 - startDaysDiff
}
if (startDaysDiff > 0) {
spanDays = Math.min(spanDays, 7 - startDaysDiff)
}
const widthStyle = `calc(max(${spanDays} * ${perDayWidth}px, ${perDayWidth}px))`
let suitableColumn = -1
@ -103,7 +112,7 @@ const calendarData = computed(() => {
recordsInDay[dayIndex][suitableColumn] = true
}
let position = ''
let position = 'none'
const isStartInRange =
ogStartDate && ogStartDate.isBetween(selectedDateRange.value.start, selectedDateRange.value.end, 'day', '[]')
@ -198,11 +207,6 @@ const calendarData = computed(() => {
<div
v-for="(record, id) in calendarData"
:key="id"
:class="{
'ml-3': record.rowMeta.position === 'leftRounded',
'mr-3': record.rowMeta.position === 'rightRounded',
'': record.rowMeta.position === 'rounded',
}"
:style="record.rowMeta.style"
class="absolute pointer-events-auto"
draggable="true"

140
packages/nc-gui/composables/useCalendarViewStore.ts

@ -266,18 +266,20 @@ const [useProvideCalendarViewStore, useCalendarViewStore] = useInjectionState(
if (displayField.value && searchQuery.value) {
if (combinedFilters.length > 0) {
combinedFilters.push({
is_group: true,
logical_op: 'and',
children: [
...combinedFilters,
{
fk_column_id: displayField.value.id,
comparison_op: 'like',
value: searchQuery.value,
},
],
})
combinedFilters = [
{
is_group: true,
logical_op: 'and',
children: [
...combinedFilters,
{
fk_column_id: displayField.value.id,
comparison_op: 'like',
value: searchQuery.value,
},
],
},
]
} else {
combinedFilters.push({
fk_column_id: displayField.value.id,
@ -293,25 +295,28 @@ const [useProvideCalendarViewStore, useCalendarViewStore] = useInjectionState(
async function loadMoreSidebarData(params: Parameters<Api<any>['dbViewRow']['list']>[4] = {}) {
if ((!base?.value?.id || !meta.value?.id || !viewMeta.value?.id) && !isPublic.value) return
if (isSidebarLoading.value) return
const response = !isPublic.value
? await api.dbViewRow.list('noco', base.value.id!, meta.value!.id!, viewMeta.value.id, {
...params,
offset: params.offset,
...{},
...{},
...(isUIAllowed('filterSync')
? { filterArrJson: JSON.stringify([...sideBarFilter.value]) }
: { filterArrJson: JSON.stringify([nestedFilters.value, ...sideBarFilter.value]) }),
})
: await fetchSharedViewData({
...params,
sortsArr: sorts.value,
filtersArr: [nestedFilters.value, ...sideBarFilter.value],
offset: params.offset,
where: where?.value ?? '',
})
formattedSideBarData.value = [...formattedSideBarData.value, ...formatData(response!.list)]
try {
const response = !isPublic.value
? await api.dbViewRow.list('noco', base.value.id!, meta.value!.id!, viewMeta.value.id, {
...params,
offset: params.offset,
...{},
...{},
...(isUIAllowed('filterSync')
? { filterArrJson: JSON.stringify([...sideBarFilter.value]) }
: { filterArrJson: JSON.stringify([nestedFilters.value, ...sideBarFilter.value]) }),
})
: await fetchSharedViewData({
...params,
sortsArr: sorts.value,
filtersArr: [nestedFilters.value, ...sideBarFilter.value],
offset: params.offset,
where: where?.value ?? '',
})
formattedSideBarData.value = [...formattedSideBarData.value, ...formatData(response!.list)]
} catch (e) {
console.log(e)
}
}
const filterJSON = computed(() => {
@ -324,19 +329,25 @@ const [useProvideCalendarViewStore, useCalendarViewStore] = useInjectionState(
let fromDate: dayjs.Dayjs | null | string = null
let toDate: dayjs.Dayjs | null | string = null
if (activeCalendarView.value === 'week') {
fromDate = dayjs(selectedDateRange.value.start).startOf('day')
toDate = dayjs(selectedDateRange.value.end).endOf('day')
} else if (activeCalendarView.value === 'day') {
fromDate = dayjs(selectedDate.value).startOf('day')
toDate = dayjs(selectedDate.value).endOf('day')
} else if (activeCalendarView.value === 'month') {
fromDate = dayjs(selectedMonth.value).startOf('month')
toDate = dayjs(selectedMonth.value).endOf('month')
} else if (activeCalendarView.value === 'year') {
fromDate = dayjs(selectedDate.value).startOf('year')
toDate = dayjs(selectedDate.value).endOf('year')
switch (activeCalendarView.value) {
case 'week':
fromDate = dayjs(selectedDateRange.value.start).startOf('day')
toDate = dayjs(selectedDateRange.value.end).endOf('day')
break
case 'month':
fromDate = dayjs(selectedMonth.value).startOf('month')
toDate = dayjs(selectedMonth.value).endOf('month')
break
case 'year':
fromDate = dayjs(selectedDate.value).startOf('year')
toDate = dayjs(selectedDate.value).endOf('year')
break
case 'day':
fromDate = dayjs(selectedDate.value).startOf('day')
toDate = dayjs(selectedDate.value).endOf('day')
break
}
if (calDataType.value === UITypes.Date) {
fromDate = dayjs(fromDate).format('YYYY-MM-DD')
toDate = dayjs(toDate).format('YYYY-MM-DD')
@ -361,7 +372,6 @@ const [useProvideCalendarViewStore, useCalendarViewStore] = useInjectionState(
logical_op: 'or',
children: [
{
// Check for overlap or within range
is_group: true,
logical_op: 'and',
children: [
@ -432,28 +442,30 @@ const [useProvideCalendarViewStore, useCalendarViewStore] = useInjectionState(
if (!formattedData.value || !calendarRange.value) return []
const dates = new Set<Date>()
formattedData.value.forEach((row) => {
const start = row.row[calendarRange.value[0].fk_from_col?.title ?? '']
let end
if (calendarRange.value[0].fk_to_col) {
end = row.row[calendarRange.value[0].fk_to_col.title ?? '']
}
if (start && end) {
const startDate = dayjs(start)
let endDate = dayjs(end)
let currentDate = startDate
// We have to check whether the start is after the end date, if so, loop through the end date
if (startDate.isAfter(endDate)) {
endDate = startDate
currentDate = endDate
calendarRange.value.forEach((range) => {
formattedData.value.forEach((row) => {
const start = row.row[range.fk_from_col?.title ?? '']
let end
if (range.fk_to_col) {
end = row.row[range.fk_to_col.title ?? '']
}
while (currentDate.isSameOrBefore(endDate)) {
dates.add(currentDate.toDate())
currentDate = currentDate.add(1, 'day')
if (start && end) {
const startDate = dayjs(start)
let endDate = dayjs(end)
let currentDate = startDate
// We have to check whether the start is after the end date, if so, loop through the end date
if (startDate.isAfter(endDate)) {
endDate = startDate
currentDate = endDate
}
while (currentDate.isSameOrBefore(endDate)) {
dates.add(currentDate.toDate())
currentDate = currentDate.add(1, 'day')
}
} else if (start) {
dates.add(new Date(start))
}
} else if (start) {
dates.add(new Date(start))
}
})
})
return Array.from(dates)

Loading…
Cancel
Save