further store tidy up, derive selected page

This commit is contained in:
Martin McKeaveney 2020-11-19 11:15:29 +00:00
parent a5827a9c53
commit d473786d7e
10 changed files with 95 additions and 49 deletions

View File

@ -31,6 +31,12 @@ export const currentScreens = derived(store, $store => {
: Object.values(currentScreens)
})
export const selectedPage = derived(store, $store => {
if (!$store.pages) return null
return $store.pages[$store.currentPageName || "main"]
})
export const initialise = async () => {
try {
await analytics.activate()

View File

@ -5,8 +5,7 @@ import {
getBuiltin,
makePropsSafe,
} from "components/userInterface/pagesParsing/createProps"
import { getExactComponent } from "components/userInterface/pagesParsing/searchComponents"
import { allScreens, backendUiStore } from "builderStore"
import { allScreens, backendUiStore, selectedPage } from "builderStore"
import { generate_screen_css } from "../generate_css"
import { fetchComponentLibDefinitions } from "../loadComponentLibraries"
import api from "../api"
@ -112,10 +111,9 @@ export const getFrontendStore = () => {
store.update(state => {
state.currentFrontEndType = type
const pageOrScreen =
type === "page"
? state.pages[state.currentPageName]
: state.pages[state.currentPageName]._screens[0]
const page = get(selectedPage)
const pageOrScreen = type === "page" ? page : page._screens[0]
state.currentComponentInfo = pageOrScreen ? pageOrScreen.props : null
state.currentPreviewItem = pageOrScreen
@ -159,32 +157,25 @@ export const getFrontendStore = () => {
await savePromise
},
save: async screen => {
const storeContents = get(store)
const pageName = storeContents.currentPageName || "main"
const currentPage = storeContents.pages[pageName]
const currentPageScreens = currentPage._screens
const page = get(selectedPage)
const currentPageScreens = page._screens
const creatingNewScreen = screen._id === undefined
let savePromise
const response = await api.post(
`/api/screens/${currentPage._id}`,
screen
)
const response = await api.post(`/api/screens/${page._id}`, screen)
const json = await response.json()
screen._rev = json.rev
screen._id = json.id
const foundScreen = currentPageScreens.findIndex(
el => el._id === screen._id
)
const foundScreen = page._screens.findIndex(el => el._id === screen._id)
if (foundScreen !== -1) {
currentPageScreens.splice(foundScreen, 1)
page._screens.splice(foundScreen, 1)
}
currentPageScreens.push(screen)
page._screens.push(screen)
// TODO: should carry out all server updates to screen in a single call
store.update(state => {
state.pages[pageName]._screens = currentPageScreens
page._screens = currentPageScreens
if (creatingNewScreen) {
state.currentPreviewItem = screen
@ -210,21 +201,20 @@ export const getFrontendStore = () => {
store.actions.screens.regenerateCss(currentPreviewItem)
}
},
delete: async (screensToDelete, pageName) => {
delete: async screens => {
let deletePromise
const screensToDelete = Array.isArray(screens) ? screens : [screens]
store.update(state => {
if (pageName == null) {
pageName = state.pages.main.name
}
for (let screenToDelete of Array.isArray(screensToDelete)
? screensToDelete
: [screensToDelete]) {
const currentPage = get(selectedPage)
for (let screenToDelete of screensToDelete) {
// Remove screen from current page as well
// TODO: Should be done server side
state.pages[pageName]._screens = state.pages[
pageName
]._screens.filter(scr => scr._id !== screenToDelete._id)
currentPage._screens = currentPage._screens.filter(
scr => scr._id !== screenToDelete._id
)
deletePromise = api.delete(
`/api/screens/${screenToDelete._id}/${screenToDelete._rev}`
)
@ -310,14 +300,13 @@ export const getFrontendStore = () => {
create: (componentToAdd, presetProps) => {
store.update(state => {
function findSlot(component_array) {
for (let i = 0; i < component_array.length; i += 1) {
if (component_array[i]._component === "##builtin/screenslot") {
for (let component of component_array) {
if (component._component === "##builtin/screenslot") {
return true
}
if (component_array[i]._children) findSlot(component_array[i])
if (component._children) findSlot(component)
}
return false
}

View File

@ -1,11 +1,10 @@
<script>
import { goto } from "@sveltech/routify"
import { store } from "builderStore"
import { last } from "lodash/fp"
import { getComponentDefinition } from "builderStore/storeUtils"
import { DropEffect, DropPosition } from "./dragDropStore"
import ComponentDropdownMenu from "../ComponentDropdownMenu.svelte"
import NavItem from "components/common/NavItem.svelte"
import { getComponentDefinition } from "builderStore/storeUtils"
export let components = []
export let currentComponent
@ -56,7 +55,7 @@
<ul>
{#each components as component, index (component._id)}
<li on:click|stopPropagation={() => selectComponent(component)}>
{#if $dragDropStore && $dragDropStore.targetComponent === component && $dragDropStore.dropPosition === DropPosition.ABOVE}
{#if $dragDropStore?.targetComponent === component && $dragDropStore.dropPosition === DropPosition.ABOVE}
<div
on:drop={dragDropStore.actions.drop}
ondragover="return false"
@ -87,7 +86,7 @@
level={level + 1} />
{/if}
{#if $dragDropStore && $dragDropStore.targetComponent === component && ($dragDropStore.dropPosition === DropPosition.INSIDE || $dragDropStore.dropPosition === DropPosition.BELOW)}
{#if $dragDropStore?.targetComponent === component && ($dragDropStore.dropPosition === DropPosition.INSIDE || $dragDropStore.dropPosition === DropPosition.BELOW)}
<div
on:drop={dragDropStore.actions.drop}
ondragover="return false"

View File

@ -1,12 +1,14 @@
<script>
import { writable } from "svelte/store"
import { goto } from "@sveltech/routify"
import { store } from "builderStore"
import instantiateStore from "./dragDropStore"
import ComponentsTree from "./ComponentTree.svelte"
import NavItem from "components/common/NavItem.svelte"
import { store } from "builderStore"
import ScreenDropdownMenu from "./ScreenDropdownMenu.svelte"
const dragDropStore = instantiateStore()
const dragDropStore = instantiateStore()
export let route
export let indent
@ -27,16 +29,17 @@
text={route.fullpath}
withArrow={route.subpaths}
on:click={() => console.log(route)} />
{#each Object.keys(route.screens) as screen}
<NavItem
icon="ri-artboard-2-line"
indentLevel={indent || 1}
selected={$store.currentComponentInfo._id === route.screens[screen]}
selected={$store.currentPreviewItem._id === route.screens[screen]}
opened={$store.currentPreviewItem._id === route.screens[screen]}
text={screen || 'DEFAULT'}
withArrow={route.subpaths}
on:click={() => changeScreen(route.screens[screen])}>
<!-- <ScreenDropdownMenu screen={route.screens[screen]} /> -->
<ScreenDropdownMenu screen={route.screens[screen]} />
</NavItem>
{#if selectedScreen?._id === route.screens[screen]}
<ComponentsTree

View File

@ -0,0 +1,53 @@
<script>
import { goto } from "@sveltech/routify"
import { store } from "builderStore"
import { notifier } from "builderStore/store/notifications"
import ConfirmDialog from "components/common/ConfirmDialog.svelte"
import { DropdownMenu } from "@budibase/bbui"
import { DropdownContainer, DropdownItem } from "components/common/Dropdowns"
export let screen
let confirmDeleteDialog
let dropdown
let anchor
const deleteScreen = () => {
store.actions.screens.delete(screen, $store.currentPageName)
// update the page if required
store.update(state => {
if (state.currentPreviewItem._id === screen._id) {
store.actions.pages.select($store.currentPageName)
notifier.success(`Screen ${screen.name} deleted successfully.`)
$goto(`./:page/page-layout`)
}
return state
})
}
</script>
<div bind:this={anchor} on:click|stopPropagation>
<div class="icon" on:click={() => dropdown.show()}>
<i class="ri-more-line" />
</div>
<DropdownMenu bind:this={dropdown} {anchor} align="left">
<DropdownContainer>
<DropdownItem
icon="ri-delete-bin-line"
title="Delete"
on:click={() => confirmDeleteDialog.show()} />
</DropdownContainer>
</DropdownMenu>
</div>
<ConfirmDialog
bind:this={confirmDeleteDialog}
title="Confirm Deletion"
body={'Are you sure you wish to delete this screen?'}
okText="Delete Screen"
onOk={deleteScreen} />
<style>
.icon i {
font-size: 16px;
}
</style>

View File

@ -46,7 +46,7 @@ export default function() {
// hovered in center of target
if (mousePosition > 0.4 && mousePosition < 0.8) {
state.dropPosition = DropPosition.BELOW
state.dropPosition = DropPosition.INSIDE
}
return
}

View File

@ -1,10 +1,6 @@
<script>
import { goto } from "@sveltech/routify"
import ComponentTree from "./ComponentTree.svelte"
import { store } from "builderStore"
import ScreenDropdownMenu from "../ScreenDropdownMenu.svelte"
import { writable } from "svelte/store"
import NavItem from "components/common/NavItem.svelte"
import PathTree from "./PathTree.svelte"
export let routes = {}

View File

@ -100,7 +100,7 @@
const drop = () => {
if ($dragDropStore.targetComponent !== $dragDropStore.componentToDrop) {
store.actions.components.cut($dragDropStore.componentToDrop)
store.actions.components.copy($dragDropStore.componentToDrop)
store.actions.components.paste(
$dragDropStore.targetComponent,
$dragDropStore.dropPosition

View File

@ -43,7 +43,7 @@ export const screenRouter = ({ screens, onScreenSelected, window }) => {
return sanitize(url)
}
const routes = screens.map(s => makeRootedPath(s.routing && s.routing.route))
const routes = screens.map(screen => makeRootedPath(screen.routing.route))
let fallback = routes.findIndex(([p]) => p === makeRootedPath("*"))
if (fallback < 0) fallback = 0