Automatically migrate old apps server-side when importing or using templates

This commit is contained in:
Andrew Kingston 2022-08-24 21:35:24 +01:00
parent e77e6b070f
commit 452eba8635
6 changed files with 114 additions and 53 deletions

View File

@ -19,7 +19,6 @@ import {
makeComponentUnique,
} from "../componentUtils"
import { Helpers } from "@budibase/bbui"
import { DefaultAppTheme, LAYOUT_NAMES } from "../../constants"
import { Utils } from "@budibase/frontend-core"
const INITIAL_FRONTEND_STATE = {
@ -124,35 +123,6 @@ export const getFrontendStore = () => {
await integrations.init()
await queries.init()
await tables.init()
// Add navigation settings to old apps
if (!application.navigation) {
const layout = layouts.find(x => x._id === LAYOUT_NAMES.MASTER.PRIVATE)
const customTheme = application.customTheme
let navigationSettings = {
navigation: "Top",
title: application.name,
navWidth: "Large",
navBackground:
customTheme?.navBackground || DefaultAppTheme.navBackground,
navTextColor:
customTheme?.navTextColor || DefaultAppTheme.navTextColor,
}
if (layout) {
navigationSettings.hideLogo = layout.props.hideLogo
navigationSettings.hideTitle = layout.props.hideTitle
navigationSettings.title = layout.props.title || application.name
navigationSettings.logoUrl = layout.props.logoUrl
navigationSettings.links = layout.props.links
navigationSettings.navigation = layout.props.navigation || "Top"
navigationSettings.sticky = layout.props.sticky
navigationSettings.navWidth = layout.props.width || "Large"
if (navigationSettings.navigation === "None") {
navigationSettings.navigation = "Top"
}
}
await store.actions.navigation.save(navigationSettings)
}
},
theme: {
save: async theme => {

View File

@ -47,7 +47,14 @@ import { checkAppMetadata } from "../../automations/logging"
import { getUniqueRows } from "../../utilities/usageQuota/rows"
import { quotas } from "@budibase/pro"
import { errors, events, migrations } from "@budibase/backend-core"
import { App, MigrationType } from "@budibase/types"
import {
App,
Layout,
Screen,
MigrationType,
AppNavigation,
} from "@budibase/types"
import { BASE_LAYOUT_PROP_IDS } from "../../constants/layouts"
const URL_REGEX_SLASH = /\/|\\/g
@ -243,26 +250,19 @@ const performAppCreate = async (ctx: any) => {
}
const instance = await createInstance(instanceConfig)
const appId = instance._id
const db = context.getAppDB()
let _rev
try {
// if template there will be an existing doc
const existing = await db.get(DocumentType.APP_METADATA)
_rev = existing._rev
} catch (err) {
// nothing to do
}
const newApplication: App = {
// Create new app doc
let newApplication: App = {
_id: DocumentType.APP_METADATA,
_rev,
appId: instance._id,
_rev: undefined,
appId,
type: "app",
version: packageJson.version,
componentLibraries: ["@budibase/standard-components"],
name: name,
url: url,
template: ctx.request.body.template,
template: templateKey,
instance: instance,
tenantId: getTenantId(),
updatedAt: new Date().toISOString(),
@ -285,6 +285,37 @@ const performAppCreate = async (ctx: any) => {
buttonBorderRadius: "16px",
},
}
// If we used a template or imported an app there will be an existing doc.
// Fetch and migrate some metadata from the existing app.
try {
const existing: App = await db.get(DocumentType.APP_METADATA)
const keys: string[] = [
"_rev",
"navigation",
"theme",
"customTheme",
"icon",
]
keys.forEach((key: string) => {
// @ts-ignore
if (existing[key]) {
// @ts-ignore
newApplication[key] = existing[key]
}
})
// Migrate navigation settings and screens if required
if (existing && !existing.navigation) {
const navigation = await migrateAppNavigation()
if (navigation) {
newApplication.navigation = navigation
}
}
} catch (err) {
// Nothing to do
}
const response = await db.put(newApplication, { force: true })
newApplication._rev = response.rev
@ -567,3 +598,57 @@ const updateAppPackage = async (appPackage: any, appId: any) => {
return newAppPackage
})
}
const migrateAppNavigation = async () => {
const db = context.getAppDB()
const existing: App = await db.get(DocumentType.APP_METADATA)
const layouts = await getLayouts()
const screens = await getScreens()
// Migrate all screens, removing custom layouts
for (let screen of screens) {
if (!screen.layoutId) {
return
}
const layout = layouts.find(
(layout: Layout) => layout._id === screen.layoutId
)
screen.layoutId = undefined
screen.showNavigation = layout?.props.navigation !== "None"
screen.width = layout?.props.width || "Large"
await db.put(screen)
}
// Migrate layout navigation settings
const { name, customTheme } = existing
const layout = layouts?.find(
(layout: Layout) => layout._id === BASE_LAYOUT_PROP_IDS.PRIVATE
)
if (layout) {
let navigationSettings: any = {
navigation: "Top",
title: name,
navWidth: "Large",
navBackground:
customTheme?.navBackground || "var(--spectrum-global-color-gray-50)",
navTextColor:
customTheme?.navTextColor || "var(--spectrum-global-color-gray-800)",
}
if (layout) {
navigationSettings.hideLogo = layout.props.hideLogo
navigationSettings.hideTitle = layout.props.hideTitle
navigationSettings.title = layout.props.title || name
navigationSettings.logoUrl = layout.props.logoUrl
navigationSettings.links = layout.props.links
navigationSettings.navigation = layout.props.navigation || "Top"
navigationSettings.sticky = layout.props.sticky
navigationSettings.navWidth = layout.props.width || "Large"
if (navigationSettings.navigation === "None") {
navigationSettings.navigation = "Top"
}
}
return navigationSettings
} else {
return null
}
}

View File

@ -98,7 +98,7 @@ module.exports = server.listen(env.PORT || 0, async () => {
// not recommended in a clustered environment
if (!env.HTTP_MIGRATIONS && !env.isTest()) {
try {
await migrations.migrate()
// await migrations.migrate()
} catch (e) {
logAlert("Error performing migrations. Exiting.", e)
shutdown()

View File

@ -14,11 +14,7 @@ export interface App extends Document {
tenantId: string
status: string
theme?: string
customTheme?: {
buttonBorderRadius?: string
primaryColor?: string
primaryColorHover?: string
}
customTheme?: AppCustomTheme
revertableVersion?: string
navigation?: AppNavigation
automationErrors?: AppMetadataErrors
@ -47,3 +43,13 @@ export interface AppNavigationLink {
id?: string
roleId?: string
}
export interface AppCustomTheme {
buttonBorderRadius?: string
primaryColor?: string
primaryColorHover?: string
// Used to exist before new design UI
navTextColor?: string
navBackground?: string
}

View File

@ -1,7 +1,7 @@
import { Document } from "../document"
export interface Screen extends Document {
layoutId: string
layoutId?: string
showNavigation?: boolean
width?: string
routing: {

View File

@ -2,12 +2,12 @@ import { BaseEvent } from "./event"
export interface ScreenCreatedEvent extends BaseEvent {
screenId: string
layoutId: string
layoutId?: string
roleId: string
}
export interface ScreenDeletedEvent extends BaseEvent {
screenId: string
layoutId: string
layoutId?: string
roleId: string
}