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

2
packages/nocodb/package.json

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

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

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

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

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

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

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

Loading…
Cancel
Save