Browse Source

feat: impelement shared grid view(WIP)

Signed-off-by: Pranav C <pranavxc@gmail.com>
pull/655/head
Pranav C 3 years ago
parent
commit
da9da645a6
  1. 7
      packages/nc-gui/components/project/spreadsheet/components/spreadsheetNavDrawer.vue
  2. 4
      packages/nc-gui/components/project/spreadsheet/components/virtualCell.vue
  3. 3
      packages/nc-gui/components/project/spreadsheet/components/virtualCell/belongsToCell.vue
  4. 25
      packages/nc-gui/components/project/spreadsheet/components/virtualCell/components/listChildItems.vue
  5. 10
      packages/nc-gui/components/project/spreadsheet/components/virtualCell/components/listChildItemsModal.vue
  6. 8
      packages/nc-gui/components/project/spreadsheet/components/virtualCell/hasManyCell.vue
  7. 15
      packages/nc-gui/components/project/spreadsheet/components/virtualCell/lookupCell.vue
  8. 6
      packages/nc-gui/components/project/spreadsheet/components/virtualCell/manyToManyCell.vue
  9. 112
      packages/nc-gui/components/project/spreadsheet/public/xcTable.vue
  10. 5
      packages/nc-gui/components/project/spreadsheet/views/xcGridView.vue
  11. 6
      packages/nocodb/src/lib/dataMapper/lib/sql/CustomKnex.ts
  12. 119
      packages/nocodb/src/lib/noco/meta/NcMetaMgr.ts
  13. 8
      packages/nocodb/src/lib/noco/meta/NcMetaMgrEE.ts

7
packages/nc-gui/components/project/spreadsheet/components/spreadsheetNavDrawer.vue

@ -353,10 +353,11 @@
<!-- <v-menu offset-x left>--> <!-- <v-menu offset-x left>-->
<!-- <template v-slot:activator="{on}">--> <!-- <template v-slot:activator="{on}">-->
<!-- v-show="-->
<!-- selectedView && selectedView.show_as === 'form'-->
<!-- "-->
<v-list-item <v-list-item
v-show="
selectedView && selectedView.show_as === 'form'
"
v-if="_isUIAllowed('shareview')" v-if="_isUIAllowed('shareview')"
@click="genShareLink" @click="genShareLink"
> >

4
packages/nc-gui/components/project/spreadsheet/components/virtualCell.vue

@ -18,6 +18,7 @@
:required="required" :required="required"
:is-public="isPublic" :is-public="isPublic"
:metas="metas" :metas="metas"
:column="column"
:password="password" :password="password"
v-on="$listeners" v-on="$listeners"
/> />
@ -38,6 +39,7 @@
:breadcrumbs="breadcrumbs" :breadcrumbs="breadcrumbs"
:is-locked="isLocked" :is-locked="isLocked"
:required="required" :required="required"
:column="column"
:metas="metas" :metas="metas"
:password="password" :password="password"
v-on="$listeners" v-on="$listeners"
@ -60,6 +62,7 @@
:breadcrumbs="breadcrumbs" :breadcrumbs="breadcrumbs"
:is-locked="isLocked" :is-locked="isLocked"
:metas="metas" :metas="metas"
:column="column"
:password="password" :password="password"
v-on="$listeners" v-on="$listeners"
/> />
@ -69,6 +72,7 @@
:active="active" :active="active"
:row="row" :row="row"
:meta="meta" :meta="meta"
:metas="metas"
:nodes="nodes" :nodes="nodes"
:api="api" :api="api"
:sql-ui="sqlUi" :sql-ui="sqlUi"

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

@ -14,7 +14,7 @@
</template> </template>
</div> </div>
<div <div
v-if="!isLocked && _isUIAllowed('xcDatatableEditable')" v-if="!isLocked && _isUIAllowed('xcDatatableEditable') && !isPublic"
class="action align-center justify-center px-1 flex-shrink-1" class="action align-center justify-center px-1 flex-shrink-1"
:class="{'d-none': !active, 'd-flex':active }" :class="{'d-none': !active, 'd-flex':active }"
> >
@ -60,6 +60,7 @@
}" }"
:bt="value" :bt="value"
:is-public="isPublic" :is-public="isPublic"
:row-id="parentId"
@new-record="showNewRecordModal" @new-record="showNewRecordModal"
@edit="editParent" @edit="editParent"
@unlink="unlink" @unlink="unlink"

