1
0
mirror of https://gitlab.com/bramw/baserow.git synced 2024-11-21 23:37:55 +00:00
bramw_baserow/web-frontend/modules/builder/store/page.js
2024-10-17 15:49:51 +00:00

207 lines
5.6 KiB
JavaScript

import { StoreItemLookupError } from '@baserow/modules/core/errors'
import { BuilderApplicationType } from '@baserow/modules/builder/applicationTypes'
import PageService from '@baserow/modules/builder/services/page'
import { generateHash } from '@baserow/modules/core/utils/hashing'
export function populatePage(page) {
return {
...page,
_: {
selected: false,
dataSourceContentLoading: false,
dataSourceLoading: false,
},
dataSources: [],
elements: [],
elementMap: {},
orderedElements: [],
workflowActions: [],
contents: null,
}
}
const state = {
// Holds the value of which page is currently selected
selected: {},
// By default, the device type will be desktop. This will be overridden
// in the editor, and in the public page. We set a default as otherwise
// in the public page, we can trigger a repaint, causing some layouts to
// redraw.
deviceTypeSelected: 'desktop',
// A job object that tracks the progress of a page duplication currently running
duplicateJob: null,
}
const mutations = {
ADD_ITEM(state, { builder, page }) {
builder.pages.push(populatePage(page))
},
UPDATE_ITEM(state, { page, values }) {
Object.assign(page, page, values)
},
DELETE_ITEM(state, { builder, id }) {
const index = builder.pages.findIndex((item) => item.id === id)
builder.pages.splice(index, 1)
},
SET_SELECTED(state, { builder, page }) {
Object.values(builder.pages).forEach((item) => {
item._.selected = false
})
page._.selected = true
state.selected = page
},
UNSELECT(state) {
if (state.selected?._?.selected) {
state.selected._.selected = false
}
state.selected = {}
},
SET_DUPLICATE_JOB(state, job) {
state.duplicateJob = job
},
ORDER_PAGES(state, { builder, order, isHashed = false }) {
builder.pages.forEach((page) => {
const pageId = isHashed ? generateHash(page.id) : page.id
const index = order.findIndex((value) => value === pageId)
page.order = index === -1 ? 0 : index + 1
})
},
SET_DEVICE_TYPE_SELECTED(state, deviceType) {
state.deviceTypeSelected = deviceType
},
}
const actions = {
forceUpdate({ commit }, { page, values }) {
commit('UPDATE_ITEM', { page, values })
},
forceCreate({ commit }, { builder, page }) {
commit('ADD_ITEM', { builder, page })
},
selectById({ commit, getters }, { builder, pageId }) {
const type = BuilderApplicationType.getType()
// Check if the just selected application is a builder
if (builder.type !== type) {
throw new StoreItemLookupError(
`The application doesn't have the required ${type} type.`
)
}
// Check if the provided page id is found in the just selected builder.
const page = getters.getById(builder, pageId)
commit('SET_SELECTED', { builder, page })
return page
},
unselect({ commit }) {
commit('UNSELECT')
},
async forceDelete({ commit }, { builder, page }) {
if (page._.selected) {
// Redirect back to the dashboard because the page doesn't exist anymore.
await this.$router.push({ name: 'dashboard' })
}
commit('DELETE_ITEM', { builder, id: page.id })
},
async create({ commit, dispatch }, { builder, name, path, pathParams }) {
const { data: page } = await PageService(this.$client).create(
builder.id,
name,
path,
pathParams
)
commit('ADD_ITEM', { builder, page })
await dispatch('selectById', { builder, pageId: page.id })
return page
},
async update({ dispatch }, { builder, page, values }) {
const { data } = await PageService(this.$client).update(page.id, values)
const update = Object.keys(values).reduce((result, key) => {
result[key] = data[key]
return result
}, {})
await dispatch('forceUpdate', { builder, page, values: update })
},
async delete({ dispatch }, { builder, page }) {
await PageService(this.$client).delete(page.id)
await dispatch('forceDelete', { builder, page })
},
async order(
{ commit, getters },
{ builder, order, oldOrder, isHashed = false }
) {
commit('ORDER_PAGES', { builder, order, isHashed })
try {
await PageService(this.$client).order(builder.id, order)
} catch (error) {
commit('ORDER_PAGES', { builder, order: oldOrder, isHashed })
throw error
}
},
setDeviceTypeSelected({ commit }, deviceType) {
commit('SET_DEVICE_TYPE_SELECTED', deviceType)
},
async duplicate({ commit, dispatch }, { page }) {
const { data: job } = await PageService(this.$client).duplicate(page.id)
await dispatch('job/create', job, { root: true })
commit('SET_DUPLICATE_JOB', job)
},
}
const getters = {
getAllPages: (state) => (builder) => {
return builder.pages
},
getById: (state, getters) => (builder, pageId) => {
const index = getters
.getAllPages(builder)
.findIndex((item) => item.id === pageId)
if (index === -1) {
throw new StoreItemLookupError(
'The page is not found in the selected application.'
)
}
return getters.getAllPages(builder)[index]
},
getVisiblePages: (state, getters) => (builder) => {
return getters
.getAllPages(builder)
.filter((page) => page.shared === false)
.sort((a, b) => a.order - b.order)
},
getSharedPage: (state, getters) => (builder) => {
return getters.getAllPages(builder).find((page) => page.shared === true)
},
getSelected(state) {
return state.selected
},
getDeviceTypeSelected(state) {
return state.deviceTypeSelected
},
getDuplicateJob(state) {
return state.duplicateJob
},
}
export default {
namespaced: true,
state,
getters,
actions,
mutations,
}