Cache roles in store and add role selector for screens
This commit is contained in:
parent
74d7316e2f
commit
b842a2addc
|
@ -6,6 +6,7 @@ const INITIAL_BACKEND_UI_STATE = {
|
|||
tables: [],
|
||||
views: [],
|
||||
users: [],
|
||||
roles: [],
|
||||
selectedDatabase: {},
|
||||
selectedTable: {},
|
||||
draftTable: {},
|
||||
|
@ -177,6 +178,26 @@ export const getBackendUiStore = () => {
|
|||
return state
|
||||
}),
|
||||
},
|
||||
roles: {
|
||||
fetch: async () => {
|
||||
const response = await api.get("/api/roles")
|
||||
const roles = await response.json()
|
||||
store.update(state => {
|
||||
state.roles = roles
|
||||
return state
|
||||
})
|
||||
},
|
||||
delete: async role => {
|
||||
const response = await api.delete(`/api/roles/${role._id}/${role._rev}`)
|
||||
await store.actions.roles.fetch()
|
||||
return response
|
||||
},
|
||||
save: async role => {
|
||||
const response = await api.post("/api/roles", role)
|
||||
await store.actions.roles.fetch()
|
||||
return response
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
return store
|
||||
|
|
|
@ -1,42 +1,10 @@
|
|||
<!-- Module scoped cache of saved role options -->
|
||||
<script context="module">
|
||||
import builderApi from "builderStore/api"
|
||||
|
||||
let cachedRoles
|
||||
|
||||
async function getRoles(force = false) {
|
||||
if (cachedRoles && !force) {
|
||||
return await cachedRoles
|
||||
}
|
||||
cachedRoles = new Promise(resolve => {
|
||||
builderApi
|
||||
.get("/api/roles")
|
||||
.then(response => response.json())
|
||||
.then(resolve)
|
||||
})
|
||||
return await cachedRoles
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
import { backendUiStore } from "builderStore"
|
||||
|
||||
export let roleId
|
||||
|
||||
let roleName
|
||||
$: getRole()
|
||||
|
||||
async function getRole() {
|
||||
// Try to find a matching role
|
||||
let roles = await getRoles()
|
||||
let role = roles.find(role => role._id === roleId)
|
||||
|
||||
// If we didn't find a matching role, try updating the cached results
|
||||
if (!role) {
|
||||
let roles = await getRoles(true)
|
||||
let role = roles.find(role => role._id === roleId)
|
||||
}
|
||||
role = roles.find(role => role._id === roleId)
|
||||
roleName = role?.name ?? "Unknown role"
|
||||
}
|
||||
$: role = $backendUiStore.roles.find(role => role._id === roleId)
|
||||
$: roleName = role?.name ?? "Unknown role"
|
||||
</script>
|
||||
|
||||
<div>{roleName}</div>
|
||||
|
|
|
@ -1,18 +1,14 @@
|
|||
<script>
|
||||
import { onMount } from "svelte"
|
||||
import { backendUiStore } from "builderStore"
|
||||
import { notifier } from "builderStore/store/notifications"
|
||||
import RowFieldControl from "../RowFieldControl.svelte"
|
||||
import * as backendApi from "../api"
|
||||
import builderApi from "builderStore/api"
|
||||
import { ModalContent, Select } from "@budibase/bbui"
|
||||
import ErrorsBox from "components/common/ErrorsBox.svelte"
|
||||
|
||||
export let row = {}
|
||||
|
||||
let errors = []
|
||||
let roles = []
|
||||
let rolesLoaded = false
|
||||
|
||||
$: creating = row?._id == null
|
||||
$: table = row.tableId
|
||||
|
@ -56,14 +52,6 @@
|
|||
notifier.success("User saved successfully.")
|
||||
backendUiStore.actions.rows.save(rowResponse)
|
||||
}
|
||||
|
||||
const fetchRoles = async () => {
|
||||
const rolesResponse = await builderApi.get("/api/roles")
|
||||
roles = await rolesResponse.json()
|
||||
rolesLoaded = true
|
||||
}
|
||||
|
||||
onMount(fetchRoles)
|
||||
</script>
|
||||
|
||||
<ModalContent
|
||||
|
@ -80,19 +68,17 @@
|
|||
bind:value={row.password} />
|
||||
<!-- Defer rendering this select until roles load, otherwise the initial
|
||||
selection is always undefined -->
|
||||
{#if rolesLoaded}
|
||||
<Select
|
||||
thin
|
||||
secondary
|
||||
label="Role"
|
||||
data-cy="roleId-select"
|
||||
bind:value={row.roleId}>
|
||||
<option value="">Choose an option</option>
|
||||
{#each roles as role}
|
||||
<option value={role._id}>{role.name}</option>
|
||||
{/each}
|
||||
</Select>
|
||||
{/if}
|
||||
<Select
|
||||
thin
|
||||
secondary
|
||||
label="Role"
|
||||
data-cy="roleId-select"
|
||||
bind:value={row.roleId}>
|
||||
<option value="">Choose an option</option>
|
||||
{#each $backendUiStore.roles as role}
|
||||
<option value={role._id}>{role.name}</option>
|
||||
{/each}
|
||||
</Select>
|
||||
{#each customSchemaKeys as [key, meta]}
|
||||
<RowFieldControl {meta} bind:value={row[key]} {creating} />
|
||||
{/each}
|
||||
|
|
|
@ -4,27 +4,26 @@
|
|||
import api from "builderStore/api"
|
||||
import { notifier } from "builderStore/store/notifications"
|
||||
import ErrorsBox from "components/common/ErrorsBox.svelte"
|
||||
import { backendUiStore } from "builderStore"
|
||||
|
||||
let roles = []
|
||||
let permissions = []
|
||||
let selectedRole = {}
|
||||
let errors = []
|
||||
$: selectedRoleId = selectedRole._id
|
||||
$: otherRoles = roles.filter(role => role._id !== selectedRoleId)
|
||||
$: otherRoles = $backendUiStore.roles.filter(
|
||||
role => role._id !== selectedRoleId
|
||||
)
|
||||
$: isCreating = selectedRoleId == null || selectedRoleId === ""
|
||||
|
||||
// Loads available roles and permissions from the server
|
||||
const fetchRoles = async () => {
|
||||
const rolesResponse = await api.get("/api/roles")
|
||||
roles = await rolesResponse.json()
|
||||
const fetchPermissions = async () => {
|
||||
const permissionsResponse = await api.get("/api/permissions")
|
||||
permissions = await permissionsResponse.json()
|
||||
}
|
||||
|
||||
// Changes the seleced role
|
||||
// Changes the selected role
|
||||
const changeRole = event => {
|
||||
const id = event?.target?.value
|
||||
const role = roles.find(role => role._id === id)
|
||||
const role = $backendUiStore.roles.find(role => role._id === id)
|
||||
if (role) {
|
||||
selectedRole = {
|
||||
...role,
|
||||
|
@ -61,7 +60,7 @@
|
|||
}
|
||||
|
||||
// Save/create the role
|
||||
const response = await api.post("/api/roles", selectedRole)
|
||||
const response = await backendUiStore.actions.roles.save(selectedRole)
|
||||
if (response.status === 200) {
|
||||
notifier.success("Role saved successfully.")
|
||||
} else {
|
||||
|
@ -72,11 +71,8 @@
|
|||
|
||||
// Deletes the selected role
|
||||
const deleteRole = async () => {
|
||||
const response = await api.delete(
|
||||
`/api/roles/${selectedRole._id}/${selectedRole._rev}`
|
||||
)
|
||||
const response = await backendUiStore.actions.roles.delete(selectedRole)
|
||||
if (response.status === 200) {
|
||||
await fetchRoles()
|
||||
changeRole()
|
||||
notifier.success("Role deleted successfully.")
|
||||
} else {
|
||||
|
@ -84,7 +80,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
onMount(fetchRoles)
|
||||
onMount(fetchPermissions)
|
||||
</script>
|
||||
|
||||
<ModalContent
|
||||
|
@ -101,7 +97,7 @@
|
|||
value={selectedRoleId}
|
||||
on:change={changeRole}>
|
||||
<option value="">Create new role</option>
|
||||
{#each roles as role}
|
||||
{#each $backendUiStore.roles as role}
|
||||
<option value={role._id}>{role.name}</option>
|
||||
{/each}
|
||||
</Select>
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
let templateIndex
|
||||
let draftScreen
|
||||
let createLink = true
|
||||
let roles = []
|
||||
let roleId = "BASIC"
|
||||
|
||||
$: templates = getTemplates($store, $backendUiStore.tables)
|
||||
|
@ -30,11 +29,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
const fetchRoles = async () => {
|
||||
const response = await api.get("/api/roles")
|
||||
roles = await response.json()
|
||||
}
|
||||
|
||||
const templateChanged = newTemplateIndex => {
|
||||
if (newTemplateIndex === undefined) return
|
||||
const template = templates[newTemplateIndex]
|
||||
|
@ -96,8 +90,6 @@
|
|||
route = "/" + event.target.value
|
||||
}
|
||||
}
|
||||
|
||||
onMount(fetchRoles)
|
||||
</script>
|
||||
|
||||
<ModalContent title="New Screen" confirmText="Create Screen" onConfirm={save}>
|
||||
|
@ -118,12 +110,10 @@
|
|||
error={routeError}
|
||||
bind:value={route}
|
||||
on:change={routeChanged} />
|
||||
{#if roles.length}
|
||||
<Select label="Access" bind:value={roleId} secondary>
|
||||
{#each roles as role}
|
||||
<option value={role._id}>{role.name}</option>
|
||||
{/each}
|
||||
</Select>
|
||||
{/if}
|
||||
<Select label="Access" bind:value={roleId} secondary>
|
||||
{#each $backendUiStore as role}
|
||||
<option value={role._id}>{role.name}</option>
|
||||
{/each}
|
||||
</Select>
|
||||
<Toggle text="Create link in navigation bar" bind:checked={createLink} />
|
||||
</ModalContent>
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
<script>
|
||||
import { Select } from "@budibase/bbui"
|
||||
import { backendUiStore } from "builderStore"
|
||||
|
||||
export let value
|
||||
|
||||
let roles = []
|
||||
</script>
|
||||
|
||||
<Select bind:value extraThin secondary on:change>
|
||||
<option value="">Choose an option</option>
|
||||
{#each $backendUiStore.roles as role}
|
||||
<option value={role._id}>{role.name}</option>
|
||||
{/each}
|
||||
</Select>
|
|
@ -4,6 +4,7 @@
|
|||
import { FrontendTypes } from "constants"
|
||||
import PropertyControl from "./PropertyControl.svelte"
|
||||
import LayoutSelect from "./LayoutSelect.svelte"
|
||||
import RoleSelect from "./RoleSelect.svelte"
|
||||
import Input from "./PropertyPanelControls/Input.svelte"
|
||||
import { excludeProps } from "./propertyCategories.js"
|
||||
import { store, allScreens, currentAsset } from "builderStore"
|
||||
|
@ -36,8 +37,8 @@
|
|||
const screenDefinition = [
|
||||
{ key: "description", label: "Description", control: Input },
|
||||
{ key: "routing.route", label: "Route", control: Input },
|
||||
{ key: "routing.roleId", label: "Access", control: RoleSelect },
|
||||
{ key: "layoutId", label: "Layout", control: LayoutSelect },
|
||||
{ key: "routing.roleId", label: "Role", control: Input },
|
||||
]
|
||||
|
||||
const layoutDefinition = [{ key: "title", label: "Title", control: Input }]
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
backendUiStore.actions.reset()
|
||||
await store.actions.initialise(pkg)
|
||||
await automationStore.actions.fetch()
|
||||
await backendUiStore.actions.roles.fetch()
|
||||
return pkg
|
||||
} else {
|
||||
throw new Error(pkg)
|
||||
|
|
Loading…
Reference in New Issue