diff --git a/packages/nc-gui/components/smartsheet/Grid.vue b/packages/nc-gui/components/smartsheet/Grid.vue index 000b41f034..77311eaed3 100644 --- a/packages/nc-gui/components/smartsheet/Grid.vue +++ b/packages/nc-gui/components/smartsheet/Grid.vue @@ -173,130 +173,138 @@ const getContainerScrollForElement = ( return scroll } -const { isCellSelected, activeCell, handleMouseDown, handleMouseOver, handleCellClick, clearSelectedRange, copyValue } = - useMultiSelect( - meta, - fields, - data, - $$(editEnabled), - isPkAvail, - clearCell, - makeEditable, - scrollToCell, - (e: KeyboardEvent) => { - // ignore navigating if picker(Date, Time, DateTime, Year) - // or single/multi select options is open - const activePickerOrDropdownEl = document.querySelector( - '.nc-picker-datetime.active,.nc-dropdown-single-select-cell.active,.nc-dropdown-multi-select-cell.active,.nc-picker-date.active,.nc-picker-year.active,.nc-picker-time.active', - ) - if (activePickerOrDropdownEl) { +const { + isCellSelected, + activeCell, + handleMouseDown, + handleMouseOver, + handleCellClick, + clearSelectedRange, + copyValue, + isCellActive, +} = useMultiSelect( + meta, + fields, + data, + $$(editEnabled), + isPkAvail, + clearCell, + makeEditable, + scrollToCell, + (e: KeyboardEvent) => { + // ignore navigating if picker(Date, Time, DateTime, Year) + // or single/multi select options is open + const activePickerOrDropdownEl = document.querySelector( + '.nc-picker-datetime.active,.nc-dropdown-single-select-cell.active,.nc-dropdown-multi-select-cell.active,.nc-picker-date.active,.nc-picker-year.active,.nc-picker-time.active', + ) + if (activePickerOrDropdownEl) { + e.preventDefault() + return true + } + + // skip keyboard event handling if there is a drawer / modal + if (isDrawerOrModalExist()) { + return true + } + + const cmdOrCtrl = isMac() ? e.metaKey : e.ctrlKey + const altOrOptionKey = e.altKey + if (e.key === ' ') { + if (isCellActive.value && !editEnabled && hasEditPermission) { e.preventDefault() + clearSelectedRange() + const row = data.value[activeCell.row] + expandForm(row) return true } - - // skip keyboard event handling if there is a drawer / modal - if (isDrawerOrModalExist()) { + } else if (e.key === 'Escape') { + if (editEnabled) { + editEnabled = false + return true + } + } else if (e.key === 'Enter') { + if (e.shiftKey) { + // add a line break for types like LongText / JSON + return true + } + if (editEnabled) { + editEnabled = false return true } + } + + if (cmdOrCtrl) { + if (!isCellActive.value) return - const cmdOrCtrl = isMac() ? e.metaKey : e.ctrlKey - const altOrOptionKey = e.altKey - if (e.key === ' ') { - if (activeCell.row != null && !isNaN(activeCell.row) && !editEnabled && hasEditPermission) { + switch (e.key) { + case 'ArrowUp': e.preventDefault() clearSelectedRange() - const row = data.value[activeCell.row] - expandForm(row) + activeCell.row = 0 + activeCell.col = activeCell.col ?? 0 + scrollToCell?.() + editEnabled = false return true - } - } else if (e.key === 'Escape') { - if (editEnabled) { + case 'ArrowDown': + e.preventDefault() + clearSelectedRange() + activeCell.row = data.value.length - 1 + activeCell.col = activeCell.col ?? 0 + scrollToCell?.() editEnabled = false return true - } - } else if (e.key === 'Enter') { - if (e.shiftKey) { - // add a line break for types like LongText / JSON + case 'ArrowRight': + e.preventDefault() + clearSelectedRange() + activeCell.row = activeCell.row ?? 0 + activeCell.col = fields.value?.length - 1 + scrollToCell?.() + editEnabled = false return true - } - if (editEnabled) { + case 'ArrowLeft': + e.preventDefault() + clearSelectedRange() + activeCell.row = activeCell.row ?? 0 + activeCell.col = 0 + scrollToCell?.() editEnabled = false return true - } - } - - if (cmdOrCtrl) { - if (activeCell.row === null || isNaN(activeCell.row) || activeCell.col === null || isNaN(activeCell.col)) return - - switch (e.key) { - case 'ArrowUp': - e.preventDefault() - clearSelectedRange() - activeCell.row = 0 - activeCell.col = activeCell.col ?? 0 - scrollToCell?.() - editEnabled = false - return true - case 'ArrowDown': - e.preventDefault() - clearSelectedRange() - activeCell.row = data.value.length - 1 - activeCell.col = activeCell.col ?? 0 - scrollToCell?.() - editEnabled = false - return true - case 'ArrowRight': - e.preventDefault() - clearSelectedRange() - activeCell.row = activeCell.row ?? 0 - activeCell.col = fields.value?.length - 1 - scrollToCell?.() - editEnabled = false - return true - case 'ArrowLeft': - e.preventDefault() - clearSelectedRange() - activeCell.row = activeCell.row ?? 0 - activeCell.col = 0 - scrollToCell?.() - editEnabled = false - return true - } } + } - if (altOrOptionKey) { - switch (e.keyCode) { - case 82: { - // ALT + R - if (isAddingEmptyRowAllowed) { - $e('c:shortcut', { key: 'ALT + R' }) - addEmptyRow() - } - break + if (altOrOptionKey) { + switch (e.keyCode) { + case 82: { + // ALT + R + if (isAddingEmptyRowAllowed) { + $e('c:shortcut', { key: 'ALT + R' }) + addEmptyRow() } - case 67: { - // ALT + C - if (isAddingColumnAllowed) { - $e('c:shortcut', { key: 'ALT + C' }) - addColumnDropdown.value = true - } - break + break + } + case 67: { + // ALT + C + if (isAddingColumnAllowed) { + $e('c:shortcut', { key: 'ALT + C' }) + addColumnDropdown.value = true } + break } } - }, - async (ctx: { row: number; col?: number; updatedColumnTitle?: string }) => { - const rowObj = data.value[ctx.row] - const columnObj = ctx.col !== undefined ? fields.value[ctx.col] : null + } + }, + async (ctx: { row: number; col?: number; updatedColumnTitle?: string }) => { + const rowObj = data.value[ctx.row] + const columnObj = ctx.col !== undefined ? fields.value[ctx.col] : null - if (!ctx.updatedColumnTitle && isVirtualCol(columnObj)) { - return - } + if (!ctx.updatedColumnTitle && isVirtualCol(columnObj)) { + return + } - // update/save cell value - await updateOrSaveRow(rowObj, ctx.updatedColumnTitle || columnObj.title) - }, - ) + // update/save cell value + await updateOrSaveRow(rowObj, ctx.updatedColumnTitle || columnObj.title) + }, +) function scrollToCell(row?: number | null, col?: number | null) { row = row ?? activeCell.row diff --git a/packages/nc-gui/composables/useMultiSelect/index.ts b/packages/nc-gui/composables/useMultiSelect/index.ts index d596e82e84..5d7c4c7239 100644 --- a/packages/nc-gui/composables/useMultiSelect/index.ts +++ b/packages/nc-gui/composables/useMultiSelect/index.ts @@ -61,6 +61,10 @@ export function useMultiSelect( const columnLength = $computed(() => unref(fields)?.length) + const isCellActive = computed( + () => !(activeCell.row === null || activeCell.col === null || isNaN(activeCell.row) || isNaN(activeCell.col)), + ) + function makeActive(row: number, col: number) { if (activeCell.row === row && activeCell.col === col) { return @@ -171,7 +175,7 @@ export function useMultiSelect( return true } - if (activeCell.row === null || activeCell.col === null || isNaN(activeCell.row) || isNaN(activeCell.col)) { + if (!isCellActive.value) { return } @@ -367,6 +371,7 @@ export function useMultiSelect( useEventListener(document, 'mouseup', handleMouseUp) return { + isCellActive, handleMouseDown, handleMouseOver, clearSelectedRange,