Allow deleting built in layouts and hide layouts tab when no layouts exist

This commit is contained in:
Andrew Kingston 2022-05-13 11:23:27 +01:00
parent 68156fee3d
commit 71aedf4d9d
6 changed files with 51 additions and 38 deletions

View File

@ -47,12 +47,14 @@
active={$isActive("./navigation")} active={$isActive("./navigation")}
on:click={() => $goto("./navigation")} on:click={() => $goto("./navigation")}
/> />
<IconSideNavItem {#if $store.layouts?.length}
icon="Experience" <IconSideNavItem
tooltip="Layouts" icon="Experience"
active={$isActive("./layouts")} tooltip="Layouts"
on:click={() => $goto("./layouts")} active={$isActive("./layouts")}
/> on:click={() => $goto("./layouts")}
/>
{/if}
</IconSideNav> </IconSideNav>
</div> </div>

View File

@ -13,7 +13,7 @@
await store.actions.layouts.delete(layout) await store.actions.layouts.delete(layout)
notifications.success("Layout deleted successfully") notifications.success("Layout deleted successfully")
} catch (err) { } catch (err) {
notifications.error("Error deleting layout") notifications.error(err?.message || "Error deleting layout")
} }
} }
</script> </script>

View File

@ -1,25 +1,29 @@
<script> <script>
import Panel from "components/design/Panel.svelte" import Panel from "components/design/Panel.svelte"
import { Layout } from "@budibase/bbui"
import NavItem from "components/common/NavItem.svelte" import NavItem from "components/common/NavItem.svelte"
import { store } from "builderStore" import { store } from "builderStore"
import LayoutDropdownMenu from "./LayoutDropdownMenu.svelte" import LayoutDropdownMenu from "./LayoutDropdownMenu.svelte"
</script> </script>
<Panel title="Layouts" borderRight> <Panel title="Layouts" borderRight>
<Layout paddingY="XL" paddingX=""> <div class="layouts">
<div> {#each $store.layouts as layout (layout._id)}
{#each $store.layouts as layout (layout._id)} <NavItem
<NavItem icon="Experience"
icon="Experience" indentLevel={0}
indentLevel={0} selected={$store.selectedLayoutId === layout._id}
selected={$store.selectedLayoutId === layout._id} text={layout.name}
text={layout.name} on:click={() => ($store.selectedLayoutId = layout._id)}
on:click={() => ($store.selectedLayoutId = layout._id)} >
> <LayoutDropdownMenu {layout} />
<LayoutDropdownMenu {layout} /> </NavItem>
</NavItem> {/each}
{/each} </div>
</div>
</Layout>
</Panel> </Panel>
<style>
.layouts {
margin-top: var(--spacing-xl);
overflow: hidden;
}
</style>

View File

@ -0,0 +1,12 @@
<script>
import { store } from "builderStore"
import { redirect } from "@roxi/routify"
$: {
if (!$store.layouts?.length) {
$redirect("../")
}
}
</script>
<slot />

View File

@ -6,8 +6,7 @@
onMount(() => { onMount(() => {
if ($store.layouts?.length) { if ($store.layouts?.length) {
$redirect(`./${$store.layouts[0]._id}`) $redirect(`./${$store.layouts[0]._id}`)
} else {
$redirect("../")
} }
// The redirection when no layouts exist is handled by the routify layout
}) })
</script> </script>

View File

@ -30,19 +30,15 @@ exports.destroy = async function (ctx) {
const layoutId = ctx.params.layoutId, const layoutId = ctx.params.layoutId,
layoutRev = ctx.params.layoutRev layoutRev = ctx.params.layoutRev
if (Object.values(BASE_LAYOUT_PROP_IDS).includes(layoutId)) { const layoutsUsedByScreens = (
ctx.throw(400, "Cannot delete a built-in layout") await db.allDocs(
} else { getScreenParams(null, {
const layoutsUsedByScreens = ( include_docs: true,
await db.allDocs( })
getScreenParams(null, { )
include_docs: true, ).rows.map(element => element.doc.layoutId)
}) if (layoutsUsedByScreens.includes(layoutId)) {
) ctx.throw(400, "Cannot delete a layout that's being used by a screen")
).rows.map(element => element.doc.layoutId)
if (layoutsUsedByScreens.includes(layoutId)) {
ctx.throw(400, "Cannot delete a layout that's being used by a screen")
}
} }
await db.remove(layoutId, layoutRev) await db.remove(layoutId, layoutRev)