Add role selection for viewing screens and smart handling of preview screen

This commit is contained in:
Andrew Kingston 2020-12-09 18:18:47 +00:00
parent 248a1f456f
commit e5a34871c7
7 changed files with 96 additions and 11 deletions

View File

@ -2,7 +2,7 @@ import { getFrontendStore } from "./store/frontend"
import { getBackendUiStore } from "./store/backend" import { getBackendUiStore } from "./store/backend"
import { getAutomationStore } from "./store/automation/" import { getAutomationStore } from "./store/automation/"
import { getThemeStore } from "./store/theme" import { getThemeStore } from "./store/theme"
import { derived } from "svelte/store" import { derived, writable } from "svelte/store"
import analytics from "analytics" import analytics from "analytics"
import { LAYOUT_NAMES } from "../constants" import { LAYOUT_NAMES } from "../constants"
import { makePropsSafe } from "components/userInterface/assetParsing/createProps" import { makePropsSafe } from "components/userInterface/assetParsing/createProps"
@ -74,6 +74,8 @@ export const mainLayout = derived(store, $store => {
) )
}) })
export const selectedAccessRole = writable("BASIC")
export const initialise = async () => { export const initialise = async () => {
try { try {
await analytics.activate() await analytics.activate()

View File

@ -110,6 +110,7 @@ export const getFrontendStore = () => {
const creatingNewScreen = screen._id === undefined const creatingNewScreen = screen._id === undefined
const response = await api.post(`/api/screens`, screen) const response = await api.post(`/api/screens`, screen)
screen = await response.json() screen = await response.json()
await store.actions.routing.fetch()
store.update(state => { store.update(state => {
const foundScreen = state.screens.findIndex( const foundScreen = state.screens.findIndex(

View File

@ -20,6 +20,7 @@
export let route export let route
export let path export let path
export let indent export let indent
export let border
$: selectedScreen = $currentAsset $: selectedScreen = $currentAsset
@ -34,6 +35,7 @@
icon="ri-folder-line" icon="ri-folder-line"
text={path} text={path}
opened={true} opened={true}
{border}
withArrow={route.subpaths} /> withArrow={route.subpaths} />
{#each Object.entries(route.subpaths) as [url, subpath]} {#each Object.entries(route.subpaths) as [url, subpath]}

View File

@ -1,12 +1,69 @@
<script> <script>
import { store } from "builderStore" import { store, selectedAccessRole } from "builderStore"
import PathTree from "./PathTree.svelte" import PathTree from "./PathTree.svelte"
$: paths = Object.keys($store.routes || {}).sort() let routes = {}
$: paths = Object.keys(routes || {}).sort()
$: {
const allRoutes = $store.routes
const sortedPaths = Object.keys(allRoutes).sort()
const selectedRoleId = $selectedAccessRole
const selectedScreenId = $store.currentAssetId
let found = false
let firstValidScreenId
let filteredRoutes = {}
// Filter all routes down to only those which match the current role
sortedPaths.forEach(path => {
const config = allRoutes[path]
Object.entries(config.subpaths).forEach(([subpath, pathConfig]) => {
Object.entries(pathConfig.screens).forEach(([roleId, screenId]) => {
if (roleId === selectedRoleId) {
if (screenId === selectedScreenId) {
found = roleId === selectedRoleId
}
if (!firstValidScreenId) {
firstValidScreenId = screenId
}
if (!filteredRoutes[path]) {
filteredRoutes[path] = { subpaths: {} }
}
filteredRoutes[path].subpaths[subpath] = {
screens: {
[selectedRoleId]: screenId,
},
}
}
})
})
})
routes = filteredRoutes
// If the selected screen isn't in this filtered list, select the first one
if (!found && firstValidScreenId) {
store.actions.screens.select(firstValidScreenId)
}
}
</script> </script>
<div class="root"> <div class="root">
{#each paths as path} {#each paths as path, idx}
<PathTree {path} route={$store.routes[path]} /> <PathTree border={idx > 0} {path} route={routes[path]} />
{/each} {/each}
{#if !paths.length}
<div class="empty">
There aren't any screens configured with this access role.
</div> </div>
{/if}
</div>
<style>
div.empty {
font-size: var(--font-size-xs);
color: var(--grey-5);
padding-top: var(--spacing-xs);
}
</style>

View File

@ -1,13 +1,18 @@
<script> <script>
import { onMount } from "svelte" import { onMount } from "svelte"
import { goto, params, url } from "@sveltech/routify" import { goto, params, url } from "@sveltech/routify"
import { store, currentAsset, selectedComponent } from "builderStore" import {
store,
currentAsset,
backendUiStore,
selectedAccessRole,
} from "builderStore"
import { FrontendTypes } from "constants" import { FrontendTypes } from "constants"
import ComponentNavigationTree from "components/userInterface/ComponentNavigationTree/index.svelte" import ComponentNavigationTree from "components/userInterface/ComponentNavigationTree/index.svelte"
import Layout from "components/userInterface/Layout.svelte" import Layout from "components/userInterface/Layout.svelte"
import NewScreenModal from "components/userInterface/NewScreenModal.svelte" import NewScreenModal from "components/userInterface/NewScreenModal.svelte"
import NewLayoutModal from "components/userInterface/NewLayoutModal.svelte" import NewLayoutModal from "components/userInterface/NewLayoutModal.svelte"
import { Modal, Switcher } from "@budibase/bbui" import { Modal, Switcher, Select } from "@budibase/bbui"
const tabs = [ const tabs = [
{ {
@ -41,6 +46,19 @@
on:click={modal.show} on:click={modal.show}
data-cy="new-screen" data-cy="new-screen"
class="ri-add-circle-fill" /> class="ri-add-circle-fill" />
<div class="role-select">
<Select
extraThin
secondary
bind:value={$selectedAccessRole}
label="Filter by Access">
{#each $backendUiStore.roles as role}
<option value={role._id}>{role.name}</option>
{/each}
</Select>
</div>
{#if $currentAsset} {#if $currentAsset}
<div class="nav-items-container"> <div class="nav-items-container">
<ComponentNavigationTree /> <ComponentNavigationTree />
@ -54,8 +72,8 @@
on:click={modal.show} on:click={modal.show}
data-cy="new-layout" data-cy="new-layout"
class="ri-add-circle-fill" /> class="ri-add-circle-fill" />
{#each $store.layouts as layout (layout._id)} {#each $store.layouts as layout, idx (layout._id)}
<Layout {layout} /> <Layout {layout} border={idx > 0} />
{/each} {/each}
<Modal bind:this={modal}> <Modal bind:this={modal}>
<NewLayoutModal /> <NewLayoutModal />
@ -82,4 +100,8 @@
cursor: pointer; cursor: pointer;
color: var(--blue); color: var(--blue);
} }
.role-select {
margin-bottom: var(--spacing-m);
}
</style> </style>

View File

@ -10,6 +10,7 @@
import { writable } from "svelte/store" import { writable } from "svelte/store"
export let layout export let layout
export let border
let confirmDeleteDialog let confirmDeleteDialog
let componentToDelete = "" let componentToDelete = ""
@ -23,7 +24,7 @@
</script> </script>
<NavItem <NavItem
border={false} {border}
icon="ri-layout-3-line" icon="ri-layout-3-line"
text={layout.name} text={layout.name}
withArrow withArrow

View File

@ -111,7 +111,7 @@
bind:value={route} bind:value={route}
on:change={routeChanged} /> on:change={routeChanged} />
<Select label="Access" bind:value={roleId} secondary> <Select label="Access" bind:value={roleId} secondary>
{#each $backendUiStore as role} {#each $backendUiStore.roles as role}
<option value={role._id}>{role.name}</option> <option value={role._id}>{role.name}</option>
{/each} {/each}
</Select> </Select>