Fix adding/removing users to group. Remove add all button

This commit is contained in:
Andrew Kingston 2022-08-04 13:25:44 +01:00
parent 4d475c3cd4
commit 095bb83202
2 changed files with 122 additions and 116 deletions

View File

@ -1,42 +1,60 @@
<script>
import { ActionButton, Icon, Search, Divider, Detail } from "@budibase/bbui"
import { Icon, Search, Divider, Layout } from "@budibase/bbui"
import { createEventDispatcher } from "svelte"
export let searchTerm = ""
export let selected
export let filtered = []
export let addAll
export let select
export let title
export let key
export let list = []
export let labelKey
const dispatch = createEventDispatcher()
$: enrichedList = enrich(list, selected)
$: sortedList = sort(enrichedList)
const enrich = (list, selected) => {
return list.map(item => {
return {
...item,
selected: selected.find(x => x._id === item._id) != null,
}
})
}
const sort = list => {
let sortedList = list.slice()
sortedList.sort((a, b) => {
if (a.selected === b.selected) {
return a[labelKey] < b[labelKey] ? -1 : 1
} else if (a.selected) {
return -1
} else if (b.selected) {
return 1
}
return 0
})
return sortedList
}
</script>
<div style="padding: var(--spacing-m)">
<div class="container">
<Layout gap="S">
<div class="header">
<Search placeholder="Search" bind:value={searchTerm} />
<div class="header sub-header">
<div>
<Detail
>{filtered.length} {title}{filtered.length === 1 ? "" : "s"}</Detail
>
</div>
<div>
<ActionButton on:click={addAll} emphasized size="S">Add all</ActionButton>
</div>
</div>
<Divider noMargin />
<div>
{#each filtered as item}
<div class="items">
{#each sortedList as item}
<div
on:click={() => {
select(item._id)
dispatch(item.selected ? "deselect" : "select", item._id)
}}
style="padding-bottom: var(--spacing-m)"
class="selection"
class="item"
>
<div>
{item[key]}
<div class="text">
{item[labelKey]}
</div>
{#if selected.includes(item._id)}
{#if item.selected}
<div>
<Icon
color="var(--spectrum-global-color-blue-600);"
@ -47,29 +65,45 @@
</div>
{/each}
</div>
</Layout>
</div>
<style>
.container {
width: 280px;
}
.header {
align-items: center;
padding: var(--spacing-m) 0 var(--spacing-m) 0;
display: flex;
justify-content: space-between;
display: grid;
gap: var(--spacing-m);
grid-template-columns: 1fr;
}
.selection {
.items {
max-height: 242px;
overflow: auto;
overflow-x: hidden;
margin: 0 calc(-1 * var(--spacing-m));
margin-top: -8px;
}
.item {
align-items: end;
display: flex;
justify-content: space-between;
cursor: pointer;
padding: var(--spacing-s) var(--spacing-l);
background: var(--spectrum-global-color-gray-50);
transition: background 130ms ease-out;
gap: var(--spacing-xl);
}
.selection > :first-child {
padding-top: var(--spacing-m);
.item:hover {
background: var(--spectrum-global-color-gray-100);
cursor: pointer;
}
.sub-header {
display: flex;
justify-content: space-between;
.text {
flex: 1 1 auto;
width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
</style>

View File

@ -31,7 +31,6 @@
let popoverAnchor
let popover
let searchTerm = ""
let selectedUsers = []
let prevSearch = undefined
let pageInfo = createPaginationStore()
let loaded = false
@ -41,9 +40,7 @@
$: page = $pageInfo.page
$: fetchUsers(page, searchTerm)
$: group = $groups.find(x => x._id === groupId)
$: filtered =
$users.data?.filter(x => !group?.users.map(y => y._id).includes(x._id)) ||
[]
$: filtered = $users.data
$: groupApps = $apps.filter(x => group?.apps.includes(x.appId))
$: {
if (loaded && !group?._id) {
@ -51,53 +48,24 @@
}
}
async function addAll() {
selectedUsers = [...selectedUsers, ...filtered.map(u => u._id)]
let reducedUserObjects = filtered.map(u => {
return {
_id: u._id,
email: u.email,
const adduserToGroup = async id => {
const user = await users.get(id)
if (!user?._id) {
return
}
// Check we haven't already been added
if (group.users?.find(x => x._id === user._id)) {
return
}
// Update group
await groups.actions.save({
...group,
users: [...group.users, { _id: user._id, email: user.email }],
})
group.users = [...reducedUserObjects, ...group.users]
await groups.actions.save(group)
$users.data.forEach(async user => {
let userToEdit = await users.get(user._id)
let userGroups = userToEdit.userGroups || []
userGroups.push(groupId)
await users.save({
...userToEdit,
userGroups,
})
})
}
async function selectUser(id) {
let selectedUser = selectedUsers.includes(id)
if (selectedUser) {
selectedUsers = selectedUsers.filter(id => id !== selectedUser)
let newUsers = group.users.filter(user => user._id !== id)
group.users = newUsers
} else {
let enrichedUser = $users.data
.filter(user => user._id === id)
.map(u => {
return {
_id: u._id,
email: u.email,
}
})[0]
selectedUsers = [...selectedUsers, id]
group.users.push(enrichedUser)
}
await groups.actions.save(group)
let user = await users.get(id)
// Update user
let userGroups = user.userGroups || []
userGroups.push(groupId)
await users.save({
@ -106,17 +74,23 @@
})
}
async function removeUser(id) {
let newUsers = group.users.filter(user => user._id !== id)
group.users = newUsers
let user = await users.get(id)
const removeUserFromGroup = async id => {
const user = await users.get(id)
if (!user?._id) {
return
}
await users.save({
...user,
userGroups: [],
// Update group
await groups.actions.save({
...group,
users: group.users.filter(x => x._id !== id),
})
await groups.actions.save(group)
// Update user
await users.save({
...user,
userGroups: user.userGroups.filter(x => x !== groupId),
})
}
async function fetchUsers(page, search) {
@ -150,7 +124,6 @@
notifications.success("User group deleted successfully")
$goto("./")
} catch (error) {
console.log(error)
notifications.error(`Failed to delete user group`)
}
}
@ -216,13 +189,12 @@
</div>
<Popover align="right" bind:this={popover} anchor={popoverAnchor}>
<UserGroupPicker
key={"email"}
title={"User"}
bind:searchTerm
bind:selected={selectedUsers}
bind:filtered
{addAll}
select={selectUser}
labelKey="email"
selected={group.users}
list={$users.data}
on:select={e => adduserToGroup(e.detail)}
on:deselect={e => removeUserFromGroup(e.detail)}
/>
</Popover>
</div>
@ -236,7 +208,7 @@
hoverable
>
<Icon
on:click={() => removeUser(user._id)}
on:click={() => removeUserFromGroup(user._id)}
hoverable
size="S"
name="Close"