diff --git a/packages/nc-gui/components/project/spreadsheet/components/spreadsheetNavDrawer.vue b/packages/nc-gui/components/project/spreadsheet/components/spreadsheetNavDrawer.vue
index c637939b25..51db48b1a0 100644
--- a/packages/nc-gui/components/project/spreadsheet/components/spreadsheetNavDrawer.vue
+++ b/packages/nc-gui/components/project/spreadsheet/components/spreadsheetNavDrawer.vue
@@ -470,6 +470,7 @@
Create templates from multiple Excel files
+
+
onUidtChange(col.uidt,v,col,table)"
>
@@ -261,7 +265,7 @@
>
onRtnChange(col.rtn,v, col, table)"
/>
|
-
-
-
-
+
+
+
+
+ onRTypeChange(col.type, v, col,table)"
+ />
+
|
mdi-delete
@@ -615,7 +623,7 @@ export default {
return {
...this.project,
tables: (this.project.tables || []).map((t) => {
- const table = { tn: t.tn, columns: [], hasMany: [], manyToMany: [], v: [] }
+ const table = { tn: t.tn, columns: [], hasMany: [], manyToMany: [], belongsTo: [], v: [] }
for (const column of (t.columns || [])) {
if (this.isRelation(column)) {
@@ -629,6 +637,11 @@ export default {
rtn: column.rtn,
_cn: column.cn
})
+ } else if (column.uidt === UITypes.ForeignKey) {
+ table.belongsTo.push({
+ tn: column.rtn,
+ _cn: column.cn
+ })
}
} else if (this.isLookup(column)) {
if (column.rtn) {
@@ -745,9 +758,29 @@ export default {
}
this.project.tables.splice(i, 1)
},
- deleteTableColumn(i, j) {
+ deleteTableColumn(i, j, col, table) {
const deleteTable = this.project.tables[i]
const deleteColumn = deleteTable.columns[j]
+
+ let rTable, index
+ // if relation column, delete the corresponding relation from other table
+ if (col.uidt === UITypes.LinkToAnotherRecord) {
+ if (col.type === 'hm') {
+ rTable = this.project.tables.find(t => t.tn === col.rtn)
+ index = rTable && rTable.columns.findIndex(c => c.uidt === UITypes.ForeignKey && c.rtn === table.tn)
+ } else if (col.type === 'mm') {
+ rTable = this.project.tables.find(t => t.tn === col.rtn)
+ index = rTable && rTable.columns.findIndex(c => c.uidt === UITypes.LinkToAnotherRecord && c.rtn === table.tn && c.type === 'mm')
+ }
+ } else if (col.uidt === UITypes.ForeignKey) {
+ rTable = this.project.tables.find(t => t.tn === col.rtn)
+ index = rTable && rTable.columns.findIndex(c => c.uidt === UITypes.LinkToAnotherRecord && c.rtn === table.tn && c.type === 'hm')
+ }
+
+ if (rTable && index > -1) {
+ rTable.columns.splice(index, 1)
+ }
+
for (const table of this.project.tables) {
if (table === deleteTable) {
continue
@@ -778,8 +811,8 @@ export default {
})).filter((v, i, arr) => i === arr.findIndex(c => c.cn === v.cn))
})
}
- this.tableNamesInput = ''
this.createTablesDialog = false
+ this.tableNamesInput = ''
},
compareRel(a, b) {
return ((a && a.tn) || a) === ((b && b.tn) || b) && (a && a.type) === (b && b.type)
@@ -939,7 +972,7 @@ export default {
parseTemplate({ tables = [], ...rest }) {
const parsedTemplate = {
...rest,
- tables: tables.map(({ manyToMany, hasMany, v, columns, ...rest }) => ({
+ tables: tables.map(({ manyToMany = [], hasMany = [], belongsTo = [], v = [], columns = [], ...rest }) => ({
...rest,
columns: [
...columns,
@@ -956,6 +989,12 @@ export default {
rtn: hm.tn,
...hm
})),
+ ...belongsTo.map(bt => ({
+ cn: bt._cn || `${rest.tn} => ${bt.rtn}`,
+ uidt: UITypes.ForeignKey,
+ rtn: bt.tn,
+ ...bt
+ })),
...v.map((v) => {
const res = {
cn: v._cn,
@@ -1041,11 +1080,6 @@ export default {
this.$toast.error(e.message).goAway(5000)
}
},
- onUidtChange(col) {
- if (col.uidt === LinkToAnotherRecord) {
- col.type = 'mm'
- }
- },
navigateToTable(tn) {
const index = this.projectTemplate.tables.findIndex(t => t.tn === tn)
if (Array.isArray(this.expansionPanel)) {
@@ -1132,6 +1166,128 @@ export default {
}
}
}
+ },
+ async onRtnChange(oldVal, newVal, col, table) {
+ this.$set(col, 'rtn', newVal)
+
+ await this.$nextTick()
+
+ if (col.uidt !== UITypes.LinkToAnotherRecord && col.uidt !== UITypes.ForeignKey) {
+ return
+ }
+
+ if (oldVal) {
+ const rTable = this.project.tables.find(t => t.tn === oldVal)
+ // delete relation from other table if exist
+
+ let index = -1
+ if (col.uidt === UITypes.LinkToAnotherRecord && col.type === 'mm') {
+ index = rTable.columns.findIndex(c => c.uidt === UITypes.LinkToAnotherRecord && c.rtn === table.tn && c.type === 'mm')
+ } else if (col.uidt === UITypes.LinkToAnotherRecord && col.type === 'hm') {
+ index = rTable.columns.findIndex(c => c.uidt === UITypes.ForeignKey && c.rtn === table.tn)
+ } else if (col.uidt === UITypes.ForeignKey) {
+ index = rTable.columns.findIndex(c => c.uidt === UITypes.LinkToAnotherRecord && c.rtn === table.tn && c.type === 'hm')
+ }
+
+ if (index > -1) {
+ rTable.columns.splice(index, 1)
+ }
+ }
+ if (newVal) {
+ const rTable = this.project.tables.find(t => t.tn === newVal)
+
+ // check relation relation exist in other table
+ // if not create a relation
+ if (col.uidt === UITypes.LinkToAnotherRecord && col.type === 'mm') {
+ if (!rTable.columns.find(c => c.uidt === UITypes.LinkToAnotherRecord && c.rtn === table.tn && c.type === 'mm')) {
+ rTable.columns.push({
+ cn: `title${rTable.columns.length + 1}`,
+ uidt: UITypes.LinkToAnotherRecord,
+ type: 'mm',
+ rtn: table.tn
+ })
+ }
+ } else if (col.uidt === UITypes.LinkToAnotherRecord && col.type === 'hm') {
+ if (!rTable.columns.find(c => c.uidt === UITypes.ForeignKey && c.rtn === table.tn)) {
+ rTable.columns.push({
+ cn: `title${rTable.columns.length + 1}`,
+ uidt: UITypes.ForeignKey,
+ rtn: table.tn
+ })
+ }
+ } else if (col.uidt === UITypes.ForeignKey) {
+ if (!rTable.columns.find(c => c.uidt === UITypes.LinkToAnotherRecord && c.rtn === table.tn && c.type === 'hm')) {
+ rTable.columns.push({
+ cn: `title${rTable.columns.length + 1}`,
+ uidt: UITypes.LinkToAnotherRecord,
+ type: 'hm',
+ rtn: table.tn
+ })
+ }
+ }
+ }
+ },
+ onRTypeChange(oldType, newType, col, table) {
+ this.$set(col, 'type', newType)
+
+ const rTable = this.project.tables.find(t => t.tn === col.rtn)
+
+ let index = -1
+
+ // find column and update relation
+ // or create a new column
+
+ if (oldType === 'hm') {
+ index = rTable.columns.findIndex(c => c.uidt === UITypes.ForeignKey && c.rtn === table.tn)
+ } else if (oldType === 'mm') {
+ index = rTable.columns.findIndex(c => c.uidt === UITypes.LinkToAnotherRecord && c.rtn === table.tn && c.type === 'mm')
+ }
+
+ const rCol = index === -1 ? { cn: `title${rTable.columns.length + 1}` } : { ...rTable.columns[index] }
+ index = index === -1 ? rTable.columns.length : index
+
+ if (newType === 'mm') {
+ rCol.type = 'mm'
+ rCol.uidt = UITypes.LinkToAnotherRecord
+ } else if (newType === 'hm') {
+ rCol.type = 'bt'
+ rCol.uidt = UITypes.ForeignKey
+ }
+ rCol.rtn = table.tn
+
+ this.$set(rTable.columns, index, rCol)
+ },
+ onUidtChange(oldVal, newVal, col, table) {
+ this.$set(col, 'uidt', newVal)
+
+ // delete relation column from other table
+ // if previous type is relation
+
+ let index = -1
+ let rTable
+
+ if (oldVal === UITypes.LinkToAnotherRecord) {
+ rTable = this.project.tables.find(t => t.tn === col.rtn)
+ if (col.type === 'hm') {
+ index = rTable.columns.findIndex(c => c.uidt === UITypes.ForeignKey && c.rtn === table.tn)
+ } else if (col.type === 'mm') {
+ index = rTable.columns.findIndex(c => c.uidt === UITypes.LinkToAnotherRecord && c.rtn === table.tn && c.type === 'mm')
+ }
+ } else if (oldVal === UITypes.ForeignKey) {
+ rTable = this.project.tables.find(t => t.tn === col.rtn)
+ index = rTable.columns.findIndex(c => c.uidt === UITypes.LinkToAnotherRecord && c.rtn === table.tn && c.type === 'hm')
+ }
+ if (rTable && index > -1) {
+ rTable.columns.splice(index, 1)
+ }
+
+ col.rtn = undefined
+ col.type = undefined
+ col.rcn = undefined
+
+ if (col.uidt === LinkToAnotherRecord) {
+ col.type = col.type || 'mm'
+ }
}
}
}
diff --git a/packages/nc-gui/components/templates/list.vue b/packages/nc-gui/components/templates/list.vue
index 156eed09f3..72a26f8695 100644
--- a/packages/nc-gui/components/templates/list.vue
+++ b/packages/nc-gui/components/templates/list.vue
@@ -12,6 +12,7 @@
+ {{ category }}
column.uidt === UITypes.ID
);
+ //
+ // // if duplicate relation ignore
+ // if (
+ // this._relations.some(rl => {
+ // return (
+ // (rl.childTable === childTable.tn &&
+ // rl.parentTable === parentTable.tn) ||
+ // (rl.parentTable === childTable.tn &&
+ // rl.childTable === parentTable.tn)
+ // );
+ // })
+ // ) {
+ // continue;f
+ // }
// add a column in child table
const childColumnName = `${tableTemplate.tn}_id`;
@@ -176,6 +190,20 @@ export default class NcTemplateParser {
column => column.uidt === UITypes.ID
);
+ // if duplicate relation ignore
+ if (
+ this._m2mRelations.some(mm => {
+ return (
+ (mm.childTable === childTable.tn &&
+ mm.parentTable === parentTable.tn) ||
+ (mm.parentTable === childTable.tn &&
+ mm.childTable === parentTable.tn)
+ );
+ })
+ ) {
+ continue;
+ }
+
// add many to many relation create entry
this._m2mRelations.push({
alias: 'title8',
|