Add deletion modal and hover on delete icon
This commit is contained in:
parent
35f0384b17
commit
fba0975c54
|
@ -3,18 +3,19 @@
|
||||||
import { store, selectedAccessRole, allScreens } from "builderStore"
|
import { store, selectedAccessRole, allScreens } from "builderStore"
|
||||||
import { cloneDeep } from "lodash/fp"
|
import { cloneDeep } from "lodash/fp"
|
||||||
import sanitizeUrl from "builderStore/store/screenTemplates/utils/sanitizeUrl"
|
import sanitizeUrl from "builderStore/store/screenTemplates/utils/sanitizeUrl"
|
||||||
|
import { onDestroy } from "svelte"
|
||||||
|
|
||||||
export let screenNameModal
|
export let screenNameModal
|
||||||
export let selectedScreens
|
export let selectedScreens
|
||||||
export let modal
|
export let modal
|
||||||
export let screenName
|
export let screenName
|
||||||
|
export let url
|
||||||
|
|
||||||
let roleId = $selectedAccessRole || "BASIC"
|
let roleId = $selectedAccessRole || "BASIC"
|
||||||
|
|
||||||
let routeError
|
let routeError
|
||||||
let selectedNav
|
let selectedNav
|
||||||
let createdScreens = []
|
let createdScreens = []
|
||||||
let createLink = true
|
|
||||||
|
|
||||||
$: {
|
$: {
|
||||||
selectedScreens.forEach(screen => {
|
selectedScreens.forEach(screen => {
|
||||||
createdScreens = [...createdScreens, screen.create()]
|
createdScreens = [...createdScreens, screen.create()]
|
||||||
|
@ -24,22 +25,33 @@
|
||||||
$: blankSelected = selectedScreens.find(x => x.id === "createFromScratch")
|
$: blankSelected = selectedScreens.find(x => x.id === "createFromScratch")
|
||||||
|
|
||||||
const save = async screens => {
|
const save = async screens => {
|
||||||
screens.forEach(screen => {
|
for (let screen of screens) {
|
||||||
saveScreens(screen)
|
await saveScreens(screen)
|
||||||
})
|
}
|
||||||
|
|
||||||
let navLayout = cloneDeep(
|
let navLayout = cloneDeep(
|
||||||
$store.layouts.find(layout => layout._id === "layout_private_master")
|
$store.layouts.find(layout => layout._id === "layout_private_master")
|
||||||
)
|
)
|
||||||
navLayout.props.navigation = selectedNav
|
navLayout.props.navigation = selectedNav
|
||||||
|
|
||||||
|
await store.actions.routing.fetch()
|
||||||
await store.actions.layouts.save(navLayout)
|
await store.actions.layouts.save(navLayout)
|
||||||
|
selectedScreens = []
|
||||||
|
screenName = ""
|
||||||
|
url = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
const saveScreens = async draftScreen => {
|
const saveScreens = async draftScreen => {
|
||||||
let route = screenName
|
let existingScreenCount = $store.screens.filter(
|
||||||
? sanitizeUrl(`/${screenName}`)
|
s => s.props._instanceName == draftScreen.props._instanceName
|
||||||
: draftScreen.routing.route
|
).length
|
||||||
|
|
||||||
|
if (existingScreenCount > 0) {
|
||||||
|
let oldUrlArr = draftScreen.routing.route.split("/")
|
||||||
|
oldUrlArr[1] = `${oldUrlArr[1]}-${existingScreenCount + 1}`
|
||||||
|
draftScreen.routing.route = oldUrlArr.join("/")
|
||||||
|
}
|
||||||
|
|
||||||
|
let route = url ? sanitizeUrl(`${url}`) : draftScreen.routing.route
|
||||||
if (draftScreen) {
|
if (draftScreen) {
|
||||||
if (!route) {
|
if (!route) {
|
||||||
routeError = "URL is required"
|
routeError = "URL is required"
|
||||||
|
@ -53,15 +65,19 @@
|
||||||
|
|
||||||
if (routeError) return false
|
if (routeError) return false
|
||||||
|
|
||||||
|
if (screenName) {
|
||||||
|
draftScreen.props._instanceName = screenName
|
||||||
|
}
|
||||||
|
|
||||||
draftScreen.routing.route = route
|
draftScreen.routing.route = route
|
||||||
|
|
||||||
await store.actions.screens.create(draftScreen)
|
await store.actions.screens.create(draftScreen)
|
||||||
if (createLink) {
|
if (draftScreen.props._instanceName.endsWith("List")) {
|
||||||
await store.actions.components.links.save(
|
await store.actions.components.links.save(
|
||||||
draftScreen.routing.route,
|
draftScreen.routing.route,
|
||||||
draftScreen.props._instanceName
|
draftScreen.routing.route.split("/")[1]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
await store.actions.routing.fetch()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,6 +88,12 @@
|
||||||
screen.routing.roleId === roleId
|
screen.routing.roleId === roleId
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onDestroy(() => {
|
||||||
|
selectedScreens = []
|
||||||
|
screenName = ""
|
||||||
|
url = ""
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<ModalContent
|
<ModalContent
|
||||||
|
@ -90,6 +112,7 @@
|
||||||
|
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
<div
|
<div
|
||||||
|
data-cy="left-nav"
|
||||||
on:click={() => (selectedNav = "Left")}
|
on:click={() => (selectedNav = "Left")}
|
||||||
class:unselected={selectedNav && selectedNav !== "Left"}
|
class:unselected={selectedNav && selectedNav !== "Left"}
|
||||||
>
|
>
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
toggleScreenSelection(templates.find(t => t.id === blankScreen))}
|
toggleScreenSelection(templates.find(t => t.id === blankScreen))}
|
||||||
class:disabled={autoSelected}
|
class:disabled={autoSelected}
|
||||||
>
|
>
|
||||||
<div class="content">
|
<div data-cy="blank-screen" class="content">
|
||||||
<Body size="S">Blank</Body>
|
<Body size="S">Blank</Body>
|
||||||
</div>
|
</div>
|
||||||
<div style="color: var(--spectrum-global-color-green-600); float: right">
|
<div style="color: var(--spectrum-global-color-green-600); float: right">
|
||||||
|
|
|
@ -1,19 +1,52 @@
|
||||||
<script>
|
<script>
|
||||||
import { ModalContent, Input } from "@budibase/bbui"
|
import { ModalContent, Input } from "@budibase/bbui"
|
||||||
|
import sanitizeUrl from "builderStore/store/screenTemplates/utils/sanitizeUrl"
|
||||||
|
import { selectedAccessRole, allScreens } from "builderStore"
|
||||||
|
|
||||||
export let modal
|
export let modal
|
||||||
export let navigationSelectionModal
|
export let navigationSelectionModal
|
||||||
export let screenName
|
export let screenName
|
||||||
|
export let url
|
||||||
|
|
||||||
|
let routeError
|
||||||
|
let roleId = $selectedAccessRole || "BASIC"
|
||||||
|
|
||||||
|
const routeChanged = event => {
|
||||||
|
if (!event.detail.startsWith("/")) {
|
||||||
|
url = "/" + event.detail
|
||||||
|
}
|
||||||
|
url = sanitizeUrl(url)
|
||||||
|
|
||||||
|
if (routeExists(url, roleId)) {
|
||||||
|
routeError = "This URL is already taken for this access role"
|
||||||
|
} else {
|
||||||
|
routeError = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const routeExists = (url, roleId) => {
|
||||||
|
return $allScreens.some(
|
||||||
|
screen =>
|
||||||
|
screen.routing.route.toLowerCase() === url.toLowerCase() &&
|
||||||
|
screen.routing.roleId === roleId
|
||||||
|
)
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<ModalContent
|
<ModalContent
|
||||||
size="M"
|
size="M"
|
||||||
title={"Enter name"}
|
title={"Enter Details"}
|
||||||
confirmText={"Continue"}
|
confirmText={"Continue"}
|
||||||
onCancel={() => modal.show()}
|
onCancel={() => modal.show()}
|
||||||
onConfirm={() => navigationSelectionModal.show()}
|
onConfirm={() => navigationSelectionModal.show()}
|
||||||
cancelText={"Back"}
|
cancelText={"Back"}
|
||||||
disabled={!screenName}
|
disabled={!screenName || !url || routeError}
|
||||||
>
|
>
|
||||||
<Input label="Name" bind:value={screenName} />
|
<Input label="Name" bind:value={screenName} />
|
||||||
|
<Input
|
||||||
|
label="URL"
|
||||||
|
error={routeError}
|
||||||
|
bind:value={url}
|
||||||
|
on:change={routeChanged}
|
||||||
|
/>
|
||||||
</ModalContent>
|
</ModalContent>
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
let navigationSelectionModal
|
let navigationSelectionModal
|
||||||
let screenNameModal
|
let screenNameModal
|
||||||
let screenName = ""
|
let screenName = ""
|
||||||
|
let url = ""
|
||||||
let selectedScreens = []
|
let selectedScreens = []
|
||||||
|
|
||||||
// Hydrate state from URL params
|
// Hydrate state from URL params
|
||||||
|
@ -185,7 +186,7 @@
|
||||||
<Layout gap="S" justifyItems="center">
|
<Layout gap="S" justifyItems="center">
|
||||||
<img class="img-size" alt="logo" src={Logo} />
|
<img class="img-size" alt="logo" src={Logo} />
|
||||||
<div class="new-screen-text">
|
<div class="new-screen-text">
|
||||||
<Detail size="L">Let's add some life to this screen</Detail>
|
<Detail size="M">Let's add some life to this screen</Detail>
|
||||||
</div>
|
</div>
|
||||||
<Button on:click={() => modal.show()} size="M" cta>
|
<Button on:click={() => modal.show()} size="M" cta>
|
||||||
<div class="new-screen-button">
|
<div class="new-screen-button">
|
||||||
|
@ -218,13 +219,19 @@
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
||||||
<Modal bind:this={screenNameModal}>
|
<Modal bind:this={screenNameModal}>
|
||||||
<ScreenNameModal bind:screenName {modal} {navigationSelectionModal} />
|
<ScreenNameModal
|
||||||
|
bind:screenName
|
||||||
|
bind:url
|
||||||
|
{modal}
|
||||||
|
{navigationSelectionModal}
|
||||||
|
/>
|
||||||
</Modal>
|
</Modal>
|
||||||
<Modal bind:this={navigationSelectionModal}>
|
<Modal bind:this={navigationSelectionModal}>
|
||||||
<NavigationSelectionModal
|
<NavigationSelectionModal
|
||||||
{screenName}
|
bind:url
|
||||||
|
bind:screenName
|
||||||
{modal}
|
{modal}
|
||||||
{selectedScreens}
|
bind:selectedScreens
|
||||||
{screenNameModal}
|
{screenNameModal}
|
||||||
/>
|
/>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
@ -240,6 +247,8 @@
|
||||||
.new-screen-text {
|
.new-screen-text {
|
||||||
width: 160px;
|
width: 160px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
color: #2c2c2c;
|
||||||
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
.new-screen-button {
|
.new-screen-button {
|
||||||
|
|
Loading…
Reference in New Issue