Browse Source

Merge pull request #6950 from nocodb/feat/group-by-custom

feat: env variables to control pagination of group by
pull/6955/head
Raju Udava 1 year ago committed by GitHub
parent
commit
dfee7e766f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      packages/nc-gui/composables/useGlobal/types.ts
  2. 42
      packages/nc-gui/composables/useViewGroupBy.ts
  3. 2
      packages/noco-docs/docs/020.getting-started/050.self-hosted/020.environment-variables.md
  4. 5
      packages/nocodb/src/helpers/extractLimitAndOffset.ts
  5. 6
      packages/nocodb/src/services/utils.service.ts

4
packages/nc-gui/composables/useGlobal/types.ts

@ -9,6 +9,10 @@ export interface AppInfo {
authType: 'jwt' | 'none' authType: 'jwt' | 'none'
connectToExternalDB: boolean connectToExternalDB: boolean
defaultLimit: number defaultLimit: number
defaultGroupByLimit: {
limitGroup: number
limitRecord: number
}
firstUser: boolean firstUser: boolean
githubAuthEnabled: boolean githubAuthEnabled: boolean
googleAuthEnabled: boolean googleAuthEnabled: boolean

42
packages/nc-gui/composables/useViewGroupBy.ts

@ -6,6 +6,8 @@ import type { Group, GroupNestedIn, Row } from '#imports'
export const useViewGroupBy = (view: Ref<ViewType | undefined>, where?: ComputedRef<string | undefined>) => { export const useViewGroupBy = (view: Ref<ViewType | undefined>, where?: ComputedRef<string | undefined>) => {
const { api } = useApi() const { api } = useApi()
const { appInfo } = useGlobal()
const { base } = storeToRefs(useBase()) const { base } = storeToRefs(useBase())
const { sharedView, fetchSharedViewData } = useSharedView() const { sharedView, fetchSharedViewData } = useSharedView()
@ -42,7 +44,13 @@ export const useViewGroupBy = (view: Ref<ViewType | undefined>, where?: Computed
const reloadViewDataHook = inject(ReloadViewDataHookInj, createEventHook()) const reloadViewDataHook = inject(ReloadViewDataHookInj, createEventHook())
const groupByLimit = 10 const groupByGroupLimit = computed(() => {
return appInfo.value.defaultGroupByLimit?.limitGroup || 10
})
const groupByRecordLimit = computed(() => {
return appInfo.value.defaultGroupByLimit?.limitRecord || 10
})
const rootGroup = ref<Group>({ const rootGroup = ref<Group>({
key: 'root', key: 'root',
@ -50,7 +58,7 @@ export const useViewGroupBy = (view: Ref<ViewType | undefined>, where?: Computed
count: 0, count: 0,
column: {} as any, column: {} as any,
nestedIn: [], nestedIn: [],
paginationData: { page: 1, pageSize: groupByLimit }, paginationData: { page: 1, pageSize: groupByGroupLimit.value },
nested: true, nested: true,
children: [], children: [],
root: true, root: true,
@ -64,7 +72,7 @@ export const useViewGroupBy = (view: Ref<ViewType | undefined>, where?: Computed
groupWrapper.paginationData.page = page groupWrapper.paginationData.page = page
await loadGroups( await loadGroups(
{ {
offset: (page - 1) * (groupWrapper.paginationData.pageSize || groupByLimit), offset: (page - 1) * (groupWrapper.paginationData.pageSize || groupByGroupLimit.value),
} as any, } as any,
groupWrapper, groupWrapper,
) )
@ -172,8 +180,8 @@ export const useViewGroupBy = (view: Ref<ViewType | undefined>, where?: Computed
const response = !isPublic.value const response = !isPublic.value
? await api.dbViewRow.groupBy('noco', base.value.id, view.value.fk_model_id, view.value.id, { ? await api.dbViewRow.groupBy('noco', base.value.id, view.value.fk_model_id, view.value.id, {
offset: ((group.paginationData.page ?? 0) - 1) * (group.paginationData.pageSize ?? groupByLimit), offset: ((group.paginationData.page ?? 0) - 1) * (group.paginationData.pageSize ?? groupByGroupLimit.value),
limit: group.paginationData.pageSize ?? groupByLimit, limit: group.paginationData.pageSize ?? groupByGroupLimit.value,
...params, ...params,
...(isUIAllowed('sortSync') ? {} : { sortArrJson: JSON.stringify(sorts.value) }), ...(isUIAllowed('sortSync') ? {} : { sortArrJson: JSON.stringify(sorts.value) }),
...(isUIAllowed('filterSync') ? {} : { filterArrJson: JSON.stringify(nestedFilters.value) }), ...(isUIAllowed('filterSync') ? {} : { filterArrJson: JSON.stringify(nestedFilters.value) }),
@ -182,8 +190,8 @@ export const useViewGroupBy = (view: Ref<ViewType | undefined>, where?: Computed
column_name: groupby.column.title, column_name: groupby.column.title,
} as any) } as any)
: await api.public.dataGroupBy(sharedView.value!.uuid!, { : await api.public.dataGroupBy(sharedView.value!.uuid!, {
offset: ((group.paginationData.page ?? 0) - 1) * (group.paginationData.pageSize ?? groupByLimit), offset: ((group.paginationData.page ?? 0) - 1) * (group.paginationData.pageSize ?? groupByGroupLimit.value),
limit: group.paginationData.pageSize ?? groupByLimit, limit: group.paginationData.pageSize ?? groupByGroupLimit.value,
...params, ...params,
where: nestedWhere, where: nestedWhere,
sort: `${groupby.sort === 'desc' ? '-' : ''}${groupby.column.title}`, sort: `${groupby.sort === 'desc' ? '-' : ''}${groupby.column.title}`,
@ -198,7 +206,7 @@ export const useViewGroupBy = (view: Ref<ViewType | undefined>, where?: Computed
) )
if (keyExists) { if (keyExists) {
keyExists.count += +curr.count keyExists.count += +curr.count
keyExists.paginationData = { page: 1, pageSize: groupByLimit, totalRows: keyExists.count } keyExists.paginationData = { page: 1, pageSize: groupByGroupLimit.value, totalRows: keyExists.count }
return acc return acc
} }
if (groupby.column.title && groupby.column.uidt) { if (groupby.column.title && groupby.column.uidt) {
@ -216,7 +224,11 @@ export const useViewGroupBy = (view: Ref<ViewType | undefined>, where?: Computed
column_uidt: groupby.column.uidt, column_uidt: groupby.column.uidt,
}, },
], ],
paginationData: { page: 1, pageSize: groupByLimit, totalRows: +curr.count }, paginationData: {
page: 1,
pageSize: group!.nestedIn.length < groupBy.value.length - 1 ? groupByGroupLimit.value : groupByRecordLimit.value,
totalRows: +curr.count,
},
nested: group!.nestedIn.length < groupBy.value.length - 1, nested: group!.nestedIn.length < groupBy.value.length - 1,
}) })
} }
@ -244,7 +256,7 @@ export const useViewGroupBy = (view: Ref<ViewType | undefined>, where?: Computed
// clear rest of the children // clear rest of the children
group.children = group.children.filter((c) => tempList.find((t) => t.key === c.key)) group.children = group.children.filter((c) => tempList.find((t) => t.key === c.key))
if (group.count <= (group.paginationData.pageSize ?? groupByLimit)) { if (group.count <= (group.paginationData.pageSize ?? groupByGroupLimit.value)) {
group.children.sort((a, b) => { group.children.sort((a, b) => {
const orderA = tempList.findIndex((t) => t.key === a.key) const orderA = tempList.findIndex((t) => t.key === a.key)
const orderB = tempList.findIndex((t) => t.key === b.key) const orderB = tempList.findIndex((t) => t.key === b.key)
@ -268,14 +280,14 @@ export const useViewGroupBy = (view: Ref<ViewType | undefined>, where?: Computed
if (group.children && !force) return if (group.children && !force) return
if (!group.paginationData) { if (!group.paginationData) {
group.paginationData = { page: 1, pageSize: groupByLimit } group.paginationData = { page: 1, pageSize: groupByRecordLimit.value }
} }
const nestedWhere = calculateNestedWhere(group.nestedIn, where?.value) const nestedWhere = calculateNestedWhere(group.nestedIn, where?.value)
const query = { const query = {
offset: ((group.paginationData.page ?? 0) - 1) * (group.paginationData.pageSize ?? groupByLimit), offset: ((group.paginationData.page ?? 0) - 1) * (group.paginationData.pageSize ?? groupByRecordLimit.value),
limit: group.paginationData.pageSize ?? groupByLimit, limit: group.paginationData.pageSize ?? groupByRecordLimit.value,
where: `${nestedWhere}`, where: `${nestedWhere}`,
} }
@ -294,7 +306,7 @@ export const useViewGroupBy = (view: Ref<ViewType | undefined>, where?: Computed
const loadGroupPage = async (group: Group, p: number) => { const loadGroupPage = async (group: Group, p: number) => {
if (!group.paginationData) { if (!group.paginationData) {
group.paginationData = { page: 1, pageSize: groupByLimit } group.paginationData = { page: 1, pageSize: groupByRecordLimit.value }
} }
group.paginationData.page = p group.paginationData.page = p
await loadGroupData(group, true) await loadGroupData(group, true)
@ -331,7 +343,7 @@ export const useViewGroupBy = (view: Ref<ViewType | undefined>, where?: Computed
() => groupBy.value.length, () => groupBy.value.length,
async () => { async () => {
if (groupBy.value.length > 0) { if (groupBy.value.length > 0) {
rootGroup.value.paginationData = { page: 1, pageSize: groupByLimit } rootGroup.value.paginationData = { page: 1, pageSize: groupByGroupLimit.value }
rootGroup.value.column = {} as any rootGroup.value.column = {} as any
await loadGroups() await loadGroups()
refreshNested() refreshNested()

2
packages/noco-docs/docs/020.getting-started/050.self-hosted/020.environment-variables.md

@ -22,6 +22,8 @@ For production use-cases, it is **recommended** to configure
| NC_AUTH_JWT_SECRET | JWT secret used for auth and storing other secrets | A random secret will be generated | | NC_AUTH_JWT_SECRET | JWT secret used for auth and storing other secrets | A random secret will be generated |
| PORT | For setting app running port | `8080` | | PORT | For setting app running port | `8080` |
| DB_QUERY_LIMIT_DEFAULT | Pagination limit | 25 | | DB_QUERY_LIMIT_DEFAULT | Pagination limit | 25 |
| DB_QUERY_LIMIT_GROUP_BY_GROUP | Group per page limit | 10 |
| DB_QUERY_LIMIT_GROUP_BY_RECORD | Record per group limit | 10 |
| DB_QUERY_LIMIT_MAX | Maximum allowed pagination limit | 1000 | | DB_QUERY_LIMIT_MAX | Maximum allowed pagination limit | 1000 |
| DB_QUERY_LIMIT_MIN | Minimum allowed pagination limit | 1 | | DB_QUERY_LIMIT_MIN | Minimum allowed pagination limit | 1 |
| NC_TOOL_DIR | App directory to keep metadata and app related files | Defaults to current working directory. In docker maps to `/usr/app/data/` for mounting volume. | | NC_TOOL_DIR | App directory to keep metadata and app related files | Defaults to current working directory. In docker maps to `/usr/app/data/` for mounting volume. |

5
packages/nocodb/src/helpers/extractLimitAndOffset.ts

@ -4,6 +4,11 @@ export const defaultLimitConfig = {
limitMax: Math.max(+process.env.DB_QUERY_LIMIT_MAX || 1000, 1), limitMax: Math.max(+process.env.DB_QUERY_LIMIT_MAX || 1000, 1),
}; };
export const defaultGroupByLimitConfig = {
limitGroup: Math.max(+process.env.DB_QUERY_LIMIT_GROUP_BY_GROUP || 10, 1),
limitRecord: Math.max(+process.env.DB_QUERY_LIMIT_GROUP_BY_RECORD || 10, 1),
};
export function extractLimitAndOffset( export function extractLimitAndOffset(
args: { args: {
limit?: number | string; limit?: number | string;

6
packages/nocodb/src/services/utils.service.ts

@ -14,7 +14,10 @@ import NcConnectionMgrv2 from '~/utils/common/NcConnectionMgrv2';
import { MetaTable } from '~/utils/globals'; import { MetaTable } from '~/utils/globals';
import { jdbcToXcConfig } from '~/utils/nc-config/helpers'; import { jdbcToXcConfig } from '~/utils/nc-config/helpers';
import { packageVersion } from '~/utils/packageVersion'; import { packageVersion } from '~/utils/packageVersion';
import { defaultLimitConfig } from '~/helpers/extractLimitAndOffset'; import {
defaultGroupByLimitConfig,
defaultLimitConfig,
} from '~/helpers/extractLimitAndOffset';
const versionCache = { const versionCache = {
releaseVersion: null, releaseVersion: null,
@ -395,6 +398,7 @@ export class UtilsService {
Math.min(defaultLimitConfig.limitDefault, defaultLimitConfig.limitMax), Math.min(defaultLimitConfig.limitDefault, defaultLimitConfig.limitMax),
defaultLimitConfig.limitMin, defaultLimitConfig.limitMin,
), ),
defaultGroupByLimit: defaultGroupByLimitConfig,
timezone: defaultConnectionConfig.timezone, timezone: defaultConnectionConfig.timezone,
ncMin: !!process.env.NC_MIN, ncMin: !!process.env.NC_MIN,
teleEnabled: process.env.NC_DISABLE_TELE !== 'true', teleEnabled: process.env.NC_DISABLE_TELE !== 'true',

Loading…
Cancel
Save