Browse Source

feat: Group by on lookup column, Links and formula

Signed-off-by: Pranav C <pranavxc@gmail.com>
pull/6489/head
Pranav C 1 year ago
parent
commit
72d041102f
  1. 22
      packages/nc-gui/composables/useViewGroupBy.ts
  2. 60
      packages/nocodb/src/db/BaseModelSqlv2.ts

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

@ -161,12 +161,10 @@ export const useViewGroupBy = (view: Ref<ViewType | undefined>, where?: Computed
if (group.nestedIn.length > groupBy.value.length) return
if (group.nestedIn.length === 0) nextGroupColor.value = colors.value[0]
const groupby = groupBy.value[group.nestedIn.length]
const nestedWhere = calculateNestedWhere(group.nestedIn, where?.value)
if (!groupby || !groupby.column.column_name) return
if (!groupby || !(groupby.column.column_name || groupby.column.title)) return
if (isPublic.value && !sharedView.value?.uuid) {
return
@ -181,7 +179,7 @@ export const useViewGroupBy = (view: Ref<ViewType | undefined>, where?: Computed
...(isUIAllowed('filterSync') ? {} : { filterArrJson: JSON.stringify(nestedFilters.value) }),
where: `${nestedWhere}`,
sort: `${groupby.sort === 'desc' ? '-' : ''}${groupby.column.title}`,
column_name: groupby.column.column_name,
column_name: groupby.column.column_name || groupby.column.title,
} as any)
: await api.public.dataGroupBy(sharedView.value!.uuid!, {
offset: ((group.paginationData.page ?? 0) - 1) * (group.paginationData.pageSize ?? groupByLimit),
@ -189,30 +187,32 @@ export const useViewGroupBy = (view: Ref<ViewType | undefined>, where?: Computed
...params,
where: nestedWhere,
sort: `${groupby.sort === 'desc' ? '-' : ''}${groupby.column.title}`,
column_name: groupby.column.column_name,
column_name: groupby.column.column_name || groupby.column.title,
sortsArr: sorts.value,
filtersArr: nestedFilters.value,
})
const tempList: Group[] = response.list.reduce((acc: Group[], curr: Record<string, any>) => {
const keyExists = acc.find((a) => a.key === valueToTitle(curr[groupby.column.column_name!], groupby.column))
const keyExists = acc.find(
(a) => a.key === valueToTitle(curr[groupby.column.column_name!] ?? curr[groupby.column.title!], groupby.column),
)
if (keyExists) {
keyExists.count += +curr.count
keyExists.paginationData = { page: 1, pageSize: groupByLimit, totalRows: keyExists.count }
return acc
}
if (groupby.column.title && groupby.column.column_name && groupby.column.uidt) {
if (groupby.column.title && groupby.column.uidt) {
acc.push({
key: valueToTitle(curr[groupby.column.column_name!], groupby.column),
key: valueToTitle(curr[(groupby.column.column_name || groupby.column.title)!], groupby.column),
column: groupby.column,
count: +curr.count,
color: findKeyColor(curr[groupby.column.column_name!], groupby.column),
color: findKeyColor(curr[(groupby.column.column_name || groupby.column.title)!], groupby.column),
nestedIn: [
...group!.nestedIn,
{
title: groupby.column.title,
column_name: groupby.column.column_name!,
key: valueToTitle(curr[groupby.column.column_name!], groupby.column),
column_name: (groupby.column.column_name || groupby.column.title)!,
key: valueToTitle(curr[(groupby.column.column_name || groupby.column.title)!], groupby.column),
column_uidt: groupby.column.uidt,
},
],

60
packages/nocodb/src/db/BaseModelSqlv2.ts

@ -339,6 +339,12 @@ class BaseModelSqlv2 {
let data;
console.log(`
${qb.toQuery()}
`);
try {
data = await this.execAndParse(qb);
} catch (e) {
@ -499,6 +505,7 @@ class BaseModelSqlv2 {
args.column_name = args.column_name || '';
const cols = await this.model.getColumns();
const groupByColumns: Record<string, Column> = {};
const selectors = [];
const groupBySelectors = [];
@ -508,11 +515,13 @@ class BaseModelSqlv2 {
const column = cols.find(
(c) => c.column_name === col || c.title === col,
);
groupByColumns[column.id] = column;
if (!column) {
throw NcError.notFound('Column not found');
}
switch (column.uidt) {
case UITypes.Links:
case UITypes.Rollup:
selectors.push(
(
@ -554,34 +563,25 @@ class BaseModelSqlv2 {
break;
case UITypes.Lookup:
{
let selectQb;
try {
const _selectQb = await generateBTLookupSelectQuery({
baseModelSqlv2: this,
column,
alias: null,
model: this.model,
});
const _selectQb = await generateBTLookupSelectQuery({
baseModelSqlv2: this,
column,
alias: null,
model: this.model,
});
selectQb = this.dbDriver.raw(`?? as ??`, [
this.dbDriver.raw(_selectQb.builder).wrap('(', ')'),
sanitize(column.title),
]);
} catch (e) {
console.log(e);
// return dummy select
selectQb = this.dbDriver.raw(`'ERR' as ??`, [
sanitize(column.title),
]);
}
const selectQb = this.dbDriver.raw(`?? as ??`, [
this.dbDriver.raw(_selectQb.builder).wrap('(', ')'),
sanitize(column.title),
]);
selectors.push(selectQb);
groupBySelectors.push(column.title);
groupBySelectors.push(sanitize(column.title));
}
break;
default:
selectors.push(column.column_name);
groupBySelectors.push(sanitize(column.title));
groupBySelectors.push(sanitize(column.column_name));
break;
}
}),
@ -634,6 +634,17 @@ class BaseModelSqlv2 {
? args.sortArr
: await Sort.list({ viewId: this.viewId });
sorts = sorts.filter((sort) => {
if (!groupByColumns[sort.fk_column_id]) {
return true;
}
qb.orderBy(
groupByColumns[sort.fk_column_id].column_name ||
groupByColumns[sort.fk_column_id].title,
);
});
if (sorts) await sortV2(this, sorts, qb);
applyPaginate(qb, rest);
return await qb;
@ -668,6 +679,7 @@ class BaseModelSqlv2 {
switch (column.uidt) {
case UITypes.Rollup:
case UITypes.Links:
selectors.push(
(
await genRollupSelectv2({
@ -725,7 +737,7 @@ class BaseModelSqlv2 {
break;
default:
selectors.push(column.column_name);
groupBySelectors.push(sanitize(column.title));
groupBySelectors.push(sanitize(column.column_name));
break;
}
}),
@ -4894,7 +4906,7 @@ async function generateBTLookupSelectQuery({
{
let aliasCount = 0,
selectQb;
const alias = `__nc_lookup${aliasCount++}`;
const alias = `__nc_lk_${aliasCount++}`;
const lookup = await column.getColOptions<LookupColumn>();
{
const relationCol = await lookup.getRelationColumn();
@ -4925,7 +4937,7 @@ async function generateBTLookupSelectQuery({
let lookupColumn = await lookup.getLookupColumn();
let prevAlias = alias;
while (lookupColumn.uidt === UITypes.Lookup) {
const nestedAlias = `__nc_sort${aliasCount++}`;
const nestedAlias = `__nc_lk_nested_${aliasCount++}`;
const nestedLookup = await lookupColumn.getColOptions<LookupColumn>();
const relationCol = await nestedLookup.getRelationColumn();
const relation =

Loading…
Cancel
Save