mirror of
https://gitlab.com/bramw/baserow.git
synced 2024-11-24 16:36:46 +00:00
258 lines
7.3 KiB
Vue
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>
|