Add deletion modal and hover on delete icon

This commit is contained in:
Peter Clement 2021-11-15 11:03:09 +00:00
parent 35f0384b17
commit fba0975c54
4 changed files with 84 additions and 19 deletions

View File

@ -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 => {
let existingScreenCount = $store.screens.filter(
s => s.props._instanceName == draftScreen.props._instanceName
).length
if (existingScreenCount > 0) {
let oldUrlArr = draftScreen.routing.route.split("/")
oldUrlArr[1] = `${oldUrlArr[1]}-${existingScreenCount + 1}`
draftScreen.routing.route = oldUrlArr.join("/")
} }
const saveScreens = async draftScreen => { let route = url ? sanitizeUrl(`${url}`) : draftScreen.routing.route
let route = screenName
? sanitizeUrl(`/${screenName}`)
: 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"}
> >

View File

@ -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">

View File

@ -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>

View File

@ -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 {