Browse Source

feat: make nested field avail under webhooks

Signed-off-by: Pranav C <61551451+pranavxc@users.noreply.github.com>
pull/401/head
Pranav C 3 years ago
parent
commit
433feb96af
  1. 16
      packages/nc-gui/components/project/spreadsheet/rowsXcDataTable.vue
  2. 1
      packages/nocodb/src/lib/dataMapper/lib/BaseModel.ts
  3. 85
      packages/nocodb/src/lib/dataMapper/lib/sql/BaseModelSql.ts
  4. 15
      packages/nocodb/src/lib/noco/common/BaseModel.ts

16
packages/nc-gui/components/project/spreadsheet/rowsXcDataTable.vue

@ -744,21 +744,7 @@ export default {
return o
}, {})
let insertedData = await this.api.insert(insertObj)
// todo: optimize
if (this.meta.v && this.meta.v.length) {
try {
const where = this.meta.columns.filter(c => c.pk).map(c => `(${c._cn},eq,${insertedData[c._cn]})`).join('~and')
if (where) {
const { childs, parents, many } = this.queryParams
const data = (await this.api.list({ where, childs, parents, many }) || [insertedData])
insertedData = data.length ? data[0] : insertedData
}
} catch (e) {
// ignore
}
}
const insertedData = await this.api.insert(insertObj)
this.data.splice(row, 1, {
row: insertedData,

1
packages/nocodb/src/lib/dataMapper/lib/BaseModel.ts

@ -62,6 +62,7 @@ abstract class BaseModel {
protected hasManyRelations: any;
protected belongsToRelations: any;
protected manyToManyRelations: any;
protected virtualColumns: any;
protected config: any;
protected clientType: string;
public readonly type: string;

85
packages/nocodb/src/lib/dataMapper/lib/sql/BaseModelSql.ts

@ -41,6 +41,7 @@ class BaseModelSql extends BaseModel {
hasMany = [],
belongsTo = [],
manyToMany = [],
v,
type,
dbModels
}: {
@ -66,6 +67,7 @@ class BaseModelSql extends BaseModel {
this.hasManyRelations = hasMany;
this.belongsToRelations = belongsTo;
this.manyToManyRelations = manyToMany;
this.virtualColumns = v;
this.config = {
limitDefault: process.env.DB_QUERY_LIMIT_DEFAULT || 10,
limitMax: process.env.DB_QUERY_LIMIT_MAX || 500,
@ -157,7 +159,9 @@ class BaseModelSql extends BaseModel {
* @returns {Object} Copy of the object excluding primary keys
* @private
*/
_extractPks(obj) {
_extractPks(obj): {
[key: string]: any
} {
const objCopy = this.mapAliasToColumn(obj);
for (const key in objCopy) {
if (this.pks.filter(pk => pk._cn === key).length === 0) {
@ -173,7 +177,7 @@ class BaseModelSql extends BaseModel {
* @returns {Object} Copy of the object excluding primary keys
* @private
*/
_extractPksValues(obj) {
_extractPksValues(obj): string {
const objCopy = this.mapAliasToColumn(obj);
for (const key in objCopy) {
if (this.pks.filter(pk => pk._cn === key).length === 0) {
@ -238,6 +242,7 @@ class BaseModelSql extends BaseModel {
* @param {Object} [trx] - knex transaction object
* @returns {Promise<Object[]>|Promise<Number[]>}
*/
// todo: optimize
async insert(data, trx = null, cookie?: any) {
try {
@ -260,6 +265,7 @@ class BaseModelSql extends BaseModel {
response = await this._run(query);
}
const ai = this.columns.find(c => c.ai);
if (!response || (typeof response?.[0] !== 'object' && response?.[0] !== null)) {
let id;
if (response?.length) {
@ -268,12 +274,14 @@ class BaseModelSql extends BaseModel {
id = (await this._run(query))[0];
}
const ai = this.columns.find(c => c.ai);
if (ai) {
response = await this.readByPk(id)
// response = await this.readByPk(id)
response = await this.nestedRead(id, this.defaultNestedBtQueryParams)
} else {
response = data;
}
} else if (ai) {
response = await this.nestedRead(Array.isArray(response) ? response?.[0]?.[ai._cn] : response?.[ai._cn], this.defaultNestedBtQueryParams)
}
if (Array.isArray(response)) {
@ -1765,6 +1773,75 @@ class BaseModelSql extends BaseModel {
return obj;
}
protected get defaultNestedBtQueryParams(): any {
return Object.entries(this.defaultNestedQueryParams || {}).reduce((paramsObj, [key, val]) => {
if (key.startsWith('bfield') || key.startsWith('bf') || key === 'bt') {
return {...paramsObj, [key]: val}
}
return paramsObj;
}, {})
}
protected get defaultNestedQueryParams(): any {
// generate default nested fields args based on virtual column list
try {
const nestedFields: {
[key: string]: string[]
} = (this.virtualColumns || []).reduce((obj, vc) => {
if (vc.hm) {
obj.hm.push(vc.hm.tn)
} else if (vc.bt) {
obj.bt.push(vc.bt.rtn)
} else if (vc.mm) {
obj.mm.push(vc.mm.rtn)
}
return obj
}, {hm: [], bt: [], mm: []})
// todo: handle if virtual column missing
// construct fields args based on lookup columns
const fieldsObj = (this.virtualColumns || []).reduce((obj, vc) => {
if (!vc.lk) {
return obj
}
let key
let index
let column
switch (vc.lk.type) {
case 'mm':
index = nestedFields.mm.indexOf(vc.lk.ltn) + 1
key = `mfields${index}`
column = vc.lk.lcn
break
case 'hm':
index = nestedFields.hm.indexOf(vc.lk.ltn) + 1
key = `hfields${index}`
column = vc.lk.lcn
break
case 'bt':
index = nestedFields.bt.indexOf(vc.lk.ltn) + 1
key = `bfields${index}`
column = vc.lk.lcn
break
}
if (index && column) {
obj[key] = `${obj[key] ? `${obj[key]},` : ''}${column}`
}
return obj
}, {})
return {
...Object.entries(nestedFields).reduce((ro, [k, a]) => ({...ro, [k]: a.join(',')}), {}),
...fieldsObj
}
} catch (e) {
return {}
}
}
}

15
packages/nocodb/src/lib/noco/common/BaseModel.ts

@ -76,12 +76,25 @@ class BaseModel<T extends BaseApiBuilder<any>> extends BaseModelSql {
await this.handleHooks('after.delete', data, req)
}
private async handleHooks(hookName, data, req): Promise<void> {
private async handleHooks(hookName, _data, req): Promise<void> {
let data = _data;
try {
if (this.tn in this.builder.hooks
&& hookName in this.builder.hooks[this.tn]
&& this.builder.hooks[this.tn][hookName]
) {
if (hookName === 'after.update') {
try {
data = await this.nestedRead(req.params.id, this.defaultNestedQueryParams)
} catch (_) {
/* ignore */
}
}
for (const hook of this.builder.hooks[this.tn][hookName]) {
if (!hook.active) {
continue

Loading…
Cancel
Save