From bc535a84e37f38b7240d8019fd2ea59b98bd2ed4 Mon Sep 17 00:00:00 2001 From: DarkPhoenix2704 Date: Tue, 20 Feb 2024 07:16:04 +0000 Subject: [PATCH] feat(nc-gui): additional drag & drop support --- .../smartsheet/calendar/MonthView.vue | 94 ++++++++++++++----- .../smartsheet/calendar/SideMenu.vue | 29 +++++- .../smartsheet/calendar/WeekView.vue | 94 +++++++++++++------ 3 files changed, 164 insertions(+), 53 deletions(-) diff --git a/packages/nc-gui/components/smartsheet/calendar/MonthView.vue b/packages/nc-gui/components/smartsheet/calendar/MonthView.vue index 4e40cf2e00..b6d74297e3 100644 --- a/packages/nc-gui/components/smartsheet/calendar/MonthView.vue +++ b/packages/nc-gui/components/smartsheet/calendar/MonthView.vue @@ -5,8 +5,16 @@ import type { Row } from '#imports' const emit = defineEmits(['new-record', 'expand-record']) -const { selectedDate, selectedMonth, formattedData, displayField, calendarRange, calDataType, updateRowProperty } = - useCalendarViewStoreOrThrow() +const { + selectedDate, + selectedMonth, + formattedData, + formattedSideBarData, + displayField, + calendarRange, + calDataType, + updateRowProperty, +} = useCalendarViewStoreOrThrow() const isMondayFirst = ref(true) @@ -299,6 +307,21 @@ const dragStart = (event: DragEvent, record: Row) => { ) } +const dragEnter = (event: DragEvent) => { + event.preventDefault() + const { top, height, width, left } = calendarGridContainer.value.getBoundingClientRect() + + const percentY = (event.clientY - top - window.scrollY) / height + + const percentX = (event.clientX - left - window.scrollX) / width + + const week = Math.floor(percentY * dates.value.length) + const day = Math.floor(percentX * 7) + + const currSelectedDate = dayjs(selectedDate.value).startOf('month').add(week, 'week').add(day, 'day') + selectedDate.value = currSelectedDate.toDate() +} + const dropEvent = (event: DragEvent) => { event.preventDefault() const data = event.dataTransfer?.getData('text/plain') @@ -315,9 +338,11 @@ const dropEvent = (event: DragEvent) => { const { top, height, width, left } = calendarGridContainer.value.getBoundingClientRect() const percentY = (event.clientY - top - initialClickOffsetY - window.scrollY) / height - const percentX = (event.clientX - left - initialClickOffsetX - window.scrollX) / width + const fromCol = record.rowMeta.range?.fk_from_col + const toCol = record.rowMeta.range?.fk_to_col + const week = Math.floor(percentY * dates.value.length) const day = Math.floor(percentX * 7) @@ -329,39 +354,59 @@ const dropEvent = (event: DragEvent) => { ...record, row: { ...record.row, - [record.rowMeta.range.fk_from_col.title]: dayjs(newStartDate).format('YYYY-MM-DD'), + [fromCol.title]: dayjs(newStartDate).format('YYYY-MM-DD'), }, } - const updateProperty = [record.rowMeta.range.fk_from_col.title] + const updateProperty = [fromCol.title] + + if (toCol) { + const fromDate = record.row[fromCol.title] ? dayjs(record.row[fromCol.title]) : null + const toDate = record.row[toCol.title] ? dayjs(record.row[toCol.title]) : null + + if (fromDate && toDate) { + endDate = dayjs(newStartDate).add(toDate.diff(fromDate, 'day'), 'day') + } else if (fromDate && !toDate) { + endDate = dayjs(newStartDate).endOf('day') + } else if (!fromDate && toDate) { + endDate = dayjs(newStartDate).endOf('day') + } else { + endDate = newStartDate.clone() + } - if (record.rowMeta.range.fk_to_col) { - const diffDays = dayjs(record.row[record.rowMeta.range.fk_to_col.title]).diff( - record.row[record.rowMeta.range.fk_from_col.title], - 'day', - ) - endDate = dayjs(newStartDate).add(diffDays, 'day') - newRow.row[record.rowMeta.range.fk_to_col.title] = dayjs(endDate).format('YYYY-MM-DD') - updateProperty.push(record.rowMeta.range.fk_to_col.title) + newRow.row[toCol.title] = dayjs(endDate).format('YYYY-MM-DD') + + updateProperty.push(toCol.title) } if (!newRow) return - dragElement.value.style.boxShadow = 'none' - dragElement.value.classList.remove('hide') + if (dragElement.value) { + formattedData.value = formattedData.value.map((r) => { + const pk = extractPkFromRow(r.row, meta.value.columns) - dragElement.value = null + if (pk === extractPkFromRow(newRow.row, meta.value.columns)) { + return newRow + } + return r + }) + } else { + formattedData.value = [...formattedData.value, newRow] + formattedSideBarData.value = formattedSideBarData.value.filter((r) => { + const pk = extractPkFromRow(r.row, meta.value.columns) - updateRowProperty(newRow, updateProperty, false) + return pk !== extractPkFromRow(newRow.row, meta.value.columns) + }) + } - formattedData.value = formattedData.value.map((r) => { - const pk = extractPkFromRow(r.row, meta.value.columns) + if (dragElement.value) { + dragElement.value.style.boxShadow = 'none' + dragElement.value.classList.remove('hide') - if (pk === extractPkFromRow(newRow.row, meta.value.columns)) { - return newRow - } - return r - }) + dragElement.value = null + } + + updateRowProperty(newRow, updateProperty, false) } } @@ -395,6 +440,7 @@ const isDateSelected = (date: Date) => { }" class="grid h-full pb-7.5" @drop="dropEvent" + @dragenter.prevent="dragEnter" >
, record: Row, range) => { }) } +const dragElement = ref(null) + +const dragStart = (event: DragEvent, record: Row) => { + dragElement.value = event.target as HTMLElement + + dragElement.value.classList.add('hide') + dragElement.value.style.boxShadow = '0px 8px 8px -4px rgba(0, 0, 0, 0.04), 0px 20px 24px -4px rgba(0, 0, 0, 0.10)' + const eventRect = dragElement.value.getBoundingClientRect() + + const initialClickOffsetX = event.clientX - eventRect.left + const initialClickOffsetY = event.clientY - eventRect.top + + event.dataTransfer?.setData( + 'text/plain', + JSON.stringify({ + record, + initialClickOffsetY, + initialClickOffsetX, + }), + ) +} + const renderData = computed>(() => { if (!calendarRange.value) return [] @@ -281,8 +303,9 @@ const sideBarListScrollHandle = useDebounceFn(async (e: Event) => {
diff --git a/packages/nc-gui/components/smartsheet/calendar/WeekView.vue b/packages/nc-gui/components/smartsheet/calendar/WeekView.vue index 404ad2a1eb..0690c0aa84 100644 --- a/packages/nc-gui/components/smartsheet/calendar/WeekView.vue +++ b/packages/nc-gui/components/smartsheet/calendar/WeekView.vue @@ -5,8 +5,16 @@ import type { Row } from '~/lib' const emits = defineEmits(['expand-record']) -const { selectedDateRange, formattedData, calendarRange, selectedDate, displayField, calDataType, updateRowProperty } = - useCalendarViewStoreOrThrow() +const { + selectedDateRange, + formattedData, + formattedSideBarData, + calendarRange, + selectedDate, + displayField, + calDataType, + updateRowProperty, +} = useCalendarViewStoreOrThrow() const container = ref(null) @@ -206,6 +214,18 @@ const dragStart = (event: DragEvent, record: Row) => { ) } +const dragEnter = (event: DragEvent) => { + event.preventDefault() + const { width, left } = container.value.getBoundingClientRect() + + const percentX = (event.clientX - left - window.scrollX) / width + + const day = Math.floor(percentX * 7) + + const currSelectedDate = dayjs(selectedDateRange.value.start).add(day, 'day') + selectedDate.value = currSelectedDate.toDate() +} + const dropEvent = (event: DragEvent) => { event.preventDefault() const data = event.dataTransfer?.getData('text/plain') @@ -222,9 +242,11 @@ const dropEvent = (event: DragEvent) => { const { top, height, width, left } = container.value.getBoundingClientRect() const percentY = (event.clientY - top - initialClickOffsetY - window.scrollY) / height - const percentX = (event.clientX - left - initialClickOffsetX - window.scrollX) / width + const fromCol = record.rowMeta.range?.fk_from_col + const toCol = record.rowMeta.range?.fk_to_col + const day = Math.floor(percentX * 7) const newStartDate = dayjs(selectedDateRange.value.start).add(day, 'day') @@ -235,39 +257,57 @@ const dropEvent = (event: DragEvent) => { ...record, row: { ...record.row, - [record.rowMeta.range.fk_from_col.title]: dayjs(newStartDate).format('YYYY-MM-DD'), + [fromCol.title]: dayjs(newStartDate).format('YYYY-MM-DD'), }, } + const updateProperty = [fromCol.title] + + if (toCol) { + const fromDate = record.row[fromCol.title] ? dayjs(record.row[fromCol.title]) : null + const toDate = record.row[toCol.title] ? dayjs(record.row[toCol.title]) : null + + if (fromDate && toDate) { + endDate = dayjs(newStartDate).add(toDate.diff(fromDate, 'day'), 'day') + } else if (fromDate && !toDate) { + endDate = dayjs(newStartDate).endOf('day') + } else if (!fromDate && toDate) { + endDate = dayjs(newStartDate).endOf('day') + } else { + endDate = newStartDate.clone() + } - const updateProperty = [record.rowMeta.range.fk_from_col.title] - - if (record.rowMeta.range.fk_to_col) { - const diffDays = dayjs(record.row[record.rowMeta.range.fk_to_col.title]).diff( - record.row[record.rowMeta.range.fk_from_col.title], - 'day', - ) - endDate = dayjs(newStartDate).add(diffDays, 'day') - newRow.row[record.rowMeta.range.fk_to_col.title] = dayjs(endDate).format('YYYY-MM-DD') - updateProperty.push(record.rowMeta.range.fk_to_col.title) + newRow.row[toCol.title] = dayjs(endDate).format('YYYY-MM-DD') + updateProperty.push(toCol.title) } if (!newRow) return - dragElement.value.style.boxShadow = 'none' - dragElement.value.classList.remove('hide') - - dragElement.value = null + if (dragElement.value) { + formattedData.value = formattedData.value.map((r) => { + const pk = extractPkFromRow(r.row, meta.value.columns) - updateRowProperty(newRow, updateProperty, false) + if (pk === extractPkFromRow(newRow.row, meta.value.columns)) { + return newRow + } + return r + }) + } else { + formattedData.value = [...formattedData.value, newRow] + formattedSideBarData.value = formattedSideBarData.value.filter((r) => { + const pk = extractPkFromRow(r.row, meta.value.columns) + + return pk !== extractPkFromRow(newRow.row, meta.value.columns) + }) + } - formattedData.value = formattedData.value.map((r) => { - const pk = extractPkFromRow(r.row, meta.value.columns) + if (dragElement.value) { + dragElement.value.style.boxShadow = 'none' + dragElement.value.classList.remove('hide') - if (pk === extractPkFromRow(newRow.row, meta.value.columns)) { - return newRow - } - return r - }) + dragElement.value = null + } + console.log(newRow, updateProperty) + updateRowProperty(newRow, updateProperty, false) } } @@ -283,7 +323,7 @@ const dropEvent = (event: DragEvent) => { {{ dayjs(date).format('DD ddd') }} -
+