Browse Source

Merge pull request #6863 from nocodb/nc-fix/keyboard-shortcut-for-changing-page

Nc fix/keyboard shortcut for changing page
pull/6865/head
Raju Udava 11 months ago committed by GitHub
parent
commit
d6ce14ea19
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 16
      packages/nc-gui/components/dlg/KeyboardShortcuts.vue
  2. 113
      packages/nc-gui/components/nc/Pagination.vue
  3. 8
      packages/nc-gui/components/smartsheet/Pagination.vue
  4. 12
      packages/nc-gui/components/smartsheet/grid/Table.vue
  5. 73
      packages/nc-gui/components/smartsheet/grid/usePaginationShortcuts.ts
  6. 4
      packages/noco-docs/docs/020.getting-started/040.keyboard-shortcuts.md

16
packages/nc-gui/components/dlg/KeyboardShortcuts.vue

@ -52,6 +52,22 @@ const shortcutList = [
{
title: 'Grid View',
shortcuts: [
{
keys: [renderAltOrOptlKey(), '←'],
behaviour: 'Jump to previous page in this view',
},
{
keys: [renderAltOrOptlKey(), '→'],
behaviour: 'Jump to next page in this view',
},
{
keys: [renderAltOrOptlKey(), '↑'],
behaviour: 'Jump to last page in this view',
},
{
keys: [renderAltOrOptlKey(), '↓'],
behaviour: 'Jump to first page in this view',
},
{
keys: [renderCmdOrCtrlKey(), '←'],
behaviour: 'Jump to leftmost column in this row',

113
packages/nc-gui/components/nc/Pagination.vue

@ -1,10 +1,16 @@
<script setup lang="ts">
import NcTooltip from '~/components/nc/Tooltip.vue'
const props = defineProps<{
current: number
total: number
pageSize: number
entityName?: string
mode?: 'simple' | 'full'
prevPageTooltip?: string
nextPageTooltip?: string
firstPageTooltip?: string
lastPageTooltip?: string
}>()
const emits = defineEmits(['update:current', 'update:pageSize'])
@ -51,28 +57,38 @@ const pagesList = computed(() => {
<template>
<div class="nc-pagination flex flex-row items-center gap-x-2">
<NcButton
v-if="mode === 'full'"
v-e="[`a:pagination:${entityName}:first-page`]"
class="first-page"
type="secondary"
size="small"
:disabled="current === 1"
@click="goToFirstPage"
>
<GeneralIcon icon="doubleLeftArrow" />
</NcButton>
<NcButton
v-e="[`a:pagination:${entityName}:prev-page`]"
class="prev-page"
type="secondary"
size="small"
:disabled="current === 1"
@click="changePage({ increase: false })"
>
<GeneralIcon icon="arrowLeft" />
</NcButton>
<component :is="props.firstPageTooltip && mode === 'full' ? NcTooltip : 'div'" v-if="mode === 'full'">
<template v-if="props.firstPageTooltip" #title>
{{ props.firstPageTooltip }}
</template>
<NcButton
v-e="[`a:pagination:${entityName}:first-page`]"
class="first-page"
type="secondary"
size="small"
:disabled="current === 1"
@click="goToFirstPage"
>
<GeneralIcon icon="doubleLeftArrow" />
</NcButton>
</component>
<component :is="props.prevPageTooltip && mode === 'full' ? NcTooltip : 'div'">
<template v-if="props.prevPageTooltip" #title>
{{ props.prevPageTooltip }}
</template>
<NcButton
v-e="[`a:pagination:${entityName}:prev-page`]"
class="prev-page"
type="secondary"
size="small"
:disabled="current === 1"
@click="changePage({ increase: false })"
>
<GeneralIcon icon="arrowLeft" />
</NcButton>
</component>
<div v-if="!isMobileMode" class="text-gray-600">
<a-select v-model:value="current" class="!mr-[2px]" :options="pagesList">
<template #suffixIcon>
@ -85,28 +101,37 @@ const pagesList = computed(() => {
</span>
</div>
<NcButton
v-e="[`a:pagination:${entityName}:next-page`]"
class="next-page"
type="secondary"
size="small"
:disabled="current === totalPages"
@click="changePage({ increase: true })"
>
<GeneralIcon icon="arrowRight" />
</NcButton>
<NcButton
v-if="mode === 'full'"
v-e="[`a:pagination:${entityName}:last-page`]"
class="last-page"
type="secondary"
size="small"
:disabled="current === totalPages"
@click="goToLastPage"
>
<GeneralIcon icon="doubleRightArrow" />
</NcButton>
<component :is="props.nextPageTooltip && mode === 'full' ? NcTooltip : 'div'">
<template v-if="props.nextPageTooltip" #title>
{{ props.nextPageTooltip }}
</template>
<NcButton
v-e="[`a:pagination:${entityName}:next-page`]"
class="next-page"
type="secondary"
size="small"
:disabled="current === totalPages"
@click="changePage({ increase: true })"
>
<GeneralIcon icon="arrowRight" />
</NcButton>
</component>
<component :is="props.lastPageTooltip && mode === 'full' ? NcTooltip : 'div'" v-if="mode === 'full'">
<template v-if="props.lastPageTooltip" #title>
{{ props.lastPageTooltip }}
</template>
<NcButton
v-e="[`a:pagination:${entityName}:last-page`]"
class="last-page"
type="secondary"
size="small"
:disabled="current === totalPages"
@click="goToLastPage"
>
<GeneralIcon icon="doubleRightArrow" />
</NcButton>
</component>
</div>
</template>

8
packages/nc-gui/components/smartsheet/Pagination.vue

@ -62,6 +62,10 @@ const page = computed({
})
const isRTLLanguage = computed(() => isRtlLang(locale.value as keyof typeof Language))
const renderAltOrOptlKey = () => {
return isMac() ? '⌥' : 'ALT'
}
</script>
<template>
@ -107,6 +111,10 @@ const isRTLLanguage = computed(() => isRtlLang(locale.value as keyof typeof Lang
:class="{ 'rtl-pagination': isRTLLanguage }"
:total="+count"
entity-name="grid"
:prev-page-tooltip="`${renderAltOrOptlKey()}+←`"
:next-page-tooltip="`${renderAltOrOptlKey()}+→`"
:first-page-tooltip="`${renderAltOrOptlKey()}+↓`"
:last-page-tooltip="`${renderAltOrOptlKey()}+↑`"
/>
<div v-else class="mx-auto flex items-center mt-n1" style="max-width: 250px">
<span class="text-xs" style="white-space: nowrap"> Change page:</span>

12
packages/nc-gui/components/smartsheet/grid/Table.vue

@ -5,6 +5,7 @@ import type { ColumnReqType, ColumnType, PaginatedType, TableType, ViewType } fr
import { UITypes, ViewTypes, isLinksOrLTAR, isSystemColumn, isVirtualCol } from 'nocodb-sdk'
import { useColumnDrag } from './useColumnDrag'
import usePaginationShortcuts from './usePaginationShortcuts'
import {
ActiveViewInj,
CellUrlDisableOverlayInj,
@ -187,6 +188,11 @@ const { onDrag, onDragStart, draggedCol, dragColPlaceholderDomRef, toBeDroppedCo
gridWrapper,
})
const { onLeft, onRight, onUp, onDown } = usePaginationShortcuts({
paginationDataRef,
changePage: changePage as any,
})
// #Variables
const addColumnDropdown = ref(false)
@ -1204,6 +1210,12 @@ const loaderText = computed(() => {
}
}
})
// Keyboard shortcuts for pagination
onKeyStroke('ArrowLeft', onLeft)
onKeyStroke('ArrowRight', onRight)
onKeyStroke('ArrowUp', onUp)
onKeyStroke('ArrowDown', onDown)
</script>
<template>

73
packages/nc-gui/components/smartsheet/grid/usePaginationShortcuts.ts

@ -0,0 +1,73 @@
import axios from 'axios'
import type { PaginatedType } from 'nocodb-sdk'
const usePaginationShortcuts = ({
changePage,
paginationDataRef,
}: {
changePage: (page: number) => Promise<void> | undefined
paginationDataRef: Ref<PaginatedType | undefined>
}) => {
const { isViewDataLoading } = storeToRefs(useViewsStore())
const getTotalPages = () => {
return Math.ceil(paginationDataRef.value!.totalRows! / paginationDataRef.value!.pageSize!)
}
const changePageWithLoading = async (page: number) => {
isViewDataLoading.value = true
try {
await changePage?.(page)
isViewDataLoading.value = false
} catch (e) {
if (axios.isCancel(e)) return
isViewDataLoading.value = false
}
}
const onLeft = async (e: KeyboardEvent) => {
if (!e.altKey) return
e.preventDefault()
const page = paginationDataRef.value!.page! - 1
if (page < 1) return
await changePageWithLoading(page)
}
const onRight = async (e: KeyboardEvent) => {
if (!e.altKey) return
e.preventDefault()
const page = paginationDataRef.value!.page! + 1
if (page > getTotalPages()) return
await changePageWithLoading(page)
}
const onDown = async (e: KeyboardEvent) => {
if (!e.altKey) return
e.preventDefault()
const page = 1
await changePageWithLoading(page)
}
const onUp = async (e: KeyboardEvent) => {
if (!e.altKey) return
e.preventDefault()
await changePageWithLoading(getTotalPages())
}
return {
onLeft,
onRight,
onUp,
onDown,
}
}
export default usePaginationShortcuts

4
packages/noco-docs/docs/020.getting-started/040.keyboard-shortcuts.md

@ -84,6 +84,10 @@ To navigate within ⌘+K menu,
| `⌘` + `c` | Copy cell contents |
| `⌘` + `v` | Paste copied contents |
| `alt` + `r` | Inserts new record in grid view |
| `alt` + `↑` | Jump to last page in this view |
| `alt` + `↓` | Jump to first page in this view |
| `alt` + `←` | Jump to previous page in this view |
| `alt` + `→` | Jump to next page in this view |
## Field type specific shortcuts

Loading…
Cancel
Save