From ca20cbeecac510597b27ea331c6da5753d948e81 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Wed, 10 Feb 2021 17:55:19 +0000 Subject: [PATCH] First lot of work to update the auto fields into schema. --- .../modals/CreateTableModal.svelte | 40 ++++++++++++------- .../builder/src/constants/backend/index.js | 7 ++++ packages/server/src/api/controllers/row.js | 5 ++- packages/server/src/api/controllers/table.js | 3 +- packages/server/src/api/routes/table.js | 6 --- packages/server/src/constants/index.js | 12 ++++++ .../src/db/linkedRows/LinkController.js | 18 +++++---- .../server/src/db/linkedRows/linkUtils.js | 3 +- packages/server/src/utilities/rowProcessor.js | 19 ++++----- 9 files changed, 73 insertions(+), 40 deletions(-) diff --git a/packages/builder/src/components/backend/TableNavigator/modals/CreateTableModal.svelte b/packages/builder/src/components/backend/TableNavigator/modals/CreateTableModal.svelte index b6bf9ec8d7..b9a2307433 100644 --- a/packages/builder/src/components/backend/TableNavigator/modals/CreateTableModal.svelte +++ b/packages/builder/src/components/backend/TableNavigator/modals/CreateTableModal.svelte @@ -14,6 +14,8 @@ import { NEW_ROW_TEMPLATE } from "builderStore/store/screenTemplates/newRowScreen" import { ROW_DETAIL_TEMPLATE } from "builderStore/store/screenTemplates/rowDetailScreen" import { ROW_LIST_TEMPLATE } from "builderStore/store/screenTemplates/rowListScreen" + import { FIELDS } from "constants/backend" + import { cloneDeep } from "lodash/fp" const defaultScreens = [ NEW_ROW_TEMPLATE, @@ -27,11 +29,22 @@ let error = "" let createAutoscreens = true let autoColumns = { - createdBy: false, - createdAt: false, - updatedBy: false, - updatedAt: false, - autoNumber: false, + createdBy: true, + createdAt: true, + updatedBy: true, + updatedAt: true, + 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) { @@ -46,8 +59,7 @@ async function saveTable() { let newTable = { name, - schema: dataImport.schema || {}, - autoColumns, + schema: addAutoColumns(dataImport.schema || {}), dataImport, } @@ -100,7 +112,7 @@ bind:value={name} {error} />
- +
+ text="Auto ID" + bind:checked={autoColumns.autoID} />
*) { - margin-top: 10px; + margin-bottom: 10px; } + .toggle-2 :global(> *) { - margin-top: 10px; - margin-left: 10px; + margin-bottom: 10px; + margin-left: 20px; } diff --git a/packages/builder/src/constants/backend/index.js b/packages/builder/src/constants/backend/index.js index 80eaf613f8..9ef95f3c61 100644 --- a/packages/builder/src/constants/backend/index.js +++ b/packages/builder/src/constants/backend/index.js @@ -80,6 +80,13 @@ export const FIELDS = { 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 = { diff --git a/packages/server/src/api/controllers/row.js b/packages/server/src/api/controllers/row.js index 0c4163aa22..34f027002c 100644 --- a/packages/server/src/api/controllers/row.js +++ b/packages/server/src/api/controllers/row.js @@ -13,6 +13,7 @@ const { inputProcessing, outputProcessing, } = require("../../utilities/rowProcessor") +const { FieldTypes } = require("../../constants") 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) - ctx.body = await enrichRows(appId, table, rows) + ctx.body = await outputProcessing(appId, table, rows) } 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 for (let fieldName of Object.keys(table.schema)) { let field = table.schema[fieldName] - if (field.type === "link") { + if (field.type === FieldTypes.LINK) { row[fieldName] = linkedRows.filter( linkRow => linkRow.tableId === field.tableId ) diff --git a/packages/server/src/api/controllers/table.js b/packages/server/src/api/controllers/table.js index 1fa77b0b2b..d3e7213fdb 100644 --- a/packages/server/src/api/controllers/table.js +++ b/packages/server/src/api/controllers/table.js @@ -8,6 +8,7 @@ const { generateRowID, } = require("../../db/utils") const { isEqual } = require("lodash/fp") +const { FieldTypes } = require("../../constants") async function checkForColumnUpdates(db, oldTable, updatedTable) { let updatedRows @@ -91,7 +92,7 @@ exports.save = async function(ctx) { } // 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.") } else if (_rename && tableToSave.primaryDisplay === _rename.old) { ctx.throw(400, "Cannot rename the display column.") diff --git a/packages/server/src/api/routes/table.js b/packages/server/src/api/routes/table.js index 0e6b916c24..7c7f45afeb 100644 --- a/packages/server/src/api/routes/table.js +++ b/packages/server/src/api/routes/table.js @@ -22,12 +22,6 @@ function generateSaveValidator() { schema: Joi.object().required(), name: Joi.string().required(), views: Joi.object(), - autoColumns: Joi.object({ - createdBy: Joi.boolean(), - createdAt: Joi.boolean(), - updatedBy: Joi.boolean(), - updatedAt: Joi.boolean(), - }), dataImport: Joi.object(), }).unknown(true)) } diff --git a/packages/server/src/constants/index.js b/packages/server/src/constants/index.js index 2e18de98af..54dedbcf11 100644 --- a/packages/server/src/constants/index.js +++ b/packages/server/src/constants/index.js @@ -39,6 +39,18 @@ const USERS_TABLE_SCHEMA = { 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.USERS_TABLE_SCHEMA = USERS_TABLE_SCHEMA exports.BUILDER_CONFIG_DB = "builder-config-db" diff --git a/packages/server/src/db/linkedRows/LinkController.js b/packages/server/src/db/linkedRows/LinkController.js index 061a9ac1ae..ca64cb3430 100644 --- a/packages/server/src/db/linkedRows/LinkController.js +++ b/packages/server/src/db/linkedRows/LinkController.js @@ -2,6 +2,7 @@ const CouchDB = require("../index") const { IncludeDocs, getLinkDocuments } = require("./linkUtils") const { generateLinkID } = require("../utils") 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 @@ -26,7 +27,7 @@ function LinkDocument( // build the ID out of unique references to this link document this._id = generateLinkID(tableId1, tableId2, rowId1, rowId2) // required for referencing in view - this.type = "link" + this.type = FieldTypes.LINK this.doc1 = { tableId: tableId1, fieldName: fieldName1, @@ -75,7 +76,7 @@ class LinkController { } for (let fieldName of Object.keys(table.schema)) { const { type } = table.schema[fieldName] - if (type === "link") { + if (type === FieldTypes.LINK) { return true } } @@ -123,7 +124,7 @@ class LinkController { // get the links this row wants to make const rowField = row[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 const thisFieldLinkDocs = linkDocs.filter( linkDoc => @@ -234,7 +235,7 @@ class LinkController { const schema = table.schema for (let fieldName of Object.keys(schema)) { const field = schema[fieldName] - if (field.type === "link") { + if (field.type === FieldTypes.LINK) { // handle this in a separate try catch, want // the put to bubble up as an error, if can't update // table for some reason @@ -247,7 +248,7 @@ class LinkController { // create the link field in the other table linkedTable.schema[field.fieldName] = { name: field.fieldName, - type: "link", + type: FieldTypes.LINK, // these are the props of the table that initiated the link tableId: table._id, fieldName: fieldName, @@ -274,7 +275,10 @@ class LinkController { for (let fieldName of Object.keys(oldTable.schema)) { const field = oldTable.schema[fieldName] // 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) } } @@ -295,7 +299,7 @@ class LinkController { for (let fieldName of Object.keys(schema)) { const field = schema[fieldName] try { - if (field.type === "link") { + if (field.type === FieldTypes.LINK) { const linkedTable = await this._db.get(field.tableId) delete linkedTable.schema[field.fieldName] await this._db.put(linkedTable) diff --git a/packages/server/src/db/linkedRows/linkUtils.js b/packages/server/src/db/linkedRows/linkUtils.js index cb669cf5c7..ee22a87410 100644 --- a/packages/server/src/db/linkedRows/linkUtils.js +++ b/packages/server/src/db/linkedRows/linkUtils.js @@ -1,6 +1,7 @@ const CouchDB = require("../index") const Sentry = require("@sentry/node") const { ViewNames, getQueryIndex } = require("../utils") +const { FieldTypes } = require("../../constants") /** * 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 view = { map: function(doc) { - if (doc.type === "link") { + if (doc.type === FieldTypes.LINK) { let doc1 = doc.doc1 let doc2 = doc.doc2 emit([doc1.tableId, doc1.rowId], { diff --git a/packages/server/src/utilities/rowProcessor.js b/packages/server/src/utilities/rowProcessor.js index 270f636aae..7ce080cf9f 100644 --- a/packages/server/src/utilities/rowProcessor.js +++ b/packages/server/src/utilities/rowProcessor.js @@ -2,48 +2,49 @@ const env = require("../environment") const { OBJ_STORE_DIRECTORY } = require("../constants") const linkRows = require("../db/linkedRows") 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. */ const TYPE_TRANSFORM_MAP = { - link: { + [FieldTypes.LINK]: { "": [], [null]: [], [undefined]: undefined, }, - options: { + [FieldTypes.OPTIONS]: { "": "", [null]: "", [undefined]: undefined, }, - string: { + [FieldTypes.STRING]: { "": "", [null]: "", [undefined]: undefined, }, - longform: { + [FieldTypes.LONGFORM]: { "": "", [null]: "", [undefined]: undefined, }, - number: { + [FieldTypes.NUMBER]: { "": null, [null]: null, [undefined]: undefined, parse: n => parseFloat(n), }, - datetime: { + [FieldTypes.DATETIME]: { "": null, [undefined]: undefined, [null]: null, }, - attachment: { + [FieldTypes.ATTACHMENT]: { "": [], [null]: [], [undefined]: undefined, }, - boolean: { + [FieldTypes.BOOLEAN]: { "": null, [null]: null, [undefined]: undefined, @@ -102,7 +103,7 @@ exports.outputProcessing = async (appId, table, rows) => { // update the attachments URL depending on hosting if (env.CLOUD && env.SELF_HOSTED) { for (let [property, column] of Object.entries(table.schema)) { - if (column.type === "attachment") { + if (column.type === FieldTypes.ATTACHMENT) { for (let row of outputRows) { if (row[property] == null || row[property].length === 0) { continue