1
0
Fork 0
mirror of synced 2024-06-03 02:55:14 +12:00
budibase/packages/builder/src/pages/builder/portal/manage/groups/[groupId].svelte
2022-07-21 09:52:01 +01:00

219 lines
5.2 KiB
Svelte

<script>
import { goto } from "@roxi/routify"
import {
ActionButton,
Button,
Layout,
Heading,
Body,
Icon,
Popover,
notifications,
List,
ListItem,
StatusLight,
} from "@budibase/bbui"
import UserGroupPicker from "components/settings/UserGroupPicker.svelte"
import { createPaginationStore } from "helpers/pagination"
import { users, apps, groups } from "stores/portal"
import { onMount } from "svelte"
import { RoleUtils } from "@budibase/frontend-core"
export let groupId
let popoverAnchor
let popover
let searchTerm = ""
let selectedUsers = []
let prevSearch = undefined,
search = undefined
let pageInfo = createPaginationStore()
$: page = $pageInfo.page
$: fetchUsers(page, search)
$: group = $groups.find(x => x._id === groupId)
async function addAll() {
group.users = selectedUsers
await groups.actions.save(group)
}
async function selectUser(id) {
let selectedUser = selectedUsers.includes(id)
let enrichedUser = $users.data.find(user => user._id === id)
if (selectedUser) {
selectedUsers = selectedUsers.filter(id => id !== selectedUser)
let newUsers = group.users.filter(user => user._id !== id)
group.users = newUsers
} else {
selectedUsers = [...selectedUsers, id]
group.users.push(enrichedUser)
}
await groups.actions.save(group)
let user = await users.get(id)
let userGroups = user.userGroups || []
userGroups.push(groupId)
await users.save({
...user,
userGroups,
})
}
$: filtered =
$users.data?.filter(x => !group?.users.map(y => y._id).includes(x._id)) ||
[]
async function removeUser(id) {
let newUsers = group.users.filter(user => user._id !== id)
group.users = newUsers
let user = await users.get(id)
await users.save({
...user,
userGroups: [],
})
await groups.actions.save(group)
}
async function fetchUsers(page, search) {
if ($pageInfo.loading) {
return
}
// need to remove the page if they've started searching
if (search && !prevSearch) {
pageInfo.reset()
page = undefined
}
prevSearch = search
try {
pageInfo.loading()
await users.search({ page, search })
pageInfo.fetched($users.hasNextPage, $users.nextPage)
} catch (error) {
notifications.error("Error getting user list")
}
}
onMount(async () => {
try {
await groups.actions.init()
await apps.load()
} catch (error) {
notifications.error("Error fetching User Group data")
}
})
</script>
<Layout noPadding>
<div>
<ActionButton on:click={() => $goto("../groups")} size="S" icon="ArrowLeft">
Back
</ActionButton>
</div>
<div class="header">
<div class="title">
<div style="background: {group?.color};" class="circle">
<div>
<Icon size="M" name={group?.icon} />
</div>
</div>
<div class="text-padding">
<Heading>{group?.name}</Heading>
</div>
</div>
<div bind:this={popoverAnchor}>
<Button on:click={popover.show()} icon="UserAdd" cta>Add User</Button>
</div>
<Popover align="right" bind:this={popover} anchor={popoverAnchor}>
<UserGroupPicker
key={"email"}
title={"User"}
bind:searchTerm
bind:selected={selectedUsers}
bind:filtered
{addAll}
select={selectUser}
/>
</Popover>
</div>
<List>
{#if group?.users.length}
{#each group.users as user}
<ListItem subtitle={user?.access} title={user?.email} avatar
><Icon
on:click={() => removeUser(user?._id)}
hoverable
size="L"
name="Close"
/></ListItem
>
{/each}
{:else}
<ListItem icon="UserGroup" title="You have no users in this team" />
{/if}
</List>
<div
style="flex-direction: column; margin-top: var(--spacing-m)"
class="title"
>
<Heading weight="light" size="XS">Apps</Heading>
<div style="margin-top: var(--spacing-xs)">
<Body size="S">Manage apps that this User group has been assigned to</Body
>
</div>
</div>
<List>
{#if group?.apps.length}
{#each group.apps as app}
<ListItem
title={app.name}
icon={app?.icon?.name || "Apps"}
iconBackground={app?.icon?.color || ""}
>
<div class="title ">
<StatusLight
color={RoleUtils.getRoleColour(group.roles[app.prodId])}
/>
<div style="margin-left: var(--spacing-s);">
<Body size="XS">{group.roles[app.prodId]}</Body>
</div>
</div>
</ListItem>
{/each}
{:else}
<ListItem icon="UserGroup" title="No apps" />
{/if}
</List>
</Layout>
<style>
.text-padding {
margin-left: var(--spacing-l);
}
.header {
display: flex;
justify-content: space-between;
}
.title {
display: flex;
}
.circle {
border-radius: 50%;
height: 30px;
color: white;
font-weight: bold;
display: inline-block;
font-size: 1.2em;
width: 30px;
}
.circle > div {
padding: calc(1.5 * var(--spacing-xs)) var(--spacing-xs);
}
</style>