Browse Source

Merge pull request #1333 from nocodb/fix/issue1299

fix: bt & hm logic
pull/1356/head
աɨռɢӄաօռɢ 2 years ago committed by GitHub
parent
commit
8c1564943a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 34
      packages/nc-gui/components/project/spreadsheet/components/virtualCell/belongsToCell.vue
  2. 5
      packages/nc-gui/components/project/spreadsheet/components/virtualCell/components/listItems.vue
  3. 40
      packages/nc-gui/components/project/spreadsheet/components/virtualCell/hasManyCell.vue
  4. 3
      packages/nocodb/src/lib/dataMapper/lib/sql/BaseModelSql.ts

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

@ -34,7 +34,10 @@
:primary-col="parentPrimaryCol" :primary-col="parentPrimaryCol"
:primary-key="parentPrimaryKey" :primary-key="parentPrimaryKey"
:api="parentApi" :api="parentApi"
:query-params="parentQueryParams" :query-params="{
...parentQueryParams,
where: isNew ? null :`${btWhereClause}`,
}"
:is-public="isPublic" :is-public="isPublic"
:tn="bt && bt.rtn" :tn="bt && bt.rtn"
:password="password" :password="password"
@ -106,6 +109,7 @@
import ListItems from '@/components/project/spreadsheet/components/virtualCell/components/listItems' import ListItems from '@/components/project/spreadsheet/components/virtualCell/components/listItems'
import ListChildItems from '@/components/project/spreadsheet/components/virtualCell/components/listChildItems' import ListChildItems from '@/components/project/spreadsheet/components/virtualCell/components/listChildItems'
import ItemChip from '~/components/project/spreadsheet/components/virtualCell/components/itemChip' import ItemChip from '~/components/project/spreadsheet/components/virtualCell/components/itemChip'
import { parseIfInteger } from '@/helpers'
export default { export default {
name: 'BelongsToCell', name: 'BelongsToCell',
@ -173,6 +177,20 @@ export default {
parentPrimaryKey() { parentPrimaryKey() {
return this.parentMeta && (this.parentMeta.columns.find(c => c.pk) || {})._cn return this.parentMeta && (this.parentMeta.columns.find(c => c.pk) || {})._cn
}, },
parentReferenceKey() {
return this.parentMeta && (this.parentMeta.columns.find(c => c.cn === this.bt.rcn) || {})._cn
},
btWhereClause() {
// if parent reference key is pk, then filter out the selected value
// else, filter out the selected value + empty values (as we can't set an empty value)
const prk = this.parentReferenceKey
const isPk = !!(this.parentMeta && (this.parentMeta.columns.find(c => c.pk && c._cn === prk))) || false
let selectedValue = this.meta && this.meta.columns ? this.meta.columns.filter(c => c.cn === this.bt.cn).map(c => this.row[c._cn] || '').join('___') : ''
if (this.parentMeta && (this.parentMeta.columns.find(c => c._cn === prk)).type !== 'string') {
selectedValue = selectedValue || 0
}
return `(${prk},not,${selectedValue})` + (!isPk ? `~and(${prk},not,)` : '')
},
parentQueryParams() { parentQueryParams() {
if (!this.parentMeta) { if (!this.parentMeta) {
return {} return {}
@ -211,7 +229,7 @@ export default {
return Object.values(this.value || this.localState)[1] return Object.values(this.value || this.localState)[1]
} }
return null return null
} },
}, },
watch: { watch: {
isNew(n, o) { isNew(n, o) {
@ -319,11 +337,11 @@ export default {
const pid = pkColumns.map(c => parent[c._cn]).join('___') const pid = pkColumns.map(c => parent[c._cn]).join('___')
const id = this.meta.columns.filter(c => c.pk).map(c => this.row[c._cn]).join('___') const id = this.meta.columns.filter(c => c.pk).map(c => this.row[c._cn]).join('___')
const _cn = this.meta.columns.find(c => c.cn === this.bt.cn)._cn const _cn = this.meta.columns.find(c => c.cn === this.bt.cn)._cn
let isNum = false // let isNum = false
if (pkColumns.length === 1) { // if (pkColumns.length === 1) {
isNum = ['float', 'integer'].includes(this.sqlUi.getAbstractType(pkColumns[0])) // isNum = ['float', 'integer'].includes(this.sqlUi.getAbstractType(pkColumns[0]))
} // }
if (this.isNew) { if (this.isNew) {
this.localState = parent this.localState = parent
@ -332,9 +350,8 @@ export default {
this.newRecordModal = false this.newRecordModal = false
return return
} }
await this.api.update(id, { await this.api.update(id, {
[_cn]: isNum ? +pid : pid [_cn]: parseIfInteger(parent[this.parentReferenceKey])
}, { }, {
[_cn]: this.value && this.value[this.parentPrimaryKey] [_cn]: this.value && this.value[this.parentPrimaryKey]
}) })
@ -413,6 +430,7 @@ export default {
* @author Naveen MR <oof1lab@gmail.com> * @author Naveen MR <oof1lab@gmail.com>
* @author Pranav C Balan <pranavxc@gmail.com> * @author Pranav C Balan <pranavxc@gmail.com>
* @author Md Ishtiaque Zafar <ishtiaque.zafar92@gmail.com> * @author Md Ishtiaque Zafar <ishtiaque.zafar92@gmail.com>
* @author Wing-Kam Wong <wingkwong.code@gmail.com>
* *
* @license GNU AGPL version 3 or any later version * @license GNU AGPL version 3 or any later version
* *

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

@ -151,7 +151,10 @@ export default {
if (!this.api) { if (!this.api) {
return return
} }
const isByPass = this.queryParams.isByPass || false
if (isByPass) {
return
}
let where = this.queryParams.where || '' let where = this.queryParams.where || ''
if (this.query) { if (this.query) {
where += (where ? '~and' : '') + `(${this.primaryCol},like,%${this.query}%)` where += (where ? '~and' : '') + `(${this.primaryCol},like,%${this.query}%)`

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

@ -2,7 +2,7 @@
<div class="d-flex d-100 chips-wrapper" :class="{active}"> <div class="d-flex d-100 chips-wrapper" :class="{active}">
<template v-if="!isForm"> <template v-if="!isForm">
<div class="chips d-flex align-center img-container flex-grow-1 hm-items"> <div class="chips d-flex align-center img-container flex-grow-1 hm-items">
<template v-if="value||localState"> <template v-if="value|| localState">
<item-chip <item-chip
v-for="(ch,i) in (value|| localState)" v-for="(ch,i) in (value|| localState)"
:key="i" :key="i"
@ -54,7 +54,16 @@
:parent-meta="meta" :parent-meta="meta"
:query-params="{ :query-params="{
...childQueryParams, ...childQueryParams,
where: isNew ? null :`~not(${childForeignKey},eq,${parentId})~or(${childForeignKey},is,null)`, // check if it needs to bypass to
// avoid foreign key constraint violation in real relation
isByPass,
where:
// show all for new record
isNew ? null :
// filter out those selected items
`~not(${childForeignKey},eq,${parentId})` +
// allow the child with empty key
'~or(' + childForeignKey + ',is,null)'
}" }"
:is-public="isPublic" :is-public="isPublic"
:password="password" :password="password"
@ -142,7 +151,7 @@ import Pagination from '@/components/project/spreadsheet/components/pagination'
import ListItems from '@/components/project/spreadsheet/components/virtualCell/components/listItems' import ListItems from '@/components/project/spreadsheet/components/virtualCell/components/listItems'
import ListChildItems from '@/components/project/spreadsheet/components/virtualCell/components/listChildItems' import ListChildItems from '@/components/project/spreadsheet/components/virtualCell/components/listChildItems'
import listChildItemsModal import listChildItemsModal
from '@/components/project/spreadsheet/components/virtualCell/components/listChildItemsModal' from '@/components/project/spreadsheet/components/virtualCell/components/listChildItemsModal'
import { parseIfInteger } from '@/helpers' import { parseIfInteger } from '@/helpers'
import ItemChip from '~/components/project/spreadsheet/components/virtualCell/components/itemChip' import ItemChip from '~/components/project/spreadsheet/components/virtualCell/components/itemChip'
@ -221,6 +230,23 @@ export default {
childForeignKey() { childForeignKey() {
return this.childMeta && (this.childMeta.columns.find(c => c.cn === this.hm.cn) || {})._cn return this.childMeta && (this.childMeta.columns.find(c => c.cn === this.hm.cn) || {})._cn
}, },
childForeignKeyVal() {
return this.meta && this.meta.columns ? this.meta.columns.filter(c => c._cn === this.childForeignKey).map(c => this.row[c._cn] || '').join('___') : ''
},
isVirtualRelation() {
return (this.childMeta && (!!this.childMeta.columns.find(c => c.cn === this.hm.cn && this.hm.type === 'virtual'))) || false
},
isByPass() {
if (this.isVirtualRelation) {
return false
}
// if child fk references a column in parent which is not pk,
// then this column has to be filled
if (((this.meta && this.meta.columns.find(c => !c.pk && c.cn === this.hm.rcn)) || false)) {
return this.childForeignKeyVal === ''
}
return false
},
disabledChildColumns() { disabledChildColumns() {
return { [this.childForeignKey]: true } return { [this.childForeignKey]: true }
}, },
@ -251,7 +277,9 @@ export default {
} }
}, },
parentId() { parentId() {
return this.meta && this.meta.columns ? this.meta.columns.filter(c => c.pk).map(c => this.row[c._cn]).join('___') : '' return (this.meta && this.meta.columns &&
(this.meta.columns.filter(c => c._cn === this.childForeignKey).map(c => this.row[c._cn] || '').join('___') ||
this.meta.columns.filter(c => c.pk).map(c => this.row[c._cn]).join('___'))) || ''
} }
}, },
watch: { watch: {
@ -358,7 +386,6 @@ export default {
const id = this.childMeta.columns.filter(c => c.pk).map(c => child[c._cn]).join('___') const id = this.childMeta.columns.filter(c => c.pk).map(c => child[c._cn]).join('___')
const _cn = this.childForeignKey const _cn = this.childForeignKey
this.newRecordModal = false this.newRecordModal = false
await this.childApi.update(id, { await this.childApi.update(id, {
[_cn]: parseIfInteger(this.parentId) [_cn]: parseIfInteger(this.parentId)
}, { }, {
@ -367,7 +394,7 @@ export default {
this.$emit('loadTableData') this.$emit('loadTableData')
if ((this.childListModal || this.isForm) && this.$refs.childList) { if ((this.childListModal || this.isForm) && this.$refs.childList) {
this.$refs.childList.loadData() await this.$refs.childList.loadData()
} }
}, },
async editChild(child) { async editChild(child) {
@ -496,6 +523,7 @@ export default {
* *
* @author Naveen MR <oof1lab@gmail.com> * @author Naveen MR <oof1lab@gmail.com>
* @author Pranav C Balan <pranavxc@gmail.com> * @author Pranav C Balan <pranavxc@gmail.com>
* @author Wing-Kam Wong <wingkwong.code@gmail.com>
* *
* @license GNU AGPL version 3 or any later version * @license GNU AGPL version 3 or any later version
* *

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

@ -1279,6 +1279,7 @@ class BaseModelSql extends BaseModel {
driver.union( driver.union(
parent.map(p => { parent.map(p => {
const id = const id =
p[_cn] ||
p[this.columnToAlias?.[this.pks[0].cn] || this.pks[0].cn] || p[this.columnToAlias?.[this.pks[0].cn] || this.pks[0].cn] ||
p[this.pks[0].cn]; p[this.pks[0].cn];
const query = driver(this.dbModels[child].tnPath) const query = driver(this.dbModels[child].tnPath)
@ -1296,7 +1297,7 @@ class BaseModelSql extends BaseModel {
const gs = _.groupBy(childs, _cn); const gs = _.groupBy(childs, _cn);
parent.forEach(row => { parent.forEach(row => {
row[`${this.dbModels?.[child]?._tn || child}List`] = row[`${this.dbModels?.[child]?._tn || child}List`] =
gs[row[this.pks[0]._cn]] || []; gs[row[_cn] || row[this.pks[0]._cn]] || [];
}); });
} }

Loading…
Cancel
Save