Browse Source

fix: handle group by load method exceptions

pull/7787/head
Pranav C 8 months ago
parent
commit
dcbaeffe7e
  1. 250
      packages/nc-gui/composables/useViewGroupBy.ts

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

@ -1,5 +1,7 @@
import { type ColumnType, type SelectOptionsType, UITypes, type ViewType } from 'nocodb-sdk' import { type ColumnType, type SelectOptionsType, UITypes, type ViewType } from 'nocodb-sdk'
import type { Ref } from 'vue' import type { Ref } from 'vue'
import { message } from 'ant-design-vue'
import { extractSdkResponseErrorMsg } from '../utils'
import { GROUP_BY_VARS, ref, storeToRefs, useApi, useBase, useViewColumnsOrThrow } from '#imports' import { GROUP_BY_VARS, ref, storeToRefs, useApi, useBase, useViewColumnsOrThrow } from '#imports'
import type { Group, GroupNestedIn, Row } from '#imports' import type { Group, GroupNestedIn, Row } from '#imports'
@ -178,152 +180,160 @@ export const useViewGroupBy = (view: Ref<ViewType | undefined>, where?: Computed
} }
async function loadGroups(params: any = {}, group?: Group) { async function loadGroups(params: any = {}, group?: Group) {
group = group || rootGroup.value try {
group = group || rootGroup.value
if (!base?.value?.id || !view.value?.id || !view.value?.fk_model_id || !group) return if (!base?.value?.id || !view.value?.id || !view.value?.fk_model_id || !group) return
if (groupBy.value.length === 0) { if (groupBy.value.length === 0) {
group.children = [] group.children = []
return return
} }
if (group.nestedIn.length > groupBy.value.length) return if (group.nestedIn.length > groupBy.value.length) return
if (group.nestedIn.length === 0) nextGroupColor.value = colors.value[0] if (group.nestedIn.length === 0) nextGroupColor.value = colors.value[0]
const groupby = groupBy.value[group.nestedIn.length] const groupby = groupBy.value[group.nestedIn.length]
const nestedWhere = calculateNestedWhere(group.nestedIn, where?.value) const nestedWhere = calculateNestedWhere(group.nestedIn, where?.value)
if (!groupby || !groupby.column.title) return if (!groupby || !groupby.column.title) return
if (isPublic.value && !sharedView.value?.uuid) { if (isPublic.value && !sharedView.value?.uuid) {
return return
} }
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 ?? groupByGroupLimit.value), offset: ((group.paginationData.page ?? 0) - 1) * (group.paginationData.pageSize ?? groupByGroupLimit.value),
limit: group.paginationData.pageSize ?? groupByGroupLimit.value, 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) }),
where: `${nestedWhere}`, where: `${nestedWhere}`,
sort: `${groupby.sort === 'desc' ? '-' : ''}${groupby.column.title}`, sort: `${groupby.sort === 'desc' ? '-' : ''}${groupby.column.title}`,
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 ?? groupByGroupLimit.value), offset: ((group.paginationData.page ?? 0) - 1) * (group.paginationData.pageSize ?? groupByGroupLimit.value),
limit: group.paginationData.pageSize ?? groupByGroupLimit.value, 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}`,
column_name: groupby.column.title, column_name: groupby.column.title,
sortsArr: sorts.value, sortsArr: sorts.value,
filtersArr: nestedFilters.value, filtersArr: nestedFilters.value,
}) })
const tempList: Group[] = response.list.reduce((acc: Group[], curr: Record<string, any>) => { const tempList: Group[] = response.list.reduce((acc: Group[], curr: Record<string, any>) => {
const keyExists = acc.find( const keyExists = acc.find(
(a) => a.key === valueToTitle(curr[groupby.column.column_name!] ?? curr[groupby.column.title!], groupby.column), (a) => a.key === valueToTitle(curr[groupby.column.column_name!] ?? curr[groupby.column.title!], groupby.column),
) )
if (keyExists) { if (keyExists) {
keyExists.count += +curr.count keyExists.count += +curr.count
keyExists.paginationData = { page: 1, pageSize: groupByGroupLimit.value, 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) {
acc.push({ acc.push({
key: valueToTitle(curr[groupby.column.title!], groupby.column), key: valueToTitle(curr[groupby.column.title!], groupby.column),
column: groupby.column, column: groupby.column,
count: +curr.count, count: +curr.count,
color: findKeyColor(curr[groupby.column.title!], groupby.column), color: findKeyColor(curr[groupby.column.title!], groupby.column),
nestedIn: [ nestedIn: [
...group!.nestedIn, ...group!.nestedIn,
{ {
title: groupby.column.title, title: groupby.column.title,
column_name: groupby.column.title!, column_name: groupby.column.title!,
key: valueToTitle(curr[groupby.column.title!], groupby.column), key: valueToTitle(curr[groupby.column.title!], groupby.column),
column_uidt: groupby.column.uidt, column_uidt: groupby.column.uidt,
},
],
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,
paginationData: { })
page: 1, }
pageSize: group!.nestedIn.length < groupBy.value.length - 1 ? groupByGroupLimit.value : groupByRecordLimit.value, return acc
totalRows: +curr.count, }, [])
},
nested: group!.nestedIn.length < groupBy.value.length - 1,
})
}
return acc
}, [])
if (!group.children) group.children = [] if (!group.children) group.children = []
for (const temp of tempList) { for (const temp of tempList) {
const keyExists = group.children?.find((a) => a.key === temp.key) const keyExists = group.children?.find((a) => a.key === temp.key)
if (keyExists) { if (keyExists) {
temp.paginationData = { temp.paginationData = {
page: keyExists.paginationData.page || temp.paginationData.page, page: keyExists.paginationData.page || temp.paginationData.page,
pageSize: keyExists.paginationData.pageSize || temp.paginationData.pageSize, pageSize: keyExists.paginationData.pageSize || temp.paginationData.pageSize,
totalRows: temp.count, totalRows: temp.count,
}
temp.color = keyExists.color
// update group
Object.assign(keyExists, temp)
continue
} }
temp.color = keyExists.color group.children.push(temp)
// update group
Object.assign(keyExists, temp)
continue
} }
group.children.push(temp)
}
// 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 ?? groupByGroupLimit.value)) { 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)
return orderA - orderB return orderA - orderB
}) })
} }
group.paginationData = response.pageInfo group.paginationData = response.pageInfo
// to cater the case like when querying with a non-zero offset // to cater the case like when querying with a non-zero offset
// the result page may point to the target page where the actual returned data don't display on // the result page may point to the target page where the actual returned data don't display on
const expectedPage = Math.max(1, Math.ceil(group.paginationData.totalRows! / group.paginationData.pageSize!)) const expectedPage = Math.max(1, Math.ceil(group.paginationData.totalRows! / group.paginationData.pageSize!))
if (expectedPage < group.paginationData.page!) { if (expectedPage < group.paginationData.page!) {
await groupWrapperChangePage(expectedPage, group) await groupWrapperChangePage(expectedPage, group)
}
} catch (e) {
message.error(await extractSdkResponseErrorMsg(e))
} }
} }
async function loadGroupData(group: Group, force = false, params: any = {}) { async function loadGroupData(group: Group, force = false, params: any = {}) {
if (!base?.value?.id || !view.value?.id || !view.value?.fk_model_id) return try {
if (!base?.value?.id || !view.value?.id || !view.value?.fk_model_id) return
if (group.children && !force) return if (group.children && !force) return
if (!group.paginationData) { if (!group.paginationData) {
group.paginationData = { page: 1, pageSize: groupByRecordLimit.value } 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 ?? groupByRecordLimit.value), offset: ((group.paginationData.page ?? 0) - 1) * (group.paginationData.pageSize ?? groupByRecordLimit.value),
limit: group.paginationData.pageSize ?? groupByRecordLimit.value, limit: group.paginationData.pageSize ?? groupByRecordLimit.value,
where: `${nestedWhere}`, where: `${nestedWhere}`,
} }
const response = !isPublic.value const response = !isPublic.value
? await api.dbViewRow.list('noco', base.value.id, view.value.fk_model_id, view.value.id, { ? await api.dbViewRow.list('noco', base.value.id, view.value.fk_model_id, view.value.id, {
...query, ...query,
...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) }),
} as any) } as any)
: await fetchSharedViewData({ sortsArr: sorts.value, filtersArr: nestedFilters.value, ...query }) : await fetchSharedViewData({ sortsArr: sorts.value, filtersArr: nestedFilters.value, ...query })
group.count = response.pageInfo.totalRows ?? 0 group.count = response.pageInfo.totalRows ?? 0
group.rows = formatData(response.list) group.rows = formatData(response.list)
group.paginationData = response.pageInfo group.paginationData = response.pageInfo
} catch (e) {
message.error(await extractSdkResponseErrorMsg(e))
}
} }
const loadGroupPage = async (group: Group, p: number) => { const loadGroupPage = async (group: Group, p: number) => {

Loading…
Cancel
Save