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