Merge pull request #483 from mjashanks/delete_screen
Can delete screens Uses new dropdown menu from bbui
This commit is contained in:
commit
b3145df87c
|
@ -55,7 +55,7 @@
|
|||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@budibase/bbui": "^1.15.8",
|
||||
"@budibase/bbui": "^1.16.0",
|
||||
"@budibase/client": "^0.1.1",
|
||||
"@budibase/colorpicker": "^1.0.1",
|
||||
"@nx-js/compiler-util": "^2.0.0",
|
||||
|
|
|
@ -53,7 +53,6 @@ export const getStore = () => {
|
|||
store.createDatabaseForApp = backendStoreActions.createDatabaseForApp(store)
|
||||
|
||||
store.saveScreen = saveScreen(store)
|
||||
store.deleteScreen = deleteScreen(store)
|
||||
store.setCurrentScreen = setCurrentScreen(store)
|
||||
store.setCurrentPage = setCurrentPage(store)
|
||||
store.createScreen = createScreen(store)
|
||||
|
@ -162,6 +161,7 @@ const createScreen = store => (screenName, route, layoutComponentName) => {
|
|||
props: createProps(rootComponent).props,
|
||||
}
|
||||
newScreen.route = route
|
||||
newScreen.name = newScreen.props._id
|
||||
newScreen.props._instanceName = screenName || ""
|
||||
state.currentPreviewItem = newScreen
|
||||
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 => {
|
||||
store.update(state => {
|
||||
if (state.currentFrontEndType !== "page" || !state.currentPageName) {
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
import { pipe } from "components/common/core"
|
||||
import { store } from "builderStore"
|
||||
import { ArrowDownIcon, ShapeIcon } from "components/common/Icons/"
|
||||
import ScreenDropdownMenu from "./ScreenDropdownMenu.svelte"
|
||||
|
||||
export let screens = []
|
||||
|
||||
|
@ -15,12 +16,15 @@
|
|||
const joinPath = join("/")
|
||||
|
||||
const normalizedName = name =>
|
||||
pipe(name, [
|
||||
pipe(
|
||||
name,
|
||||
[
|
||||
trimCharsStart("./"),
|
||||
trimCharsStart("~/"),
|
||||
trimCharsStart("../"),
|
||||
trimChars(" "),
|
||||
])
|
||||
]
|
||||
)
|
||||
|
||||
const changeScreen = screen => {
|
||||
store.setCurrentScreen(screen.props._instanceName)
|
||||
|
@ -31,7 +35,7 @@
|
|||
<div class="root">
|
||||
{#each screens as screen}
|
||||
<div
|
||||
class="budibase__nav-item component"
|
||||
class="budibase__nav-item screen-header-row"
|
||||
class:selected={$store.currentComponentInfo._id === screen.props._id}
|
||||
on:click|stopPropagation={() => changeScreen(screen)}>
|
||||
|
||||
|
@ -46,6 +50,10 @@
|
|||
<i class="ri-artboard-2-fill icon" />
|
||||
|
||||
<span class="title">{screen.props._instanceName}</span>
|
||||
|
||||
<div class="dropdown-menu">
|
||||
<ScreenDropdownMenu {screen} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{#if $store.currentPreviewItem.props._instanceName && $store.currentPreviewItem.props._instanceName === screen.props._instanceName && screen.props._children}
|
||||
|
@ -63,10 +71,16 @@
|
|||
color: var(--ink);
|
||||
}
|
||||
|
||||
.screen-header-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-left: 14px;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.icon {
|
||||
|
@ -89,4 +103,20 @@
|
|||
.rotate :global(svg) {
|
||||
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>
|
||||
|
|
|
@ -19,7 +19,11 @@
|
|||
const capitalise = s => s.substring(0, 1).toUpperCase() + s.substring(1)
|
||||
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 selectComponent = component => {
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
<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"
|
||||
import Portal from "svelte-portal"
|
||||
import { DropdownMenu } from "@budibase/bbui"
|
||||
|
||||
export let screen
|
||||
|
||||
let confirmDeleteDialog
|
||||
let dropdown
|
||||
let buttonForDropdown
|
||||
|
||||
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 on:click={() => dropdown.show()} bind:this={buttonForDropdown}>
|
||||
<MoreIcon />
|
||||
</button>
|
||||
<DropdownMenu bind:this={dropdown} anchor={buttonForDropdown}>
|
||||
<ul class="menu" on:click={hideDropdown}>
|
||||
<li class="item" on:click={() => confirmDeleteDialog.show()}>
|
||||
<i class="icon ri-delete-bin-2-line" />
|
||||
Delete
|
||||
</li>
|
||||
</ul>
|
||||
</DropdownMenu>
|
||||
</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;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.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(
|
||||
"/_builder/api/:appname/pages/:pagename/screen/*",
|
||||
"/_builder/api/pages/:pagename/screens/:id",
|
||||
authorized(BUILDER),
|
||||
async ctx => {
|
||||
const name = ctx.request.path.replace(
|
||||
`/_builder/api/${ctx.params.appname}/pages/${ctx.params.pagename}/screen/`,
|
||||
""
|
||||
)
|
||||
|
||||
await deleteScreen(
|
||||
ctx.config,
|
||||
ctx.params.appname,
|
||||
ctx.user.appId,
|
||||
ctx.params.pagename,
|
||||
decodeURI(name)
|
||||
ctx.params.id
|
||||
)
|
||||
|
||||
ctx.response.status = StatusCodes.OK
|
||||
|
|
|
@ -75,8 +75,8 @@ module.exports.renameScreen = async (
|
|||
await rename(oldComponentPath, newComponentPath)
|
||||
}
|
||||
|
||||
module.exports.deleteScreen = async (config, appname, pagename, name) => {
|
||||
const appPath = appPackageFolder(config, appname)
|
||||
module.exports.deleteScreen = async (config, appId, pagename, name) => {
|
||||
const appPath = appPackageFolder(config, appId)
|
||||
const componentFile = screenPath(appPath, pagename, name)
|
||||
await unlink(componentFile)
|
||||
|
||||
|
|
Loading…
Reference in New Issue