can delete screens
This commit is contained in:
parent
09fda4b703
commit
3b4c68163d
|
@ -53,7 +53,6 @@ export const getStore = () => {
|
||||||
store.createDatabaseForApp = backendStoreActions.createDatabaseForApp(store)
|
store.createDatabaseForApp = backendStoreActions.createDatabaseForApp(store)
|
||||||
|
|
||||||
store.saveScreen = saveScreen(store)
|
store.saveScreen = saveScreen(store)
|
||||||
store.deleteScreen = deleteScreen(store)
|
|
||||||
store.setCurrentScreen = setCurrentScreen(store)
|
store.setCurrentScreen = setCurrentScreen(store)
|
||||||
store.setCurrentPage = setCurrentPage(store)
|
store.setCurrentPage = setCurrentPage(store)
|
||||||
store.createScreen = createScreen(store)
|
store.createScreen = createScreen(store)
|
||||||
|
@ -162,6 +161,7 @@ const createScreen = store => (screenName, route, layoutComponentName) => {
|
||||||
props: createProps(rootComponent).props,
|
props: createProps(rootComponent).props,
|
||||||
}
|
}
|
||||||
newScreen.route = route
|
newScreen.route = route
|
||||||
|
newScreen.name = newScreen.props._id
|
||||||
newScreen.props._instanceName = screenName || ""
|
newScreen.props._instanceName = screenName || ""
|
||||||
state.currentPreviewItem = newScreen
|
state.currentPreviewItem = newScreen
|
||||||
state.currentComponentInfo = newScreen.props
|
state.currentComponentInfo = newScreen.props
|
||||||
|
@ -191,24 +191,6 @@ const setCurrentScreen = store => screenName => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const deleteScreen = store => name => {
|
|
||||||
store.update(s => {
|
|
||||||
const components = s.components.filter(c => c.name !== name)
|
|
||||||
const screens = s.screens.filter(c => c.name !== name)
|
|
||||||
|
|
||||||
s.components = components
|
|
||||||
s.screens = screens
|
|
||||||
if (s.currentPreviewItem.name === name) {
|
|
||||||
s.currentPreviewItem = null
|
|
||||||
s.currentFrontEndType = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
api.delete(`/_builder/api/${s.appId}/screen/${name}`)
|
|
||||||
|
|
||||||
return s
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const savePage = store => async page => {
|
const savePage = store => async page => {
|
||||||
store.update(state => {
|
store.update(state => {
|
||||||
if (state.currentFrontEndType !== "page" || !state.currentPageName) {
|
if (state.currentFrontEndType !== "page" || !state.currentPageName) {
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
import { pipe } from "components/common/core"
|
import { pipe } from "components/common/core"
|
||||||
import { store } from "builderStore"
|
import { store } from "builderStore"
|
||||||
import { ArrowDownIcon, ShapeIcon } from "components/common/Icons/"
|
import { ArrowDownIcon, ShapeIcon } from "components/common/Icons/"
|
||||||
|
import ScreenDropdownMenu from "./ScreenDropdownMenu.svelte"
|
||||||
|
|
||||||
export let screens = []
|
export let screens = []
|
||||||
|
|
||||||
|
@ -15,12 +16,15 @@
|
||||||
const joinPath = join("/")
|
const joinPath = join("/")
|
||||||
|
|
||||||
const normalizedName = name =>
|
const normalizedName = name =>
|
||||||
pipe(name, [
|
pipe(
|
||||||
trimCharsStart("./"),
|
name,
|
||||||
trimCharsStart("~/"),
|
[
|
||||||
trimCharsStart("../"),
|
trimCharsStart("./"),
|
||||||
trimChars(" "),
|
trimCharsStart("~/"),
|
||||||
])
|
trimCharsStart("../"),
|
||||||
|
trimChars(" "),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
const changeScreen = screen => {
|
const changeScreen = screen => {
|
||||||
store.setCurrentScreen(screen.props._instanceName)
|
store.setCurrentScreen(screen.props._instanceName)
|
||||||
|
@ -31,7 +35,7 @@
|
||||||
<div class="root">
|
<div class="root">
|
||||||
{#each screens as screen}
|
{#each screens as screen}
|
||||||
<div
|
<div
|
||||||
class="budibase__nav-item component"
|
class="budibase__nav-item screen-header-row"
|
||||||
class:selected={$store.currentComponentInfo._id === screen.props._id}
|
class:selected={$store.currentComponentInfo._id === screen.props._id}
|
||||||
on:click|stopPropagation={() => changeScreen(screen)}>
|
on:click|stopPropagation={() => changeScreen(screen)}>
|
||||||
|
|
||||||
|
@ -46,6 +50,10 @@
|
||||||
<i class="ri-artboard-2-fill icon" />
|
<i class="ri-artboard-2-fill icon" />
|
||||||
|
|
||||||
<span class="title">{screen.props._instanceName}</span>
|
<span class="title">{screen.props._instanceName}</span>
|
||||||
|
|
||||||
|
<div class="dropdown-menu">
|
||||||
|
<ScreenDropdownMenu {screen} />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if $store.currentPreviewItem.props._instanceName && $store.currentPreviewItem.props._instanceName === screen.props._instanceName && screen.props._children}
|
{#if $store.currentPreviewItem.props._instanceName && $store.currentPreviewItem.props._instanceName === screen.props._instanceName && screen.props._children}
|
||||||
|
@ -63,10 +71,16 @@
|
||||||
color: var(--ink);
|
color: var(--ink);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.screen-header-row {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
margin-left: 14px;
|
margin-left: 14px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
|
@ -89,4 +103,20 @@
|
||||||
.rotate :global(svg) {
|
.rotate :global(svg) {
|
||||||
transform: rotate(-90deg);
|
transform: rotate(-90deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dropdown-menu {
|
||||||
|
display: none;
|
||||||
|
height: 24px;
|
||||||
|
width: 24px;
|
||||||
|
color: var(--ink);
|
||||||
|
padding: 0px 5px;
|
||||||
|
border-style: none;
|
||||||
|
background: rgba(0, 0, 0, 0);
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.budibase__nav-item:hover .dropdown-menu {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -19,7 +19,11 @@
|
||||||
const capitalise = s => s.substring(0, 1).toUpperCase() + s.substring(1)
|
const capitalise = s => s.substring(0, 1).toUpperCase() + s.substring(1)
|
||||||
const get_name = s => (!s ? "" : last(s.split("/")))
|
const get_name = s => (!s ? "" : last(s.split("/")))
|
||||||
|
|
||||||
const get_capitalised_name = name => pipe(name, [get_name, capitalise])
|
const get_capitalised_name = name =>
|
||||||
|
pipe(
|
||||||
|
name,
|
||||||
|
[get_name, capitalise]
|
||||||
|
)
|
||||||
const isScreenslot = name => name === "##builtin/screenslot"
|
const isScreenslot = name => name === "##builtin/screenslot"
|
||||||
|
|
||||||
const selectComponent = component => {
|
const selectComponent = component => {
|
||||||
|
|
|
@ -0,0 +1,115 @@
|
||||||
|
<script>
|
||||||
|
import { MoreIcon } from "components/common/Icons"
|
||||||
|
import { store } from "builderStore"
|
||||||
|
import ConfirmDialog from "components/common/ConfirmDialog.svelte"
|
||||||
|
import UIkit from "uikit"
|
||||||
|
import api from "builderStore/api"
|
||||||
|
|
||||||
|
export let screen
|
||||||
|
|
||||||
|
let confirmDeleteDialog
|
||||||
|
let dropdownEl
|
||||||
|
|
||||||
|
$: dropdown = UIkit.dropdown(dropdownEl, {
|
||||||
|
mode: "click",
|
||||||
|
offset: 0,
|
||||||
|
pos: "bottom-right",
|
||||||
|
"delay-hide": 0,
|
||||||
|
animation: false,
|
||||||
|
})
|
||||||
|
$: dropdown && UIkit.util.on(dropdown, "shown", () => (hidden = false))
|
||||||
|
|
||||||
|
const hideDropdown = () => {
|
||||||
|
dropdown.hide()
|
||||||
|
}
|
||||||
|
|
||||||
|
const deleteScreen = () => {
|
||||||
|
store.update(s => {
|
||||||
|
const screens = s.screens.filter(c => c.name !== screen.name)
|
||||||
|
s.screens = screens
|
||||||
|
if (s.currentPreviewItem.name === screen.name) {
|
||||||
|
s.currentPreviewItem = s.pages[s.currentPageName]
|
||||||
|
s.currentFrontEndType = "page"
|
||||||
|
}
|
||||||
|
|
||||||
|
api.delete(
|
||||||
|
`/_builder/api/pages/${s.currentPageName}/screens/${screen.name}`
|
||||||
|
)
|
||||||
|
|
||||||
|
return s
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="root boundary" on:click|stopPropagation={() => {}}>
|
||||||
|
<button>
|
||||||
|
<MoreIcon />
|
||||||
|
</button>
|
||||||
|
<ul class="menu" bind:this={dropdownEl} on:click={hideDropdown}>
|
||||||
|
<li class="item" on:click={() => confirmDeleteDialog.show()}>
|
||||||
|
<i class="icon ri-delete-bin-2-line" />
|
||||||
|
Delete
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ConfirmDialog
|
||||||
|
bind:this={confirmDeleteDialog}
|
||||||
|
title="Confirm Delete"
|
||||||
|
body={`Are you sure you wish to delete the screen '${screen.props._instanceName}' ?`}
|
||||||
|
okText="Delete Screen"
|
||||||
|
onOk={deleteScreen} />
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.root {
|
||||||
|
overflow: hidden;
|
||||||
|
z-index: 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.root button {
|
||||||
|
border-style: none;
|
||||||
|
border-radius: 2px;
|
||||||
|
padding: 5px;
|
||||||
|
background: transparent;
|
||||||
|
cursor: pointer;
|
||||||
|
color: var(--ink);
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu {
|
||||||
|
z-index: 100000;
|
||||||
|
overflow: visible;
|
||||||
|
padding: 12px 0px;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu li {
|
||||||
|
border-style: none;
|
||||||
|
background-color: transparent;
|
||||||
|
list-style-type: none;
|
||||||
|
padding: 4px 16px;
|
||||||
|
margin: 0;
|
||||||
|
width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu li:not(.disabled) {
|
||||||
|
cursor: pointer;
|
||||||
|
color: var(--grey-7);
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu li:not(.disabled):hover {
|
||||||
|
color: var(--ink);
|
||||||
|
background-color: var(--grey-1);
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -69,19 +69,14 @@ router.patch(
|
||||||
)
|
)
|
||||||
|
|
||||||
router.delete(
|
router.delete(
|
||||||
"/_builder/api/:appname/pages/:pagename/screen/*",
|
"/_builder/api/pages/:pagename/screens/:id",
|
||||||
authorized(BUILDER),
|
authorized(BUILDER),
|
||||||
async ctx => {
|
async ctx => {
|
||||||
const name = ctx.request.path.replace(
|
|
||||||
`/_builder/api/${ctx.params.appname}/pages/${ctx.params.pagename}/screen/`,
|
|
||||||
""
|
|
||||||
)
|
|
||||||
|
|
||||||
await deleteScreen(
|
await deleteScreen(
|
||||||
ctx.config,
|
ctx.config,
|
||||||
ctx.params.appname,
|
ctx.user.appId,
|
||||||
ctx.params.pagename,
|
ctx.params.pagename,
|
||||||
decodeURI(name)
|
ctx.params.id
|
||||||
)
|
)
|
||||||
|
|
||||||
ctx.response.status = StatusCodes.OK
|
ctx.response.status = StatusCodes.OK
|
||||||
|
|
|
@ -75,8 +75,8 @@ module.exports.renameScreen = async (
|
||||||
await rename(oldComponentPath, newComponentPath)
|
await rename(oldComponentPath, newComponentPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports.deleteScreen = async (config, appname, pagename, name) => {
|
module.exports.deleteScreen = async (config, appId, pagename, name) => {
|
||||||
const appPath = appPackageFolder(config, appname)
|
const appPath = appPackageFolder(config, appId)
|
||||||
const componentFile = screenPath(appPath, pagename, name)
|
const componentFile = screenPath(appPath, pagename, name)
|
||||||
await unlink(componentFile)
|
await unlink(componentFile)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue