Browse Source

Merge pull request #3818 from nocodb/fix/kanban-groupby-api-improvements

Fix/kanban groupby api improvements
pull/3563/head
աɨռɢӄաօռɢ 2 years ago committed by GitHub
parent
commit
9245c1171f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 700
      packages/nocodb-sdk/package-lock.json
  2. 14
      packages/nocodb/package-lock.json
  3. 2
      packages/nocodb/package.json
  4. 45
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts
  5. 11
      packages/nocodb/src/lib/meta/api/dataApis/dataAliasApis.ts
  6. 17
      packages/nocodb/src/lib/meta/api/utilApis.ts

700
packages/nocodb-sdk/package-lock.json generated

File diff suppressed because it is too large Load Diff

14
packages/nocodb/package-lock.json generated

@ -70,7 +70,7 @@
"mysql2": "^2.2.5",
"nanoid": "^3.1.20",
"nc-common": "0.0.6",
"nc-help": "0.2.68",
"nc-help": "0.2.73",
"nc-lib-gui": "0.97.0",
"nc-plugin": "0.1.2",
"ncp": "^2.0.0",
@ -15254,9 +15254,9 @@
}
},
"node_modules/nc-help": {
"version": "0.2.68",
"resolved": "https://registry.npmjs.org/nc-help/-/nc-help-0.2.68.tgz",
"integrity": "sha512-KaG+cykMPU165RDwcJbpJvXhhg631/pD+ubsF7L/w7NneOaYqE22zNb+jAAzF0M2jHPk65yXDp3tyXOILpz2Ig==",
"version": "0.2.73",
"resolved": "https://registry.npmjs.org/nc-help/-/nc-help-0.2.73.tgz",
"integrity": "sha512-YYh3UzcpofcPteGASffpD8raHhI8B9PZd3SQs2hfbzu9YIkeEpRzygciWdHgqkovZOv50I5wdDU9LQAi0+9Iew==",
"dependencies": {
"@rudderstack/rudder-sdk-node": "^1.1.3",
"axios": "^0.21.1",
@ -36722,9 +36722,9 @@
"integrity": "sha512-3AryS9uwa5NfISLxMciUonrH7YfXp+nlahB9T7girXIsLQrmwX4MdnuKs32akduCOGpKmjTJSWmATULbuMkbfw=="
},
"nc-help": {
"version": "0.2.68",
"resolved": "https://registry.npmjs.org/nc-help/-/nc-help-0.2.68.tgz",
"integrity": "sha512-KaG+cykMPU165RDwcJbpJvXhhg631/pD+ubsF7L/w7NneOaYqE22zNb+jAAzF0M2jHPk65yXDp3tyXOILpz2Ig==",
"version": "0.2.73",
"resolved": "https://registry.npmjs.org/nc-help/-/nc-help-0.2.73.tgz",
"integrity": "sha512-YYh3UzcpofcPteGASffpD8raHhI8B9PZd3SQs2hfbzu9YIkeEpRzygciWdHgqkovZOv50I5wdDU9LQAi0+9Iew==",
"requires": {
"@rudderstack/rudder-sdk-node": "^1.1.3",
"axios": "^0.21.1",

2
packages/nocodb/package.json

@ -155,7 +155,7 @@
"mysql2": "^2.2.5",
"nanoid": "^3.1.20",
"nc-common": "0.0.6",
"nc-help": "0.2.68",
"nc-help": "0.2.73",
"nc-lib-gui": "0.97.0",
"nc-plugin": "0.1.2",
"ncp": "^2.0.0",

45
packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSqlv2.ts

@ -2334,8 +2334,7 @@ class BaseModelSqlv2 {
args: {
groupColumnId: string;
ignoreFilterSort?: boolean;
sortArr?: any;
filterArr?: any;
options?: (string | number | null | boolean)[];
} & Partial<XcFilter>
): Promise<
{
@ -2354,19 +2353,24 @@ class BaseModelSqlv2 {
NcError.notImplemented('Grouping for virtual columns not implemented');
// extract distinct group column values
let groupingValues;
if (column.uidt === UITypes.SingleSelect) {
let groupingValues: Set<any>;
if (args.options?.length) {
groupingValues = new Set(args.options);
} else if (column.uidt === UITypes.SingleSelect) {
const colOptions = await column.getColOptions<
SelectOption[] & { options }
>();
groupingValues = colOptions.options.map((opt) => opt.title);
groupingValues = new Set(colOptions.options.map((opt) => opt.title));
} else {
groupingValues = (
await this.dbDriver(this.model.table_name)
.select(column.column_name)
.distinct()
).map((row) => row[column.column_name]);
groupingValues = new Set(
(
await this.dbDriver(this.model.table_name)
.select(column.column_name)
.distinct()
).map((row) => row[column.column_name])
);
}
groupingValues.add(null);
const qb = this.dbDriver(this.model.table_name);
qb.limit(+rest?.limit || 25);
@ -2450,7 +2454,7 @@ class BaseModelSqlv2 {
this.isSqlite
? this.dbDriver.select().from(nullListQb)
: nullListQb,
...groupingValues.map((r) => {
...[...groupingValues].map((r) => {
const query = qb.clone().where(column.title, r);
return this.isSqlite
@ -2470,13 +2474,22 @@ class BaseModelSqlv2 {
return d;
});
// todo: handle null values
const groupedResult: Record<string, Record<string, unknown>[]> =
_.groupBy(result, column.title);
const groupedResult = result.reduce<Map<string | number | null, any[]>>(
(aggObj, row) => {
if (!aggObj.has(row[column.title])) {
aggObj.set(row[column.title], []);
}
aggObj.get(row[column.title]).push(row);
return aggObj;
},
new Map()
);
const r = Object.entries(groupedResult).map(([key, value]) => ({
const r = [...groupingValues].map((key) => ({
key,
value,
value: groupedResult.get(key) ?? [],
}));
return r;

11
packages/nocodb/src/lib/meta/api/dataApis/dataAliasApis.ts

@ -246,6 +246,9 @@ async function getGroupedDataList(model, view: View, req) {
try {
listArgs.sortArr = JSON.parse(listArgs.sortArrJson);
} catch (e) {}
try {
listArgs.options = JSON.parse(listArgs.optionsArrJson);
} catch (e) {}
let data = [];
// let count = 0
@ -266,13 +269,13 @@ async function getGroupedDataList(model, view: View, req) {
});
data = data.map((item) => {
// todo: use map to avoid loop
const count = countArr.find(
(countItem) => countItem.key || 'null' === item.key
)?.count;
const count =
countArr.find((countItem) => countItem.key || 'null' === item.key)
?.count ?? 0;
item.value = new PagedResponseImpl(item.value, {
...req.query,
count,
count: count,
});
return item;
});

17
packages/nocodb/src/lib/meta/api/utilApis.ts

@ -10,6 +10,7 @@ import NcConfigFactory, {
import User from '../../models/User';
import catchError from '../helpers/catchError';
import axios from 'axios';
import { feedbackFormGet } from 'nc-help';
const versionCache = {
releaseVersion: null,
@ -19,6 +20,7 @@ const versionCache = {
export async function testConnection(req: Request, res: Response) {
res.json(await SqlMgrv2.testConnection(req.body));
}
export async function appInfo(req: Request, res: Response) {
const projectHasAdmin = !(await User.isFirst());
const result = {
@ -80,17 +82,8 @@ export async function versionInfo(_req: Request, res: Response) {
res.json(response);
}
export async function feedbackFormGet(_req: Request, res: Response) {
axios
.get('https://nocodb.com/api/v1/feedback_form', {
timeout: 5000,
})
.then((response) => {
res.json(response.data);
})
.catch((e) => {
res.json({ error: e.message });
});
export function feedbackFormGetHandler(_req: Request, res: Response) {
res.json(feedbackFormGet());
}
export async function appHealth(_: Request, res: Response) {
@ -188,6 +181,6 @@ export default (router) => {
router.post('/api/v1/db/meta/axiosRequestMake', catchError(axiosRequestMake));
router.get('/api/v1/version', catchError(versionInfo));
router.get('/api/v1/health', catchError(appHealth));
router.get('/api/v1/feedback_form', catchError(feedbackFormGet));
router.get('/api/v1/feedback_form', catchError(feedbackFormGetHandler));
router.post('/api/v1/url_to_config', catchError(urlToDbConfig));
};

Loading…
Cancel
Save