Move some role logic to frontend core and enable client library to preferentially route to home screens

This commit is contained in:
Andrew Kingston 2022-04-28 15:13:33 +01:00
parent 709782783e
commit afa5f5e6cd
8 changed files with 92 additions and 65 deletions

View File

@ -1,7 +1,7 @@
<script>
import { Label, notifications, Select } from "@budibase/bbui"
import { permissions, roles } from "stores/backend"
import { Roles } from "constants/backend"
import { Constants } from "@budibase/frontend-core"
export let query
export let label
@ -35,14 +35,14 @@
}
fetched = queryToFetch
if (!queryToFetch || !queryToFetch._id) {
roleId = Roles.BASIC
roleId = Constants.Roles.BASIC
loaded = true
return
}
try {
roleId = (await permissions.forResource(queryToFetch._id))["read"]
} catch (err) {
roleId = Roles.BASIC
roleId = Constants.Roles.BASIC
}
loaded = true
}

View File

@ -1,23 +1,7 @@
import { Roles } from "./backend"
export const TableNames = {
USERS: "ta_users",
}
export const RoleColours = {
[Roles.ADMIN]: "var(--spectrum-global-color-static-seafoam-400)",
[Roles.POWER]: "var(--spectrum-global-color-static-purple-400)",
[Roles.BASIC]: "var(--spectrum-global-color-static-magenta-400)",
[Roles.PUBLIC]: "var(--spectrum-global-color-static-yellow-400)",
}
export const RolePriorities = {
[Roles.ADMIN]: 4,
[Roles.POWER]: 3,
[Roles.BASIC]: 2,
[Roles.PUBLIC]: 1,
}
export const FrontendTypes = {
PAGE: "page",
SCREEN: "screen",

View File

@ -3,17 +3,13 @@
import AppPreview from "./AppPreview.svelte"
import { store, selectedScreen } from "builderStore"
import { Button, Select, StatusLight, Body } from "@budibase/bbui"
import { RoleColours } from "constants"
import { RoleUtils } from "@budibase/frontend-core"
import { roles } from "stores/backend"
import { goto } from "@roxi/routify"
$: roleId = $selectedScreen?.routing.roleId
$: roleColor = getRoleColor(roleId)
$: roleColor = RoleUtils.getRoleColour(roleId)
$: roleName = $roles.find(x => x._id === roleId)?.name || "Unknown"
const getRoleColor = roleId => {
return RoleColours[roleId] || "#ff6500"
}
</script>
<div class="app-panel">

View File

@ -5,8 +5,9 @@
import { store } from "builderStore"
import NavItem from "components/common/NavItem.svelte"
import ScreenDropdownMenu from "./ScreenDropdownMenu.svelte"
import { RoleColours, RolePriorities } from "constants"
import ScreenWizard from "./ScreenWizard.svelte"
import { RoleUtils } from "@budibase/frontend-core"
let searchString
let accessRole = "all"
let showNewScreenModal
@ -28,8 +29,8 @@
.slice()
.sort((a, b) => {
// Sort by role first
const roleA = RolePriorities[a.routing.roleId] ?? 0
const roleB = RolePriorities[b.routing.roleId] ?? 0
const roleA = RoleUtils.getRolePriority(a.routing.roleId)
const roleB = RoleUtils.getRolePriority(b.routing.roleId)
if (roleA !== roleB) {
return roleA > roleB ? -1 : 1
}
@ -43,10 +44,6 @@
return a.routing.route < b.routing.route ? -1 : 1
})
}
const getRoleColor = roleId => {
return RoleColours[roleId] || "#ff6500"
}
</script>
<NavigationPanel
@ -75,7 +72,7 @@
selected={$store.selectedScreenId === screen._id}
text={screen.routing.route}
on:click={() => ($store.selectedScreenId = screen._id)}
color={getRoleColor(screen.routing.roleId)}
color={RoleUtils.getRoleColour(screen.routing.roleId)}
>
<ScreenDropdownMenu screenId={screen._id} />
</NavItem>

View File

