Merge pull request #11483 from Budibase/BUDI-7189/handle_tableschema_changes_on_views
Handle tableschema changes on views
This commit is contained in:
commit
ff620a496d
7 changed files with 436 additions and 58 deletions
|
@ -22,9 +22,12 @@ import {
|
||||||
QueryJson,
|
QueryJson,
|
||||||
RelationshipType,
|
RelationshipType,
|
||||||
RenameColumn,
|
RenameColumn,
|
||||||
|
SaveTableRequest,
|
||||||
|
SaveTableResponse,
|
||||||
Table,
|
Table,
|
||||||
TableRequest,
|
TableRequest,
|
||||||
UserCtx,
|
UserCtx,
|
||||||
|
ViewV2,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
import sdk from "../../../sdk"
|
import sdk from "../../../sdk"
|
||||||
import { builderSocket } from "../../../websockets"
|
import { builderSocket } from "../../../websockets"
|
||||||
|
@ -198,8 +201,8 @@ function isRelationshipSetup(column: FieldSchema) {
|
||||||
return column.foreignKey || column.through
|
return column.foreignKey || column.through
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function save(ctx: UserCtx) {
|
export async function save(ctx: UserCtx<SaveTableRequest, SaveTableResponse>) {
|
||||||
const inputs: TableRequest = ctx.request.body
|
const inputs = ctx.request.body
|
||||||
const renamed = inputs?._rename
|
const renamed = inputs?._rename
|
||||||
// can't do this right now
|
// can't do this right now
|
||||||
delete inputs.rows
|
delete inputs.rows
|
||||||
|
@ -215,7 +218,7 @@ export async function save(ctx: UserCtx) {
|
||||||
...inputs,
|
...inputs,
|
||||||
}
|
}
|
||||||
|
|
||||||
let oldTable
|
let oldTable: Table | undefined
|
||||||
if (ctx.request.body && ctx.request.body._id) {
|
if (ctx.request.body && ctx.request.body._id) {
|
||||||
oldTable = await sdk.tables.getTable(ctx.request.body._id)
|
oldTable = await sdk.tables.getTable(ctx.request.body._id)
|
||||||
}
|
}
|
||||||
|
@ -224,6 +227,17 @@ export async function save(ctx: UserCtx) {
|
||||||
ctx.throw(400, "A column type has changed.")
|
ctx.throw(400, "A column type has changed.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (let view in tableToSave.views) {
|
||||||
|
const tableView = tableToSave.views[view]
|
||||||
|
if (!tableView || !sdk.views.isV2(tableView)) continue
|
||||||
|
|
||||||
|
tableToSave.views[view] = sdk.views.syncSchema(
|
||||||
|
oldTable!.views![view] as ViewV2,
|
||||||
|
tableToSave.schema,
|
||||||
|
renamed
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
const db = context.getAppDB()
|
const db = context.getAppDB()
|
||||||
const datasource = await sdk.datasources.get(datasourceId)
|
const datasource = await sdk.datasources.get(datasourceId)
|
||||||
if (!datasource.entities) {
|
if (!datasource.entities) {
|
||||||
|
|
|
@ -9,6 +9,8 @@ import { isExternalTable, isSQL } from "../../../integrations/utils"
|
||||||
import { events } from "@budibase/backend-core"
|
import { events } from "@budibase/backend-core"
|
||||||
import {
|
import {
|
||||||
FetchTablesResponse,
|
FetchTablesResponse,
|
||||||
|
SaveTableResponse,
|
||||||
|
SaveTableRequest,
|
||||||
Table,
|
Table,
|
||||||
TableResponse,
|
TableResponse,
|
||||||
UserCtx,
|
UserCtx,
|
||||||
|
@ -60,7 +62,7 @@ export async function find(ctx: UserCtx<void, TableResponse>) {
|
||||||
ctx.body = sdk.tables.enrichViewSchemas(table)
|
ctx.body = sdk.tables.enrichViewSchemas(table)
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function save(ctx: UserCtx) {
|
export async function save(ctx: UserCtx<SaveTableRequest, SaveTableResponse>) {
|
||||||
const appId = ctx.appId
|
const appId = ctx.appId
|
||||||
const table = ctx.request.body
|
const table = ctx.request.body
|
||||||
const isImport = table.rows
|
const isImport = table.rows
|
||||||
|
|
|
@ -9,7 +9,15 @@ import {
|
||||||
fixAutoColumnSubType,
|
fixAutoColumnSubType,
|
||||||
} from "../../../utilities/rowProcessor"
|
} from "../../../utilities/rowProcessor"
|
||||||
import { runStaticFormulaChecks } from "./bulkFormula"
|
import { runStaticFormulaChecks } from "./bulkFormula"
|
||||||
import { Table } from "@budibase/types"
|
import {
|
||||||
|
SaveTableRequest,
|
||||||
|
SaveTableResponse,
|
||||||
|
Table,
|
||||||
|
TableRequest,
|
||||||
|
UserCtx,
|
||||||
|
ViewStatisticsSchema,
|
||||||
|
ViewV2,
|
||||||
|
} from "@budibase/types"
|
||||||
import { quotas } from "@budibase/pro"
|
import { quotas } from "@budibase/pro"
|
||||||
import isEqual from "lodash/isEqual"
|
import isEqual from "lodash/isEqual"
|
||||||
import { cloneDeep } from "lodash/fp"
|
import { cloneDeep } from "lodash/fp"
|
||||||
|
@ -33,10 +41,10 @@ function checkAutoColumns(table: Table, oldTable?: Table) {
|
||||||
return table
|
return table
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function save(ctx: any) {
|
export async function save(ctx: UserCtx<SaveTableRequest, SaveTableResponse>) {
|
||||||
const db = context.getAppDB()
|
const db = context.getAppDB()
|
||||||
const { rows, ...rest } = ctx.request.body
|
const { rows, ...rest } = ctx.request.body
|
||||||
let tableToSave = {
|
let tableToSave: TableRequest = {
|
||||||
type: "table",
|
type: "table",
|
||||||
_id: generateTableID(),
|
_id: generateTableID(),
|
||||||
views: {},
|
views: {},
|
||||||
|
@ -44,7 +52,7 @@ export async function save(ctx: any) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the table obj had an _id then it will have been retrieved
|
// if the table obj had an _id then it will have been retrieved
|
||||||
let oldTable
|
let oldTable: Table | undefined
|
||||||
if (ctx.request.body && ctx.request.body._id) {
|
if (ctx.request.body && ctx.request.body._id) {
|
||||||
oldTable = await sdk.tables.getTable(ctx.request.body._id)
|
oldTable = await sdk.tables.getTable(ctx.request.body._id)
|
||||||
}
|
}
|
||||||
|
@ -80,7 +88,7 @@ export async function save(ctx: any) {
|
||||||
let { _rename } = tableToSave
|
let { _rename } = tableToSave
|
||||||
/* istanbul ignore next */
|
/* istanbul ignore next */
|
||||||
if (_rename && _rename.old === _rename.updated) {
|
if (_rename && _rename.old === _rename.updated) {
|
||||||
_rename = null
|
_rename = undefined
|
||||||
delete tableToSave._rename
|
delete tableToSave._rename
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,7 +105,20 @@ export async function save(ctx: any) {
|
||||||
const tableView = tableToSave.views[view]
|
const tableView = tableToSave.views[view]
|
||||||
if (!tableView) continue
|
if (!tableView) continue
|
||||||
|
|
||||||
if (tableView.schema.group || tableView.schema.field) continue
|
if (sdk.views.isV2(tableView)) {
|
||||||
|
tableToSave.views[view] = sdk.views.syncSchema(
|
||||||
|
oldTable!.views![view] as ViewV2,
|
||||||
|
tableToSave.schema,
|
||||||
|
_rename
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
(tableView.schema as ViewStatisticsSchema).group ||
|
||||||
|
tableView.schema.field
|
||||||
|
)
|
||||||
|
continue
|
||||||
tableView.schema = tableToSave.schema
|
tableView.schema = tableToSave.schema
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +133,7 @@ export async function save(ctx: any) {
|
||||||
tableToSave._rev = linkResp._rev
|
tableToSave._rev = linkResp._rev
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
ctx.throw(400, err)
|
ctx.throw(400, err as string)
|
||||||
}
|
}
|
||||||
|
|
||||||
// don't perform any updates until relationships have been
|
// don't perform any updates until relationships have been
|
||||||
|
|
|
@ -418,7 +418,7 @@ export function areSwitchableTypes(type1: any, type2: any) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
export function hasTypeChanged(table: any, oldTable: any) {
|
export function hasTypeChanged(table: Table, oldTable: Table | undefined) {
|
||||||
if (!oldTable) {
|
if (!oldTable) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
|
import {
|
||||||
|
FieldSchema,
|
||||||
|
RenameColumn,
|
||||||
|
TableSchema,
|
||||||
|
View,
|
||||||
|
ViewV2,
|
||||||
|
} from "@budibase/types"
|
||||||
import { context, HTTPError } from "@budibase/backend-core"
|
import { context, HTTPError } from "@budibase/backend-core"
|
||||||
import { FieldSchema, TableSchema, View, ViewV2 } from "@budibase/types"
|
|
||||||
|
|
||||||
import sdk from "../../../sdk"
|
import sdk from "../../../sdk"
|
||||||
import * as utils from "../../../db/utils"
|
import * as utils from "../../../db/utils"
|
||||||
|
@ -103,3 +109,37 @@ export function enrichSchema(view: View | ViewV2, tableSchema: TableSchema) {
|
||||||
schema: schema,
|
schema: schema,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function syncSchema(
|
||||||
|
view: ViewV2,
|
||||||
|
schema: TableSchema,
|
||||||
|
renameColumn: RenameColumn | undefined
|
||||||
|
): ViewV2 {
|
||||||
|
if (renameColumn) {
|
||||||
|
if (view.columns) {
|
||||||
|
view.columns[view.columns.indexOf(renameColumn.old)] =
|
||||||
|
renameColumn.updated
|
||||||
|
}
|
||||||
|
if (view.schemaUI) {
|
||||||
|
view.schemaUI[renameColumn.updated] = view.schemaUI[renameColumn.old]
|
||||||
|
delete view.schemaUI[renameColumn.old]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (view.schemaUI) {
|
||||||
|
for (const fieldName of Object.keys(view.schemaUI)) {
|
||||||
|
if (!schema[fieldName]) {
|
||||||
|
delete view.schemaUI[fieldName]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const fieldName of Object.keys(schema)) {
|
||||||
|
if (!view.schemaUI[fieldName]) {
|
||||||
|
view.schemaUI[fieldName] = { visible: false }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
view.columns = view.columns?.filter(x => schema[x])
|
||||||
|
|
||||||
|
return view
|
||||||
|
}
|
||||||
|
|
|
@ -1,53 +1,54 @@
|
||||||
import { FieldType, Table, ViewV2 } from "@budibase/types"
|
import _ from "lodash"
|
||||||
|
import { FieldType, Table, TableSchema, ViewV2 } from "@budibase/types"
|
||||||
import { generator } from "@budibase/backend-core/tests"
|
import { generator } from "@budibase/backend-core/tests"
|
||||||
import { enrichSchema } from ".."
|
import { enrichSchema, syncSchema } from ".."
|
||||||
|
|
||||||
describe("table sdk", () => {
|
describe("table sdk", () => {
|
||||||
describe("enrichViewSchemas", () => {
|
const basicTable: Table = {
|
||||||
const basicTable: Table = {
|
_id: generator.guid(),
|
||||||
_id: generator.guid(),
|
name: "TestTable",
|
||||||
name: "TestTable",
|
type: "table",
|
||||||
type: "table",
|
schema: {
|
||||||
schema: {
|
name: {
|
||||||
name: {
|
type: FieldType.STRING,
|
||||||
type: FieldType.STRING,
|
name: "name",
|
||||||
name: "name",
|
visible: true,
|
||||||
visible: true,
|
width: 80,
|
||||||
width: 80,
|
order: 2,
|
||||||
order: 2,
|
constraints: {
|
||||||
constraints: {
|
type: "string",
|
||||||
type: "string",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
description: {
|
|
||||||
type: FieldType.STRING,
|
|
||||||
name: "description",
|
|
||||||
visible: true,
|
|
||||||
width: 200,
|
|
||||||
constraints: {
|
|
||||||
type: "string",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
id: {
|
|
||||||
type: FieldType.NUMBER,
|
|
||||||
name: "id",
|
|
||||||
visible: true,
|
|
||||||
order: 1,
|
|
||||||
constraints: {
|
|
||||||
type: "number",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
hiddenField: {
|
|
||||||
type: FieldType.STRING,
|
|
||||||
name: "hiddenField",
|
|
||||||
visible: false,
|
|
||||||
constraints: {
|
|
||||||
type: "string",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
description: {
|
||||||
|
type: FieldType.STRING,
|
||||||
|
name: "description",
|
||||||
|
visible: true,
|
||||||
|
width: 200,
|
||||||
|
constraints: {
|
||||||
|
type: "string",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
id: {
|
||||||
|
type: FieldType.NUMBER,
|
||||||
|
name: "id",
|
||||||
|
visible: true,
|
||||||
|
order: 1,
|
||||||
|
constraints: {
|
||||||
|
type: "number",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
hiddenField: {
|
||||||
|
type: FieldType.STRING,
|
||||||
|
name: "hiddenField",
|
||||||
|
visible: false,
|
||||||
|
constraints: {
|
||||||
|
type: "string",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("enrichViewSchemas", () => {
|
||||||
it("should fetch the default schema if not overriden", async () => {
|
it("should fetch the default schema if not overriden", async () => {
|
||||||
const tableId = basicTable._id!
|
const tableId = basicTable._id!
|
||||||
const view: ViewV2 = {
|
const view: ViewV2 = {
|
||||||
|
@ -280,4 +281,294 @@ describe("table sdk", () => {
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("syncSchema", () => {
|
||||||
|
const basicView: ViewV2 = {
|
||||||
|
version: 2,
|
||||||
|
id: generator.guid(),
|
||||||
|
name: generator.guid(),
|
||||||
|
tableId: basicTable._id!,
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("view without schema", () => {
|
||||||
|
it("no table schema changes will not amend the view", () => {
|
||||||
|
const view: ViewV2 = {
|
||||||
|
...basicView,
|
||||||
|
columns: ["name", "id", "description"],
|
||||||
|
}
|
||||||
|
const result = syncSchema(
|
||||||
|
_.cloneDeep(view),
|
||||||
|
basicTable.schema,
|
||||||
|
undefined
|
||||||
|
)
|
||||||
|
expect(result).toEqual(view)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("adding new columns will not change the view schema", () => {
|
||||||
|
const view: ViewV2 = {
|
||||||
|
...basicView,
|
||||||
|
columns: ["name", "id", "description"],
|
||||||
|
}
|
||||||
|
|
||||||
|
const newTableSchema = {
|
||||||
|
...basicTable.schema,
|
||||||
|
newField1: {
|
||||||
|
type: FieldType.STRING,
|
||||||
|
name: "newField1",
|
||||||
|
visible: true,
|
||||||
|
},
|
||||||
|
newField2: {
|
||||||
|
type: FieldType.NUMBER,
|
||||||
|
name: "newField2",
|
||||||
|
visible: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = syncSchema(_.cloneDeep(view), newTableSchema, undefined)
|
||||||
|
expect(result).toEqual({
|
||||||
|
...view,
|
||||||
|
schemaUI: undefined,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it("deleting columns will not change the view schema", () => {
|
||||||
|
const view: ViewV2 = {
|
||||||
|
...basicView,
|
||||||
|
columns: ["name", "id", "description"],
|
||||||
|
}
|
||||||
|
const { name, description, ...newTableSchema } = basicTable.schema
|
||||||
|
|
||||||
|
const result = syncSchema(_.cloneDeep(view), newTableSchema, undefined)
|
||||||
|
expect(result).toEqual({
|
||||||
|
...view,
|
||||||
|
columns: ["id"],
|
||||||
|
schemaUI: undefined,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it("renaming mapped columns will update the view column mapping", () => {
|
||||||
|
const view: ViewV2 = {
|
||||||
|
...basicView,
|
||||||
|
columns: ["name", "id", "description"],
|
||||||
|
}
|
||||||
|
const { description, ...newTableSchema } = {
|
||||||
|
...basicTable.schema,
|
||||||
|
updatedDescription: {
|
||||||
|
...basicTable.schema.description,
|
||||||
|
name: "updatedDescription",
|
||||||
|
},
|
||||||
|
} as TableSchema
|
||||||
|
|
||||||
|
const result = syncSchema(_.cloneDeep(view), newTableSchema, {
|
||||||
|
old: "description",
|
||||||
|
updated: "updatedDescription",
|
||||||
|
})
|
||||||
|
expect(result).toEqual({
|
||||||
|
...view,
|
||||||
|
columns: ["name", "id", "updatedDescription"],
|
||||||
|
schemaUI: undefined,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("view with schema", () => {
|
||||||
|
it("no table schema changes will not amend the view", () => {
|
||||||
|
const view: ViewV2 = {
|
||||||
|
...basicView,
|
||||||
|
columns: ["name", "id", "description"],
|
||||||
|
schemaUI: {
|
||||||
|
name: { visible: true, width: 100 },
|
||||||
|
id: { visible: true, width: 20 },
|
||||||
|
description: { visible: false },
|
||||||
|
hiddenField: { visible: false },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
const result = syncSchema(
|
||||||
|
_.cloneDeep(view),
|
||||||
|
basicTable.schema,
|
||||||
|
undefined
|
||||||
|
)
|
||||||
|
expect(result).toEqual(view)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("adding new columns will add them as not visible to the view", () => {
|
||||||
|
const view: ViewV2 = {
|
||||||
|
...basicView,
|
||||||
|
columns: ["name", "id", "description"],
|
||||||
|
schemaUI: {
|
||||||
|
name: { visible: true, width: 100 },
|
||||||
|
id: { visible: true, width: 20 },
|
||||||
|
description: { visible: false },
|
||||||
|
hiddenField: { visible: false },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const newTableSchema = {
|
||||||
|
...basicTable.schema,
|
||||||
|
newField1: {
|
||||||
|
type: FieldType.STRING,
|
||||||
|
name: "newField1",
|
||||||
|
visible: true,
|
||||||
|
},
|
||||||
|
newField2: {
|
||||||
|
type: FieldType.NUMBER,
|
||||||
|
name: "newField2",
|
||||||
|
visible: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = syncSchema(_.cloneDeep(view), newTableSchema, undefined)
|
||||||
|
expect(result).toEqual({
|
||||||
|
...view,
|
||||||
|
schemaUI: {
|
||||||
|
...view.schemaUI,
|
||||||
|
newField1: { visible: false },
|
||||||
|
newField2: { visible: false },
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it("deleting columns will remove them from the UI", () => {
|
||||||
|
const view: ViewV2 = {
|
||||||
|
...basicView,
|
||||||
|
columns: ["name", "id", "description"],
|
||||||
|
schemaUI: {
|
||||||
|
name: { visible: true, width: 100 },
|
||||||
|
id: { visible: true, width: 20 },
|
||||||
|
description: { visible: false },
|
||||||
|
hiddenField: { visible: false },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
const { name, description, ...newTableSchema } = basicTable.schema
|
||||||
|
|
||||||
|
const result = syncSchema(_.cloneDeep(view), newTableSchema, undefined)
|
||||||
|
expect(result).toEqual({
|
||||||
|
...view,
|
||||||
|
columns: ["id"],
|
||||||
|
schemaUI: {
|
||||||
|
...view.schemaUI,
|
||||||
|
name: undefined,
|
||||||
|
description: undefined,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it("can handle additions and deletions at the same them UI", () => {
|
||||||
|
const view: ViewV2 = {
|
||||||
|
...basicView,
|
||||||
|
columns: ["name", "id", "description"],
|
||||||
|
schemaUI: {
|
||||||
|
name: { visible: true, width: 100 },
|
||||||
|
id: { visible: true, width: 20 },
|
||||||
|
description: { visible: false },
|
||||||
|
hiddenField: { visible: false },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
const { name, description, ...newTableSchema } = {
|
||||||
|
...basicTable.schema,
|
||||||
|
newField1: {
|
||||||
|
type: FieldType.STRING,
|
||||||
|
name: "newField1",
|
||||||
|
visible: true,
|
||||||
|
},
|
||||||
|
} as TableSchema
|
||||||
|
|
||||||
|
const result = syncSchema(_.cloneDeep(view), newTableSchema, undefined)
|
||||||
|
expect(result).toEqual({
|
||||||
|
...view,
|
||||||
|
columns: ["id"],
|
||||||
|
schemaUI: {
|
||||||
|
...view.schemaUI,
|
||||||
|
name: undefined,
|
||||||
|
description: undefined,
|
||||||
|
newField1: { visible: false },
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it("renaming mapped columns will update the view column mapping and it's schema", () => {
|
||||||
|
const view: ViewV2 = {
|
||||||
|
...basicView,
|
||||||
|
columns: ["name", "id", "description"],
|
||||||
|
schemaUI: {
|
||||||
|
name: { visible: true },
|
||||||
|
id: { visible: true },
|
||||||
|
description: { visible: true, width: 150, icon: "ic-any" },
|
||||||
|
hiddenField: { visible: false },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
const { description, ...newTableSchema } = {
|
||||||
|
...basicTable.schema,
|
||||||
|
updatedDescription: {
|
||||||
|
...basicTable.schema.description,
|
||||||
|
name: "updatedDescription",
|
||||||
|
},
|
||||||
|
} as TableSchema
|
||||||
|
|
||||||
|
const result = syncSchema(_.cloneDeep(view), newTableSchema, {
|
||||||
|
old: "description",
|
||||||
|
updated: "updatedDescription",
|
||||||
|
})
|
||||||
|
expect(result).toEqual({
|
||||||
|
...view,
|
||||||
|
columns: ["name", "id", "updatedDescription"],
|
||||||
|
schemaUI: {
|
||||||
|
...view.schemaUI,
|
||||||
|
description: undefined,
|
||||||
|
updatedDescription: { visible: true, width: 150, icon: "ic-any" },
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it("changing no UI schema will not affect the view", () => {
|
||||||
|
const view: ViewV2 = {
|
||||||
|
...basicView,
|
||||||
|
columns: ["name", "id", "description"],
|
||||||
|
schemaUI: {
|
||||||
|
name: { visible: true, width: 100 },
|
||||||
|
id: { visible: true, width: 20 },
|
||||||
|
description: { visible: false },
|
||||||
|
hiddenField: { visible: false },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
const result = syncSchema(
|
||||||
|
_.cloneDeep(view),
|
||||||
|
{
|
||||||
|
...basicTable.schema,
|
||||||
|
id: {
|
||||||
|
...basicTable.schema.id,
|
||||||
|
type: FieldType.NUMBER,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
undefined
|
||||||
|
)
|
||||||
|
expect(result).toEqual(view)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("changing table column UI fields will not affect the view schema", () => {
|
||||||
|
const view: ViewV2 = {
|
||||||
|
...basicView,
|
||||||
|
columns: ["name", "id", "description"],
|
||||||
|
schemaUI: {
|
||||||
|
name: { visible: true, width: 100 },
|
||||||
|
id: { visible: true, width: 20 },
|
||||||
|
description: { visible: false },
|
||||||
|
hiddenField: { visible: false },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
const result = syncSchema(
|
||||||
|
_.cloneDeep(view),
|
||||||
|
{
|
||||||
|
...basicTable.schema,
|
||||||
|
id: {
|
||||||
|
...basicTable.schema.id,
|
||||||
|
visible: !basicTable.schema.id.visible,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
undefined
|
||||||
|
)
|
||||||
|
expect(result).toEqual(view)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,4 +1,10 @@
|
||||||
import { Table, TableSchema, View, ViewV2 } from "../../../documents"
|
import {
|
||||||
|
Table,
|
||||||
|
TableRequest,
|
||||||
|
TableSchema,
|
||||||
|
View,
|
||||||
|
ViewV2,
|
||||||
|
} from "../../../documents"
|
||||||
|
|
||||||
interface ViewV2Response extends ViewV2 {
|
interface ViewV2Response extends ViewV2 {
|
||||||
schema: TableSchema
|
schema: TableSchema
|
||||||
|
@ -11,3 +17,7 @@ export interface TableResponse extends Table {
|
||||||
}
|
}
|
||||||
|
|
||||||
export type FetchTablesResponse = TableResponse[]
|
export type FetchTablesResponse = TableResponse[]
|
||||||
|
|
||||||
|
export interface SaveTableRequest extends TableRequest {}
|
||||||
|
|
||||||
|
export type SaveTableResponse = Table
|
||||||
|
|
Loading…
Reference in a new issue