diff --git a/packages/nc-gui/components/project/spreadsheet/components/expandedForm.vue b/packages/nc-gui/components/project/spreadsheet/components/expandedForm.vue index c5b61215bb..aeb10b0084 100644 --- a/packages/nc-gui/components/project/spreadsheet/components/expandedForm.vue +++ b/packages/nc-gui/components/project/spreadsheet/components/expandedForm.vue @@ -418,12 +418,12 @@ export default { } }, async reload() { - // const id = this.meta.columns.filter((c) => c.pk).map(c => this.localState[c._cn]).join('___'); - const where = this.meta.columns.filter(c => c.pk).map(c => `(${c._cn},eq,${this.localState[c._cn]})`).join('~and') + const id = this.meta.columns.filter(c => c.pk).map(c => this.localState[c._cn]).join('___') + // const where = this.meta.columns.filter(c => c.pk).map(c => `(${c._cn},eq,${this.localState[c._cn]})`).join('~and') this.$set(this, 'changedColumns', {}) - // this.localState = await this.api.read(id); - const data = await this.api.list({ ...(this.queryParams || {}), where }) || [{}] - this.localState = data[0] || this.localState + this.localState = await this.api.read(id, this.queryParams || {}) + // const data = await this.api.list({ ...(this.queryParams || {}), where }) || [{}] + // this.localState = data[0] || this.localState if (!this.isNew && this.toggleDrawer) { this.getAuditsAndComments() } diff --git a/packages/nc-gui/plugins/ncApis/gqlApi.js b/packages/nc-gui/plugins/ncApis/gqlApi.js index 3169ce6017..9672616c30 100644 --- a/packages/nc-gui/plugins/ncApis/gqlApi.js +++ b/packages/nc-gui/plugins/ncApis/gqlApi.js @@ -65,8 +65,8 @@ export default class GqlApi { return `{${this.gqlQueryListName}${this.generateQueryParams(params)}{${this.gqlReqBody}${await this.gqlRelationReqBody(params)}}}` } - gqlReadQuery(id) { - return `{${this.gqlQueryReadName}(id:"${id}"){${this.gqlReqBody}}}` + async gqlReadQuery(id) { + return `{${this.gqlQueryReadName}(id:"${id}"){${this.gqlReqBody}${await this.gqlRelationReqBody(params)}}}` } gqlCountQuery(params) { @@ -209,7 +209,7 @@ export default class GqlApi { async read(id) { const data = await this.post(`/nc/${this.$ctx.projectId}/v1/graphql`, { - query: this.gqlReadQuery(id), + query: await this.gqlReadQuery(id), variables: null }) return data.data.data[this.gqlQueryReadName] diff --git a/packages/nc-gui/plugins/ncApis/restApi.js b/packages/nc-gui/plugins/ncApis/restApi.js index 84915ac0f8..08cafb60ca 100644 --- a/packages/nc-gui/plugins/ncApis/restApi.js +++ b/packages/nc-gui/plugins/ncApis/restApi.js @@ -11,8 +11,8 @@ export default class RestApi { return data.data } - async read(id) { - const data = await this.get(`/nc/${this.$ctx.projectId}/api/v1/${this.table}/${id}`) + async read(id, params = {}) { + const data = await this.get(`/nc/${this.$ctx.projectId}/api/v1/${this.table}/${id}`, params) return data.data } diff --git a/packages/nocodb/src/lib/dataMapper/lib/sql/BaseModelSql.ts b/packages/nocodb/src/lib/dataMapper/lib/sql/BaseModelSql.ts index 311d7483d4..d919e9686d 100644 --- a/packages/nocodb/src/lib/dataMapper/lib/sql/BaseModelSql.ts +++ b/packages/nocodb/src/lib/dataMapper/lib/sql/BaseModelSql.ts @@ -1334,6 +1334,63 @@ class BaseModelSql extends BaseModel { } } + async nestedRead(id, {hm: childs = '', bt: parents = '', mm: many = '', where, fields: fields1, f, ...rest}) { + + + let fields = fields1 || f || '*'; + try { + + // todo: use fields in readbyPk + if (fields !== '*' && fields.split(',').indexOf(this.pks[0].cn) === -1) { + fields += ',' + this.pks[0].cn; + } + + + const item = await this.readByPk(id); + if (!item) return item; + + for (const parent of parents.split(',')) { + const {cn} = this.belongsToRelations.find(({rtn}) => rtn === parent) || {}; + if (fields !== '*' && fields.split(',').indexOf(cn) === -1) { + fields += ',' + cn; + } + } + + + const items = [item]; + + if (items && items.length) { + await Promise.all([...new Set(childs.split(','))].map((child, index) => child && this._getChildListInParent({ + parent: items, + child + }, rest, index))); + } + + await Promise.all(parents.split(',').map((parent, index): any => { + if (!parent) { + return; + } + const {cn, rcn} = this.belongsToRelations.find(({rtn}) => rtn === parent) || {}; + const parentIds = [...new Set(items.map(c => c[cn] || c[this.columnToAlias[cn]]))]; + return this._belongsTo({parent, rcn, parentIds, childs: items, cn, ...rest}, index); + })) + + + if (items && items.length) { + await Promise.all([...new Set(many.split(','))].map((child, index) => child && this._getManyToManyList({ + parent: items, + child + }, rest, index))); + } + + + return item; + } catch (e) { + console.log(e); + throw e; + } + } + // todo: naming public m2mNotChildren({pid = null, assoc = null, ...args}): Promise { if (pid === null || assoc === null) { diff --git a/packages/nocodb/src/lib/noco/rest/RestCtrl.ts b/packages/nocodb/src/lib/noco/rest/RestCtrl.ts index 7ce11678fb..a41b5d2cef 100644 --- a/packages/nocodb/src/lib/noco/rest/RestCtrl.ts +++ b/packages/nocodb/src/lib/noco/rest/RestCtrl.ts @@ -60,7 +60,8 @@ export class RestCtrl extends RestBaseCtrl { } public async get(req: Request | any, res): Promise { - const data = await req.model.readByPk(req.params.id, req.query); + // const data = await req.model.readByPk(req.params.id, req.query); + const data = await req.model.nestedRead(req.params.id, req.query); res.xcJson(data); } diff --git a/packages/nocodb/src/lib/sqlMgr/code/routers/xc-ts/SwaggerXc.ts b/packages/nocodb/src/lib/sqlMgr/code/routers/xc-ts/SwaggerXc.ts index d6fe7a534c..6845e95ca1 100644 --- a/packages/nocodb/src/lib/sqlMgr/code/routers/xc-ts/SwaggerXc.ts +++ b/packages/nocodb/src/lib/sqlMgr/code/routers/xc-ts/SwaggerXc.ts @@ -221,7 +221,25 @@ class SwaggerXc extends BaseRender { "required": true, "type": "integer", "format": "int64" - } + }, + { + "in": "query", + "name": "bt", + "type": "String", + "description": "Comma separated parent table names(Belongs To)" + }, + { + "in": "query", + "name": "hm", + "type": "String", + "description": "Comma separated child table names(Has Many)" + }, + { + "in": "query", + "name": "mm", + "type": "String", + "description": "Comma separated child table names(Many to Many)" + }, ], "responses": { "200": {