First lot of work to update the auto fields into schema.
This commit is contained in:
parent
fa921951a3
commit
7a2405c756
|
@ -14,6 +14,8 @@
|
||||||
import { NEW_ROW_TEMPLATE } from "builderStore/store/screenTemplates/newRowScreen"
|
import { NEW_ROW_TEMPLATE } from "builderStore/store/screenTemplates/newRowScreen"
|
||||||
import { ROW_DETAIL_TEMPLATE } from "builderStore/store/screenTemplates/rowDetailScreen"
|
import { ROW_DETAIL_TEMPLATE } from "builderStore/store/screenTemplates/rowDetailScreen"
|
||||||
import { ROW_LIST_TEMPLATE } from "builderStore/store/screenTemplates/rowListScreen"
|
import { ROW_LIST_TEMPLATE } from "builderStore/store/screenTemplates/rowListScreen"
|
||||||
|
import { FIELDS } from "constants/backend"
|
||||||
|
import { cloneDeep } from "lodash/fp"
|
||||||
|
|
||||||
const defaultScreens = [
|
const defaultScreens = [
|
||||||
NEW_ROW_TEMPLATE,
|
NEW_ROW_TEMPLATE,
|
||||||
|
@ -27,11 +29,22 @@
|
||||||
let error = ""
|
let error = ""
|
||||||
let createAutoscreens = true
|
let createAutoscreens = true
|
||||||
let autoColumns = {
|
let autoColumns = {
|
||||||
createdBy: false,
|
createdBy: true,
|
||||||
createdAt: false,
|
createdAt: true,
|
||||||
updatedBy: false,
|
updatedBy: true,
|
||||||
updatedAt: false,
|
updatedAt: true,
|
||||||
autoNumber: false,
|
autoID: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
function addAutoColumns(schema) {
|
||||||
|
for (let [property, enabled] of Object.entries(autoColumns)) {
|
||||||
|
if (!enabled) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
const autoColDef = cloneDeep(FIELDS.AUTO)
|
||||||
|
autoColDef.subtype = property
|
||||||
|
schema[property] = autoColDef
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkValid(evt) {
|
function checkValid(evt) {
|
||||||
|
@ -46,8 +59,7 @@
|
||||||
async function saveTable() {
|
async function saveTable() {
|
||||||
let newTable = {
|
let newTable = {
|
||||||
name,
|
name,
|
||||||
schema: dataImport.schema || {},
|
schema: addAutoColumns(dataImport.schema || {}),
|
||||||
autoColumns,
|
|
||||||
dataImport,
|
dataImport,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +112,7 @@
|
||||||
bind:value={name}
|
bind:value={name}
|
||||||
{error} />
|
{error} />
|
||||||
<div class="autocolumns">
|
<div class="autocolumns">
|
||||||
<label>Auto columns</label>
|
<Label extraSmall grey>Auto Columns</Label>
|
||||||
<div class="toggles">
|
<div class="toggles">
|
||||||
<div class="toggle-1">
|
<div class="toggle-1">
|
||||||
<Toggle
|
<Toggle
|
||||||
|
@ -110,8 +122,8 @@
|
||||||
text="Created at"
|
text="Created at"
|
||||||
bind:checked={autoColumns.createdAt} />
|
bind:checked={autoColumns.createdAt} />
|
||||||
<Toggle
|
<Toggle
|
||||||
text="Autonumber"
|
text="Auto ID"
|
||||||
bind:checked={autoColumns.autoNumber} />
|
bind:checked={autoColumns.autoID} />
|
||||||
</div>
|
</div>
|
||||||
<div class="toggle-2">
|
<div class="toggle-2">
|
||||||
<Toggle
|
<Toggle
|
||||||
|
@ -142,14 +154,14 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-top: 6px;
|
margin-top: 6px;
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.toggle-1 :global(> *) {
|
.toggle-1 :global(> *) {
|
||||||
margin-top: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.toggle-2 :global(> *) {
|
.toggle-2 :global(> *) {
|
||||||
margin-top: 10px;
|
margin-bottom: 10px;
|
||||||
margin-left: 10px;
|
margin-left: 20px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -80,6 +80,13 @@ export const FIELDS = {
|
||||||
presence: false,
|
presence: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
AUTO: {
|
||||||
|
name: "Auto Column",
|
||||||
|
icon: "ri-magic-line",
|
||||||
|
type: "auto",
|
||||||
|
// no constraints for auto-columns
|
||||||
|
// these are fully created serverside
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const FILE_TYPES = {
|
export const FILE_TYPES = {
|
||||||
|
|
|
@ -13,6 +13,7 @@ const {
|
||||||
inputProcessing,
|
inputProcessing,
|
||||||
outputProcessing,
|
outputProcessing,
|
||||||
} = require("../../utilities/rowProcessor")
|
} = require("../../utilities/rowProcessor")
|
||||||
|
const { FieldTypes } = require("../../constants")
|
||||||
|
|
||||||
const TABLE_VIEW_BEGINS_WITH = `all${SEPARATOR}${DocumentTypes.TABLE}${SEPARATOR}`
|
const TABLE_VIEW_BEGINS_WITH = `all${SEPARATOR}${DocumentTypes.TABLE}${SEPARATOR}`
|
||||||
|
|
||||||
|
@ -261,7 +262,7 @@ exports.search = async function(ctx) {
|
||||||
|
|
||||||
const table = await db.get(ctx.params.tableId)
|
const table = await db.get(ctx.params.tableId)
|
||||||
|
|
||||||
ctx.body = await enrichRows(appId, table, rows)
|
ctx.body = await outputProcessing(appId, table, rows)
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.fetchTableRows = async function(ctx) {
|
exports.fetchTableRows = async function(ctx) {
|
||||||
|
@ -384,7 +385,7 @@ exports.fetchEnrichedRow = async function(ctx) {
|
||||||
// insert the link rows in the correct place throughout the main row
|
// insert the link rows in the correct place throughout the main row
|
||||||
for (let fieldName of Object.keys(table.schema)) {
|
for (let fieldName of Object.keys(table.schema)) {
|
||||||
let field = table.schema[fieldName]
|
let field = table.schema[fieldName]
|
||||||
if (field.type === "link") {
|
if (field.type === FieldTypes.LINK) {
|
||||||
row[fieldName] = linkedRows.filter(
|
row[fieldName] = linkedRows.filter(
|
||||||
linkRow => linkRow.tableId === field.tableId
|
linkRow => linkRow.tableId === field.tableId
|
||||||
)
|
)
|
||||||
|
|
|
@ -8,6 +8,7 @@ const {
|
||||||
generateRowID,
|
generateRowID,
|
||||||
} = require("../../db/utils")
|
} = require("../../db/utils")
|
||||||
const { isEqual } = require("lodash/fp")
|
const { isEqual } = require("lodash/fp")
|
||||||
|
const { FieldTypes } = require("../../constants")
|
||||||
|
|
||||||
async function checkForColumnUpdates(db, oldTable, updatedTable) {
|
async function checkForColumnUpdates(db, oldTable, updatedTable) {
|
||||||
let updatedRows
|
let updatedRows
|
||||||
|
@ -91,7 +92,7 @@ exports.save = async function(ctx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// rename row fields when table column is renamed
|
// rename row fields when table column is renamed
|
||||||
if (_rename && tableToSave.schema[_rename.updated].type === "link") {
|
if (_rename && tableToSave.schema[_rename.updated].type === FieldTypes.LINK) {
|
||||||
ctx.throw(400, "Cannot rename a linked column.")
|
ctx.throw(400, "Cannot rename a linked column.")
|
||||||
} else if (_rename && tableToSave.primaryDisplay === _rename.old) {
|
} else if (_rename && tableToSave.primaryDisplay === _rename.old) {
|
||||||
ctx.throw(400, "Cannot rename the display column.")
|
ctx.throw(400, "Cannot rename the display column.")
|
||||||
|
|
|
@ -22,12 +22,6 @@ function generateSaveValidator() {
|
||||||
schema: Joi.object().required(),
|
schema: Joi.object().required(),
|
||||||
name: Joi.string().required(),
|
name: Joi.string().required(),
|
||||||
views: Joi.object(),
|
views: Joi.object(),
|
||||||
autoColumns: Joi.object({
|
|
||||||
createdBy: Joi.boolean(),
|
|
||||||
createdAt: Joi.boolean(),
|
|
||||||
updatedBy: Joi.boolean(),
|
|
||||||
updatedAt: Joi.boolean(),
|
|
||||||
}),
|
|
||||||
dataImport: Joi.object(),
|
dataImport: Joi.object(),
|
||||||
}).unknown(true))
|
}).unknown(true))
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,18 @@ const USERS_TABLE_SCHEMA = {
|
||||||
primaryDisplay: "email",
|
primaryDisplay: "email",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exports.FieldTypes = {
|
||||||
|
STRING: "string",
|
||||||
|
LONGFORM: "longform",
|
||||||
|
OPTIONS: "options",
|
||||||
|
NUMBER: "number",
|
||||||
|
BOOLEAN: "boolean",
|
||||||
|
DATETIME: "datetime",
|
||||||
|
ATTACHMENT: "attachment",
|
||||||
|
LINK: "link",
|
||||||
|
AUTO: "auto",
|
||||||
|
}
|
||||||
|
|
||||||
exports.AuthTypes = AuthTypes
|
exports.AuthTypes = AuthTypes
|
||||||
exports.USERS_TABLE_SCHEMA = USERS_TABLE_SCHEMA
|
exports.USERS_TABLE_SCHEMA = USERS_TABLE_SCHEMA
|
||||||
exports.BUILDER_CONFIG_DB = "builder-config-db"
|
exports.BUILDER_CONFIG_DB = "builder-config-db"
|
||||||
|
|
|
@ -2,6 +2,7 @@ const CouchDB = require("../index")
|
||||||
const { IncludeDocs, getLinkDocuments } = require("./linkUtils")
|
const { IncludeDocs, getLinkDocuments } = require("./linkUtils")
|
||||||
const { generateLinkID } = require("../utils")
|
const { generateLinkID } = require("../utils")
|
||||||
const Sentry = require("@sentry/node")
|
const Sentry = require("@sentry/node")
|
||||||
|
const { FieldTypes } = require("../../constants")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new link document structure which can be put to the database. It is important to
|
* Creates a new link document structure which can be put to the database. It is important to
|
||||||
|
@ -26,7 +27,7 @@ function LinkDocument(
|
||||||
// build the ID out of unique references to this link document
|
// build the ID out of unique references to this link document
|
||||||
this._id = generateLinkID(tableId1, tableId2, rowId1, rowId2)
|
this._id = generateLinkID(tableId1, tableId2, rowId1, rowId2)
|
||||||
// required for referencing in view
|
// required for referencing in view
|
||||||
this.type = "link"
|
this.type = FieldTypes.LINK
|
||||||
this.doc1 = {
|
this.doc1 = {
|
||||||
tableId: tableId1,
|
tableId: tableId1,
|
||||||
fieldName: fieldName1,
|
fieldName: fieldName1,
|
||||||
|
@ -75,7 +76,7 @@ class LinkController {
|
||||||
}
|
}
|
||||||
for (let fieldName of Object.keys(table.schema)) {
|
for (let fieldName of Object.keys(table.schema)) {
|
||||||
const { type } = table.schema[fieldName]
|
const { type } = table.schema[fieldName]
|
||||||
if (type === "link") {
|
if (type === FieldTypes.LINK) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -123,7 +124,7 @@ class LinkController {
|
||||||
// get the links this row wants to make
|
// get the links this row wants to make
|
||||||
const rowField = row[fieldName]
|
const rowField = row[fieldName]
|
||||||
const field = table.schema[fieldName]
|
const field = table.schema[fieldName]
|
||||||
if (field.type === "link" && rowField != null) {
|
if (field.type === FieldTypes.LINK && rowField != null) {
|
||||||
// check which links actual pertain to the update in this row
|
// check which links actual pertain to the update in this row
|
||||||
const thisFieldLinkDocs = linkDocs.filter(
|
const thisFieldLinkDocs = linkDocs.filter(
|
||||||
linkDoc =>
|
linkDoc =>
|
||||||
|
@ -234,7 +235,7 @@ class LinkController {
|
||||||
const schema = table.schema
|
const schema = table.schema
|
||||||
for (let fieldName of Object.keys(schema)) {
|
for (let fieldName of Object.keys(schema)) {
|
||||||
const field = schema[fieldName]
|
const field = schema[fieldName]
|
||||||
if (field.type === "link") {
|
if (field.type === FieldTypes.LINK) {
|
||||||
// handle this in a separate try catch, want
|
// handle this in a separate try catch, want
|
||||||
// the put to bubble up as an error, if can't update
|
// the put to bubble up as an error, if can't update
|
||||||
// table for some reason
|
// table for some reason
|
||||||
|
@ -247,7 +248,7 @@ class LinkController {
|
||||||
// create the link field in the other table
|
// create the link field in the other table
|
||||||
linkedTable.schema[field.fieldName] = {
|
linkedTable.schema[field.fieldName] = {
|
||||||
name: field.fieldName,
|
name: field.fieldName,
|
||||||
type: "link",
|
type: FieldTypes.LINK,
|
||||||
// these are the props of the table that initiated the link
|
// these are the props of the table that initiated the link
|
||||||
tableId: table._id,
|
tableId: table._id,
|
||||||
fieldName: fieldName,
|
fieldName: fieldName,
|
||||||
|
@ -274,7 +275,10 @@ class LinkController {
|
||||||
for (let fieldName of Object.keys(oldTable.schema)) {
|
for (let fieldName of Object.keys(oldTable.schema)) {
|
||||||
const field = oldTable.schema[fieldName]
|
const field = oldTable.schema[fieldName]
|
||||||
// this field has been removed from the table schema
|
// this field has been removed from the table schema
|
||||||
if (field.type === "link" && newTable.schema[fieldName] == null) {
|
if (
|
||||||
|
field.type === FieldTypes.LINK &&
|
||||||
|
newTable.schema[fieldName] == null
|
||||||
|
) {
|
||||||
await this.removeFieldFromTable(fieldName)
|
await this.removeFieldFromTable(fieldName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -295,7 +299,7 @@ class LinkController {
|
||||||
for (let fieldName of Object.keys(schema)) {
|
for (let fieldName of Object.keys(schema)) {
|
||||||
const field = schema[fieldName]
|
const field = schema[fieldName]
|
||||||
try {
|
try {
|
||||||
if (field.type === "link") {
|
if (field.type === FieldTypes.LINK) {
|
||||||
const linkedTable = await this._db.get(field.tableId)
|
const linkedTable = await this._db.get(field.tableId)
|
||||||
delete linkedTable.schema[field.fieldName]
|
delete linkedTable.schema[field.fieldName]
|
||||||
await this._db.put(linkedTable)
|
await this._db.put(linkedTable)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
const CouchDB = require("../index")
|
const CouchDB = require("../index")
|
||||||
const Sentry = require("@sentry/node")
|
const Sentry = require("@sentry/node")
|
||||||
const { ViewNames, getQueryIndex } = require("../utils")
|
const { ViewNames, getQueryIndex } = require("../utils")
|
||||||
|
const { FieldTypes } = require("../../constants")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Only needed so that boolean parameters are being used for includeDocs
|
* Only needed so that boolean parameters are being used for includeDocs
|
||||||
|
@ -23,7 +24,7 @@ exports.createLinkView = async appId => {
|
||||||
const designDoc = await db.get("_design/database")
|
const designDoc = await db.get("_design/database")
|
||||||
const view = {
|
const view = {
|
||||||
map: function(doc) {
|
map: function(doc) {
|
||||||
if (doc.type === "link") {
|
if (doc.type === FieldTypes.LINK) {
|
||||||
let doc1 = doc.doc1
|
let doc1 = doc.doc1
|
||||||
let doc2 = doc.doc2
|
let doc2 = doc.doc2
|
||||||
emit([doc1.tableId, doc1.rowId], {
|
emit([doc1.tableId, doc1.rowId], {
|
||||||
|
|
|
@ -2,48 +2,49 @@ const env = require("../environment")
|
||||||
const { OBJ_STORE_DIRECTORY } = require("../constants")
|
const { OBJ_STORE_DIRECTORY } = require("../constants")
|
||||||
const linkRows = require("../db/linkedRows")
|
const linkRows = require("../db/linkedRows")
|
||||||
const { cloneDeep } = require("lodash/fp")
|
const { cloneDeep } = require("lodash/fp")
|
||||||
|
const { FieldTypes } = require("../constants")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A map of how we convert various properties in rows to each other based on the row type.
|
* A map of how we convert various properties in rows to each other based on the row type.
|
||||||
*/
|
*/
|
||||||
const TYPE_TRANSFORM_MAP = {
|
const TYPE_TRANSFORM_MAP = {
|
||||||
link: {
|
[FieldTypes.LINK]: {
|
||||||
"": [],
|
"": [],
|
||||||
[null]: [],
|
[null]: [],
|
||||||
[undefined]: undefined,
|
[undefined]: undefined,
|
||||||
},
|
},
|
||||||
options: {
|
[FieldTypes.OPTIONS]: {
|
||||||
"": "",
|
"": "",
|
||||||
[null]: "",
|
[null]: "",
|
||||||
[undefined]: undefined,
|
[undefined]: undefined,
|
||||||
},
|
},
|
||||||
string: {
|
[FieldTypes.STRING]: {
|
||||||
"": "",
|
"": "",
|
||||||
[null]: "",
|
[null]: "",
|
||||||
[undefined]: undefined,
|
[undefined]: undefined,
|
||||||
},
|
},
|
||||||
longform: {
|
[FieldTypes.LONGFORM]: {
|
||||||
"": "",
|
"": "",
|
||||||
[null]: "",
|
[null]: "",
|
||||||
[undefined]: undefined,
|
[undefined]: undefined,
|
||||||
},
|
},
|
||||||
number: {
|
[FieldTypes.NUMBER]: {
|
||||||
"": null,
|
"": null,
|
||||||
[null]: null,
|
[null]: null,
|
||||||
[undefined]: undefined,
|
[undefined]: undefined,
|
||||||
parse: n => parseFloat(n),
|
parse: n => parseFloat(n),
|
||||||
},
|
},
|
||||||
datetime: {
|
[FieldTypes.DATETIME]: {
|
||||||
"": null,
|
"": null,
|
||||||
[undefined]: undefined,
|
[undefined]: undefined,
|
||||||
[null]: null,
|
[null]: null,
|
||||||
},
|
},
|
||||||
attachment: {
|
[FieldTypes.ATTACHMENT]: {
|
||||||
"": [],
|
"": [],
|
||||||
[null]: [],
|
[null]: [],
|
||||||
[undefined]: undefined,
|
[undefined]: undefined,
|
||||||
},
|
},
|
||||||
boolean: {
|
[FieldTypes.BOOLEAN]: {
|
||||||
"": null,
|
"": null,
|
||||||
[null]: null,
|
[null]: null,
|
||||||
[undefined]: undefined,
|
[undefined]: undefined,
|
||||||
|
@ -102,7 +103,7 @@ exports.outputProcessing = async (appId, table, rows) => {
|
||||||
// update the attachments URL depending on hosting
|
// update the attachments URL depending on hosting
|
||||||
if (env.CLOUD && env.SELF_HOSTED) {
|
if (env.CLOUD && env.SELF_HOSTED) {
|
||||||
for (let [property, column] of Object.entries(table.schema)) {
|
for (let [property, column] of Object.entries(table.schema)) {
|
||||||
if (column.type === "attachment") {
|
if (column.type === FieldTypes.ATTACHMENT) {
|
||||||
for (let row of outputRows) {
|
for (let row of outputRows) {
|
||||||
if (row[property] == null || row[property].length === 0) {
|
if (row[property] == null || row[property].length === 0) {
|
||||||
continue
|
continue
|
||||||
|
|
Loading…
Reference in New Issue