diff --git a/packages/nc-gui/composables/useViewGroupBy.ts b/packages/nc-gui/composables/useViewGroupBy.ts index 873ff8488e..6c14c93a8c 100644 --- a/packages/nc-gui/composables/useViewGroupBy.ts +++ b/packages/nc-gui/composables/useViewGroupBy.ts @@ -391,7 +391,7 @@ const [useProvideViewGroupBy, useViewGroupBy] = useInjectionState( } if (appInfo.value.ee) { - const aggregationMap = new Map() + const aggregationAliasMapper = new AliasMapper() const aggregation = Object.values(gridViewCols.value) .map((f) => ({ @@ -401,29 +401,9 @@ const [useProvideViewGroupBy, useViewGroupBy] = useInjectionState( .filter((f) => f.type !== CommonAggregations.None) const aggregationParams = (group.children ?? []).map((child) => { - let key = child.key - - if (!key?.length || key.startsWith(' ') || key.endsWith(' ')) { - key = Math.random().toString(36).substring(7) - aggregationMap.set(key, child.key) - } - - try { - key = JSON.parse(key) - if (typeof key === 'object') { - key = Math.random().toString(36).substring(7) - aggregationMap.set(key, child.key) - return { - where: calculateNestedWhere(child.nestedIn, where?.value), - alias: key, - ...(isUIAllowed('filterSync') ? {} : { filterArrJson: JSON.stringify(nestedFilters.value) }), - } - } - } catch (e) {} - return { where: calculateNestedWhere(child.nestedIn, where?.value), - alias: key, + alias: aggregationAliasMapper.generateAlias(child.key), ...(isUIAllowed('filterSync') ? {} : { filterArrJson: JSON.stringify(nestedFilters.value) }), } }) @@ -444,42 +424,20 @@ const [useProvideViewGroupBy, useViewGroupBy] = useInjectionState( aggregationParams, ) - Object.entries(aggResponse).forEach(([key, value]) => { - const child = (group?.children ?? []).find((c) => c.key.toString() === key.toString()) + await aggregationAliasMapper.process(aggResponse, (originalKey, value) => { + const child = (group?.children ?? []).find((c) => c.key.toString() === (originalKey as any).toString()) if (child) { Object.assign(child.aggregations, value) - } else { - const originalKey = aggregationMap.get(key) - const child = (group?.children ?? []).find((c) => c.key.toString() === originalKey.toString()) - if (child) { - Object.assign(child.aggregations, value) - } } }) } - if (group?.children && group.nestedIn.length === groupBy.value.length - 1) { - const aliasMap = new Map() + if (group?.children?.length && group.nestedIn.length === groupBy.value.length - 1) { + const aliasMapper = new AliasMapper() const childViewFilters = group?.children?.map((childGroup) => { - let key = childGroup.key - - if (!key?.length || key.startsWith(' ') || key.endsWith(' ')) { - key = Math.random().toString(36).substring(7) - aliasMap.set(key, childGroup.key) - } - - try { - key = JSON.parse(key) - - if (typeof key === 'object') { - key = Math.random().toString(36).substring(7) - aliasMap.set(key, childGroup.key) - } - } catch (e) {} - return { - alias: key, + alias: aliasMapper.generateAlias(childGroup.key), where: calculateNestedWhere(childGroup.nestedIn, where?.value), offset: ((childGroup.paginationData.page ?? 0) - 1) * (childGroup.paginationData.pageSize ?? groupByRecordLimit.value), @@ -501,49 +459,26 @@ const [useProvideViewGroupBy, useViewGroupBy] = useInjectionState( ) : await fetchBulkListData({}, childViewFilters) - Object.entries(bulkData).forEach(([key, value]: { key: string; value: any }) => { - const child = (group?.children ?? []).find((c) => c.key.toString() === key.toString()) + await aliasMapper.process(bulkData, (originalKey, value: any) => { + const child = (group?.children ?? []).find((c) => c.key.toString() === (originalKey as any).toString()) if (child) { child.count = value.pageInfo.totalRows ?? 0 child.rows = formatData(value.list) child.paginationData = value.pageInfo - } else { - const originalKey = aliasMap.get(key) - const child = (group?.children ?? []).find((c) => c.key.toString() === originalKey.toString()) - if (child) { - child.count = value.pageInfo.totalRows ?? 0 - child.rows = formatData(value.list) - child.paginationData = value.pageInfo - } } }) } } - if (group?.children && group.nestedIn.length < groupBy.value.length - 1) { - const aliasMap = new Map() + if (group?.children?.length && group.nestedIn.length < groupBy.value.length - 1) { + const aliasMapper = new AliasMapper() const childGroupFilters = group?.children?.map((childGroup) => { const childGroupBy = groupBy.value[childGroup.nestedIn.length] const childNestedWhere = calculateNestedWhere(childGroup.nestedIn, where?.value) - let key = childGroup.key - - if (!key?.length || key.startsWith(' ') || key.endsWith(' ')) { - key = Math.random().toString(36).substring(7) - aliasMap.set(key, childGroup.key) - } - - try { - key = JSON.parse(key) - if (typeof key === 'object') { - key = Math.random().toString(36).substring(7) - aliasMap.set(key, childGroup.key) - } - } catch (e) {} - return { - alias: key, + alias: aliasMapper.generateAlias(childGroup.key), offset: ((childGroup.paginationData.page ?? 0) - 1) * (childGroup.paginationData.pageSize ?? groupByGroupLimit.value), limit: childGroup.paginationData.pageSize ?? groupByGroupLimit.value, @@ -555,7 +490,7 @@ const [useProvideViewGroupBy, useViewGroupBy] = useInjectionState( } }) - if (childGroupFilters.length > 0) { + if (childGroupFilters?.length > 0) { const bulkGroupData = !isPublic ? await api.dbDataTableBulkGroupList.dbDataTableBulkGroupList( meta.value.id, @@ -566,14 +501,12 @@ const [useProvideViewGroupBy, useViewGroupBy] = useInjectionState( ) : await fetchBulkGroupData({}, childGroupFilters) - for (const [key, value] of Object.entries(bulkGroupData)) { - let child = (group?.children ?? []).find((c) => c.key.toString() === key.toString()) - if (!child) { - const originalKey = aliasMap.get(key) - child = (group?.children ?? []).find((c) => c.key.toString() === originalKey.toString())! + await aliasMapper.process(bulkGroupData, async (originalKey, value) => { + const child = (group?.children ?? []).find((c) => c.key.toString() === originalKey.toString()) + if (child) { + Object.assign(child, await processGroupData(value, child)) } - Object.assign(child, await processGroupData(value, child)) - } + }) } } } catch (e) { @@ -637,29 +570,14 @@ const [useProvideViewGroupBy, useViewGroupBy] = useInjectionState( filteredFields = filteredFields?.filter((x) => x.type !== CommonAggregations.None) - if (filteredFields && !filteredFields?.length) return + if ((filteredFields && !filteredFields?.length) || !group.children?.length) return - const aggregationMap = new Map() + const aliasMapper = new AliasMapper() const aggregationParams = (group.children ?? []).map((child) => { - let key = child.key - - if (!key?.length || key.startsWith(' ') || key.endsWith(' ')) { - key = Math.random().toString(36).substring(7) - aggregationMap.set(key, child.key) - } - - try { - key = JSON.parse(child.key) - if (typeof key === 'object') { - key = Math.random().toString(36).substring(7) - aggregationMap.set(key, child.key) - } - } catch (e) {} - return { where: calculateNestedWhere(child.nestedIn, where?.value), - alias: key, + alias: aliasMapper.generateAlias(child.key), ...(isUIAllowed('filterSync') ? {} : { filterArrJson: JSON.stringify(nestedFilters.value) }), } }) @@ -680,18 +598,10 @@ const [useProvideViewGroupBy, useViewGroupBy] = useInjectionState( aggregationParams, ) - Object.entries(response).forEach(([key, value]) => { - const child = (group.children ?? []).find((c) => c.key.toString() === key.toString()) + await aliasMapper.process(response, (originalKey, value) => { + const child = (group.children ?? []).find((c) => c.key.toString() === originalKey.toString()) if (child) { Object.assign(child.aggregations, value) - } else { - const originalKey = aggregationMap.get(key) - if (originalKey) { - const child = (group.children ?? []).find((c) => c.key.toString() === originalKey.toString()) - if (child) { - Object.assign(child.aggregations, value) - } - } } }) } catch (e) { diff --git a/packages/nc-gui/utils/aliasUtils.ts b/packages/nc-gui/utils/aliasUtils.ts new file mode 100644 index 0000000000..595eae5d29 --- /dev/null +++ b/packages/nc-gui/utils/aliasUtils.ts @@ -0,0 +1,29 @@ +export class AliasMapper { + private aliasMap = new Map() + + generateAlias(key: unknown): string { + const alias = Math.random().toString(36).substring(2, 15) + this.aliasMap.set(alias, key) + return alias + } + + getAlias(alias: string): unknown { + return this.aliasMap.get(alias) + } + + clear() { + this.aliasMap.clear() + } + + async process>( + data: Record, + processor: (key: unknown, value: T) => void | Promise, + ): Promise { + for (const [alias, value] of Object.entries(data)) { + const originalKey = this.getAlias(alias) + if (originalKey !== undefined) { + await processor(originalKey, value) + } + } + } +}