1
0
mirror of https://gitlab.com/bramw/baserow.git synced 2024-11-24 16:36:46 +00:00
bramw_baserow/web-frontend/modules/builder/pages/pageEditor.vue
2024-10-17 15:49:51 +00:00

258 lines
7.3 KiB
Vue

<template>
<div class="page-editor">
<PageHeader :page="page" />
<div class="layout__col-2-2 page-editor__content">
<div :style="{ width: `calc(100% - ${panelWidth}px)` }">
<PagePreview />
</div>
<div
class="page-editor__side-panel"
:style="{ width: `${panelWidth}px` }"
>
<PageSidePanels />
</div>
</div>
</div>
</template>
<script>
import { StoreItemLookupError } from '@baserow/modules/core/errors'
import PageHeader from '@baserow/modules/builder/components/page/header/PageHeader'
import PagePreview from '@baserow/modules/builder/components/page/PagePreview'
import PageSidePanels from '@baserow/modules/builder/components/page/PageSidePanels'
import { DataProviderType } from '@baserow/modules/core/dataProviderTypes'
import { BuilderApplicationType } from '@baserow/modules/builder/applicationTypes'
import ApplicationBuilderFormulaInput from '@baserow/modules/builder/components/ApplicationBuilderFormulaInput'
import _ from 'lodash'
const mode = 'editing'
export default {
name: 'PageEditor',
components: { PagePreview, PageHeader, PageSidePanels },
provide() {
return {
workspace: this.workspace,
builder: this.builder,
page: this.page,
mode,
formulaComponent: ApplicationBuilderFormulaInput,
applicationContext: this.applicationContext,
}
},
/**
* When the route is updated we want to unselect the element
*/
beforeRouteUpdate(to, from, next) {
// Unselect previously selected element
this.$store.dispatch('element/select', {
element: null,
})
if (from.params.builderId !== to.params?.builderId) {
// When we switch from one application to another we want to logoff the current
// user
const builder = this.$store.getters['application/get'](
parseInt(from.params.builderId)
)
if (builder) {
// We want to reload once only data for this builder next time
this.$store.dispatch('application/forceUpdate', {
application: builder,
data: { _loadedOnce: false },
})
this.$store.dispatch('userSourceUser/logoff', { application: builder })
}
}
next()
},
/**
* When the user leaves to another page we want to unselect the selected page. This
* way it will not be highlighted the left sidebar.
*/
beforeRouteLeave(to, from, next) {
this.$store.dispatch('page/unselect')
// Unselect previously selected element
this.$store.dispatch('element/select', {
element: null,
})
const builder = this.$store.getters['application/get'](
parseInt(from.params.builderId)
)
if (builder) {
// We want to reload once only data for this builder next time
this.$store.dispatch('application/forceUpdate', {
application: builder,
data: { _loadedOnce: false },
})
this.$store.dispatch('userSourceUser/logoff', { application: builder })
}
next()
},
layout: 'app',
async asyncData({ store, params, error, $registry }) {
const builderId = parseInt(params.builderId)
const pageId = parseInt(params.pageId)
const data = { panelWidth: 360 }
try {
const builder = await store.dispatch('application/selectById', builderId)
store.dispatch('userSourceUser/setCurrentApplication', {
application: builder,
})
const workspace = await store.dispatch(
'workspace/selectById',
builder.workspace.id
)
const builderApplicationType = $registry.get(
'application',
BuilderApplicationType.getType()
)
const page = store.getters['page/getById'](builder, pageId)
await builderApplicationType.loadExtraData(builder, page, mode)
await Promise.all([
store.dispatch('dataSource/fetch', {
page,
}),
store.dispatch('element/fetch', { page }),
store.dispatch('workflowAction/fetch', { page }),
])
await DataProviderType.initAll($registry.getAll('builderDataProvider'), {
builder,
page,
mode,
})
// And finally select the page to display it
await store.dispatch('page/selectById', {
builder,
pageId,
})
data.workspace = workspace
data.builder = builder
data.page = page
} catch (e) {
// In case of a network error we want to fail hard.
if (e.response === undefined && !(e instanceof StoreItemLookupError)) {
throw e
}
return error({ statusCode: 404, message: 'page not found.' })
}
return data
},
computed: {
applicationContext() {
return {
builder: this.builder,
page: this.page,
mode,
}
},
dataSources() {
return this.$store.getters['dataSource/getPageDataSources'](this.page)
},
sharedPage() {
return this.$store.getters['page/getSharedPage'](this.builder)
},
sharedDataSources() {
return this.$store.getters['dataSource/getPageDataSources'](
this.sharedPage
)
},
dispatchContext() {
return DataProviderType.getAllDataSourceDispatchContext(
this.$registry.getAll('builderDataProvider'),
this.applicationContext
)
},
// Separate dispatch context for application level shared data sources
// This one doesn't contain the page.
applicationDispatchContext() {
return DataProviderType.getAllDataSourceDispatchContext(
this.$registry.getAll('builderDataProvider'),
{ builder: this.builder, mode }
)
},
},
watch: {
dataSources: {
deep: true,
/**
* Update data source content on data source configuration changes
*/
handler() {
this.$store.dispatch(
'dataSourceContent/debouncedFetchPageDataSourceContent',
{
page: this.page,
data: this.dispatchContext,
mode: this.mode,
}
)
},
},
sharedDataSources: {
deep: true,
/**
* Update shared data source content on data source configuration changes
*/
handler() {
this.$store.dispatch(
'dataSourceContent/debouncedFetchPageDataSourceContent',
{
page: this.sharedPage,
data: this.dispatchContext,
}
)
},
},
dispatchContext: {
deep: true,
/**
* Update data source content on backend context changes
*/
handler(newDispatchContext, oldDispatchContext) {
if (!_.isEqual(newDispatchContext, oldDispatchContext)) {
this.$store.dispatch(
'dataSourceContent/debouncedFetchPageDataSourceContent',
{
page: this.page,
data: newDispatchContext,
mode: this.mode,
}
)
}
},
},
applicationDispatchContext: {
deep: true,
/**
* Update data source content on backend context changes
*/
handler(newDispatchContext, oldDispatchContext) {
if (!_.isEqual(newDispatchContext, oldDispatchContext)) {
this.$store.dispatch(
'dataSourceContent/debouncedFetchPageDataSourceContent',
{
page: this.sharedPage,
data: newDispatchContext,
}
)
}
},
},
},
}
</script>