多维表格
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

190 lines
5.9 KiB

<script setup lang="ts">
import type { PaginatedType } from 'nocodb-sdk'
import SidebarIcon from '~icons/nc-icons/sidebar'
import { IsGroupByInj, computed, iconMap, inject, isRtlLang, useI18n } from '#imports'
import type { Language } from '#imports'
interface Props {
paginationData: PaginatedType
changePage: (page: number) => void
alignCountOnRight?: boolean
hidePagination?: boolean
hideSidebars?: boolean
customLabel?: string
fixedSize?: number
extraStyle?: string
}
const props = defineProps<Props>()
const emits = defineEmits(['update:paginationData'])
const { locale } = useI18n()
const vPaginationData = useVModel(props, 'paginationData', emits)
const { alignCountOnRight, customLabel, changePage } = props
const fixedSize = toRef(props, 'fixedSize')
const extraStyle = toRef(props, 'extraStyle')
const isPublic = inject(IsPublicInj, ref(false))
const isGroupBy = inject(IsGroupByInj, ref(false))
const { isLeftSidebarOpen, isRightSidebarOpen } = storeToRefs(useSidebarStore())
const { isPaginationLoading } = storeToRefs(useViewsStore())
const count = computed(() => vPaginationData.value?.totalRows ?? Infinity)
const size = computed(() => vPaginationData.value?.pageSize ?? 25)
const page = computed({
get: () => vPaginationData?.value?.page ?? 1,
set: async (p) => {
isPaginationLoading.value = true
try {
await changePage?.(p)
} catch (e) {
console.error(e)
} finally {
isPaginationLoading.value = false
}
},
})
const isRTLLanguage = computed(() => isRtlLang(locale.value as keyof typeof Language))
</script>
<template>
<div
class="flex items-center bg-white border-gray-200 h-10 nc-pagination-wrapper"
:class="{ 'border-t-1': !isGroupBy }"
:style="`${fixedSize ? `width: ${fixedSize}px;` : ''}${
isGroupBy ? 'margin-top:1px; border-radius: 0 0 12px 12px !important;' : ''
}${extraStyle}`"
>
<NcTooltip v-if="!isPublic && hideSidebars !== true" class="ml-2" placement="topLeft" hide-on-click>
<template #title>
{{
isLeftSidebarOpen
? `${$t('general.hide')} ${$t('objects.sidebar').toLowerCase()}`
: `${$t('general.show')} ${$t('objects.sidebar').toLowerCase()}`
}}
</template>
<div
class="nc-sidebar-left-toggle-icon hover:after:(bg-primary bg-opacity-75) hover:(bg-gray-100 border-gray-200) border-gray-200 group flex items-center justify-center rounded-md h-full px-1.75 h-7 cursor-pointer text-gray-500 hover:text-gray-700"
:class="{
'bg-gray-100': !isLeftSidebarOpen,
}"
@click="isLeftSidebarOpen = !isLeftSidebarOpen"
>
<SidebarIcon class="cursor-pointer transform transition-transform duration-500 rounded-md rotate-180" />
</div>
</NcTooltip>
<slot name="add-record" />
<div class="flex-1">
<span
v-if="!alignCountOnRight && count !== null && count !== Infinity"
class="caption ml-2.5 text-gray-500 text-xs"
data-testid="grid-pagination"
>
{{ count }} {{ customLabel ? customLabel : count !== 1 ? $t('objects.records') : $t('objects.record') }}
</span>
</div>
<template v-if="!hidePagination">
<a-pagination
v-if="count !== Infinity"
v-model:current="page"
v-model:page-size="size"
size="small"
class="!text-xs !m-1 nc-pagination"
:class="{ 'rtl-pagination': isRTLLanguage }"
:total="+count"
show-less-items
:show-size-changer="false"
/>
<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>
<a-input :value="page" size="small" class="ml-1 !text-xs" type="number" @keydown.enter="changePage(page)">
<template #suffix>
<component :is="iconMap.returnKey" class="mt-1" @click="changePage(page)" />
</template>
</a-input>
</div>
</template>
<div class="flex-1 text-right pr-2">
<span
v-if="alignCountOnRight && count !== null && count !== Infinity"
class="caption nc-grid-row-count mr-2.5 text-gray-500 text-xs"
data-testid="grid-pagination"
>
{{ count }} {{ customLabel ? customLabel : count !== 1 ? $t('objects.records') : $t('objects.record') }}
</span>
</div>
<NcTooltip v-if="!isPublic && hideSidebars !== true" placement="topRight" hide-on-click>
<template #title>
{{
isRightSidebarOpen
? `${$t('general.hide')} ${$t('objects.sidebar').toLowerCase()}`
: `${$t('general.show')} ${$t('objects.sidebar').toLowerCase()}`
}}
</template>
<div
class="flex flex-row items-center justify-center !rounded-md !p-1.75 border-gray-100 cursor-pointer bg-white hover:bg-gray-100 text-gray-500 hover:text-gray-700 nc-sidebar-right-toggle-icon"
:class="{
'!bg-gray-100': !isRightSidebarOpen,
}"
type="ghost"
@click="isRightSidebarOpen = !isRightSidebarOpen"
>
<SidebarIcon class="w-4 h-4" />
</div>
</NcTooltip>
<div class="w-2"></div>
</div>
</template>
<style lang="scss">
.nc-pagination-wrapper {
.ant-pagination-item-active {
a {
@apply text-sm !text-gray-700 !hover:text-gray-800;
}
}
}
</style>
<style scoped>
:deep(.ant-pagination-item a) {
@apply text-sm !leading-[21px] !no-underline;
}
:deep(.nc-pagination .ant-pagination-item) {
@apply !border-0 !pt-0.25;
}
:deep(.ant-pagination-item:not(.ant-pagination-item-active) a) {
line-height: 21px !important;
@apply text-sm !text-gray-400;
}
:deep(.ant-pagination-item-link) {
@apply text-gray-800 flex items-center justify-center;
}
:deep(.ant-pagination-item.ant-pagination-item-active) {
@apply !bg-transparent;
}
:deep(.rtl-pagination .ant-pagination-prev .ant-pagination-item-link),
:deep(.rtl-pagination .ant-pagination-next .ant-pagination-item-link) {
@apply transform rotate-180;
}
</style>