|
|
@ -4,9 +4,22 @@ |
|
|
|
<template v-if="value"> |
|
|
|
<template v-if="value"> |
|
|
|
<v-chip |
|
|
|
<v-chip |
|
|
|
small |
|
|
|
small |
|
|
|
v-for="(v,i) in value.map(v=>Object.values(v)[1])" |
|
|
|
v-for="(ch,i) in value" |
|
|
|
:color="colors[i%colors.length]" :key="i"> |
|
|
|
:key="i" |
|
|
|
{{ v }} |
|
|
|
:color="colors[i%colors.length]" |
|
|
|
|
|
|
|
@click="editChild(ch)" |
|
|
|
|
|
|
|
> |
|
|
|
|
|
|
|
{{ Object.values(ch)[1] }} |
|
|
|
|
|
|
|
<div v-show="active" class="mr-n1 ml-2 mt-n1"> |
|
|
|
|
|
|
|
<x-icon |
|
|
|
|
|
|
|
:color="['text' , 'textLight']" |
|
|
|
|
|
|
|
x-small |
|
|
|
|
|
|
|
icon.class="unlink-icon" |
|
|
|
|
|
|
|
@click.stop="unlinkChild(ch)" |
|
|
|
|
|
|
|
>mdi-close-thick |
|
|
|
|
|
|
|
</x-icon> |
|
|
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
</v-chip> |
|
|
|
</v-chip> |
|
|
|
</template> |
|
|
|
</template> |
|
|
|
</div> |
|
|
|
</div> |
|
|
@ -15,36 +28,40 @@ |
|
|
|
<x-icon x-small :color="['primary','grey']" @click="showChildListModal" class="ml-2">mdi-arrow-expand</x-icon> |
|
|
|
<x-icon x-small :color="['primary','grey']" @click="showChildListModal" class="ml-2">mdi-arrow-expand</x-icon> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
<!-- <list-items |
|
|
|
<!-- <list-items |
|
|
|
:count="10" |
|
|
|
:count="10" |
|
|
|
:meta="childMeta" |
|
|
|
:meta="childMeta" |
|
|
|
:primary-col="childPrimaryCol" |
|
|
|
:primary-col="childPrimaryCol" |
|
|
|
:primary-key="childPrimaryKey" |
|
|
|
:primary-key="childPrimaryKey" |
|
|
|
v-model="newRecordModal" |
|
|
|
v-model="newRecordModal" |
|
|
|
:api="childApi" |
|
|
|
:api="childApi" |
|
|
|
></list-items>--> |
|
|
|
></list-items>--> |
|
|
|
<v-dialog v-if="newRecordModal" v-model="newRecordModal" width="600"> |
|
|
|
<v-dialog v-if="newRecordModal" v-model="newRecordModal" width="600"> |
|
|
|
<v-card width="600" color="backgroundColor"> |
|
|
|
<v-card width="600" color="backgroundColor"> |
|
|
|
<v-card-title class="textColor--text mx-2">Add Record |
|
|
|
<v-card-title class="textColor--text mx-2 justify-center">Link Record |
|
|
|
<v-spacer> |
|
|
|
|
|
|
|
</v-spacer> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<v-btn small class="caption" color="primary"> |
|
|
|
|
|
|
|
<v-icon small>mdi-plus</v-icon> |
|
|
|
|
|
|
|
Add New Record |
|
|
|
|
|
|
|
</v-btn> |
|
|
|
|
|
|
|
</v-card-title> |
|
|
|
</v-card-title> |
|
|
|
<v-card-text> |
|
|
|
|
|
|
|
|
|
|
|
<v-card-title> |
|
|
|
<v-text-field |
|
|
|
<v-text-field |
|
|
|
hide-details |
|
|
|
hide-details |
|
|
|
dense |
|
|
|
dense |
|
|
|
outlined |
|
|
|
outlined |
|
|
|
placeholder="Search record" |
|
|
|
placeholder="Search records" |
|
|
|
class="mb-2 mx-2 caption" |
|
|
|
class=" caption search-field ml-2" |
|
|
|
/> |
|
|
|
/> |
|
|
|
|
|
|
|
<v-spacer></v-spacer> |
|
|
|
|
|
|
|
<v-btn small class="caption mr-2" color="primary" @click="insertAndAddNewChildRecord"> |
|
|
|
|
|
|
|
<v-icon small>mdi-plus</v-icon> |
|
|
|
|
|
|
|
New Record |
|
|
|
|
|
|
|
</v-btn> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</v-card-title> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<v-card-text> |
|
|
|
|
|
|
|
|
|
|
|
<div class="items-container"> |
|
|
|
<div class="items-container"> |
|
|
|
<template v-if="list"> |
|
|
|
<template v-if="list && list.list && list.list.length"> |
|
|
|
<v-card |
|
|
|
<v-card |
|
|
|
v-for="(ch,i) in list.list" |
|
|
|
v-for="(ch,i) in list.list" |
|
|
|
class="ma-2 child-card" |
|
|
|
class="ma-2 child-card" |
|
|
@ -53,20 +70,29 @@ |
|
|
|
@click="addChildToParent(ch)" |
|
|
|
@click="addChildToParent(ch)" |
|
|
|
:key="i" |
|
|
|
:key="i" |
|
|
|
> |
|
|
|
> |
|
|
|
<v-card-title class="primary-value textColor--text text--lighten-2">{{ ch[childPrimaryCol] }} |
|
|
|
<v-card-text class="primary-value textColor--text text--lighten-2 d-flex"> |
|
|
|
<span class="grey--text caption primary-key" |
|
|
|
<span class="font-weight-bold"> {{ ch[childPrimaryCol] }}</span> |
|
|
|
|
|
|
|
<span class="grey--text caption primary-key " |
|
|
|
v-if="childPrimaryKey">(Primary Key : {{ ch[childPrimaryKey] }})</span> |
|
|
|
v-if="childPrimaryKey">(Primary Key : {{ ch[childPrimaryKey] }})</span> |
|
|
|
</v-card-title> |
|
|
|
<v-spacer/> |
|
|
|
|
|
|
|
<v-chip v-if="ch[meta._tn]" x-small> |
|
|
|
|
|
|
|
{{ ch[meta._tn][primaryCol] }} |
|
|
|
|
|
|
|
</v-chip> |
|
|
|
|
|
|
|
</v-card-text> |
|
|
|
</v-card> |
|
|
|
</v-card> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</template> |
|
|
|
</template> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div v-else class="text-center py-15 textLight--text"> |
|
|
|
|
|
|
|
No items found |
|
|
|
|
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</v-card-text> |
|
|
|
</v-card-text> |
|
|
|
<v-card-actions class="justify-center py-2 flex-column"> |
|
|
|
<v-card-actions class="justify-center py-2 flex-column"> |
|
|
|
|
|
|
|
|
|
|
|
<pagination |
|
|
|
<pagination |
|
|
|
v-if="list" |
|
|
|
v-if="list && list.list && list.list.length" |
|
|
|
:size="listPagination.size" |
|
|
|
:size="listPagination.size" |
|
|
|
:count="list.count" |
|
|
|
:count="list.count" |
|
|
|
v-model="listPagination.page" |
|
|
|
v-model="listPagination.page" |
|
|
@ -164,7 +190,7 @@ |
|
|
|
:has-many="childMeta.hasMany" |
|
|
|
:has-many="childMeta.hasMany" |
|
|
|
:belongs-to="childMeta.belongsTo" |
|
|
|
:belongs-to="childMeta.belongsTo" |
|
|
|
@cancel="selectedChild = null" |
|
|
|
@cancel="selectedChild = null" |
|
|
|
@input="$emit('loadTableData');showChildListModal();" |
|
|
|
@input="$emit('loadTableData');loadChildList();" |
|
|
|
:table="childMeta.tn" |
|
|
|
:table="childMeta.tn" |
|
|
|
v-model="selectedChild" |
|
|
|
v-model="selectedChild" |
|
|
|
:old-row="{...selectedChild}" |
|
|
|
:old-row="{...selectedChild}" |
|
|
@ -176,8 +202,11 @@ |
|
|
|
icon-color="warning" |
|
|
|
icon-color="warning" |
|
|
|
:nodes="nodes" |
|
|
|
:nodes="nodes" |
|
|
|
:query-params="childQueryParams" |
|
|
|
:query-params="childQueryParams" |
|
|
|
|
|
|
|
ref="expandedForm" |
|
|
|
|
|
|
|
:is-new="isNewChild" |
|
|
|
|
|
|
|
:disabled-columns="disabledChildColumns" |
|
|
|
></component> |
|
|
|
></component> |
|
|
|
{{childQueryParams}} |
|
|
|
{{ childQueryParams }} |
|
|
|
|
|
|
|
|
|
|
|
</v-dialog> |
|
|
|
</v-dialog> |
|
|
|
|
|
|
|
|
|
|
@ -204,7 +233,8 @@ export default { |
|
|
|
nodes: [Object], |
|
|
|
nodes: [Object], |
|
|
|
row: [Object], |
|
|
|
row: [Object], |
|
|
|
sqlUi: [Object, Function], |
|
|
|
sqlUi: [Object, Function], |
|
|
|
active: Boolean |
|
|
|
active: Boolean, |
|
|
|
|
|
|
|
isNew: Boolean |
|
|
|
}, |
|
|
|
}, |
|
|
|
data: () => ({ |
|
|
|
data: () => ({ |
|
|
|
newRecordModal: false, |
|
|
|
newRecordModal: false, |
|
|
@ -224,13 +254,17 @@ export default { |
|
|
|
childListPagination: { |
|
|
|
childListPagination: { |
|
|
|
page: 1, |
|
|
|
page: 1, |
|
|
|
size: 10 |
|
|
|
size: 10 |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
isNewChild: false |
|
|
|
}), |
|
|
|
}), |
|
|
|
|
|
|
|
|
|
|
|
methods: { |
|
|
|
methods: { |
|
|
|
async showChildListModal() { |
|
|
|
async showChildListModal() { |
|
|
|
this.childListModal = true; |
|
|
|
this.childListModal = true; |
|
|
|
await this.getChildMeta(); |
|
|
|
await this.loadChildMeta(); |
|
|
|
|
|
|
|
await this.loadChildList(); |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
async loadChildList() { |
|
|
|
const pid = this.meta.columns.filter((c) => c.pk).map(c => this.row[c._cn]).join('___'); |
|
|
|
const pid = this.meta.columns.filter((c) => c.pk).map(c => this.row[c._cn]).join('___'); |
|
|
|
const _cn = this.childMeta.columns.find(c => c.cn === this.hm.cn)._cn; |
|
|
|
const _cn = this.childMeta.columns.find(c => c.cn === this.hm.cn)._cn; |
|
|
|
this.childList = await this.childApi.paginatedList({ |
|
|
|
this.childList = await this.childApi.paginatedList({ |
|
|
@ -239,6 +273,7 @@ export default { |
|
|
|
offset: this.childListPagination.size * (this.childListPagination.page - 1), |
|
|
|
offset: this.childListPagination.size * (this.childListPagination.page - 1), |
|
|
|
...this.childQueryParams |
|
|
|
...this.childQueryParams |
|
|
|
}) |
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
}, |
|
|
|
}, |
|
|
|
async deleteChild(child) { |
|
|
|
async deleteChild(child) { |
|
|
|
this.dialogShow = true; |
|
|
|
this.dialogShow = true; |
|
|
@ -257,23 +292,30 @@ export default { |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
}, |
|
|
|
async unlinkChild(child) { |
|
|
|
async unlinkChild(child) { |
|
|
|
// todo: |
|
|
|
|
|
|
|
// this.dialogShow = true; |
|
|
|
// this.dialogShow = true; |
|
|
|
// this.confirmMessage = |
|
|
|
// this.confirmMessage = |
|
|
|
// 'Do you want to delete the record?'; |
|
|
|
// 'Do you want to unlink the record?'; |
|
|
|
// this.confirmAction = async act => { |
|
|
|
// this.confirmAction = async act => { |
|
|
|
// if (act === 'hideDialog') { |
|
|
|
// if (act === 'hideDialog') { |
|
|
|
// this.dialogShow = false; |
|
|
|
// this.dialogShow = false; |
|
|
|
// } else { |
|
|
|
// } else { |
|
|
|
// const id = this.childMeta.columns.filter((c) => c.pk).map(c => child[c._cn]).join('___'); |
|
|
|
await this.loadChildMeta(); |
|
|
|
// await this.childApi.delete(id) |
|
|
|
const column = this.childMeta.columns.find(c => c.cn === this.hm.cn); |
|
|
|
// this.showChildListModal(); |
|
|
|
if (column.rqd) { |
|
|
|
// this.dialogShow = false; |
|
|
|
this.$toast.info('Unlink is not possible, add to another record.').goAway(3000) |
|
|
|
// this.$emit('loadTableData') |
|
|
|
return |
|
|
|
// } |
|
|
|
} |
|
|
|
|
|
|
|
const _cn = column._cn; |
|
|
|
|
|
|
|
const id = this.childMeta.columns.filter((c) => c.pk).map(c => child[c._cn]).join('___'); |
|
|
|
|
|
|
|
await this.childApi.update(id, {[_cn]: null}, child) |
|
|
|
|
|
|
|
this.$emit('loadTableData') |
|
|
|
|
|
|
|
if (this.childListModal) { |
|
|
|
|
|
|
|
this.showChildListModal() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// } |
|
|
|
// } |
|
|
|
// } |
|
|
|
}, |
|
|
|
}, |
|
|
|
async getChildMeta() { |
|
|
|
async loadChildMeta() { |
|
|
|
// todo: optimize |
|
|
|
// todo: optimize |
|
|
|
if (!this.childMeta) { |
|
|
|
if (!this.childMeta) { |
|
|
|
const childTableData = await this.$store.dispatch('sqlMgr/ActSqlOp', [{ |
|
|
|
const childTableData = await this.$store.dispatch('sqlMgr/ActSqlOp', [{ |
|
|
@ -288,32 +330,51 @@ export default { |
|
|
|
}, |
|
|
|
}, |
|
|
|
async showNewRecordModal() { |
|
|
|
async showNewRecordModal() { |
|
|
|
this.newRecordModal = true; |
|
|
|
this.newRecordModal = true; |
|
|
|
await this.getChildMeta(); |
|
|
|
await this.loadChildMeta(); |
|
|
|
|
|
|
|
const _cn = this.childForeignKey; |
|
|
|
this.list = await this.childApi.paginatedList({ |
|
|
|
this.list = await this.childApi.paginatedList({ |
|
|
|
|
|
|
|
...this.childQueryParams, |
|
|
|
limit: this.listPagination.size, |
|
|
|
limit: this.listPagination.size, |
|
|
|
offset: this.listPagination.size * (this.listPagination.page - 1) |
|
|
|
offset: this.listPagination.size * (this.listPagination.page - 1), |
|
|
|
|
|
|
|
where: `~not(${_cn},eq,${this.parentId})~or(${_cn},is,null)` |
|
|
|
}) |
|
|
|
}) |
|
|
|
}, |
|
|
|
}, |
|
|
|
async addChildToParent(child) { |
|
|
|
async addChildToParent(child) { |
|
|
|
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 pid = this.meta.columns.filter((c) => c.pk).map(c => this.row[c._cn]).join('___'); |
|
|
|
const _cn = this.childForeignKey; |
|
|
|
const _cn = this.childMeta.columns.find(c => c.cn === this.hm.cn)._cn; |
|
|
|
|
|
|
|
this.newRecordModal = false; |
|
|
|
this.newRecordModal = false; |
|
|
|
|
|
|
|
|
|
|
|
await this.childApi.update(id, { |
|
|
|
await this.childApi.update(id, { |
|
|
|
[_cn]: pid |
|
|
|
[_cn]: this.parentId |
|
|
|
}, { |
|
|
|
}, { |
|
|
|
[_cn]: child[this.childPrimaryKey] |
|
|
|
[_cn]: child[this.childPrimaryKey] |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
this.$emit('loadTableData') |
|
|
|
this.$emit('loadTableData') |
|
|
|
if(this.childListModal){ |
|
|
|
if (this.childListModal) { |
|
|
|
await this.showChildListModal() |
|
|
|
await this.showChildListModal() |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
}, |
|
|
|
async editChild(child) { |
|
|
|
async editChild(child) { |
|
|
|
|
|
|
|
await this.loadChildMeta(); |
|
|
|
|
|
|
|
this.isNewChild = false; |
|
|
|
this.selectedChild = child; |
|
|
|
this.selectedChild = child; |
|
|
|
this.showExpandModal = true; |
|
|
|
this.showExpandModal = true; |
|
|
|
|
|
|
|
setTimeout(() => { |
|
|
|
|
|
|
|
this.$refs.expandedForm && this.$refs.expandedForm.reload() |
|
|
|
|
|
|
|
}, 500) |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
async insertAndAddNewChildRecord() { |
|
|
|
|
|
|
|
this.newRecordModal = false; |
|
|
|
|
|
|
|
await this.loadChildMeta(); |
|
|
|
|
|
|
|
this.isNewChild = true; |
|
|
|
|
|
|
|
this.selectedChild = { |
|
|
|
|
|
|
|
[this.childForeignKey]: this.parentId |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
this.showExpandModal = true; |
|
|
|
|
|
|
|
setTimeout(() => { |
|
|
|
|
|
|
|
this.$refs.expandedForm && this.$refs.expandedForm.$set(this.$refs.expandedForm.changedColumns, this.childForeignKey, true) |
|
|
|
|
|
|
|
}, 500) |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
}, |
|
|
|
computed: { |
|
|
|
computed: { |
|
|
@ -325,9 +386,18 @@ export default { |
|
|
|
childPrimaryCol() { |
|
|
|
childPrimaryCol() { |
|
|
|
return this.childMeta && (this.childMeta.columns.find(c => c.pv) || {})._cn |
|
|
|
return this.childMeta && (this.childMeta.columns.find(c => c.pv) || {})._cn |
|
|
|
}, |
|
|
|
}, |
|
|
|
|
|
|
|
primaryCol() { |
|
|
|
|
|
|
|
return this.meta && (this.meta.columns.find(c => c.pv) || {})._cn |
|
|
|
|
|
|
|
}, |
|
|
|
childPrimaryKey() { |
|
|
|
childPrimaryKey() { |
|
|
|
return this.childMeta && (this.childMeta.columns.find(c => c.pk) || {})._cn |
|
|
|
return this.childMeta && (this.childMeta.columns.find(c => c.pk) || {})._cn |
|
|
|
}, |
|
|
|
}, |
|
|
|
|
|
|
|
childForeignKey() { |
|
|
|
|
|
|
|
return this.childMeta && this.childMeta.columns.find(c => c.cn === this.hm.cn)._cn |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
disabledChildColumns() { |
|
|
|
|
|
|
|
return {[this.childForeignKey]: true} |
|
|
|
|
|
|
|
}, |
|
|
|
// todo: |
|
|
|
// todo: |
|
|
|
form() { |
|
|
|
form() { |
|
|
|
return () => import("@/components/project/spreadsheet/components/expandedForm") |
|
|
|
return () => import("@/components/project/spreadsheet/components/expandedForm") |
|
|
@ -352,6 +422,9 @@ export default { |
|
|
|
parents: (this.childMeta && this.childMeta.belongsTo && this.childMeta.belongsTo.map(hm => hm.rtn).join()) || '', |
|
|
|
parents: (this.childMeta && this.childMeta.belongsTo && this.childMeta.belongsTo.map(hm => hm.rtn).join()) || '', |
|
|
|
many: (this.childMeta && this.childMeta.manyToMany && this.childMeta.manyToMany.map(mm => mm.rtn).join()) || '' |
|
|
|
many: (this.childMeta && this.childMeta.manyToMany && this.childMeta.manyToMany.map(mm => mm.rtn).join()) || '' |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
parentId() { |
|
|
|
|
|
|
|
return this.meta && this.meta.columns ? this.meta.columns.filter((c) => c.pk).map(c => this.row[c._cn]).join('___') : ''; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -410,6 +483,24 @@ export default { |
|
|
|
margin: 3px auto; |
|
|
|
margin: 3px auto; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
::v-deep { |
|
|
|
|
|
|
|
.unlink-icon { |
|
|
|
|
|
|
|
padding: 0px 1px 2px 1px; |
|
|
|
|
|
|
|
margin-top: 2px; |
|
|
|
|
|
|
|
margin-right: -2px; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.search-field { |
|
|
|
|
|
|
|
input { |
|
|
|
|
|
|
|
max-height: 28px !important; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.v-input__slot { |
|
|
|
|
|
|
|
min-height: auto !important; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
</style> |
|
|
|
</style> |
|
|
|
<!-- |
|
|
|
<!-- |
|
|
|
/** |
|
|
|
/** |
|
|
|