Add role selection for viewing screens and smart handling of preview screen
This commit is contained in:
parent
248a1f456f
commit
e5a34871c7
|
@ -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()
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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]}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in New Issue