Merge pull request #3317 from Budibase/feature/switchable-types
Allow switching between string <-> options, number <-> boolean
This commit is contained in:
commit
e3358780f4
|
@ -18,6 +18,11 @@
|
||||||
FIELDS,
|
FIELDS,
|
||||||
AUTO_COLUMN_SUB_TYPES,
|
AUTO_COLUMN_SUB_TYPES,
|
||||||
RelationshipTypes,
|
RelationshipTypes,
|
||||||
|
ALLOWABLE_STRING_OPTIONS,
|
||||||
|
ALLOWABLE_NUMBER_OPTIONS,
|
||||||
|
ALLOWABLE_STRING_TYPES,
|
||||||
|
ALLOWABLE_NUMBER_TYPES,
|
||||||
|
SWITCHABLE_TYPES,
|
||||||
} from "constants/backend"
|
} from "constants/backend"
|
||||||
import { getAutoColumnInformation, buildAutoColumn } from "builderStore/utils"
|
import { getAutoColumnInformation, buildAutoColumn } from "builderStore/utils"
|
||||||
import { notifications } from "@budibase/bbui"
|
import { notifications } from "@budibase/bbui"
|
||||||
|
@ -92,6 +97,9 @@
|
||||||
opt.type === table.type &&
|
opt.type === table.type &&
|
||||||
table.sourceId === opt.sourceId
|
table.sourceId === opt.sourceId
|
||||||
)
|
)
|
||||||
|
$: typeEnabled =
|
||||||
|
!originalName ||
|
||||||
|
(originalName && SWITCHABLE_TYPES.indexOf(field.type) !== -1)
|
||||||
|
|
||||||
async function saveColumn() {
|
async function saveColumn() {
|
||||||
if (field.type === AUTO_TYPE) {
|
if (field.type === AUTO_TYPE) {
|
||||||
|
@ -204,7 +212,14 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAllowedTypes() {
|
function getAllowedTypes() {
|
||||||
if (!external) {
|
if (originalName && ALLOWABLE_STRING_TYPES.indexOf(field.type) !== -1) {
|
||||||
|
return ALLOWABLE_STRING_OPTIONS
|
||||||
|
} else if (
|
||||||
|
originalName &&
|
||||||
|
ALLOWABLE_NUMBER_TYPES.indexOf(field.type) !== -1
|
||||||
|
) {
|
||||||
|
return ALLOWABLE_NUMBER_OPTIONS
|
||||||
|
} else if (!external) {
|
||||||
return [
|
return [
|
||||||
...Object.values(fieldDefinitions),
|
...Object.values(fieldDefinitions),
|
||||||
{ name: "Auto Column", type: AUTO_TYPE },
|
{ name: "Auto Column", type: AUTO_TYPE },
|
||||||
|
@ -259,7 +274,7 @@
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Select
|
<Select
|
||||||
disabled={originalName}
|
disabled={!typeEnabled}
|
||||||
label="Type"
|
label="Type"
|
||||||
bind:value={field.type}
|
bind:value={field.type}
|
||||||
on:change={handleTypeChange}
|
on:change={handleTypeChange}
|
||||||
|
|
|
@ -138,3 +138,19 @@ export const RelationshipTypes = {
|
||||||
ONE_TO_MANY: "one-to-many",
|
ONE_TO_MANY: "one-to-many",
|
||||||
MANY_TO_ONE: "many-to-one",
|
MANY_TO_ONE: "many-to-one",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const ALLOWABLE_STRING_OPTIONS = [FIELDS.STRING, FIELDS.OPTIONS]
|
||||||
|
|
||||||
|
export const ALLOWABLE_STRING_TYPES = ALLOWABLE_STRING_OPTIONS.map(
|
||||||
|
opt => opt.type
|
||||||
|
)
|
||||||
|
|
||||||
|
export const ALLOWABLE_NUMBER_OPTIONS = [FIELDS.NUMBER, FIELDS.BOOLEAN]
|
||||||
|
|
||||||
|
export const ALLOWABLE_NUMBER_TYPES = ALLOWABLE_NUMBER_OPTIONS.map(
|
||||||
|
opt => opt.type
|
||||||
|
)
|
||||||
|
|
||||||
|
export const SWITCHABLE_TYPES = ALLOWABLE_NUMBER_TYPES.concat(
|
||||||
|
ALLOWABLE_STRING_TYPES
|
||||||
|
)
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { writable, get } from "svelte/store"
|
||||||
import { views, queries, datasources } from "./"
|
import { views, queries, datasources } from "./"
|
||||||
import { cloneDeep } from "lodash/fp"
|
import { cloneDeep } from "lodash/fp"
|
||||||
import api from "builderStore/api"
|
import api from "builderStore/api"
|
||||||
|
import { SWITCHABLE_TYPES } from "../../constants/backend"
|
||||||
|
|
||||||
export function createTablesStore() {
|
export function createTablesStore() {
|
||||||
const store = writable({})
|
const store = writable({})
|
||||||
|
@ -47,7 +48,11 @@ export function createTablesStore() {
|
||||||
const field = updatedTable.schema[key]
|
const field = updatedTable.schema[key]
|
||||||
const oldField = oldTable?.schema[key]
|
const oldField = oldTable?.schema[key]
|
||||||
// if the type has changed then revert back to the old field
|
// if the type has changed then revert back to the old field
|
||||||
if (oldField != null && oldField?.type !== field.type) {
|
if (
|
||||||
|
oldField != null &&
|
||||||
|
oldField?.type !== field.type &&
|
||||||
|
SWITCHABLE_TYPES.indexOf(oldField?.type) === -1
|
||||||
|
) {
|
||||||
updatedTable.schema[key] = oldField
|
updatedTable.schema[key] = oldField
|
||||||
}
|
}
|
||||||
// field has been renamed
|
// field has been renamed
|
||||||
|
|
|
@ -8,6 +8,7 @@ const {
|
||||||
generateForeignKey,
|
generateForeignKey,
|
||||||
generateJunctionTableName,
|
generateJunctionTableName,
|
||||||
foreignKeyStructure,
|
foreignKeyStructure,
|
||||||
|
hasTypeChanged,
|
||||||
} = require("./utils")
|
} = require("./utils")
|
||||||
const {
|
const {
|
||||||
DataSourceOperation,
|
DataSourceOperation,
|
||||||
|
@ -172,6 +173,10 @@ exports.save = async function (ctx) {
|
||||||
oldTable = await getTable(appId, ctx.request.body._id)
|
oldTable = await getTable(appId, ctx.request.body._id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hasTypeChanged(tableToSave, oldTable)) {
|
||||||
|
ctx.throw(400, "A column type has changed.")
|
||||||
|
}
|
||||||
|
|
||||||
const db = new CouchDB(appId)
|
const db = new CouchDB(appId)
|
||||||
const datasource = await db.get(datasourceId)
|
const datasource = await db.get(datasourceId)
|
||||||
const oldTables = cloneDeep(datasource.entities)
|
const oldTables = cloneDeep(datasource.entities)
|
||||||
|
|
|
@ -2,7 +2,7 @@ const CouchDB = require("../../../db")
|
||||||
const linkRows = require("../../../db/linkedRows")
|
const linkRows = require("../../../db/linkedRows")
|
||||||
const { getRowParams, generateTableID } = require("../../../db/utils")
|
const { getRowParams, generateTableID } = require("../../../db/utils")
|
||||||
const { FieldTypes } = require("../../../constants")
|
const { FieldTypes } = require("../../../constants")
|
||||||
const { TableSaveFunctions } = require("./utils")
|
const { TableSaveFunctions, hasTypeChanged } = require("./utils")
|
||||||
|
|
||||||
exports.save = async function (ctx) {
|
exports.save = async function (ctx) {
|
||||||
const appId = ctx.appId
|
const appId = ctx.appId
|
||||||
|
@ -21,6 +21,10 @@ exports.save = async function (ctx) {
|
||||||
oldTable = await db.get(ctx.request.body._id)
|
oldTable = await db.get(ctx.request.body._id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hasTypeChanged(tableToSave, oldTable)) {
|
||||||
|
ctx.throw(400, "A column type has changed.")
|
||||||
|
}
|
||||||
|
|
||||||
// saving a table is a complex operation, involving many different steps, this
|
// saving a table is a complex operation, involving many different steps, this
|
||||||
// has been broken out into a utility to make it more obvious/easier to manipulate
|
// has been broken out into a utility to make it more obvious/easier to manipulate
|
||||||
const tableSaveFunctions = new TableSaveFunctions({
|
const tableSaveFunctions = new TableSaveFunctions({
|
||||||
|
|
|
@ -8,7 +8,7 @@ const {
|
||||||
const { isEqual } = require("lodash/fp")
|
const { isEqual } = require("lodash/fp")
|
||||||
const { AutoFieldSubTypes, FieldTypes } = require("../../../constants")
|
const { AutoFieldSubTypes, FieldTypes } = require("../../../constants")
|
||||||
const { inputProcessing } = require("../../../utilities/rowProcessor")
|
const { inputProcessing } = require("../../../utilities/rowProcessor")
|
||||||
const { USERS_TABLE_SCHEMA } = require("../../../constants")
|
const { USERS_TABLE_SCHEMA, SwitchableTypes } = require("../../../constants")
|
||||||
const {
|
const {
|
||||||
isExternalTable,
|
isExternalTable,
|
||||||
breakExternalTableId,
|
breakExternalTableId,
|
||||||
|
@ -335,4 +335,21 @@ exports.foreignKeyStructure = (keyName, meta = null) => {
|
||||||
return structure
|
return structure
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exports.hasTypeChanged = (table, oldTable) => {
|
||||||
|
if (!oldTable) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for (let [key, field] of Object.entries(oldTable.schema)) {
|
||||||
|
const oldType = field.type
|
||||||
|
if (!table.schema[key]) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
const newType = table.schema[key].type
|
||||||
|
if (oldType !== newType && SwitchableTypes.indexOf(oldType) === -1) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
exports.TableSaveFunctions = TableSaveFunctions
|
exports.TableSaveFunctions = TableSaveFunctions
|
||||||
|
|
|
@ -45,6 +45,13 @@ exports.FieldTypes = {
|
||||||
INTERNAL: "internal",
|
INTERNAL: "internal",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exports.SwitchableTypes = [
|
||||||
|
exports.FieldTypes.STRING,
|
||||||
|
exports.FieldTypes.OPTIONS,
|
||||||
|
exports.FieldTypes.NUMBER,
|
||||||
|
exports.FieldTypes.BOOLEAN,
|
||||||
|
]
|
||||||
|
|
||||||
exports.RelationshipTypes = {
|
exports.RelationshipTypes = {
|
||||||
ONE_TO_MANY: "one-to-many",
|
ONE_TO_MANY: "one-to-many",
|
||||||
MANY_TO_ONE: "many-to-one",
|
MANY_TO_ONE: "many-to-one",
|
||||||
|
|
|
@ -30,7 +30,7 @@ function generateSchema(
|
||||||
// skip things that are already correct
|
// skip things that are already correct
|
||||||
const oldColumn = oldTable ? oldTable.schema[key] : null
|
const oldColumn = oldTable ? oldTable.schema[key] : null
|
||||||
if (
|
if (
|
||||||
(oldColumn && oldColumn.type === column.type) ||
|
(oldColumn && oldColumn.type) ||
|
||||||
(primaryKey === key && !isJunction)
|
(primaryKey === key && !isJunction)
|
||||||
) {
|
) {
|
||||||
continue
|
continue
|
||||||
|
|
Loading…
Reference in New Issue