From 9212b5876da999909e19325ca618746d09b3c4c6 Mon Sep 17 00:00:00 2001 From: Pranav C Date: Wed, 22 Feb 2023 11:39:39 +0530 Subject: [PATCH 01/11] feat(gui): add shortcuts to navigate bw rows in expanded form Signed-off-by: Pranav C --- .../smartsheet/expanded-form/index.vue | 19 +++++++++++++++++++ .../useSelectedCellKeyupListener/index.ts | 6 +++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/packages/nc-gui/components/smartsheet/expanded-form/index.vue b/packages/nc-gui/components/smartsheet/expanded-form/index.vue index 20eae1d22b..586a38adcb 100644 --- a/packages/nc-gui/components/smartsheet/expanded-form/index.vue +++ b/packages/nc-gui/components/smartsheet/expanded-form/index.vue @@ -22,6 +22,7 @@ import { useVModel, watch, } from '#imports' +import { useActiveKeyupListener } from '~/composables/useSelectedCellKeyupListener' import type { Row } from '~/lib' interface Props { @@ -157,6 +158,24 @@ const cellWrapperEl = ref() onMounted(() => { setTimeout(() => (cellWrapperEl.value?.querySelector('input,select,textarea') as HTMLInputElement)?.focus()) }) + +// attach keyboard listeners to switch between rows +// using alt + left/right arrow keys +useActiveKeyupListener( + isExpanded, + (e: KeyboardEvent) => { + if (!e.altKey) return + + if (e.key === 'ArrowLeft') { + e.stopPropagation() + emits('prev') + } else if (e.key === 'ArrowRight') { + e.stopPropagation() + emits('next') + } + }, + { immediate: true }, +) + + + + diff --git a/packages/nc-gui/components/smartsheet/expanded-form/index.vue b/packages/nc-gui/components/smartsheet/expanded-form/index.vue index 586a38adcb..da5b36b31c 100644 --- a/packages/nc-gui/components/smartsheet/expanded-form/index.vue +++ b/packages/nc-gui/components/smartsheet/expanded-form/index.vue @@ -203,12 +203,15 @@ export default { From cfae8f4fb0515f341a5e92e519e4d2d49deace43 Mon Sep 17 00:00:00 2001 From: Pranav C Date: Wed, 22 Feb 2023 14:08:35 +0530 Subject: [PATCH 03/11] feat(gui): add new shortcuts in shortcut list component Signed-off-by: Pranav C --- packages/nc-gui/components/general/ShortcutLabel.vue | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/nc-gui/components/general/ShortcutLabel.vue b/packages/nc-gui/components/general/ShortcutLabel.vue index f748a444ec..2e861cd948 100644 --- a/packages/nc-gui/components/general/ShortcutLabel.vue +++ b/packages/nc-gui/components/general/ShortcutLabel.vue @@ -17,6 +17,7 @@ const getLabel = (key: string) => { case 'meta': return '⌘' case 'control': + case 'ctrl': return '⌃' case 'enter': return '↩' @@ -51,6 +52,6 @@ const getLabel = (key: string) => { } .nc-shortcut-label { - @apply text-[.6rem] text-gray-200 bg-gray-200 bg-opacity-20 rounded px-1; + @apply text-[0.7rem] leading-6 min-w-5 min-h-5 text-center relative z-0 after:(content-[''] left-0 top-0 -z-1 bg-current opacity-10 absolute w-full h-full rounded) px-1; } From d55086cf89321710243a456e1258276220c5761e Mon Sep 17 00:00:00 2001 From: Pranav C Date: Wed, 22 Feb 2023 15:48:23 +0530 Subject: [PATCH 04/11] refactor(gui): update description Signed-off-by: Pranav C --- .../components/dlg/KeyboardShortcuts.vue | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/packages/nc-gui/components/dlg/KeyboardShortcuts.vue b/packages/nc-gui/components/dlg/KeyboardShortcuts.vue index 8079cd6bf8..d3cf53b122 100644 --- a/packages/nc-gui/components/dlg/KeyboardShortcuts.vue +++ b/packages/nc-gui/components/dlg/KeyboardShortcuts.vue @@ -15,6 +15,9 @@ const dialogShow = computed({ const renderCmdOrCtrlKey = () => { return isMac() ? '⌘' : 'CTRL' } +const renderAltOrOptlKey = () => { + return isMac() ? '⌥' : 'ALT' +} const shortcutList = [ { @@ -197,6 +200,22 @@ const shortcutList = [ keys: [renderCmdOrCtrlKey(), 'Enter'], behaviour: 'Save current expanded form item', }, + { + keys: [renderAltOrOptlKey(), '→'], + behaviour: 'Switch to next row', + }, + { + keys: [renderAltOrOptlKey(), '←'], + behaviour: 'Switch to previous row', + }, + { + keys: [renderAltOrOptlKey(), 'S'], + behaviour: 'Save current expanded form item', + }, + { + keys: [renderAltOrOptlKey(), 'N'], + behaviour: 'Create a new row', + }, ], }, ] From cab8ff5fff05bb0940cf685ca7b18e49378bd42c Mon Sep 17 00:00:00 2001 From: Pranav C Date: Wed, 22 Feb 2023 17:50:04 +0530 Subject: [PATCH 05/11] feat(gui): save expanded form and new expanded form shortcuts Signed-off-by: Pranav C --- .../smartsheet/expanded-form/Header.vue | 4 +- .../smartsheet/expanded-form/index.vue | 93 +++++++++++++++++-- .../composables/useExpandedFormStore.ts | 3 + 3 files changed, 88 insertions(+), 12 deletions(-) diff --git a/packages/nc-gui/components/smartsheet/expanded-form/Header.vue b/packages/nc-gui/components/smartsheet/expanded-form/Header.vue index 80ed48f93d..f453f8f8db 100644 --- a/packages/nc-gui/components/smartsheet/expanded-form/Header.vue +++ b/packages/nc-gui/components/smartsheet/expanded-form/Header.vue @@ -18,7 +18,7 @@ const route = useRoute() const { meta, isSqlView } = useSmartsheetStoreOrThrow() -const { commentsDrawer, displayValue, primaryKey, save: _save, loadRow } = useExpandedFormStoreOrThrow() +const { commentsDrawer, displayValue, primaryKey, save: _save, loadRow, saveRowAndStay } = useExpandedFormStoreOrThrow() const { isNew, syncLTARRefs, state } = useSmartsheetRowStoreOrThrow() @@ -26,8 +26,6 @@ const { isUIAllowed } = useUIPermission() const reloadTrigger = inject(ReloadRowDataHookInj, createEventHook()) -const saveRowAndStay = ref(0) - const save = async () => { if (isNew.value) { const data = await _save(state.value) diff --git a/packages/nc-gui/components/smartsheet/expanded-form/index.vue b/packages/nc-gui/components/smartsheet/expanded-form/index.vue index da5b36b31c..54be1938c0 100644 --- a/packages/nc-gui/components/smartsheet/expanded-form/index.vue +++ b/packages/nc-gui/components/smartsheet/expanded-form/index.vue @@ -65,7 +65,16 @@ const isKanban = inject(IsKanbanInj, ref(false)) provide(MetaInj, meta) -const { commentsDrawer, changedColumns, state: rowState, isNew, loadRow, save } = useProvideExpandedFormStore(meta, row) +const { + commentsDrawer, + changedColumns, + state: rowState, + isNew, + loadRow, + saveRowAndStay, + syncLTARRefs, + save, +} = useProvideExpandedFormStore(meta, row) const duplicatingRowInProgress = ref(false) @@ -159,13 +168,23 @@ onMounted(() => { setTimeout(() => (cellWrapperEl.value?.querySelector('input,select,textarea') as HTMLInputElement)?.focus()) }) +const addNewRow = () => { + setTimeout(async () => { + row.value = { + row: {}, + oldRow: {}, + rowMeta: { new: true }, + } + isExpanded.value = true + }, 500); +} + // attach keyboard listeners to switch between rows // using alt + left/right arrow keys useActiveKeyupListener( isExpanded, - (e: KeyboardEvent) => { + async (e: KeyboardEvent) => { if (!e.altKey) return - if (e.key === 'ArrowLeft') { e.stopPropagation() emits('prev') @@ -173,6 +192,60 @@ useActiveKeyupListener( e.stopPropagation() emits('next') } + // on alt + s save record + else if (e.code === 'KeyS') { + e.stopPropagation() + e.preventDefault() + if (isNew.value) { + const data = await save(rowState.value) + await syncLTARRefs(data) + reloadHook?.trigger(null) + } else { + await save() + reloadHook?.trigger(null) + } + if (!saveRowAndStay.value) { + onClose() + } + // on alt + n create new record + } else if (e.code === 'KeyN') { + e.stopPropagation() + e.preventDefault() + + if (changedColumns.value.size > 0) { + await Modal.confirm({ + title: 'Do you want to save the changes?', + okText: 'Save', + cancelText: 'Discard', + onOk: async () => { + await save() + reloadHook?.trigger(null) + addNewRow() + }, + onCancel: () => { + addNewRow() + }, + }) + } else if (isNew.value) { + await Modal.confirm({ + title: 'Do you want to save the record?', + okText: 'Save', + cancelText: 'Discard', + onOk: async () => { + const data = await save(rowState.value) + await syncLTARRefs(data) + reloadHook?.trigger(null) + addNewRow() + }, + onCancel: () => { + addNewRow() + }, + }) + } else { + addNewRow() + } + + } }, { immediate: true }, ) @@ -202,18 +275,19 @@ export default {
@@ -237,7 +311,8 @@ export default { :ref="i ? null : (el) => (cellWrapperEl = el)" class="!bg-white rounded px-1 min-h-[35px] flex items-center mt-2 relative" > - + ()) const { project } = useProject() @@ -243,6 +245,7 @@ const [useProvideExpandedFormStore, useExpandedFormStore] = useInjectionState((m changedColumns, loadRow, primaryKey, + saveRowAndStay } }, 'expanded-form-store') From db13b1d186a551666c4fd8f10a47ddf5bd4a5583 Mon Sep 17 00:00:00 2001 From: Pranav C Date: Wed, 22 Feb 2023 17:53:58 +0530 Subject: [PATCH 06/11] fix(gui): remove focus from input if focused Signed-off-by: Pranav C --- .../nc-gui/components/smartsheet/expanded-form/index.vue | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/nc-gui/components/smartsheet/expanded-form/index.vue b/packages/nc-gui/components/smartsheet/expanded-form/index.vue index 54be1938c0..dd603f795a 100644 --- a/packages/nc-gui/components/smartsheet/expanded-form/index.vue +++ b/packages/nc-gui/components/smartsheet/expanded-form/index.vue @@ -194,6 +194,9 @@ useActiveKeyupListener( } // on alt + s save record else if (e.code === 'KeyS') { + // remove focus from the active input if any + document.activeElement?.blur() + e.stopPropagation() e.preventDefault() if (isNew.value) { @@ -209,6 +212,10 @@ useActiveKeyupListener( } // on alt + n create new record } else if (e.code === 'KeyN') { + + // remove focus from the active input if any + document.activeElement?.blur() + e.stopPropagation() e.preventDefault() From 77e3796bbb8e57946345a0a88826c86a2ebabded Mon Sep 17 00:00:00 2001 From: Pranav C Date: Thu, 23 Feb 2023 00:32:53 +0530 Subject: [PATCH 07/11] fix(gui): hide prev icon for first row and next icon for last row Signed-off-by: Pranav C --- packages/nc-gui/components/smartsheet/Grid.vue | 3 +++ .../components/smartsheet/expanded-form/index.vue | 6 ++++-- packages/nc-gui/composables/useViewData.ts | 12 +++++++++--- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/packages/nc-gui/components/smartsheet/Grid.vue b/packages/nc-gui/components/smartsheet/Grid.vue index 87965126a7..2af1a31391 100644 --- a/packages/nc-gui/components/smartsheet/Grid.vue +++ b/packages/nc-gui/components/smartsheet/Grid.vue @@ -118,6 +118,7 @@ const { selectedAllRecords, removeRowIfNew, navigateToSiblingRow, + getExpandedRowIndex } = useViewData(meta, view, xWhere) const { getMeta } = useMetas() @@ -982,6 +983,8 @@ const closeAddColumnDropdown = () => { show-next-prev-icons @next="navigateToSiblingRow(NavigateDir.NEXT)" @prev="navigateToSiblingRow(NavigateDir.PREV)" + :first-row="getExpandedRowIndex() === 0" + :last-row="getExpandedRowIndex() === paginationData.totalRows - 1" />
diff --git a/packages/nc-gui/components/smartsheet/expanded-form/index.vue b/packages/nc-gui/components/smartsheet/expanded-form/index.vue index dd603f795a..10ffc75056 100644 --- a/packages/nc-gui/components/smartsheet/expanded-form/index.vue +++ b/packages/nc-gui/components/smartsheet/expanded-form/index.vue @@ -35,6 +35,8 @@ interface Props { rowId?: string view?: ViewType showNextPrevIcons?: boolean + firstRow?: boolean + lastRow?: boolean } const props = defineProps() @@ -280,7 +282,7 @@ export default {