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 { 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} />
|
||||
<div class="autocolumns">
|
||||
<label>Auto columns</label>
|
||||
<Label extraSmall grey>Auto Columns</Label>
|
||||
<div class="toggles">
|
||||
<div class="toggle-1">
|
||||
<Toggle
|
||||
|
@ -110,8 +122,8 @@
|
|||
text="Created at"
|
||||
bind:checked={autoColumns.createdAt} />
|
||||
<Toggle
|
||||
text="Autonumber"
|
||||
bind:checked={autoColumns.autoNumber} />
|
||||
text="Auto ID"
|
||||
bind:checked={autoColumns.autoID} />
|
||||
</div>
|
||||
<div class="toggle-2">
|
||||
<Toggle
|
||||
|
@ -142,14 +154,14 @@
|
|||
display: flex;
|
||||
width: 100%;
|
||||
margin-top: 6px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.toggle-1 :global(> *) {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.toggle-2 :global(> *) {
|
||||
margin-top: 10px;
|
||||
margin-left: 10px;
|
||||
margin-bottom: 10px;
|
||||
margin-left: 20px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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
|
||||
)
|
||||
|
|
|
@ -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.")
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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], {
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue