Move some role logic to frontend core and enable client library to preferentially route to home screens
This commit is contained in:
parent
5b5208dfc0
commit
3e8192552d
|
@ -1,7 +1,7 @@
|
||||||
<script>
|
<script>
|
||||||
import { Label, notifications, Select } from "@budibase/bbui"
|
import { Label, notifications, Select } from "@budibase/bbui"
|
||||||
import { permissions, roles } from "stores/backend"
|
import { permissions, roles } from "stores/backend"
|
||||||
import { Roles } from "constants/backend"
|
import { Constants } from "@budibase/frontend-core"
|
||||||
|
|
||||||
export let query
|
export let query
|
||||||
export let label
|
export let label
|
||||||
|
@ -35,14 +35,14 @@
|
||||||
}
|
}
|
||||||
fetched = queryToFetch
|
fetched = queryToFetch
|
||||||
if (!queryToFetch || !queryToFetch._id) {
|
if (!queryToFetch || !queryToFetch._id) {
|
||||||
roleId = Roles.BASIC
|
roleId = Constants.Roles.BASIC
|
||||||
loaded = true
|
loaded = true
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
roleId = (await permissions.forResource(queryToFetch._id))["read"]
|
roleId = (await permissions.forResource(queryToFetch._id))["read"]
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
roleId = Roles.BASIC
|
roleId = Constants.Roles.BASIC
|
||||||
}
|
}
|
||||||
loaded = true
|
loaded = true
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +1,7 @@
|
||||||
import { Roles } from "./backend"
|
|
||||||
|
|
||||||
export const TableNames = {
|
export const TableNames = {
|
||||||
USERS: "ta_users",
|
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 = {
|
export const FrontendTypes = {
|
||||||
PAGE: "page",
|
PAGE: "page",
|
||||||
SCREEN: "screen",
|
SCREEN: "screen",
|
||||||
|
|
|
@ -3,17 +3,13 @@
|
||||||
import AppPreview from "./AppPreview.svelte"
|
import AppPreview from "./AppPreview.svelte"
|
||||||
import { store, selectedScreen } from "builderStore"
|
import { store, selectedScreen } from "builderStore"
|
||||||
import { Button, Select, StatusLight, Body } from "@budibase/bbui"
|
import { Button, Select, StatusLight, Body } from "@budibase/bbui"
|
||||||
import { RoleColours } from "constants"
|
import { RoleUtils } from "@budibase/frontend-core"
|
||||||
import { roles } from "stores/backend"
|
import { roles } from "stores/backend"
|
||||||
import { goto } from "@roxi/routify"
|
import { goto } from "@roxi/routify"
|
||||||
|
|
||||||
$: roleId = $selectedScreen?.routing.roleId
|
$: roleId = $selectedScreen?.routing.roleId
|
||||||
$: roleColor = getRoleColor(roleId)
|
$: roleColor = RoleUtils.getRoleColour(roleId)
|
||||||
$: roleName = $roles.find(x => x._id === roleId)?.name || "Unknown"
|
$: roleName = $roles.find(x => x._id === roleId)?.name || "Unknown"
|
||||||
|
|
||||||
const getRoleColor = roleId => {
|
|
||||||
return RoleColours[roleId] || "#ff6500"
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="app-panel">
|
<div class="app-panel">
|
||||||
|
|
|
@ -5,8 +5,9 @@
|
||||||
import { store } from "builderStore"
|
import { store } from "builderStore"
|
||||||
import NavItem from "components/common/NavItem.svelte"
|
import NavItem from "components/common/NavItem.svelte"
|
||||||
import ScreenDropdownMenu from "./ScreenDropdownMenu.svelte"
|
import ScreenDropdownMenu from "./ScreenDropdownMenu.svelte"
|
||||||
import { RoleColours, RolePriorities } from "constants"
|
|
||||||
import ScreenWizard from "./ScreenWizard.svelte"
|
import ScreenWizard from "./ScreenWizard.svelte"
|
||||||
|
import { RoleUtils } from "@budibase/frontend-core"
|
||||||
|
|
||||||
let searchString
|
let searchString
|
||||||
let accessRole = "all"
|
let accessRole = "all"
|
||||||
let showNewScreenModal
|
let showNewScreenModal
|
||||||
|
@ -28,8 +29,8 @@
|
||||||
.slice()
|
.slice()
|
||||||
.sort((a, b) => {
|
.sort((a, b) => {
|
||||||
// Sort by role first
|
// Sort by role first
|
||||||
const roleA = RolePriorities[a.routing.roleId] ?? 0
|
const roleA = RoleUtils.getRolePriority(a.routing.roleId)
|
||||||
const roleB = RolePriorities[b.routing.roleId] ?? 0
|
const roleB = RoleUtils.getRolePriority(b.routing.roleId)
|
||||||
if (roleA !== roleB) {
|
if (roleA !== roleB) {
|
||||||
return roleA > roleB ? -1 : 1
|
return roleA > roleB ? -1 : 1
|
||||||
}
|
}
|
||||||
|
@ -43,10 +44,6 @@
|
||||||
return a.routing.route < b.routing.route ? -1 : 1
|
return a.routing.route < b.routing.route ? -1 : 1
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const getRoleColor = roleId => {
|
|
||||||
return RoleColours[roleId] || "#ff6500"
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<NavigationPanel
|
<NavigationPanel
|
||||||
|
@ -75,7 +72,7 @@
|
||||||
selected={$store.selectedScreenId === screen._id}
|
selected={$store.selectedScreenId === screen._id}
|
||||||
text={screen.routing.route}
|
text={screen.routing.route}
|
||||||
on:click={() => ($store.selectedScreenId = screen._id)}
|
on:click={() => ($store.selectedScreenId = screen._id)}
|
||||||
color={getRoleColor(screen.routing.roleId)}
|
color={RoleUtils.getRoleColour(screen.routing.roleId)}
|
||||||
>
|
>
|
||||||
<ScreenDropdownMenu screenId={screen._id} />
|
<ScreenDropdownMenu screenId={screen._id} />
|
||||||
</NavItem>
|
</NavItem>
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
import { setContext, onMount } from "svelte"
|
import { setContext, onMount } from "svelte"
|
||||||
import { Layout, Heading, Body } from "@budibase/bbui"
|
import { Layout, Heading, Body } from "@budibase/bbui"
|
||||||
import ErrorSVG from "@budibase/frontend-core/assets/error.svg"
|
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 Component from "./Component.svelte"
|
||||||
import SDK from "sdk"
|
import SDK from "sdk"
|
||||||
import {
|
import {
|
||||||
|
@ -41,41 +41,22 @@
|
||||||
let dataLoaded = false
|
let dataLoaded = false
|
||||||
let permissionError = false
|
let permissionError = false
|
||||||
|
|
||||||
// Load app config
|
// Determine if we should show devtools or not
|
||||||
onMount(async () => {
|
$: isDevPreview = $appStore.isDevApp && !$builderStore.inBuilder
|
||||||
await initialise()
|
|
||||||
await authStore.actions.fetchUser()
|
|
||||||
dataLoaded = true
|
|
||||||
if (get(builderStore).inBuilder) {
|
|
||||||
builderStore.actions.notifyLoaded()
|
|
||||||
} else {
|
|
||||||
builderStore.actions.pingEndUser()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// Handle no matching route - this is likely a permission error
|
// Handle no matching route
|
||||||
$: {
|
$: {
|
||||||
if (dataLoaded && $routeStore.routerLoaded && !$routeStore.activeRoute) {
|
if (dataLoaded && $routeStore.routerLoaded && !$routeStore.activeRoute) {
|
||||||
if ($authStore) {
|
if ($authStore) {
|
||||||
// There is a logged in user, so handle them
|
// There is a logged in user, so handle them
|
||||||
if ($screenStore.screens.length) {
|
if ($screenStore.screens.length) {
|
||||||
let firstRoute
|
// Find the best route to push the user to initially
|
||||||
|
const route = getBestRoute(
|
||||||
// If using devtools, find the first screen matching our role
|
$authStore,
|
||||||
if ($devToolsStore.role) {
|
$screenStore.screens,
|
||||||
const roleRoutes = $screenStore.screens.filter(
|
$devToolsStore.role
|
||||||
screen => screen.routing?.roleId === $devToolsStore.role
|
)
|
||||||
)
|
routeStore.actions.navigate(route)
|
||||||
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)
|
|
||||||
} else {
|
} else {
|
||||||
// No screens likely means the user has no permissions to view this app
|
// No screens likely means the user has no permissions to view this app
|
||||||
permissionError = true
|
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>
|
</script>
|
||||||
|
|
||||||
{#if dataLoaded}
|
{#if dataLoaded}
|
||||||
|
@ -158,7 +176,7 @@
|
||||||
<PeekScreenDisplay />
|
<PeekScreenDisplay />
|
||||||
</CustomThemeWrapper>
|
</CustomThemeWrapper>
|
||||||
|
|
||||||
{#if $appStore.isDevApp && !$builderStore.inBuilder}
|
{#if isDevPreview}
|
||||||
<DevTools />
|
<DevTools />
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -63,3 +63,12 @@ export const TableNames = {
|
||||||
* - Coerce types for search endpoint
|
* - Coerce types for search endpoint
|
||||||
*/
|
*/
|
||||||
export const ApiVersion = "1"
|
export const ApiVersion = "1"
|
||||||
|
|
||||||
|
// Role IDs
|
||||||
|
export const Roles = {
|
||||||
|
ADMIN: "ADMIN",
|
||||||
|
POWER: "POWER",
|
||||||
|
BASIC: "BASIC",
|
||||||
|
PUBLIC: "PUBLIC",
|
||||||
|
BUILDER: "BUILDER",
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
export * as LuceneUtils from "./lucene"
|
export * as LuceneUtils from "./lucene"
|
||||||
export * as JSONUtils from "./json"
|
export * as JSONUtils from "./json"
|
||||||
export * as CookieUtils from "./cookies"
|
export * as CookieUtils from "./cookies"
|
||||||
|
export * as RoleUtils from "./roles"
|
||||||
export * as Utils from "./utils"
|
export * as Utils from "./utils"
|
||||||
|
|
|
@ -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"
|
||||||
|
}
|
Loading…
Reference in New Issue