<template> <div> <Toasts></Toasts> <PageContent :page="page" :path="path" :params="params" :elements="elements" /> </div> </template> <script> import PageContent from '@baserow/modules/builder/components/page/PageContent' import { resolveApplicationRoute } from '@baserow/modules/builder/utils/routing' import { DataProviderType } from '@baserow/modules/core/dataProviderTypes' import Toasts from '@baserow/modules/core/components/toasts/Toasts' import ApplicationBuilderFormulaInputGroup from '@baserow/modules/builder/components/ApplicationBuilderFormulaInputGroup' export default { components: { PageContent, Toasts }, provide() { return { builder: this.builder, page: this.page, mode: this.mode, formulaComponent: ApplicationBuilderFormulaInputGroup, } }, async asyncData({ store, params, error, $registry, app, req }) { let mode = 'public' const builderId = parseInt(params.builderId, 10) // We have a builderId parameter in the path so it's a preview if (builderId) { mode = 'preview' } let builder = store.getters['application/getSelected'] if (!builder || builderId !== builder.id) { try { if (builderId) { // We have the builderId in the params so this is a preview // Must fetch the builder instance by this Id. await store.dispatch('publicBuilder/fetchById', { builderId, }) builder = await store.dispatch('application/selectById', builderId) } else { // We don't have the builderId so it's a public page. // Must fetch the builder instance by domain name. const host = process.server ? req.headers.host : window.location.host const domain = new URL(`http://${host}`).hostname const { id: receivedBuilderId } = await store.dispatch( 'publicBuilder/fetchByDomain', { domain, } ) builder = await store.dispatch( 'application/selectById', receivedBuilderId ) } } catch (e) { return error({ statusCode: 404, message: app.i18n.t('publicPage.siteNotFound'), }) } } const found = resolveApplicationRoute(builder.pages, params.pathMatch) // Handle 404 if (!found) { return error({ statusCode: 404, message: app.i18n.t('publicPage.pageNotFound'), }) } const [pageFound, path, pageParamsValue] = found const page = await store.getters['page/getById'](builder, pageFound.id) await Promise.all([ store.dispatch('dataSource/fetchPublished', { page, }), store.dispatch('element/fetchPublished', { page }), store.dispatch('workflowAction/fetchPublished', { page }), ]) await DataProviderType.initAll($registry.getAll('builderDataProvider'), { builder, page, pageParamsValue, mode, }) // And finally select the page to display it await store.dispatch('page/selectById', { builder, pageId: pageFound.id, }) return { builder, page, path, params, mode, } }, head() { return { titleTemplate: '', title: this.page.name, bodyAttrs: { class: 'public-page', }, } }, computed: { elements() { return this.$store.getters['element/getRootElements'](this.page) }, applicationContext() { return { builder: this.builder, page: this.page, pageParamsValue: this.params, mode: this.mode, } }, dispatchContext() { return DataProviderType.getAllDispatchContext( this.$registry.getAll('builderDataProvider'), this.applicationContext ) }, }, watch: { dispatchContext: { deep: true, /** * Update data source content on backend context changes */ handler(newValue) { this.$store.dispatch( 'dataSourceContent/debouncedFetchPageDataSourceContent', { page: this.page, data: newValue, } ) }, }, }, } </script>