Allow readonly access to users and groups for developer users
This commit is contained in:
parent
e23f7dde47
commit
ad4133a777
|
@ -184,10 +184,15 @@
|
||||||
</Body>
|
</Body>
|
||||||
</Layout>
|
</Layout>
|
||||||
<Divider />
|
<Divider />
|
||||||
<Body>
|
{#if $auth?.user?.accountPortalAccess}
|
||||||
To upgrade your plan and usage limits visit your
|
<Body>
|
||||||
<Link size="L" on:click={goToAccountPortal}>account</Link>.
|
To upgrade your plan and usage limits visit your
|
||||||
</Body>
|
<Link size="L" on:click={goToAccountPortal}>account</Link>.
|
||||||
|
</Body>
|
||||||
|
{:else}
|
||||||
|
<Body>Contact your account holder to upgrade your plan.</Body>
|
||||||
|
{/if}
|
||||||
|
|
||||||
<DashCard
|
<DashCard
|
||||||
description="YOUR CURRENT PLAN"
|
description="YOUR CURRENT PLAN"
|
||||||
title={planTitle()}
|
title={planTitle()}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
} from "@budibase/bbui"
|
} from "@budibase/bbui"
|
||||||
import UserGroupPicker from "components/settings/UserGroupPicker.svelte"
|
import UserGroupPicker from "components/settings/UserGroupPicker.svelte"
|
||||||
import { createPaginationStore } from "helpers/pagination"
|
import { createPaginationStore } from "helpers/pagination"
|
||||||
import { users, apps, groups } from "stores/portal"
|
import { users, apps, groups, auth } from "stores/portal"
|
||||||
import { onMount, setContext } from "svelte"
|
import { onMount, setContext } from "svelte"
|
||||||
import { roles } from "stores/backend"
|
import { roles } from "stores/backend"
|
||||||
import ConfirmDialog from "components/common/ConfirmDialog.svelte"
|
import ConfirmDialog from "components/common/ConfirmDialog.svelte"
|
||||||
|
@ -70,6 +70,7 @@
|
||||||
let loaded = false
|
let loaded = false
|
||||||
let editModal, deleteModal
|
let editModal, deleteModal
|
||||||
|
|
||||||
|
$: readonly = !$auth.isAdmin
|
||||||
$: page = $pageInfo.page
|
$: page = $pageInfo.page
|
||||||
$: fetchUsers(page, searchTerm)
|
$: fetchUsers(page, searchTerm)
|
||||||
$: group = $groups.find(x => x._id === groupId)
|
$: group = $groups.find(x => x._id === groupId)
|
||||||
|
@ -164,24 +165,28 @@
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<GroupIcon {group} size="L" />
|
<GroupIcon {group} size="L" />
|
||||||
<Heading>{group?.name}</Heading>
|
<Heading>{group?.name}</Heading>
|
||||||
<ActionMenu align="right">
|
{#if !readonly}
|
||||||
<span slot="control">
|
<ActionMenu align="right">
|
||||||
<Icon hoverable name="More" />
|
<span slot="control">
|
||||||
</span>
|
<Icon hoverable name="More" />
|
||||||
<MenuItem icon="Refresh" on:click={() => editModal.show()}>
|
</span>
|
||||||
Edit
|
<MenuItem icon="Refresh" on:click={() => editModal.show()}>
|
||||||
</MenuItem>
|
Edit
|
||||||
<MenuItem icon="Delete" on:click={() => deleteModal.show()}>
|
</MenuItem>
|
||||||
Delete
|
<MenuItem icon="Delete" on:click={() => deleteModal.show()}>
|
||||||
</MenuItem>
|
Delete
|
||||||
</ActionMenu>
|
</MenuItem>
|
||||||
|
</ActionMenu>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Layout noPadding gap="S">
|
<Layout noPadding gap="S">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<Heading size="S">Users</Heading>
|
<Heading size="S">Users</Heading>
|
||||||
<div bind:this={popoverAnchor}>
|
<div bind:this={popoverAnchor}>
|
||||||
<Button on:click={popover.show()} cta>Add user</Button>
|
<Button disabled={readonly} on:click={popover.show()} cta
|
||||||
|
>Add user</Button
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
<Popover align="right" bind:this={popover} anchor={popoverAnchor}>
|
<Popover align="right" bind:this={popover} anchor={popoverAnchor}>
|
||||||
<UserGroupPicker
|
<UserGroupPicker
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
<script>
|
<script>
|
||||||
import { ActionButton } from "@budibase/bbui"
|
import { ActionButton } from "@budibase/bbui"
|
||||||
import { getContext } from "svelte"
|
import { getContext } from "svelte"
|
||||||
|
import { auth } from "stores/portal"
|
||||||
|
|
||||||
export let value
|
export let value
|
||||||
|
|
||||||
|
@ -12,4 +13,6 @@
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<ActionButton size="S" on:click={onClick}>Remove</ActionButton>
|
<ActionButton disabled={!$auth.isAdmin} size="S" on:click={onClick}>
|
||||||
|
Remove
|
||||||
|
</ActionButton>
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
{ column: "roles", component: GroupAppsTableRenderer },
|
{ column: "roles", component: GroupAppsTableRenderer },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
$: readonly = !$auth.isAdmin
|
||||||
$: schema = {
|
$: schema = {
|
||||||
name: { displayName: "Group", width: "2fr", minWidth: "200px" },
|
name: { displayName: "Group", width: "2fr", minWidth: "200px" },
|
||||||
users: { sortable: false, width: "1fr" },
|
users: { sortable: false, width: "1fr" },
|
||||||
|
@ -108,7 +109,9 @@
|
||||||
<ButtonGroup>
|
<ButtonGroup>
|
||||||
{#if $licensing.groupsEnabled}
|
{#if $licensing.groupsEnabled}
|
||||||
<!--Show the group create button-->
|
<!--Show the group create button-->
|
||||||
<Button cta on:click={showCreateGroupModal}>Add group</Button>
|
<Button disabled={readonly} cta on:click={showCreateGroupModal}>
|
||||||
|
Add group
|
||||||
|
</Button>
|
||||||
{:else}
|
{:else}
|
||||||
<Button
|
<Button
|
||||||
primary
|
primary
|
||||||
|
|
|
@ -81,6 +81,7 @@
|
||||||
let user
|
let user
|
||||||
let loaded = false
|
let loaded = false
|
||||||
|
|
||||||
|
$: readonly = !$auth.isAdmin
|
||||||
$: fullName = user?.firstName ? user?.firstName + " " + user?.lastName : ""
|
$: fullName = user?.firstName ? user?.firstName + " " + user?.lastName : ""
|
||||||
$: privileged = user?.admin?.global || user?.builder?.global
|
$: privileged = user?.admin?.global || user?.builder?.global
|
||||||
$: nameLabel = getNameLabel(user)
|
$: nameLabel = getNameLabel(user)
|
||||||
|
@ -235,18 +236,16 @@
|
||||||
</Breadcrumbs>
|
</Breadcrumbs>
|
||||||
|
|
||||||
<div class="title">
|
<div class="title">
|
||||||
<div>
|
<div class="user-info">
|
||||||
<div style="display: flex;">
|
<Avatar size="XXL" {initials} />
|
||||||
<Avatar size="XXL" {initials} />
|
<div class="subtitle">
|
||||||
<div class="subtitle">
|
<Heading size="M">{nameLabel}</Heading>
|
||||||
<Heading size="M">{nameLabel}</Heading>
|
{#if nameLabel !== user?.email}
|
||||||
{#if nameLabel !== user?.email}
|
<Body size="S">{user?.email}</Body>
|
||||||
<Body size="S">{user?.email}</Body>
|
{/if}
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{#if userId !== $auth.user?._id}
|
{#if userId !== $auth.user?._id && !readonly}
|
||||||
<div>
|
<div>
|
||||||
<ActionMenu align="right">
|
<ActionMenu align="right">
|
||||||
<span slot="control">
|
<span slot="control">
|
||||||
|
@ -271,17 +270,26 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<Label size="L">First name</Label>
|
<Label size="L">First name</Label>
|
||||||
<Input value={user?.firstName} on:blur={updateUserFirstName} />
|
<Input
|
||||||
|
disabled={readonly}
|
||||||
|
value={user?.firstName}
|
||||||
|
on:blur={updateUserFirstName}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<Label size="L">Last name</Label>
|
<Label size="L">Last name</Label>
|
||||||
<Input value={user?.lastName} on:blur={updateUserLastName} />
|
<Input
|
||||||
|
disabled={readonly}
|
||||||
|
value={user?.lastName}
|
||||||
|
on:blur={updateUserLastName}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<!-- don't let a user remove the privileges that let them be here -->
|
<!-- don't let a user remove the privileges that let them be here -->
|
||||||
{#if userId !== $auth.user._id}
|
{#if userId !== $auth.user._id}
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<Label size="L">Role</Label>
|
<Label size="L">Role</Label>
|
||||||
<Select
|
<Select
|
||||||
|
disabled={readonly}
|
||||||
value={globalRole}
|
value={globalRole}
|
||||||
options={Constants.BudibaseRoleOptions}
|
options={Constants.BudibaseRoleOptions}
|
||||||
on:change={updateUserRole}
|
on:change={updateUserRole}
|
||||||
|
@ -297,7 +305,9 @@
|
||||||
<div class="tableTitle">
|
<div class="tableTitle">
|
||||||
<Heading size="S">Groups</Heading>
|
<Heading size="S">Groups</Heading>
|
||||||
<div bind:this={popoverAnchor}>
|
<div bind:this={popoverAnchor}>
|
||||||
<Button on:click={popover.show()} secondary>Add to group</Button>
|
<Button disabled={readonly} on:click={popover.show()} secondary>
|
||||||
|
Add to group
|
||||||
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<Popover align="right" bind:this={popover} anchor={popoverAnchor}>
|
<Popover align="right" bind:this={popover} anchor={popoverAnchor}>
|
||||||
<UserGroupPicker
|
<UserGroupPicker
|
||||||
|
@ -375,6 +385,11 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
.user-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
.tableTitle {
|
.tableTitle {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
<script>
|
<script>
|
||||||
import { ActionButton } from "@budibase/bbui"
|
import { ActionButton } from "@budibase/bbui"
|
||||||
import { getContext } from "svelte"
|
import { getContext } from "svelte"
|
||||||
|
import { auth } from "stores/portal"
|
||||||
|
|
||||||
export let value
|
export let value
|
||||||
|
|
||||||
|
@ -12,4 +13,6 @@
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<ActionButton size="S" on:click={onClick}>Remove</ActionButton>
|
<ActionButton disabled={!$auth.isAdmin} size="S" on:click={onClick}>
|
||||||
|
Remove
|
||||||
|
</ActionButton>
|
||||||
|
|
|
@ -52,6 +52,7 @@
|
||||||
]
|
]
|
||||||
let userData = []
|
let userData = []
|
||||||
|
|
||||||
|
$: readonly = !$auth.isAdmin
|
||||||
$: debouncedUpdateFetch(searchEmail)
|
$: debouncedUpdateFetch(searchEmail)
|
||||||
$: schema = {
|
$: schema = {
|
||||||
email: {
|
email: {
|
||||||
|
@ -223,10 +224,17 @@
|
||||||
<Divider />
|
<Divider />
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<ButtonGroup>
|
<ButtonGroup>
|
||||||
<Button dataCy="add-user" on:click={createUserModal.show} cta>
|
<Button
|
||||||
|
disabled={readonly}
|
||||||
|
dataCy="add-user"
|
||||||
|
on:click={createUserModal.show}
|
||||||
|
cta
|
||||||
|
>
|
||||||
Add users
|
Add users
|
||||||
</Button>
|
</Button>
|
||||||
<Button on:click={importUsersModal.show} secondary>Import</Button>
|
<Button disabled={readonly} on:click={importUsersModal.show} secondary
|
||||||
|
>Import</Button
|
||||||
|
>
|
||||||
</ButtonGroup>
|
</ButtonGroup>
|
||||||
<div class="controls-right">
|
<div class="controls-right">
|
||||||
<Search bind:value={searchEmail} placeholder="Search" />
|
<Search bind:value={searchEmail} placeholder="Search" />
|
||||||
|
@ -247,7 +255,7 @@
|
||||||
data={enrichedUsers}
|
data={enrichedUsers}
|
||||||
allowEditColumns={false}
|
allowEditColumns={false}
|
||||||
allowEditRows={false}
|
allowEditRows={false}
|
||||||
allowSelectRows={true}
|
allowSelectRows={!readonly}
|
||||||
{customRenderers}
|
{customRenderers}
|
||||||
/>
|
/>
|
||||||
<div class="pagination">
|
<div class="pagination">
|
||||||
|
|
Loading…
Reference in New Issue