new auto screen ux

This commit is contained in:
Peter Clement 2021-11-09 09:33:34 +00:00
parent 969d2f5377
commit 1a265149e2
4 changed files with 190 additions and 50 deletions

View File

@ -2,6 +2,7 @@ import { Screen } from "./utils/Screen"
export default { export default {
name: `Create from scratch`, name: `Create from scratch`,
id: `createFromScratch`,
create: () => createScreen(), create: () => createScreen(),
} }

View File

@ -26,6 +26,7 @@
] ]
let modal let modal
let navSelectionModal
$: selected = tabs.find(t => t.key === $params.assetType)?.title || "Screens" $: selected = tabs.find(t => t.key === $params.assetType)?.title || "Screens"
const navigate = ({ detail }) => { const navigate = ({ detail }) => {
@ -85,9 +86,9 @@
<div class="nav-items-container"> <div class="nav-items-container">
<ComponentNavigationTree /> <ComponentNavigationTree />
</div> </div>
<Modal bind:this={modal}> <Modal bind:this={modal}
<NewScreenModal /> ><svelte:component this={NewScreenModal} {navSelectionModal} /></Modal
</Modal> >
</div> </div>
</Tab> </Tab>
<Tab title="Layouts"> <Tab title="Layouts">

View File

@ -0,0 +1,85 @@
<script>
import { ModalContent, Body, Detail } from "@budibase/bbui"
let selectedNav
export let navSelectionModal
</script>
<ModalContent
title="Select navigation"
cancelText="Back"
onCancel={() => navSelectionModal.show()}
size="M"
disabled={!selectedNav}
>
<Body size="S"
>Please select your preferred layout for the new application:</Body
>
<div class="wrapper">
<div
on:click={() => (selectedNav = "sideNav")}
class:unselected={selectedNav && selectedNav !== "sideNav"}
>
<div class="box">
<div class="side-nav" />
</div>
<div><Detail>Side Nav</Detail></div>
</div>
<div
on:click={() => (selectedNav = "topNav")}
class:unselected={selectedNav && selectedNav !== "topNav"}
>
<div class="box">
<div class="top-nav" />
</div>
<div><Detail>Top Nav</Detail></div>
</div>
<div
on:click={() => (selectedNav = "noNav")}
class:unselected={selectedNav && selectedNav !== "noNav"}
>
<div class="box" />
<div><Detail>No Nav</Detail></div>
</div>
</div>
</ModalContent>
<style>
.side-nav {
float: left;
background: #d3d3d3 0% 0% no-repeat padding-box;
border-radius: 2px 0px 0px 2px;
height: 100%;
width: 10%;
}
.top-nav {
background: #d3d3d3 0% 0% no-repeat padding-box;
vertical-align: top;
width: 100%;
height: 15%;
}
.box {
display: inline-block;
background: #eaeaea 0% 0% no-repeat padding-box;
border: 1px solid #d3d3d3;
border-radius: 2px;
opacity: 1;
width: 120px;
height: 70px;
margin-right: 20px;
}
.wrapper {
display: flex;
padding-top: 4%;
list-style-type: none;
margin: 0;
padding: 0;
margin-right: 5%;
}
.unselected {
opacity: 0.3;
}
</style>

View File

@ -1,21 +1,20 @@
<script> <script>
import { store, allScreens, selectedAccessRole } from "builderStore" import { store, allScreens } from "builderStore"
import { tables } from "stores/backend" import { tables } from "stores/backend"
import { roles } from "stores/backend" import { ModalContent, Body, Detail, Layout, Icon } from "@budibase/bbui"
import { Input, Select, ModalContent, Toggle } from "@budibase/bbui"
import getTemplates from "builderStore/store/screenTemplates" import getTemplates from "builderStore/store/screenTemplates"
import analytics, { Events } from "analytics"
import sanitizeUrl from "builderStore/store/screenTemplates/utils/sanitizeUrl"
const CONTAINER = "@budibase/standard-components/container" const CONTAINER = "@budibase/standard-components/container"
const blankScreen = "createFromScratch"
let selectedScreens = []
let navigationSelectionModal
let name = "" let name = ""
let routeError
let baseComponent = CONTAINER let baseComponent = CONTAINER
let templateIndex let templateIndex
let draftScreen let draftScreen
let createLink = true
let roleId = $selectedAccessRole || "BASIC" $: blankSelected = selectedScreens.includes(blankScreen)
$: autoSelected = selectedScreens.length > 0 && !blankSelected
$: templates = getTemplates($store, $tables.list) $: templates = getTemplates($store, $tables.list)
$: route = !route && $allScreens.length === 0 ? "*" : route $: route = !route && $allScreens.length === 0 ? "*" : route
@ -42,6 +41,7 @@
} }
} }
/*
const save = async () => { const save = async () => {
if (!route) { if (!route) {
routeError = "URL is required" routeError = "URL is required"
@ -72,46 +72,99 @@
}) })
} }
} }
*/
const routeExists = (route, roleId) => { const toggleScreenSelection = template => {
return $allScreens.some( if (selectedScreens.includes(template.id)) {
screen => selectedScreens = selectedScreens.filter(screen => screen !== template.id)
screen.routing.route.toLowerCase() === route.toLowerCase() && } else {
screen.routing.roleId === roleId selectedScreens = [template.id, ...selectedScreens]
)
} }
const routeChanged = event => {
if (!event.detail.startsWith("/")) {
route = "/" + event.detail
}
route = sanitizeUrl(route)
} }
</script> </script>
<ModalContent title="New Screen" confirmText="Create Screen" onConfirm={save}> <ModalContent
<Select title="Add screens"
label="Choose a Template" confirmText="Add Screens"
bind:value={templateIndex} cancelText="Cancel"
on:change={ev => templateChanged(ev.detail)} onConfirm={() => navigationSelectionModal.show()}
options={templates} disabled={!selectedScreens.length}
placeholder={null} size="L"
getOptionLabel={x => x.name} >
getOptionValue={(x, idx) => idx} <Body size="XS"
/> >Please select the screens you would like to add to your application.
<Input label="Name" bind:value={name} /> Autogenerated screens come with CRUD functionality.</Body
<Input >
label="Url"
error={routeError} <Layout noPadding>
bind:value={route} <Detail size="S">Blank screen</Detail>
on:change={routeChanged} <div
/> class="item"
<Select class:selected={selectedScreens.includes(blankScreen)}
label="Access" on:click={() => toggleScreenSelection({ id: blankScreen })}
bind:value={roleId} class:disabled={autoSelected}
options={$roles} >
getOptionLabel={x => x.name} <div class="content">
getOptionValue={x => x._id} <Body size="S">Blank</Body>
/> </div>
<Toggle text="Create link in navigation bar" bind:value={createLink} /> <div style="color: var(--spectrum-global-color-green-600); float: right">
{#if selectedScreens.includes(blankScreen)}
<Icon size="S" name="CheckmarkCircleOutline" />
{/if}
</div>
</div>
<Detail size="S">Autogenerated Screens</Detail>
{#each templates.filter(x => x.id !== blankScreen) as template}
<div
class:disabled={blankSelected}
class:selected={selectedScreens.includes(template.id)}
on:click={() => toggleScreenSelection(template)}
class="item"
>
<div class="content">
{template.name}
</div>
<div
style="color: var(--spectrum-global-color-green-600); float: right"
>
{#if selectedScreens.includes(template.id)}
<Icon size="S" name="CheckmarkCircleOutline" />
{/if}
</div>
</div>
{/each}
</Layout>
</ModalContent> </ModalContent>
<style>
.disabled {
opacity: 0.3;
pointer-events: none;
}
.content {
padding-left: 10px;
letter-spacing: 0px;
color: #2c2c2c;
}
.item {
cursor: pointer;
grid-gap: var(--spectrum-alias-grid-margin-xsmall);
padding: var(--spectrum-alias-item-padding-s);
background: var(--background);
transition: 0.3s all;
border: solid var(--spectrum-alias-border-color);
border-radius: 2px;
box-sizing: border-box;
border-width: 1px;
display: flex;
justify-content: space-between;
align-items: center;
height: 60px;
}
.item:hover,
.selected {
background: var(--spectrum-alias-background-color-tertiary);
}
</style>