Browse Source

refactor: nested data api corrections

Signed-off-by: Pranav C <pranavxc@gmail.com>
pull/1668/head
Pranav C 2 years ago
parent
commit
f156b63656
  1. 20
      packages/nc-gui/components/project/spreadsheet/components/virtualCell/belongsToCell.vue
  2. 29
      packages/nc-gui/components/project/spreadsheet/components/virtualCell/components/listChildItems.vue
  3. 27
      packages/nc-gui/components/project/spreadsheet/components/virtualCell/components/listItems.vue
  4. 8
      packages/nc-gui/components/project/spreadsheet/components/virtualCell/hasManyCell.vue
  5. 24
      packages/nc-gui/components/project/spreadsheet/components/virtualCell/manyToManyCell.vue
  6. 287
      packages/nocodb-sdk/src/lib/Api.ts
  7. 68
      packages/nocodb/src/lib/noco/meta/api/dataApis/dataAliasNestedApis.ts
  8. 9
      packages/nocodb/src/lib/noco/meta/api/dataApis/index.ts
  9. 2
      packages/nocodb/src/lib/noco/meta/api/index.ts
  10. 38
      scripts/sdk/swagger.json

20
packages/nc-gui/components/project/spreadsheet/components/virtualCell/belongsToCell.vue

