Browse Source

fix: snap fill handle

Signed-off-by: mertmit <mertmit99@gmail.com>
pull/5896/head
mertmit 1 year ago
parent
commit
c1b5e76a43
  1. 102
      packages/nc-gui/components/smartsheet/Grid.vue

102
packages/nc-gui/components/smartsheet/Grid.vue

@ -2,7 +2,6 @@
import { nextTick } from '@vue/runtime-core'
import type { ColumnReqType, ColumnType, GridType, PaginatedType, TableType, ViewType } from 'nocodb-sdk'
import { UITypes, isSystemColumn, isVirtualCol } from 'nocodb-sdk'
import type { UseElementBoundingReturn } from '@vueuse/core'
import {
ActiveViewInj,
CellUrlDisableOverlayInj,
@ -112,6 +111,8 @@ const tableHeadEl = ref<HTMLElement>()
const tableBodyEl = ref<HTMLElement>()
const fillHandle = ref<HTMLElement>()
const gridRect = useElementBounding(gridWrapper)
const isAddingColumnAllowed = $computed(() => !readOnly.value && !isLocked.value && isUIAllowed('add-column') && !isSqlView.value)
const isAddingEmptyRowAllowed = $computed(() => !isView && !isLocked.value && hasEditPermission && !isSqlView.value)
@ -891,16 +892,19 @@ function addEmptyRow(row?: number) {
return rowObj
}
const tableRect = useElementBounding(smartTable)
const { height: tableHeight, width: tableWidth } = tableRect
const { x: gridX, y: gridY } = useScroll(gridWrapper)
const fillHandleTop = ref()
const fillHandleLeft = ref()
const cellRefs = ref<{ el: HTMLElement }[]>([])
let cellRect: UseElementBoundingReturn | null = null
const showFillHandle = computed(
() =>
!readOnly.value &&
!isLocked.value &&
!editEnabled &&
(!selectedRange.isEmpty() || (activeCell.row !== null && activeCell.col !== null)) &&
!data.value[selectedRange.end.row ?? activeCell.row]?.rowMeta?.new,
)
const refreshFillHandle = () => {
const cellRef = cellRefs.value.find(
@ -908,28 +912,22 @@ const refreshFillHandle = () => {
cell.el.dataset.rowIndex === String(selectedRange.end.row) && cell.el.dataset.colIndex === String(selectedRange.end.col),
)
if (cellRef) {
cellRect = useElementBounding(cellRef.el)
if (!cellRect || !tableRect) return
if (selectedRange.end.col === 0) {
fillHandleTop.value = cellRect.top.value - tableRect.top.value + cellRect.height.value + gridY.value
fillHandleLeft.value = cellRect.left.value - tableRect.left.value + cellRect.width.value
return
}
fillHandleTop.value = cellRect.top.value - tableRect.top.value + cellRect.height.value + gridY.value
fillHandleLeft.value = cellRect.left.value - tableRect.left.value + cellRect.width.value + gridX.value
const cellRect = useElementBounding(cellRef.el)
if (!cellRect || !gridWrapper.value) return
fillHandleTop.value = cellRect.top.value + cellRect.height.value - gridRect.top.value + gridWrapper.value.scrollTop
fillHandleLeft.value = cellRect.left.value + cellRect.width.value - gridRect.left.value + gridWrapper.value.scrollLeft
}
}
watch(
() => `${selectedRange.end.row}-${selectedRange.end.col}`,
(n, o) => {
watch([() => selectedRange.end.row, () => selectedRange.end.col], (n, o) => {
if (n !== o) {
if (gridWrapper.value) {
refreshFillHandle()
}
}
},
)
})
useEventListener(gridWrapper, 'scroll', () => {
refreshFillHandle()
})
</script>
<template>
@ -940,22 +938,13 @@ watch(
</div>
</general-overlay>
<div
ref="gridWrapper"
class="nc-grid-wrapper min-h-0 flex-1 scrollbar-thin-dull"
:class="{
relative:
!readOnly &&
!isLocked &&
(!selectedRange.isEmpty() || (activeCell.row !== null && activeCell.col !== null)) &&
((!selectedRange.isEmpty() && selectedRange.end.col !== 0) || (selectedRange.isEmpty() && activeCell.col !== 0)),
}"
>
<div ref="gridWrapper" class="nc-grid-wrapper min-h-0 flex-1 scrollbar-thin-dull relative">
<a-dropdown
v-model:visible="contextMenu"
:trigger="isSqlView ? [] : ['contextmenu']"
overlay-class-name="nc-dropdown-grid-context-menu"
>
<div class="table-overlay">
<table
ref="smartTable"
class="xc-row-table nc-grid backgroundColorDefault !h-auto bg-white"
@ -1035,12 +1024,7 @@ watch(
:style="{ height: rowHeight ? `${rowHeight * 1.8}rem` : `1.8rem` }"
:data-testid="`grid-row-${rowIndex}`"
>
<td
key="row-index"
class="caption nc-grid-cell pl-5 pr-1"
:data-testid="`cell-Id-${rowIndex}`"
@contextmenu="contextMenuTarget = null"
>
<td key="row-index" class="caption nc-grid-cell pl-5 pr-1" :data-testid="`cell-Id-${rowIndex}`">
<div class="items-center flex gap-1 min-w-[60px]">
<div
v-if="!readOnly || !isLocked"
@ -1154,7 +1138,7 @@ watch(
<tr
v-if="isAddingEmptyRowAllowed"
v-e="['c:row:add:grid-bottom']"
class="cursor-pointer"
class="cursor-pointer relative z-3"
@mouseup.stop
@click="addEmptyRow()"
>
@ -1168,6 +1152,20 @@ watch(
</tbody>
</table>
<!-- Fill Handle -->
<div
v-show="showFillHandle"
ref="fillHandle"
class="nc-fill-handle"
:class="
(!selectedRange.isEmpty() && selectedRange.end.col !== 0) || (selectedRange.isEmpty() && activeCell.col !== 0)
? 'z-3'
: 'z-4'
"
:style="{ top: `${fillHandleTop}px`, left: `${fillHandleLeft}px`, cursor: 'crosshair' }"
/>
</div>
<template v-if="!isLocked && hasEditPermission" #overlay>
<a-menu class="shadow !rounded !py-0" @click="contextMenu = false">
<a-menu-item
@ -1243,28 +1241,6 @@ watch(
</a-menu>
</template>
</a-dropdown>
<div
class="table-overlay absolute top-0 left-0 pointer-events-none overflow-hidden"
:style="{ height: `${tableHeight}px`, width: `${tableWidth}px` }"
>
<!-- Fill Handle -->
<div
v-show="
!readOnly &&
!isLocked &&
!editEnabled &&
(!selectedRange.isEmpty() || (activeCell.row !== null && activeCell.col !== null))
"
ref="fillHandle"
class="nc-fill-handle"
:class="
(!selectedRange.isEmpty() && selectedRange.end.col !== 0) || (selectedRange.isEmpty() && activeCell.col !== 0)
? 'z-3'
: 'z-4'
"
:style="{ top: `${fillHandleTop}px`, left: `${fillHandleLeft}px`, cursor: 'crosshair' }"
/>
</div>
</div>
<div

Loading…
Cancel
Save