Browse Source

fix: handle form view query params detail on table operations

Handle following events
- Table delete
- Table update
- Relation delete

Signed-off-by: Pranav C <pranavxc@gmail.com>
pull/653/head
Pranav C 3 years ago
parent
commit
8307bc2970
  1. 2
      packages/nc-gui/components/project/spreadsheet/components/spreadsheetNavDrawer.vue
  2. 2
      packages/nc-gui/components/project/spreadsheet/public/xcForm.vue
  3. 2
      packages/nocodb/src/lib/noco/NcProjectBuilder.ts
  4. 379
      packages/nocodb/src/lib/noco/common/BaseApiBuilder.ts
  5. 6
      packages/nocodb/src/lib/noco/meta/NcMetaMgr.ts
  6. 2
      packages/nocodb/src/lib/noco/meta/NcMetaMgrEE.ts
  7. 2
      packages/nocodb/src/lib/noco/migrations/nc_007_alter_nc_shared_views_1.ts

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

@ -760,7 +760,7 @@ export default {
'createSharedViewLink',
{
model_name: this.table,
meta: this.meta,
// meta: this.meta,
query_params: {
where: this.concatenatedXWhere,
sort: this.sort,

2
packages/nc-gui/components/project/spreadsheet/public/xcForm.vue

@ -298,7 +298,7 @@ export default {
password: this.password
}])
this.client = client
this.meta = JSON.parse(meta)
this.meta = meta
this.query_params = JSON.parse(qp)
this.dbAlias = dbAlias
this.metas = relatedTableMetas

2
packages/nocodb/src/lib/noco/NcProjectBuilder.ts

@ -275,7 +275,7 @@ export default class NcProjectBuilder {
console.log(`Updated validations for table : ${data.req.args.tn}`);
break;
case 'xcUpdateVirtualKeyAlias':
await curBuilder.onVirtualColumnAliasUpdate(data.req.args.tn);
await curBuilder.onVirtualColumnAliasUpdate(data.req.args);
console.log(`Updated validations for table : ${data.req.args.tn}`);
break;

379
packages/nocodb/src/lib/noco/common/BaseApiBuilder.ts

@ -206,7 +206,7 @@ export default abstract class BaseApiBuilder<T extends Noco>
public async onTableDelete(tn: string): Promise<void> {
this.baseLog(`onTableDelete : '%s'`, tn);
XcCache.del([this.projectId, this.dbAlias, 'table', tn].join('::'));
return this.xcMeta.metaDelete(
await this.xcMeta.metaDelete(
this.projectId,
this.dbAlias,
'nc_relations',
@ -227,6 +227,15 @@ export default abstract class BaseApiBuilder<T extends Noco>
}
);
await this.deleteTableNameInACL(tn);
await this.xcMeta.metaDelete(
this.projectId,
this.dbAlias,
'nc_shared_views',
{
model_name: tn
}
);
}
public async onRelationCreate(
@ -311,6 +320,127 @@ export default abstract class BaseApiBuilder<T extends Noco>
XcCache.del([this.projectId, this.dbAlias, 'table', tnc].join('::'));
XcCache.del([this.projectId, this.dbAlias, 'table', tnp].join('::'));
for (const tn of [tnc, tnp]) {
const {
virtualViews,
sharedViews,
virtualViewsParamsArr,
sharedViewsParamsArr
} = await this.extractSharedAndVirtualViewsParams(tn);
// extract alias of relation virtual column
const relation = tnc === tn ? 'bt' : 'hm';
const alias = this.getMeta(tn)?.v?.find(
v => v?.[relation]?.tn === tnc && v?.[relation]?.rtn === tnp
)?._cn;
// virtual views param update
for (const qp of [...virtualViewsParamsArr, ...sharedViewsParamsArr]) {
// @ts-ignore
const { showFields = {}, fieldsOrder, extraViewParams = {} } = qp;
/* update show field */
if (alias in showFields) {
delete showFields[alias];
}
/* update fieldsOrder */
const index = fieldsOrder.indexOf(alias);
if (index > -1) {
fieldsOrder.splice(index, 0);
}
/* update formView params */
// extraViewParams.formParams.fields
if (extraViewParams?.formParams?.fields?.[alias]) {
delete extraViewParams.formParams.fields[alias];
}
}
await this.updateSharedAndVirtualViewsParams(
virtualViewsParamsArr,
virtualViews,
sharedViewsParamsArr,
sharedViews
);
}
}
private async updateSharedAndVirtualViewsParams(
virtualViewsParamsArr: any[],
virtualViews: any[],
sharedViewsParamsArr: any[],
sharedViews: any[]
) {
// update virtual views params
for (let i = 0; i < virtualViewsParamsArr.length; i++) {
await this.xcMeta.metaUpdate(
this.projectId,
this.dbAlias,
'nc_models',
{
query_params: JSON.stringify(virtualViewsParamsArr[i])
},
virtualViews[i].id
);
}
// update shared views params
for (let i = 0; i < sharedViewsParamsArr.length; i++) {
await this.xcMeta.metaUpdate(
this.projectId,
this.dbAlias,
'nc_shared_views',
{
query_params: JSON.stringify(sharedViewsParamsArr[i])
},
sharedViews[i].id
);
}
}
private async extractSharedAndVirtualViewsParams(tn: string) {
const virtualViews = await this.xcMeta.metaList(
this.projectId,
this.dbAlias,
'nc_models',
{
condition: {
type: 'vtable',
parent_model_title: tn
}
}
);
const sharedViews = await this.xcMeta.metaList(
this.projectId,
this.dbAlias,
'nc_shared_views',
{
condition: {
model_name: tn
}
}
);
const virtualViewsParamsArr = virtualViews.map(v => {
try {
return JSON.parse(v.query_params);
} catch (e) {}
return {};
});
// @ts-ignore
const sharedViewsParamsArr = sharedViews.map(v => {
try {
return JSON.parse(v.query_params);
} catch (e) {}
return {};
});
return {
virtualViews,
sharedViews,
virtualViewsParamsArr,
sharedViewsParamsArr
};
}
public async onTableRename(
@ -460,24 +590,12 @@ export default abstract class BaseApiBuilder<T extends Noco>
const belongsTo = this.extractBelongsToRelationsOfTable(relations, tn);
const hasMany = this.extractHasManyRelationsOfTable(relations, tn);
const virtualViews = await this.xcMeta.metaList(
this.projectId,
this.dbAlias,
'nc_models',
{
condition: {
type: 'vtable',
parent_model_title: tn
}
}
);
const virtualViewsParamsArr = virtualViews.map(v => {
try {
return JSON.parse(v.query_params);
} catch (e) {}
return {};
});
const {
virtualViews,
sharedViews,
virtualViewsParamsArr,
sharedViewsParamsArr
} = await this.extractSharedAndVirtualViewsParams(tn);
const ctx = this.generateContextForTable(
tn,
@ -577,12 +695,22 @@ export default abstract class BaseApiBuilder<T extends Noco>
);
// virtual views param update
for (const qp of [queryParams, ...virtualViewsParamsArr]) {
for (const qp of [
queryParams,
...virtualViewsParamsArr,
...sharedViewsParamsArr
]) {
if (!qp) continue;
// @ts-ignore
const { filters, sortList, showFields } = qp;
const {
filters,
sortList,
showFields = {},
fieldsOrder,
extraViewParams = {}
} = qp;
/* update sort field */
const s = sortList.find(v => v.field === column.cno);
const s = sortList?.find(v => v.field === column.cno);
if (s) {
s.field = column.cn;
}
@ -592,9 +720,26 @@ export default abstract class BaseApiBuilder<T extends Noco>
delete showFields[column.cno];
}
/* update filters */
if (JSON.stringify(filters).includes(`"${column.cno}"`)) {
if (
filters &&
JSON.stringify(filters).includes(`"${column.cno}"`)
) {
filters.splice(0, filters.length);
}
/* update fieldsOrder */
const index = fieldsOrder.indexOf(column.cno);
if (index > -1) {
fieldsOrder[index] = column.cn;
}
/* update formView params */
// extraViewParams.formParams.fields
if (extraViewParams?.formParams?.fields?.[column.cno]) {
extraViewParams.formParams.fields[column.cn] =
extraViewParams.formParams.fields[column.cno];
delete extraViewParams.formParams.fields[column.cno];
}
}
// update relation column name in meta data
@ -715,11 +860,19 @@ export default abstract class BaseApiBuilder<T extends Noco>
aclOper.push(async () => this.deleteColumnNameInACL(tn, column.cno));
// virtual views param update
for (const qp of virtualViewsParamsArr) {
for (const qp of [...virtualViewsParamsArr, ...sharedViewsParamsArr]) {
// @ts-ignore
const { filters, sortList, showFields } = qp;
const {
filters,
sortList,
showFields = {},
fieldsOrder,
extraViewParams = {}
} = qp;
/* update sort field */
const sIndex = sortList.findIndex(v => v.field === column.cno);
const sIndex = (sortList || []).findIndex(
v => v.field === column.cno
);
if (sIndex > -1) {
sortList.splice(sIndex, 1);
}
@ -728,9 +881,21 @@ export default abstract class BaseApiBuilder<T extends Noco>
delete showFields[column.cno];
}
/* update filters */
if (JSON.stringify(filters).includes(`"${column.cno}"`)) {
if (filters && JSON.stringify(filters)?.includes(`"${column.cno}"`)) {
filters.splice(0, filters.length);
}
/* update fieldsOrder */
const index = fieldsOrder.indexOf(column.cno);
if (index > -1) {
fieldsOrder.splice(index, 0);
}
/* update formView params */
// extraViewParams.formParams.fields
if (extraViewParams?.formParams?.fields?.[column.cno]) {
delete extraViewParams.formParams.fields[column.cno];
}
}
// Delete lookup columns mapping to current column
@ -789,6 +954,20 @@ export default abstract class BaseApiBuilder<T extends Noco>
if (queryParams?.showFields) {
queryParams.showFields[column.cno] = true;
}
for (const qp of sharedViewsParamsArr) {
if (!qp) continue;
// @ts-ignore
const { showFields = {}, extraViewParams = {} } = qp;
if (column.rqd) {
showFields[column.cn] = true;
extraViewParams.formParams = extraViewParams.formParams || {};
extraViewParams.formParams.fields =
extraViewParams.formParams.fields || {};
extraViewParams.formParams.fields[column.cn] = {};
}
}
} else {
oldCol = oldMeta.columns.find(c => c.cn === column.cn);
newCol = newMeta.columns.find(c => c.cn === column.cn);
@ -796,20 +975,15 @@ export default abstract class BaseApiBuilder<T extends Noco>
newCol.validate = oldCol.validate;
}
}
for (let i = 0; i < virtualViewsParamsArr.length; i++) {
await this.xcMeta.metaUpdate(
this.projectId,
this.dbAlias,
'nc_models',
{
query_params: JSON.stringify(virtualViewsParamsArr[i])
},
virtualViews[i].id
);
}
}
await this.updateSharedAndVirtualViewsParams(
virtualViewsParamsArr,
virtualViews,
sharedViewsParamsArr,
sharedViews
);
// update relation tables metadata
for (const relMeta of relationTableMetas) {
await this.xcMeta.metaUpdate(
@ -1187,6 +1361,54 @@ export default abstract class BaseApiBuilder<T extends Noco>
XcCache.del([this.projectId, this.dbAlias, 'table', meta.tn].join('::'));
this.models[meta.tn] = this.getBaseModel(meta);
}
// todo: many to many form view field update
for (const [tnp, tnc] of [
[parent, child],
[child, parent]
]) {
const {
virtualViews,
sharedViews,
virtualViewsParamsArr,
sharedViewsParamsArr
} = await this.extractSharedAndVirtualViewsParams(tnp);
const alias = this.getMeta(tnp)?.v?.find(
v => v?.tn === tnp && v?.mm?.rtn === tnc
)?._cn;
// virtual views param update
for (const qp of [...virtualViewsParamsArr, ...sharedViewsParamsArr]) {
// @ts-ignore
const { showFields = {}, fieldsOrder, extraViewParams = {} } = qp;
/* update show field */
if (alias in showFields) {
delete showFields[alias];
}
/* update fieldsOrder */
const index = fieldsOrder.indexOf(alias);
if (index > -1) {
fieldsOrder.splice(index, 0);
}
/* update formView params */
// extraViewParams.formParams.fields
if (extraViewParams?.formParams?.fields?.[alias]) {
delete extraViewParams.formParams.fields[alias];
}
}
await this.updateSharedAndVirtualViewsParams(
virtualViewsParamsArr,
virtualViews,
sharedViewsParamsArr,
sharedViews
);
}
}
public getProjectId(): string {
@ -1197,15 +1419,88 @@ export default abstract class BaseApiBuilder<T extends Noco>
await this.xcUpgrade();
}
public async onVirtualColumnAliasUpdate(tableName: string): Promise<void> {
public async onVirtualColumnAliasUpdate({
tn,
oldAlias,
newAlias
}: any): Promise<void> {
const model = await this.xcMeta.metaGet(
this.projectId,
this.dbAlias,
'nc_models',
{ title: tableName }
{ title: tn }
);
const meta = JSON.parse(model.meta);
this.models[tableName] = this.getBaseModel(meta);
this.models[tn] = this.getBaseModel(meta);
const virtualViews = await this.xcMeta.metaList(
this.projectId,
this.dbAlias,
'nc_models',
{
condition: {
type: 'vtable',
parent_model_title: tn
}
}
);
const sharedViews = await this.xcMeta.metaList(
this.projectId,
this.dbAlias,
'nc_shared_views',
{
condition: {
model_name: tn
}
}
);
const virtualViewsParamsArr = virtualViews.map(v => {
try {
return JSON.parse(v.query_params);
} catch (e) {}
return {};
});
// @ts-ignore
const sharedViewsParamsArr = sharedViews.map(v => {
try {
return JSON.parse(v.query_params);
} catch (e) {}
return {};
});
for (const qp of [...sharedViewsParamsArr, ...virtualViewsParamsArr]) {
if (!qp) continue;
// @ts-ignore
const { showFields = {}, fieldsOrder, extraViewParams = {} } = qp;
/* update show field */
if (oldAlias in showFields) {
showFields[newAlias] = showFields[oldAlias];
delete showFields[oldAlias];
}
/* update fieldsOrder */
const index = fieldsOrder.indexOf(oldAlias);
if (index > -1) {
fieldsOrder[index] = newAlias;
}
/* update formView params */
// extraViewParams.formParams.fields
if (extraViewParams?.formParams?.fields?.[oldAlias]) {
extraViewParams.formParams.fields[newAlias] =
extraViewParams.formParams.fields[oldAlias];
delete extraViewParams.formParams.fields[oldAlias];
}
}
await this.updateSharedAndVirtualViewsParams(
virtualViewsParamsArr,
virtualViews,
sharedViewsParamsArr,
sharedViews
);
}
protected async loadCommon(): Promise<any> {

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

@ -3421,7 +3421,7 @@ export default class NcMetaMgr {
return {
model_name: viewMeta.model_name,
meta: JSON.parse(viewMeta.meta),
meta: apiBuilder?.getMeta(viewMeta.model_name), //JSON.parse(viewMeta.meta),
data: await model.list({
...req.query,
where,
@ -3583,7 +3583,9 @@ export default class NcMetaMgr {
?.find(pb => pb.id === viewMeta.project_id)
?.apiBuilders?.find(ab => ab.dbAlias === viewMeta.db_alias);
const tableMeta = JSON.parse(viewMeta.meta);
const tableMeta = (viewMeta.meta = apiBuilder?.getMeta(
viewMeta.model_name
));
const relatedTableMetas = {};

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

@ -185,7 +185,7 @@ export default class NcMetaMgrEE extends NcMetaMgr {
db_alias: this.getDbAlias(args),
model_name: args.args.model_name,
view_name: args.args.view_name,
meta: JSON.stringify(args.args.meta),
// meta: JSON.stringify(args.args.meta),
query_params: JSON.stringify(args.args.query_params),
view_id: uuidv4(),
password: args.args.password,

2
packages/nocodb/src/lib/noco/migrations/nc_007_alter_nc_shared_views_1.ts

@ -2,7 +2,7 @@ import Knex from 'knex';
const up = async (knex: Knex) => {
await knex.schema.alterTable('nc_shared_views', table => {
table.string('view_name',255);
table.string('view_name', 255);
});
};

Loading…
Cancel
Save