@ -34,6 +34,7 @@
:column="column"
:primary-col="parentPrimaryCol"
:primary-key="parentPrimaryKey"
:parent-meta="meta"
:api="parentApi"
:query-params="{
...parentQueryParams,
@ -278,14 +279,18 @@ export default {
return
}
const id = this.meta.columns.filter(c => c.pk).map(c => this.row[c.title]).join('___')
// todo: audit
await this.$api.data.nestedDelete(
this.meta.id,
await this.$api.dbTableRow.nestedDelete(
'noco',
this.projectName,
this.meta.title,
id,
this.column.id,
'bt',
this.column.title,
parent[this.parentPrimaryKey]
)
this.$emit('loadTableData')
if (this.isForm && this.$refs.childList) {
this.$refs.childList.loadData()
@ -346,12 +351,13 @@ export default {
this.newRecordModal = false
return
}
await this.$api.data.nestedAdd(
this.meta.id,
await this.$api.dbTableRow.nestedAdd(
'noco',
this.projectName,
this.meta.title,
id,
this.column.id,
'bt',
this.column.title,
pid
)

29
packages/nc-gui/components/project/spreadsheet/components/virtualCell/components/listChildItems.vue

@ -179,7 +179,6 @@ export default {
methods: {
async loadData() {
if ((!this.isForm && this.isPublic) && this.$route.params.id) {
if (this.column && this.column.colOptions && this.rowId) {
this.data = (await this.$api.public.dataNestedList(
this.$route.params.id,
@ -198,26 +197,24 @@ export default {
return
}
if (this.column && this.column.colOptions) {
this.data = (await this.$api.data.nestedList(
this.column.fk_model_id,
this.data = (await this.$api.dbTableRow.nestedList(
'noco',
this.projectName,
this.parentMeta.title,
this.rowId,
this.column.id,
this.column.colOptions.type,
this.column.title,
{
query: {
limit: this.size,
offset: this.size * (this.page - 1)
// ...this.queryParams
}
limit: this.size,
offset: this.size * (this.page - 1)
}))
} else {
this.data = (await this.$api.data.list(
this.meta.id, {
query: {
limit: this.size,
offset: this.size * (this.page - 1),
...this.queryParams
}
this.data = (await this.$api.dbTableRow.list(
'noco',
this.projectName, this.meta.title, {
limit: this.size,
offset: this.size * (this.page - 1),
...this.queryParams
}))
}
}

27
packages/nc-gui/components/project/spreadsheet/components/virtualCell/components/listItems.vue

@ -144,7 +144,10 @@ export default {
this.data = (await this.$api.public.dataRelationList(
this.$route.params.id,
this.column.id,
{ password: this.password }, {
{}, {
headers: {
'xc-password': this.password
},
query: {
limit: this.size,
offset: this.size * (this.page - 1),
@ -156,21 +159,23 @@ export default {
// eslint-disable-next-line no-lonely-if
if (this.column && this.column.colOptions && this.rowId) {
this.data = (await this.$api.data.nestedExcludedList(
this.column.fk_model_id,
this.data = (await this.$api.dbTableRow.nestedChildrenExcludedList(
'noco',
this.projectName,
this.parentMeta.title,
this.rowId,
this.column.id,
this.column.colOptions.type,
this.column.title,
{
query: {
limit: this.size,
offset: this.size * (this.page - 1),
where: this.query && `(${this.primaryCol},like,${this.query})`
}
limit: this.size,
offset: this.size * (this.page - 1),
where: this.query && `(${this.primaryCol},like,${this.query})`
}))
} else {
this.data = (await this.$api.data.list(
this.meta.id, {
this.data = (await this.$api.dbTableRow.list(
'noco',
this.projectName,
this.meta.title, {
query: {
limit: this.size,
offset: this.size * (this.page - 1),

8
packages/nc-gui/components/project/spreadsheet/components/virtualCell/hasManyCell.vue

@ -382,11 +382,13 @@ export default {
const id = this.childMeta.columns.filter(c => c.pk).map(c => child[c.title]).join('___')
this.newRecordModal = false
await this.$api.data.nestedAdd(
this.meta.id,
await this.$api.dbTableRow.nestedAdd(
'noco',
this.projectName,
this.meta.title,
this.parentId,
this.column.id,
'hm',
this.column.title,
id
)

24
packages/nc-gui/components/project/spreadsheet/components/virtualCell/manyToManyCell.vue

@ -44,6 +44,7 @@
:meta="childMeta"
:primary-col="childPrimaryCol"
:primary-key="childPrimaryKey"
:parent-meta="meta"
:api="api"
:mm="mm"
:tn="mm && mm.rtn"
@ -316,13 +317,17 @@ export default {
await Promise.all([this.loadChildMeta(), this.loadAssociateTableMeta()])
const cid = this.childMeta.columns.filter(c => c.pk).map(c => child[c.title]).join('___')
const pid = this.meta.columns.filter(c => c.pk).map(c => this.row[c.title]).join('___')
await this.$api.data.nestedDelete(
this.meta.id,
await this.$api.dbTableRow.nestedDelete(
'noco',
this.projectName,
this.meta.title,
pid,
this.column.id,
'mm',
this.column.title,
cid
)
this.$emit('loadTableData')
if ((this.childListModal || this.isForm) && this.$refs.childList) {
this.$refs.childList.loadData()
@ -400,20 +405,17 @@ export default {
// const vcidCol = this.assocMeta.columns.find(c => c.id === this.column.colOptions.fk_mm_parent_column_id).title
// const vpidCol = this.assocMeta.columns.find(c => c.id === this.column.colOptions.fk_mm_child_column_id).title
await this.$api.data.nestedAdd(
this.meta.id,
await this.$api.dbTableRow.nestedAdd(
'noco',
this.projectName,
this.meta.title,
pid,
this.column.id,
'mm',
this.column.title,
cid
)
try {
// await this.$api.data.create(this.assocMeta.id, {
// [vcidCol]: parseIfInteger(cid),
// [vpidCol]: parseIfInteger(pid)
// })
this.$emit('loadTableData')
} catch (e) {
// todo: handle

287
packages/nocodb-sdk/src/lib/Api.ts

@ -2467,6 +2467,157 @@ export class Api<
...params,
}),
/**
* @description CSV or Excel export
*
* @tags DB table row
* @name CsvExport
* @request GET:/api/v1/db/data/{orgs}/{projectName}/{tableName}/views/{viewName}/export/{type}
* @response `200` `any` OK
*/
csvExport: (
orgs: string,
projectName: string,
tableName: string,
viewName: string,
type: 'csv' | 'excel',
params: RequestParams = {}
) =>
this.request<any, any>({
path: `/api/v1/db/data/${orgs}/${projectName}/${tableName}/views/${viewName}/export/${type}`,
method: 'GET',
wrapped: true,
...params,
}),
/**
* @description CSV or Excel export
*
* @tags DB table row
* @name CsvExport2
* @request GET:/api/v1/db/data/{orgs}/{projectName}/{tableName}/export/{type}
* @originalName csvExport
* @duplicate
* @response `200` `any` OK
*/
csvExport2: (
orgs: string,
projectName: string,
tableName: string,
type: 'csv' | 'excel',
params: RequestParams = {}
) =>
this.request<any, any>({
path: `/api/v1/db/data/${orgs}/${projectName}/${tableName}/export/${type}`,
method: 'GET',
wrapped: true,
...params,
}),
/**
* No description
*
* @tags DB table row
* @name NestedList
* @request GET:/api/v1/db/data/{orgs}/{projectName}/{tableName}/{rowId}/{relationType}/{columnName}
* @response `200` `any` OK
*/
nestedList: (
orgs: string,
projectName: string,
tableName: string,
rowId: string,
relationType: 'mm' | 'hm',
columnName: string,
query?: { limit?: string; offset?: string },
params: RequestParams = {}
) =>
this.request<any, any>({
path: `/api/v1/db/data/${orgs}/${projectName}/${tableName}/${rowId}/${relationType}/${columnName}`,
method: 'GET',
query: query,
format: 'json',
...params,
}),
/**
* No description
*
* @tags DB table row
* @name NestedAdd
* @request POST:/api/v1/db/data/{orgs}/{projectName}/{tableName}/{rowId}/{relationType}/{columnName}/{refRowId}
* @response `200` `any` OK
*/
nestedAdd: (
orgs: string,
projectName: string,
tableName: string,
rowId: string,
relationType: 'mm' | 'hm',
columnName: string,
refRowId: string,
query?: { limit?: string; offset?: string },
params: RequestParams = {}
) =>
this.request<any, any>({
path: `/api/v1/db/data/${orgs}/${projectName}/${tableName}/${rowId}/${relationType}/${columnName}/${refRowId}`,
method: 'POST',
query: query,
format: 'json',
...params,
}),
/**
* No description
*
* @tags DB table row
* @name NestedDelete
* @request DELETE:/api/v1/db/data/{orgs}/{projectName}/{tableName}/{rowId}/{relationType}/{columnName}/{refRowId}
* @response `200` `any` OK
*/
nestedDelete: (
orgs: string,
projectName: string,
tableName: string,
rowId: string,
relationType: 'mm' | 'hm',
columnName: string,
refRowId: string,
params: RequestParams = {}
) =>
this.request<any, any>({
path: `/api/v1/db/data/${orgs}/${projectName}/${tableName}/${rowId}/${relationType}/${columnName}/${refRowId}`,
method: 'DELETE',
format: 'json',
...params,
}),
/**
* No description
*
* @tags DB table row
* @name NestedChildrenExcludedList
* @request GET:/api/v1/db/data/{orgs}/{projectName}/{tableName}/{rowId}/{relationType}/{columnName}/exclude
* @response `200` `any` OK
*/
nestedChildrenExcludedList: (
orgs: string,
projectName: string,
tableName: string,
rowId: string,
relationType: 'mm' | 'hm',
columnName: string,
query?: { limit?: string; offset?: string },
params: RequestParams = {}
) =>
this.request<any, any>({
path: `/api/v1/db/data/${orgs}/${projectName}/${tableName}/${rowId}/${relationType}/${columnName}/exclude`,
method: 'GET',
query: query,
format: 'json',
...params,
}),
/**
* No description
*
@ -2707,110 +2858,7 @@ export class Api<
...params,
}),
};
data = {
/**
* @description CSV or Excel export
*
* @tags Data
* @name CsvExport
* @request GET:/api/v1/db/data/{orgs}/{projectName}/{tableName}/views/{viewName}/export/{type}
* @response `200` `any` OK
*/
csvExport: (
orgs: string,
projectName: string,
tableName: string,
viewName: string,
type: 'csv' | 'excel',
params: RequestParams = {}
) =>
this.request<any, any>({
path: `/api/v1/db/data/${orgs}/${projectName}/${tableName}/views/${viewName}/export/${type}`,
method: 'GET',
wrapped: true,
...params,
}),
/**
* @description CSV or Excel export
*
* @tags Data
* @name CsvExport2
* @request GET:/api/v1/db/data/{orgs}/{projectName}/{tableName}/export/{type}
* @originalName csvExport
* @duplicate
* @response `200` `any` OK
*/
csvExport2: (
orgs: string,
projectName: string,
tableName: string,
type: 'csv' | 'excel',
params: RequestParams = {}
) =>
this.request<any, any>({
path: `/api/v1/db/data/${orgs}/${projectName}/${tableName}/export/${type}`,
method: 'GET',
wrapped: true,
...params,
}),
};
public = {
/**
* No description
*
* @tags Public
* @name DataNestedList
* @request GET:/api/v1/db/data/{orgs}/{projectName}/{tableName}/{rowId}/{relationType}/{columnName}
* @response `200` `any` OK
*/
dataNestedList: (
orgs: string,
projectName: string,
tableName: string,
rowId: string,
relationType: 'mm' | 'hm',
columnName: string,
query?: { limit?: string; offset?: string },
params: RequestParams = {}
) =>
this.request<any, any>({
path: `/api/v1/db/data/${orgs}/${projectName}/${tableName}/${rowId}/${relationType}/${columnName}`,
method: 'GET',
query: query,
format: 'json',
...params,
}),
/**
* No description
*
* @tags Public
* @name DataNestedList2
* @request POST:/api/v1/db/data/{orgs}/{projectName}/{tableName}/{rowId}/{relationType}/{columnName}/{refRowId}
* @originalName dataNestedList
* @duplicate
* @response `200` `any` OK
*/
dataNestedList2: (
orgs: string,
projectName: string,
tableName: string,
rowId: string,
relationType: 'mm' | 'hm',
columnName: string,
refRowId: string,
query?: { limit?: string; offset?: string },
params: RequestParams = {}
) =>
this.request<any, any>({
path: `/api/v1/db/data/${orgs}/${projectName}/${tableName}/${rowId}/${relationType}/${columnName}/${refRowId}`,
method: 'POST',
query: query,
format: 'json',
...params,
}),
/**
* No description
*
@ -2858,13 +2906,11 @@ export class Api<
* No description
*
* @tags Public
* @name DataNestedList3
* @name DataNestedList
* @request GET:/api/v1/db/public/shared-view/{sharedViewUuid}/rows/{rowId}/{relationType}/{columnName}
* @originalName dataNestedList
* @duplicate
* @response `200` `any` OK
*/
dataNestedList3: (
dataNestedList: (
sharedViewUuid: string,
rowId: string,
relationType: 'mm' | 'hm',
@ -2981,33 +3027,6 @@ export class Api<
...params,
}),
};
dbData = {
/**
* No description
*
* @tags DB Data
* @name DataNestedExcludedChildrenList
* @request GET:/api/v1/db/data/{orgs}/{projectName}/{tableName}/{rowId}/{relationType}/{columnName}/exclude
* @response `200` `any` OK
*/
dataNestedExcludedChildrenList: (
orgs: string,
projectName: string,
tableName: string,
rowId: string,
relationType: 'mm' | 'hm',
columnName: string,
query?: { limit?: string; offset?: string },
params: RequestParams = {}
) =>
this.request<any, any>({
path: `/api/v1/db/data/${orgs}/${projectName}/${tableName}/${rowId}/${relationType}/${columnName}/exclude`,
method: 'GET',
query: query,
format: 'json',
...params,
}),
};
utils = {
/**
* No description

68
packages/nocodb/src/lib/noco/meta/api/dataApis/dataAliasNestedApis.ts

@ -3,7 +3,6 @@ import Model from '../../../../noco-models/Model';
import Base from '../../../../noco-models/Base';
import NcConnectionMgrv2 from '../../../common/NcConnectionMgrv2';
import { PagedResponseImpl } from '../../helpers/PagedResponse';
import View from '../../../../noco-models/View';
import ncMetaAclMw from '../../helpers/ncMetaAclMw';
import { getViewAndModelFromRequestByAliasOrId } from './helpers';
import { NcError } from '../../helpers/catchError';
@ -44,12 +43,7 @@ export async function mmList(req: Request, res: Response, next) {
}
export async function mmExcludedList(req: Request, res: Response, next) {
const view = await View.get(req.params.viewId);
const model = await Model.getByIdOrName({
id: view?.fk_model_id || req.params.viewId
});
const { model, view } = await getViewAndModelFromRequestByAliasOrId(req);
if (!model) return next(new Error('Table not found'));
const base = await Base.get(model.base_id);
@ -86,11 +80,7 @@ export async function mmExcludedList(req: Request, res: Response, next) {
}
export async function hmExcludedList(req: Request, res: Response, next) {
const view = await View.get(req.params.viewId);
const model = await Model.getByIdOrName({
id: view?.fk_model_id || req.params.viewId
});
const { model, view } = await getViewAndModelFromRequestByAliasOrId(req);
if (!model) return next(new Error('Table not found'));
@ -129,12 +119,7 @@ export async function hmExcludedList(req: Request, res: Response, next) {
}
export async function btExcludedList(req: Request, res: Response, next) {
const view = await View.get(req.params.viewId);
const model = await Model.getByIdOrName({
id: view?.fk_model_id || req.params.viewId
});
const { model, view } = await getViewAndModelFromRequestByAliasOrId(req);
if (!model) return next(new Error('Table not found'));
const base = await Base.get(model.base_id);
@ -172,12 +157,7 @@ export async function btExcludedList(req: Request, res: Response, next) {
}
export async function hmList(req: Request, res: Response, next) {
const view = await View.get(req.params.viewId);
const model = await Model.getByIdOrName({
id: view?.fk_model_id || req.params.viewId
});
const { model, view } = await getViewAndModelFromRequestByAliasOrId(req);
if (!model) return next(new Error('Table not found'));
const base = await Base.get(model.base_id);
@ -212,11 +192,7 @@ export async function hmList(req: Request, res: Response, next) {
//@ts-ignore
async function relationDataDelete(req, res) {
const view = await View.get(req.params.viewId);
const model = await Model.getByIdOrName({
id: view?.fk_model_id || req.params.viewId
});
const { model, view } = await getViewAndModelFromRequestByAliasOrId(req);
if (!model) NcError.notFound('Table not found');
@ -232,7 +208,7 @@ async function relationDataDelete(req, res) {
await baseModel.removeChild({
colId: column.id,
childId: req.params.childId,
childId: req.params.refRowId,
rowId: req.params.rowId
});
@ -241,12 +217,7 @@ async function relationDataDelete(req, res) {
//@ts-ignore
async function relationDataAdd(req, res) {
const view = await View.get(req.params.viewId);
const model = await Model.getByIdOrName({
id: view?.fk_model_id || req.params.viewId
});
const { model, view } = await getViewAndModelFromRequestByAliasOrId(req);
if (!model) NcError.notFound('Table not found');
const base = await Base.get(model.base_id);
@ -260,7 +231,7 @@ async function relationDataAdd(req, res) {
const column = await getColumnByIdOrName(req.params.columnName, model);
await baseModel.addChild({
colId: column.id,
childId: req.params.childId,
childId: req.params.refRowId,
rowId: req.params.rowId
});
@ -270,9 +241,9 @@ async function relationDataAdd(req, res) {
async function getColumnByIdOrName(columnNameOrId: string, model: Model) {
const column = (await model.getColumns()).find(
c =>
column.title === columnNameOrId ||
c.title === columnNameOrId ||
c.id === columnNameOrId ||
column.column_name === columnNameOrId
c.column_name === columnNameOrId
);
if (!column)
@ -284,25 +255,34 @@ async function getColumnByIdOrName(columnNameOrId: string, model: Model) {
const router = Router({ mergeParams: true });
router.get(
'/api/v1/db/data/:orgs/:projectName/:tableName/mm/:columnName/exclude',
'/api/v1/db/data/:orgs/:projectName/:tableName/:rowId/mm/:columnName/exclude',
ncMetaAclMw(mmExcludedList, 'mmExcludedList')
);
router.get(
'/api/v1/db/data/:orgs/:projectName/:tableName/hm/:columnName/exclude',
'/api/v1/db/data/:orgs/:projectName/:tableName/:rowId/hm/:columnName/exclude',
ncMetaAclMw(hmExcludedList, 'hmExcludedList')
);
router.get(
'/api/v1/db/data/:orgs/:projectName/:tableName/bt/:columnName/exclude',
'/api/v1/db/data/:orgs/:projectName/:tableName/:rowId/bt/:columnName/exclude',
ncMetaAclMw(btExcludedList, 'btExcludedList')
);
router.post(
'/api/v1/db/data/:orgs/:projectName/:tableName/:relationType/:columnName/:refRowId',
'/api/v1/db/data/:orgs/:projectName/:tableName/:rowId/:relationType/:columnName/:refRowId',
ncMetaAclMw(relationDataAdd, 'relationDataAdd')
);
router.delete(
'/api/v1/db/data/:orgs/:projectName/:tableName/:relationType/:columnName/:refRowId',
'/api/v1/db/data/:orgs/:projectName/:tableName/:rowId/:relationType/:columnName/:refRowId',
ncMetaAclMw(relationDataDelete, 'relationDataDelete')
);
router.get(
'/api/v1/db/data/:orgs/:projectName/:tableName/:rowId/mm/:columnName',
ncMetaAclMw(mmList, 'mmList')
);
router.get(
'/api/v1/db/data/:orgs/:projectName/:tableName/:rowId/hm/:columnName',
ncMetaAclMw(hmList, 'hmList')
);
export default router;

9
packages/nocodb/src/lib/noco/meta/api/dataApis/index.ts

@ -2,5 +2,12 @@ import dataApis from './dataApis';
import oldDataApis from './oldDataApis';
import dataAliasApis from './dataAliasApis';
import bulkDataAliasApis from './bulkDataAliasApis';
import dataAliasNestedApis from './dataAliasNestedApis';
export { dataApis, oldDataApis, dataAliasApis, bulkDataAliasApis };
export {
dataApis,
oldDataApis,
dataAliasApis,
bulkDataAliasApis,
dataAliasNestedApis
};

2
packages/nocodb/src/lib/noco/meta/api/index.ts

@ -30,6 +30,7 @@ import hookFilterApis from './hookFilterApis';
import {
bulkDataAliasApis,
dataAliasApis,
dataAliasNestedApis,
dataApis,
oldDataApis
} from './dataApis';
@ -52,6 +53,7 @@ export default function(router: Router, server) {
router.use(dataApis);
router.use(bulkDataAliasApis);
router.use(dataAliasApis);
router.use(dataAliasNestedApis);
router.use(oldDataApis);
router.use(sortApis);
router.use(filterApis);

38
scripts/sdk/swagger.json

@ -2357,6 +2357,7 @@
}
}
},
"/api/v1/db/data/{orgs}/{projectName}/{tableName}": {
"parameters": [
{
@ -2972,10 +2973,10 @@
],
"get": {
"summary": "",
"operationId": "data-csv-export",
"operationId": "db-table-row-csv-export",
"description": "CSV or Excel export",
"tags": [
"Data"
"DB table row"
],
"wrapped": true,
"responses": {
@ -3039,10 +3040,10 @@
],
"get": {
"summary": "",
"operationId": "data-csv-export",
"operationId": "db-table-row-csv-export",
"description": "CSV or Excel export",
"tags": [
"Data"
"DB table row"
],
"wrapped": true,
"responses": {
@ -3121,7 +3122,7 @@
],
"get": {
"summary": "",
"operationId": "data-nested-list",
"operationId": "db-table-row-nested-list",
"responses": {
"200": {
"description": "OK",
@ -3133,7 +3134,7 @@
}
},
"tags": [
"Public"
"DB table row"
],
"parameters": [
{
@ -3218,7 +3219,7 @@
],
"post": {
"summary": "",
"operationId": "data-nested-list",
"operationId": "db-table-row-nested-add",
"responses": {
"200": {
"description": "OK",
@ -3230,7 +3231,7 @@
}
},
"tags": [
"Public"
"DB table row"
],
"parameters": [
{
@ -3248,6 +3249,23 @@
"name": "offset"
}
]
},
"delete": {
"summary": "",
"operationId": "db-table-row-nested-delete",
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {}
}
}
}
},
"tags": [
"DB table row"
]
}
},
"/api/v1/db/data/{orgs}/{projectName}/{tableName}/{rowId}/{relationType}/{columnName}/exclude": {
@ -3307,7 +3325,7 @@
],
"get": {
"summary": "",
"operationId": "data-nested-excluded-children-list",
"operationId": "db-table-row-nested-children-excluded-list",
"responses": {
"200": {
"description": "OK",
@ -3319,7 +3337,7 @@
}
},
"tags": [
"DB Data"
"DB table row"
],
"parameters": [
{

Loading…
Cancel
Save