25
packages/nc-gui/components/project/spreadsheet/components/virtualCell/components/listChildItems.vue

@ -1,6 +1,9 @@
<template> <template>
<!-- <v-dialog v-model="show" width="600">--> <!-- <v-dialog v-model="show" width="600">-->
<v-card width="600" color=""> <v-card width="600" color="">
<pre class="caption">{{ parentMeta }}</pre>
<pre class="caption">{{ meta }}</pre>
<v-card-title v-if="!isForm" class="textColor--text mx-2" :class="{'py-2':isForm}"> <v-card-title v-if="!isForm" class="textColor--text mx-2" :class="{'py-2':isForm}">
<span v-if="!isForm">{{ meta ? meta._tn : 'Children' }}</span> <span v-if="!isForm">{{ meta ? meta._tn : 'Children' }}</span>
<v-spacer /> <v-spacer />
@ -144,7 +147,10 @@ export default {
size: Number, size: Number,
api: [Object, Function], api: [Object, Function],
mm: [Object, Boolean], mm: [Object, Boolean],
isPublic: Boolean isPublic: Boolean,
rowId: [String, Number],
column: Object,
type: String
}, },
data: () => ({ data: () => ({
data: null, data: null,
@ -173,6 +179,23 @@ export default {
}, },
methods: { methods: {
async loadData() { async loadData() {
if (this.isPublic && this.$route.params.id) {
this.data = await this.$store.dispatch('sqlMgr/ActSqlOp', [null, 'sharedViewNestedChildDataGet', {
password: this.password,
limit: this.size,
tn: this.tn,
view_id: this.$route.params.id,
row_id: this.rowId,
offset: this.size * (this.page - 1),
query: this.query,
_cn: this.column._cn,
ptn: this.parentMeta.tn,
ctn: this.meta.tn,
type: this.type
}])
return
}
if (!this.api || this.isNew) { return } if (!this.api || this.isNew) { return }
this.data = await this.api.paginatedList({ this.data = await this.api.paginatedList({
limit: this.size, limit: this.size,

10
packages/nc-gui/components/project/spreadsheet/components/virtualCell/components/listChildItemsModal.vue

@ -6,11 +6,13 @@
<list-child-items <list-child-items
v-if="show" v-if="show"
ref="child" ref="child"
:type="type"
:row-id="rowId"
:local-state="localState" :local-state="localState"
:is-new="isNew" :is-new="isNew"
:size="10" :size="10"
:meta="meta" :meta="meta"
:parent-meta="meta" :parent-meta="parentMeta"
:primary-col="primaryCol" :primary-col="primaryCol"
:primary-key="primaryKey" :primary-key="primaryKey"
:api="api" :api="api"
@ -18,6 +20,7 @@
v-bind="$attrs" v-bind="$attrs"
:read-only="readOnly" :read-only="readOnly"
:is-public="isPublic" :is-public="isPublic"
column="column"
v-on="$listeners" v-on="$listeners"
/> />
</v-dialog> </v-dialog>
@ -30,6 +33,7 @@ export default {
name: 'ListChildItemsModal', name: 'ListChildItemsModal',
components: { ListChildItems }, components: { ListChildItems },
props: { props: {
type: String,
readOnly: Boolean, readOnly: Boolean,
localState: Array, localState: Array,
isNew: Boolean, isNew: Boolean,
@ -51,7 +55,9 @@ export default {
size: Number, size: Number,
api: [Object, Function], api: [Object, Function],
mm: [Object, Boolean], mm: [Object, Boolean],
isPublic: Boolean isPublic: Boolean,
rowId: [String, Number],
column: Object
}, },
data: () => ({ data: () => ({
data: null, data: null,

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

@ -28,7 +28,7 @@
:class="{'d-none': !active, 'd-flex':active }" :class="{'d-none': !active, 'd-flex':active }"
> >
<x-icon <x-icon
v-if="_isUIAllowed('xcDatatableEditable')" v-if="_isUIAllowed('xcDatatableEditable') && !isPublic"
small small
:color="['primary','grey']" :color="['primary','grey']"
@click="showNewRecordModal" @click="showNewRecordModal"
@ -76,11 +76,14 @@
:primary-col="childPrimaryCol" :primary-col="childPrimaryCol"
:primary-key="childPrimaryKey" :primary-key="childPrimaryKey"
:api="childApi" :api="childApi"
:column="column"
:query-params="{ :query-params="{
...childQueryParams, ...childQueryParams,
where: `(${childForeignKey},eq,${parentId})` where: `(${childForeignKey},eq,${parentId})`
}" }"
:is-public="isPublic" :is-public="isPublic"
:row-id="parentId"
type="hm"
@new-record="showNewRecordModal" @new-record="showNewRecordModal"
@edit="editChild" @edit="editChild"
@unlink="unlinkChild" @unlink="unlinkChild"
@ -174,7 +177,8 @@ export default {
required: Boolean, required: Boolean,
isPublic: Boolean, isPublic: Boolean,
metas: Object, metas: Object,
password: String password: String,
column: Object
}, },
data: () => ({ data: () => ({
newRecordModal: false, newRecordModal: false,

15
packages/nc-gui/components/project/spreadsheet/components/virtualCell/lookupCell.vue

@ -44,16 +44,17 @@
<script> <script>
// import ApiFactory from '@/components/project/spreadsheet/apis/apiFactory' // import ApiFactory from '@/components/project/spreadsheet/apis/apiFactory'
import TableCell from '../cell'
import ItemChip from '@/components/project/spreadsheet/components/virtualCell/components/itemChip' import ItemChip from '@/components/project/spreadsheet/components/virtualCell/components/itemChip'
import ListChildItemsModal import ListChildItemsModal
from '@/components/project/spreadsheet/components/virtualCell/components/listChildItemsModal' from '@/components/project/spreadsheet/components/virtualCell/components/listChildItemsModal'
import TableCell from '../cell'
export default { export default {
name: 'LookupCell', name: 'LookupCell',
components: { TableCell, ListChildItemsModal, ItemChip }, components: { TableCell, ListChildItemsModal, ItemChip },
props: { props: {
meta: [Object], meta: [Object],
metas: [Object],
column: [Object], column: [Object],
nodes: [Object], nodes: [Object],
row: [Object], row: [Object],
@ -76,22 +77,22 @@ export default {
}) })
}, },
lookUpMeta() { lookUpMeta() {
return this.$store.state.meta.metas[this.column.lk.ltn] return this.metas ? this.metas[this.column.lk.ltn] : this.$store.state.meta.metas[this.column.lk.ltn]
}, },
assocMeta() { assocMeta() {
return this.column.lk.type === 'mm' && this.$store.state.meta.metas[this.column.lk.vtn] return this.column.lk.type === 'mm' && (this.metas ? this.metas[this.column.lk.vtn] : this.$store.state.meta.metas[this.column.lk.vtn])
}, },
lookUpColumnAlias() { lookUpColumnAlias() {
if (!this.lookUpMeta || !this.column.lk.lcn) { if (!this.lookUpMeta || !this.column.lk.lcn) {
return return
} }
return (this.$store.state.meta.metas[this.column.lk.ltn].columns.find(cl => cl.cn === this.column.lk.lcn) || {})._cn return (this.lookUpMeta.columns.find(cl => cl.cn === this.column.lk.lcn) || {})._cn
}, },
lookUpColumn() { lookUpColumn() {
if (!this.lookUpMeta || !this.column.lk.lcn) { if (!this.lookUpMeta || !this.column.lk.lcn) {
return return
} }
return (this.$store.state.meta.metas[this.column.lk.ltn].columns.find(cl => cl.cn === this.column.lk.lcn) || {}) return (this.lookUpMeta.columns.find(cl => cl.cn === this.column.lk.lcn) || {})
}, },
localValueObj() { localValueObj() {
if (!this.column || !this.row) { if (!this.column || !this.row) {
@ -146,14 +147,14 @@ export default {
}, },
methods: { methods: {
async loadLookupMeta() { async loadLookupMeta() {
if (!this.lookUpMeta) { if (!this.metas && !this.lookUpMeta) {
await this.$store.dispatch('meta/ActLoadMeta', { await this.$store.dispatch('meta/ActLoadMeta', {
env: this.nodes.env, env: this.nodes.env,
dbAlias: this.nodes.dbAlias, dbAlias: this.nodes.dbAlias,
tn: this.column.lk.ltn tn: this.column.lk.ltn
}) })
} }
if (this.column.lk.type === 'mm' && !this.assocMeta) { if (!this.metas && this.column.lk.type === 'mm' && !this.assocMeta) {
await this.$store.dispatch('meta/ActLoadMeta', { await this.$store.dispatch('meta/ActLoadMeta', {
env: this.nodes.env, env: this.nodes.env,
dbAlias: this.nodes.dbAlias, dbAlias: this.nodes.dbAlias,

6
packages/nc-gui/components/project/spreadsheet/components/virtualCell/manyToManyCell.vue

@ -22,7 +22,7 @@
:class="{'d-none': !active, 'd-flex':active }" :class="{'d-none': !active, 'd-flex':active }"
> >
<x-icon <x-icon
v-if="_isUIAllowed('xcDatatableEditable')" v-if="_isUIAllowed('xcDatatableEditable') && !isPublic"
small small
:color="['primary','grey']" :color="['primary','grey']"
@click="showNewRecordModal" @click="showNewRecordModal"
@ -72,6 +72,8 @@
:query-params="{...childQueryParams, conditionGraph }" :query-params="{...childQueryParams, conditionGraph }"
:local-state="localState" :local-state="localState"
:is-public="isPublic" :is-public="isPublic"
:row-id="parentPrimaryKey"
type="mm"
@new-record="showNewRecordModal" @new-record="showNewRecordModal"
@edit="editChild" @edit="editChild"
@unlink="unlinkChild" @unlink="unlinkChild"
@ -84,7 +86,7 @@
:heading="confirmMessage" :heading="confirmMessage"
/> />
<!-- todo : move to listitem component --> <!-- todo : move to list item component -->
<v-dialog <v-dialog
v-if="selectedChild && !isPublic" v-if="selectedChild && !isPublic"
v-model="expandFormModal" v-model="expandFormModal"

112
packages/nc-gui/components/project/spreadsheet/public/xcTable.vue

@ -4,7 +4,7 @@
<span class="font-weight-bold"> {{ modelName }}</span> <span class="font-weight-regular ml-1">( Main View )</span> <span class="font-weight-bold"> {{ modelName }}</span> <span class="font-weight-regular ml-1">( Main View )</span>
</div> </div>
<v-toolbar height="40" dense class="elevation-0 xc-toolbar xc-border-bottom" style="z-index: 7;border-radius: 4px"> <v-toolbar v-if="meta" height="40" dense class="elevation-0 xc-toolbar xc-border-bottom" style="z-index: 7;border-radius: 4px">
<div class="d-flex xc-border align-center search-box"> <div class="d-flex xc-border align-center search-box">
<v-menu bottom offset-y> <v-menu bottom offset-y>
<template #activator="{on}"> <template #activator="{on}">
@ -107,6 +107,7 @@
</v-toolbar> </v-toolbar>
<div <div
v-if="meta"
:class="`cell-height-${cellHeight}`" :class="`cell-height-${cellHeight}`"
style="overflow:auto;transition: width 500ms " style="overflow:auto;transition: width 500ms "
class="d-flex" class="d-flex"
@ -117,13 +118,14 @@
<xc-grid-view <xc-grid-view
v-else v-else
is-public-view
:meta="meta" :meta="meta"
:metas="metas"
:data="data" :data="data"
:available-columns="availableColumns" :available-columns="availableColumns"
:show-fields="showFields" :show-fields="showFields"
:belongs-to="belongsTo" :belongs-to="belongsTo"
:has-many="hasMany" :has-many="hasMany"
:is-public-view="true"
:nodes="{dbAlias:''}" :nodes="{dbAlias:''}"
:sql-ui="sqlUi" :sql-ui="sqlUi"
/> />
@ -170,22 +172,21 @@
<script> <script>
import ApiFactory from '@/components/project/spreadsheet/apis/apiFactory' import spreadsheet from '../mixins/spreadsheet'
// import EditableCell from "@/components/project/spreadsheet/editableCell"; import ApiFactory from '../apis/apiFactory'
// import EditableCell from "../editableCell";
import FieldsMenu from '../components/fieldsMenu'
import SortListMenu from '../components/sortListMenu'
import ColumnFilterMenu from '../components/columnFilterMenu'
import XcGridView from '../views/xcGridView'
import { SqlUI } from '@/helpers/sqlUi' import { SqlUI } from '@/helpers/sqlUi'
import FieldsMenu from '@/components/project/spreadsheet/components/fieldsMenu' // import ExpandedForm from "../expandedForm";
import SortListMenu from '@/components/project/spreadsheet/components/sortListMenu'
import ColumnFilterMenu from '@/components/project/spreadsheet/components/columnFilterMenu'
import XcGridView from '@/components/project/spreadsheet/views/xcGridView'
import spreadsheet from '@/components/project/spreadsheet/mixins/spreadsheet'
// import ExpandedForm from "@/components/project/spreadsheet/expandedForm";
export default { export default {
name: 'XcTable', name: 'XcTable',
components: { XcGridView, ColumnFilterMenu, SortListMenu, FieldsMenu }, components: { XcGridView, ColumnFilterMenu, SortListMenu, FieldsMenu },
mixins: [spreadsheet], mixins: [spreadsheet],
props: { props: {
dbAlias: String,
env: String, env: String,
nodes: Object, nodes: Object,
addNewRelationTab: Function, addNewRelationTab: Function,
@ -196,6 +197,7 @@ export default {
relationPrimaryValue: [String, Number] relationPrimaryValue: [String, Number]
}, },
data: () => ({ data: () => ({
metas: {},
fieldsOrder: [], fieldsOrder: [],
password: null, password: null,
showPasswordModal: false, showPasswordModal: false,
@ -211,7 +213,7 @@ export default {
showExpandModal: false, showExpandModal: false,
selectedExpandRowIndex: null, selectedExpandRowIndex: null,
selectedExpandRowMeta: null, selectedExpandRowMeta: null,
meta: [], meta: null,
navDrawer: true, navDrawer: true,
selected: { selected: {
row: null, row: null,
@ -361,7 +363,7 @@ export default {
}, },
async mounted() { async mounted() {
try { try {
// await this.loadMeta(); await this.loadMetaData()
await this.loadTableData() await this.loadTableData()
// const {list, count} = await this.api.paginatedList(this.queryParams); // const {list, count} = await this.api.paginatedList(this.queryParams);
// this.count = count; // this.count = count;
@ -471,34 +473,100 @@ export default {
}) })
this.filters = this.filters.slice() this.filters = this.filters.slice()
}, },
async loadMetaData() {
this.loading = true
try {
// eslint-disable-next-line camelcase
const {
meta,
// model_name,
client,
query_params: qp,
db_alias: dbAlias,
relatedTableMetas
} = await this.$store.dispatch('sqlMgr/ActSqlOp', [null, 'sharedViewGet', {
view_id: this.$route.params.id,
password: this.password
}])
this.client = client
this.meta = meta
this.query_params = JSON.parse(qp)
this.dbAlias = dbAlias
this.metas = relatedTableMetas
this.showFields = this.query_params.showFields || {}
this.fieldList = Object.keys(this.showFields)
let fields = this.query_params.fieldsOrder || []
if (!fields.length) { fields = Object.keys(this.showFields) }
// eslint-disable-next-line camelcase
let columns = this.meta.columns
if (this.meta && this.meta.v) {
columns = [...columns, ...this.meta.v.map(v => ({ ...v, virtual: 1 }))]
}
{
const _ref = {}
columns.forEach((c) => {
if (c.virtual && c.bt) {
c.prop = `${c.bt.rtn}Read`
}
if (c.virtual && c.mm) {
c.prop = `${c.mm.rtn}MMList`
}
if (c.virtual && c.hm) {
c.prop = `${c.hm.tn}List`
}
if (c.virtual && c.lk) {
c.alias = `${c.lk._lcn} (from ${c.lk._ltn})`
} else {
c.alias = c._cn
}
if (c.alias in _ref) {
c.alias += _ref[c.alias]++
} else {
_ref[c.alias] = 1
}
})
}
} catch (e) {
if (e.message === 'Not found') {
this.notFound = true
} else if (e.message === 'Invalid password') {
this.showPasswordModal = true
}
}
this.loadingData = false
},
async loadTableData() { async loadTableData() {
this.loadingData = true this.loadingData = true
try { try {
// eslint-disable-next-line camelcase // eslint-disable-next-line camelcase
const { data: list, count, meta, model_name, client } = await this.$store.dispatch('sqlMgr/ActSqlOp', [{ const { data: list, count, meta, model_name, client, queryParams } = await this.$store.dispatch('sqlMgr/ActSqlOp', [{
query: this.queryParams query: this.queryParams
}, 'getSharedViewData', { }, 'getSharedViewData', {
view_id: this.$route.params.id, view_id: this.$route.params.id,
password: this.password password: this.password
}]) }])
this.client = client this.client = client
this.meta = meta
// this.showFields = queryParams && queryParams.showFields
// this.meta = meta
// eslint-disable-next-line camelcase // eslint-disable-next-line camelcase
this.modelName = model_name this.modelName = model_name
this.fieldList = this.meta.columns.map(c => c._cn)
this.count = count this.count = count
this.data = list.map(row => ({ this.data = list.map(row => ({
row, row,
oldRow: { ...row }, oldRow: { ...row },
rowMeta: {} rowMeta: {}
})) }))
this.showFields = this.fieldList.reduce((obj, k) => {
obj[k] = true
return obj
}, {})
} catch (e) { } catch (e) {
this.showPasswordModal = true this.showPasswordModal = true
} }

5
packages/nc-gui/components/project/spreadsheet/views/xcGridView.vue

@ -151,7 +151,9 @@
> >
<virtual-cell <virtual-cell
v-if="columnObj.virtual" v-if="columnObj.virtual"
:is-locked="isLocked" :is-public="isPublicView"
:metas="metas"
:is-locked="isLocked "
:column="columnObj" :column="columnObj"
:row="rowObj" :row="rowObj"
:nodes="nodes" :nodes="nodes"
@ -252,6 +254,7 @@ export default {
}, },
mixins: [colors], mixins: [colors],
props: { props: {
metas: Object,
relationType: String, relationType: String,
availableColumns: [Object, Array], availableColumns: [Object, Array],
showFields: Object, showFields: Object,

6
packages/nocodb/src/lib/dataMapper/lib/sql/CustomKnex.ts

@ -450,7 +450,11 @@ declare module 'knex' {
_and: XcXonditionObj[]; _and: XcXonditionObj[];
_not: XcXonditionObj; _not: XcXonditionObj;
[key: string]: XcXonditionObj | XcXonditionObj[]; [key: string]:
| XcXonditionObj
| XcXonditionObj[]
| XcConditionObjVal
| XcConditionObjVal[];
} }
interface QueryBuilder { interface QueryBuilder {

119
packages/nocodb/src/lib/noco/meta/NcMetaMgr.ts

@ -1314,6 +1314,9 @@ export default class NcMetaMgr {
case 'sharedViewNestedDataGet': case 'sharedViewNestedDataGet':
result = await this.sharedViewNestedDataGet(req, args); result = await this.sharedViewNestedDataGet(req, args);
break; break;
case 'sharedViewNestedChildDataGet':
result = await this.sharedViewNestedChildDataGet(req, args);
break;
// case 'submitSharedViewFormData': // case 'submitSharedViewFormData':
// result = await this.submitSharedViewFormData(req, args); // result = await this.submitSharedViewFormData(req, args);
@ -3291,18 +3294,18 @@ export default class NcMetaMgr {
protected async createSharedViewLink(req, args: any): Promise<any> { protected async createSharedViewLink(req, args: any): Promise<any> {
try { try {
if (args.args.query_params?.fields) { // if (args.args.query_params?.fields) {
const fields = args.args.query_params?.fields.split(','); // const fields = args.args.query_params?.fields.split(',');
args.args.meta.columns = args.args.meta.columns.filter(c => // args.args.meta.columns = args.args.meta.columns.filter(c =>
fields.includes(c._cn) // fields.includes(c._cn)
); // );
} // }
const insertData = { const insertData = {
project_id: args.project_id, project_id: args.project_id,
db_alias: this.getDbAlias(args), db_alias: this.getDbAlias(args),
model_name: args.args.model_name, model_name: args.args.model_name,
meta: JSON.stringify(args.args.meta), // meta: JSON.stringify(args.args.meta),
query_params: JSON.stringify(args.args.query_params), query_params: JSON.stringify(args.args.query_params),
view_id: uuidv4() view_id: uuidv4()
// password: args.args.password // password: args.args.password
@ -3505,6 +3508,104 @@ export default class NcMetaMgr {
} }
} }
protected async sharedViewNestedChildDataGet(_req, args: any): Promise<any> {
try {
const viewMeta = await this.xcMeta
.knex('nc_shared_views')
.where({
view_id: args.args.view_id
})
.first();
if (!viewMeta) {
throw new Error('Not found');
}
if (
viewMeta &&
viewMeta.password &&
viewMeta.password !== args.args.password
) {
throw new Error(this.INVALID_PASSWORD_ERROR);
}
const tn = args.args?.ctn;
// @ts-ignore
// const queryParams = JSON.parse(viewMeta.query_params);
const apiBuilder = this.app?.projectBuilders
?.find(pb => pb.id === viewMeta.project_id)
?.apiBuilders?.find(ab => ab.dbAlias === viewMeta.db_alias);
// todo: only allow related table
// if(tn &&){
//
// }
const model = apiBuilder.xcModels?.[tn];
const meta = apiBuilder.getMeta(tn);
const primaryCol = apiBuilder?.getMeta(tn)?.columns?.find(c => c.pv)?.cn;
const commonParams: any =
primaryCol && args.args.query
? {
condition: {
[primaryCol]: {
like: `%${args.args.query}%`
}
}
}
: {};
switch (args.args?.type) {
case 'mm':
{
const mm = meta.v.find(v => v.mm && v._cn === args.args._cn)?.mm;
const assocMeta = apiBuilder.getMeta(mm.vtn);
commonParams.conditionGraph = {
condition: {
[assocMeta.tn]: {
relationType: 'hm',
[assocMeta.columns.find(c => c.cn === mm.vcn).cn]: {
eq: args.arags.row_id
}
}
},
models: apiBuilder?.xcModels
};
}
break;
case 'hm':
{
const hm = meta.v.find(v => v.hm && v._cn === args.args._cn)?.hm;
// const childMeta = apiBuilder.getMeta(hm.rtn);
commonParams.condition = {
[hm.rcn]: {
eq: args.arags.row_id
}
};
}
break;
}
return {
list: await model?.list({
fields: model.getTablePKandPVFields(),
limit: args.args.limit,
offset: args.args.offset,
...commonParams
}),
count: (await model?.countByPk(commonParams as any))?.count
};
} catch (e) {
console.log(e);
throw e;
}
}
protected async sharedViewInsert(req, args: any): Promise<any> { protected async sharedViewInsert(req, args: any): Promise<any> {
const viewMeta = await this.xcMeta const viewMeta = await this.xcMeta
.knex('nc_shared_views') .knex('nc_shared_views')
@ -3598,6 +3699,10 @@ export default class NcMetaMgr {
} else if (v.mm) { } else if (v.mm) {
tn = v.mm.rtn; tn = v.mm.rtn;
relatedTableMetas[v.mm.vtn] = apiBuilder?.getMeta(v.mm.vtn); relatedTableMetas[v.mm.vtn] = apiBuilder?.getMeta(v.mm.vtn);
} else if (v.lk) {
tn = v.lk.ltn;
if (v.lk.vtn)
relatedTableMetas[v.lk.vtn] = apiBuilder?.getMeta(v.lk.vtn);
} }
relatedTableMetas[tn] = apiBuilder?.getMeta(tn); relatedTableMetas[tn] = apiBuilder?.getMeta(tn);
} }

8
packages/nocodb/src/lib/noco/meta/NcMetaMgrEE.ts

@ -142,7 +142,10 @@ export default class NcMetaMgrEE extends NcMetaMgr {
} }
const queryParams = JSON.parse(viewMeta.query_params); const queryParams = JSON.parse(viewMeta.query_params);
if (!meta) throw new Error('Meta not found'); if (!meta) {
throw new Error('Meta not found');
}
meta = { meta = {
...meta, ...meta,
columns: meta.columns.filter(c => queryParams?.showFields?.[c._cn]) columns: meta.columns.filter(c => queryParams?.showFields?.[c._cn])
@ -163,7 +166,8 @@ export default class NcMetaMgrEE extends NcMetaMgr {
return { return {
model_name: viewMeta.model_name, model_name: viewMeta.model_name,
meta, meta,
data: await model.list({ queryParams,
data: await model.nestedList({
...req.query, ...req.query,
where, where,
fields fields

Loading…
Cancel
Save