Add migration to automatically convert legacy table settings into new action setting

This commit is contained in:
Andrew Kingston 2022-11-15 11:54:45 +00:00
parent e37027f808
commit 2b42b21b3a
6 changed files with 118 additions and 26 deletions

View File

@ -21,6 +21,10 @@ export const DEFINITIONS: MigrationDefinition[] = [
type: MigrationType.APP,
name: MigrationName.EVENT_APP_BACKFILL,
},
{
type: MigrationType.APP,
name: MigrationName.TABLE_SETTINGS,
},
{
type: MigrationType.GLOBAL,
name: MigrationName.EVENT_GLOBAL_BACKFILL,

View File

@ -19,10 +19,7 @@
export let compact
export let size
export let allowSelectRows
export let linkRows
export let linkURL
export let linkColumn
export let linkPeek
export let onClick
export let showTitleButton
export let titleButtonText
export let titleButtonURL
@ -164,10 +161,7 @@
compact,
allowSelectRows,
size,
linkRows,
linkURL,
linkColumn,
linkPeek,
onClick,
}}
/>
</BlockComponent>

View File

@ -15,14 +15,8 @@
export let compact
export let onClick
// Legacy settings, still supported for old apps
export let linkRows
export let linkURL
export let linkColumn
export let linkPeek
const component = getContext("component")
const { styleable, getAction, ActionTypes, routeStore, rowSelectionStore } =
const { styleable, getAction, ActionTypes, rowSelectionStore } =
getContext("sdk")
const customColumnKey = `custom-${Math.random()}`
const customRenderers = [
@ -126,17 +120,6 @@
if (onClick) {
onClick({ row: e.detail })
}
// Handle legacy settings
else if (linkRows && linkURL) {
const col = linkColumn || "_id"
const id = e.detail?.[col]
if (!id) {
return
}
const split = linkURL.split("/:")
routeStore.actions.navigate(`${split[0]}/${id}`, linkPeek)
}
}
onDestroy(() => {

View File

@ -0,0 +1,101 @@
import { getScreenParams } from "../../db/utils"
import { Screen } from "@budibase/types"
import { makePropSafe as safe } from "@budibase/string-templates"
/**
* Date:
* November 2022
*
* Description:
* Update table settings to use actions instead of links.
* Legacy "linkRows", "linkURL", "linkPeek" and "linkColumn" settings on tables
* and table blocks are migrated into a "Navigate To" action under the new
* "onClick" setting.
*/
export const run = async (appDb: any) => {
let screens: Screen[]
try {
screens = (
await appDb.allDocs(
getScreenParams(null, {
include_docs: true,
})
)
).rows.map((row: any) => row.doc)
} catch (e) {
// sometimes the metadata document doesn't exist
// exit early instead of failing the migration
console.error("Error retrieving app metadata. Skipping", e)
return
}
// Recursively update any relevant components and mutate the screen docs
screens.forEach((screen: any) => {
migrateTableSettings(screen.props, screen)
// Save screen if we updated it
if (screen.touched) {
delete screen.touched
appDb.put(screen)
console.log(
`Screen ${screen.routing?.route} contained tables which were migrated`
)
}
})
}
// Recursively searches and mutates a screen doc to migrate table component
// and table block settings
const migrateTableSettings = (component: any, screen: any) => {
if (!component) {
return
}
// Migrate table setting
if (
component._component.endsWith("/table") ||
component._component.endsWith("/tableblock")
) {
const { linkRows, linkURL, linkPeek, linkColumn, onClick } = component
if (linkRows && !onClick) {
const action = convertLinkSettingToAction(linkURL, linkPeek, linkColumn)
if (action) {
screen.touched = true
component.onClick = action
}
}
}
if (!component._children?.length) {
return
}
component._children.forEach((child: any) => {
migrateTableSettings(child, screen)
})
}
// Util ti convert the legacy settings into a navigation action structure
const convertLinkSettingToAction = (
linkURL: string,
linkPeek?: boolean,
linkColumn?: string
) => {
if (!linkURL?.includes("/:")) {
return null
}
// Convert old link URL setting, which is a screen URL, into a valid
// binding using the new clicked row binding
const split = linkURL.split("/:")
const col = linkColumn || "_id"
const binding = `{{ ${safe("eventContext")}.${safe("row")}.${safe(col)} }}`
const url = `${split[0]}/${binding}`
return [
{
"##eventHandlerType": "Navigate To",
parameters: {
url,
peek: !!linkPeek,
},
},
]
}

View File

@ -12,6 +12,7 @@ import env from "../environment"
import * as userEmailViewCasing from "./functions/userEmailViewCasing"
import * as syncQuotas from "./functions/syncQuotas"
import * as appUrls from "./functions/appUrls"
import * as tableSettings from "./functions/tableSettings"
import * as backfill from "./functions/backfill"
/**
* Populate the migration function and additional configuration from
@ -73,6 +74,14 @@ export const buildMigrations = () => {
})
break
}
case MigrationName.TABLE_SETTINGS: {
serverMigrations.push({
...definition,
appOpts: { all: true },
fn: tableSettings.run,
})
break
}
}
}

View File

@ -44,6 +44,7 @@ export enum MigrationName {
EVENT_GLOBAL_BACKFILL = "event_global_backfill",
EVENT_INSTALLATION_BACKFILL = "event_installation_backfill",
GLOBAL_INFO_SYNC_USERS = "global_info_sync_users",
TABLE_SETTINGS = "table_settings",
// increment this number to re-activate this migration
SYNC_QUOTAS = "sync_quotas_1",
}