@ -3,7 +3,7 @@
import { setContext, onMount } from "svelte"
import { Layout, Heading, Body } from "@budibase/bbui"
import ErrorSVG from "@budibase/frontend-core/assets/error.svg"
import { Constants, CookieUtils } from "@budibase/frontend-core"
import { Constants, CookieUtils, RoleUtils } from "@budibase/frontend-core"
import Component from "./Component.svelte"
import SDK from "sdk"
import {
@ -41,41 +41,22 @@
let dataLoaded = false
let permissionError = false
// Load app config
onMount(async () => {
await initialise()
await authStore.actions.fetchUser()
dataLoaded = true
if (get(builderStore).inBuilder) {
builderStore.actions.notifyLoaded()
} else {
builderStore.actions.pingEndUser()
}
})
// Determine if we should show devtools or not
$: isDevPreview = $appStore.isDevApp && !$builderStore.inBuilder
// Handle no matching route - this is likely a permission error
// Handle no matching route
$: {
if (dataLoaded && $routeStore.routerLoaded && !$routeStore.activeRoute) {
if ($authStore) {
// There is a logged in user, so handle them
if ($screenStore.screens.length) {
let firstRoute
// If using devtools, find the first screen matching our role
if ($devToolsStore.role) {
const roleRoutes = $screenStore.screens.filter(
screen => screen.routing?.roleId === $devToolsStore.role
)
firstRoute = roleRoutes[0]?.routing?.route || "/"
}
// Otherwise just use the first route
else {
firstRoute = $screenStore.screens[0]?.routing?.route ?? "/"
}
// Screens exist so navigate back to the home screen
routeStore.actions.navigate(firstRoute)
// Find the best route to push the user to initially
const route = getBestRoute(
$authStore,
$screenStore.screens,
$devToolsStore.role
)
routeStore.actions.navigate(route)
} else {
// No screens likely means the user has no permissions to view this app
permissionError = true
@ -89,7 +70,44 @@
}
}
$: isDevPreview = $appStore.isDevApp && !$builderStore.inBuilder
const getBestRoute = (user, screens) => {
// Rank all screens, preferring all home screens
const rankScreen = screen => {
const roleId = screen.routing.roleId
let rank = RoleUtils.getRolePriority(roleId)
if (screen.routing.homeScreen) {
rank += 100
}
return rank
}
const enrichedScreens = screens?.map(screen => ({
...screen,
rank: rankScreen(screen),
}))
const rankedScreens = enrichedScreens?.sort((a, b) => {
// First sort by rank
if (a.rank !== b.rank) {
return a.rank > b.rank ? -1 : 1
}
// Then sort alphabetically
return a.routing.route < b.routing.route ? -1 : 1
})
// Use the best ranking screen
return rankedScreens?.[0].routing?.route || "/"
}
// Load app config
onMount(async () => {
await initialise()
await authStore.actions.fetchUser()
dataLoaded = true
if (get(builderStore).inBuilder) {
builderStore.actions.notifyLoaded()
} else {
builderStore.actions.pingEndUser()
}
})
</script>
{#if dataLoaded}
@ -158,7 +176,7 @@
<PeekScreenDisplay />
</CustomThemeWrapper>
{#if $appStore.isDevApp && !$builderStore.inBuilder}
{#if isDevPreview}
<DevTools />
{/if}
</div>

View File

@ -63,3 +63,12 @@ export const TableNames = {
* - Coerce types for search endpoint
*/
export const ApiVersion = "1"
// Role IDs
export const Roles = {
ADMIN: "ADMIN",
POWER: "POWER",
BASIC: "BASIC",
PUBLIC: "PUBLIC",
BUILDER: "BUILDER",
}

View File

@ -1,4 +1,5 @@
export * as LuceneUtils from "./lucene"
export * as JSONUtils from "./json"
export * as CookieUtils from "./cookies"
export * as RoleUtils from "./roles"
export * as Utils from "./utils"

View File

@ -0,0 +1,22 @@
import { Roles } from "../constants"
const RolePriorities = {
[Roles.ADMIN]: 4,
[Roles.POWER]: 3,
[Roles.BASIC]: 2,
[Roles.PUBLIC]: 1,
}
const RoleColours = {
[Roles.ADMIN]: "var(--spectrum-global-color-static-seafoam-400)",
[Roles.POWER]: "var(--spectrum-global-color-static-purple-400)",
[Roles.BASIC]: "var(--spectrum-global-color-static-magenta-400)",
[Roles.PUBLIC]: "var(--spectrum-global-color-static-yellow-400)",
}
export const getRolePriority = roleId => {
return RolePriorities[roleId] ?? 0
}
export const getRoleColour = roleId => {
return RoleColours[roleId] ?? "#ffa500"
}