diff --git a/packages/builder/src/components/backend/DataTable/modals/FilterModal.svelte b/packages/builder/src/components/backend/DataTable/modals/FilterModal.svelte index 9c6f4956b0..12e5f23814 100644 --- a/packages/builder/src/components/backend/DataTable/modals/FilterModal.svelte +++ b/packages/builder/src/components/backend/DataTable/modals/FilterModal.svelte @@ -82,34 +82,30 @@ function isMultipleChoice(field) { return ( - (viewTable.schema[field].constraints && - viewTable.schema[field].constraints.inclusion && - viewTable.schema[field].constraints.inclusion.length) || - viewTable.schema[field].type === "boolean" + viewTable.schema[field]?.constraints?.inclusion?.length || + viewTable.schema[field]?.type === "boolean" ) } function fieldOptions(field) { - return viewTable.schema[field].type === "options" - ? viewTable.schema[field].constraints.inclusion + return viewTable.schema[field]?.type === "options" + ? viewTable.schema[field]?.constraints.inclusion : [true, false] } function isDate(field) { - return viewTable.schema[field].type === "datetime" + return viewTable.schema[field]?.type === "datetime" } function isNumber(field) { - return viewTable.schema[field].type === "number" + return viewTable.schema[field]?.type === "number" } const fieldChanged = filter => ev => { - // reset if type changed - if ( - filter.key && - ev.detail && - viewTable.schema[filter.key].type !== viewTable.schema[ev.detail].type - ) { + // Reset if type changed + const oldType = viewTable.schema[filter.key]?.type + const newType = viewTable.schema[ev.detail]?.type + if (filter.key && ev.detail && oldType !== newType) { filter.value = "" } } diff --git a/packages/server/src/api/controllers/table/utils.js b/packages/server/src/api/controllers/table/utils.js index fd3ea6693c..65c081f90e 100644 --- a/packages/server/src/api/controllers/table/utils.js +++ b/packages/server/src/api/controllers/table/utils.js @@ -13,6 +13,8 @@ const { isExternalTable, breakExternalTableId, } = require("../../../integrations/utils") +const { getViews, saveView } = require("../view/utils") +const viewTemplate = require("../view/viewBuilder") exports.checkForColumnUpdates = async (db, oldTable, updatedTable) => { let updatedRows = [] @@ -25,6 +27,7 @@ exports.checkForColumnUpdates = async (db, oldTable, updatedTable) => { } // check for renaming of columns or deleted columns if (rename || deletedColumns.length !== 0) { + // Update all rows const rows = await db.allDocs( getRowParams(updatedTable._id, null, { include_docs: true, @@ -39,6 +42,9 @@ exports.checkForColumnUpdates = async (db, oldTable, updatedTable) => { } return doc }) + + // Update views + await exports.checkForViewUpdates(db, updatedTable, rename, deletedColumns) delete updatedTable._rename } return { rows: updatedRows, table: updatedTable } @@ -237,4 +243,76 @@ exports.getTable = async (appId, tableId) => { } } +exports.checkForViewUpdates = async (db, table, rename, deletedColumns) => { + const views = await getViews(db) + const tableViews = views.filter(view => view.meta.tableId === table._id) + + // Check each table view to see if impacted by this table action + for (let view of tableViews) { + let needsUpdated = false + + // First check for renames, otherwise check for deletions + if (rename) { + // Update calculation field if required + if (view.meta.field === rename.old) { + view.meta.field = rename.updated + needsUpdated = true + } + + // Update group by field if required + if (view.meta.groupBy === rename.old) { + view.meta.groupBy = rename.updated + needsUpdated = true + } + + // Update filters if required + if (view.meta.filters) { + view.meta.filters.forEach(filter => { + if (filter.key === rename.old) { + filter.key = rename.updated + needsUpdated = true + } + }) + } + } else if (deletedColumns) { + deletedColumns.forEach(column => { + // Remove calculation statement if required + if (view.meta.field === column) { + delete view.meta.field + delete view.meta.calculation + delete view.meta.groupBy + needsUpdated = true + } + + // Remove group by field if required + if (view.meta.groupBy === column) { + delete view.meta.groupBy + needsUpdated = true + } + + // Remove filters referencing deleted field if required + if (view.meta.filters && view.meta.filters.length) { + const initialLength = view.meta.filters.length + view.meta.filters = view.meta.filters.filter(filter => { + return filter.key !== column + }) + if (initialLength !== view.meta.filters.length) { + needsUpdated = true + } + } + }) + } + + // Update view if required + if (needsUpdated) { + const newViewTemplate = viewTemplate(view.meta) + await saveView(db, null, view.name, newViewTemplate) + if (!newViewTemplate.meta.schema) { + newViewTemplate.meta.schema = table.schema + } + table.views[view.name] = newViewTemplate.meta + } + } +} + exports.TableSaveFunctions = TableSaveFunctions