Update user avatars and selection state for collaboration

This commit is contained in:
Andrew Kingston 2023-07-07 15:45:18 +01:00
parent 99ef4f2992
commit 62e452dfe7
5 changed files with 52 additions and 14 deletions

View File

@ -127,8 +127,12 @@ export const selectedAutomation = derived(automationStore, $automationStore => {
export const userSelectedResourceMap = derived(userStore, $userStore => { export const userSelectedResourceMap = derived(userStore, $userStore => {
let map = {} let map = {}
$userStore.forEach(user => { $userStore.forEach(user => {
if (user.builderMetadata?.selectedResourceId) { const resource = user.builderMetadata?.selectedResourceId
map[user.builderMetadata?.selectedResourceId] = user if (resource) {
if (!map[resource]) {
map[resource] = []
}
map[resource].push(user)
} }
}) })
return map return map

View File

@ -3,6 +3,7 @@
import { createEventDispatcher, getContext } from "svelte" import { createEventDispatcher, getContext } from "svelte"
import { helpers } from "@budibase/shared-core" import { helpers } from "@budibase/shared-core"
import { UserAvatar } from "@budibase/frontend-core" import { UserAvatar } from "@budibase/frontend-core"
import UserAvatars from "../../pages/builder/app/[application]/_components/UserAvatars.svelte"
export let icon export let icon
export let withArrow = false export let withArrow = false
@ -102,7 +103,7 @@
<div class="text" title={showTooltip ? text : null}> <div class="text" title={showTooltip ? text : null}>
{text} {text}
{#if selectedBy} {#if selectedBy}
<UserAvatar user={selectedBy} size="XS" /> <UserAvatars size="XS" users={selectedBy} />
{/if} {/if}
</div> </div>
@ -145,13 +146,16 @@
} }
.nav-item.highlighted { .nav-item.highlighted {
background-color: var(--spectrum-global-color-gray-200); background-color: var(--spectrum-global-color-gray-200);
--avatars-background: var(--spectrum-global-color-gray-200);
} }
.nav-item.selected { .nav-item.selected {
background-color: var(--spectrum-global-color-gray-300); background-color: var(--spectrum-global-color-gray-300);
--avatars-background: var(--spectrum-global-color-gray-300);
color: var(--ink); color: var(--ink);
} }
.nav-item:hover { .nav-item:hover {
background-color: var(--spectrum-global-color-gray-300); background-color: var(--spectrum-global-color-gray-300);
--avatars-background: var(--spectrum-global-color-gray-300);
} }
.nav-item:hover .actions { .nav-item:hover .actions {
visibility: visible; visibility: visible;

View File

@ -1,24 +1,54 @@
<script> <script>
import { UserAvatar } from "@budibase/frontend-core" import { UserAvatar } from "@budibase/frontend-core"
import { TooltipPosition } from "@budibase/bbui" import { TooltipPosition, Avatar } from "@budibase/bbui"
export let users = [] export let users = []
export let order = "ltr"
export let size = "S"
$: uniqueUsers = unique(users) $: uniqueUsers = unique(users, order)
$: avatars = getAvatars(uniqueUsers, order)
const unique = users => { const unique = users => {
let uniqueUsers = {} let uniqueUsers = {}
users?.forEach(user => { users?.forEach(user => {
uniqueUsers[user.email] = user uniqueUsers[user.email] = user
}) })
return Object.values(uniqueUsers) return Object.values(uniqueUsers).concat(Object.values(uniqueUsers))
}
const getAvatars = (users, order) => {
const avatars = users.slice(0, 3)
if (users.length > 3) {
const overflow = {
_id: "overflow",
label: `+${users.length - 3}`,
}
if (order === "ltr") {
avatars.push(overflow)
} else {
avatars.unshift(overflow)
}
}
return avatars.map((user, idx) => ({
...user,
zIndex: order === "ltr" ? idx : uniqueUsers.length - idx,
}))
} }
</script> </script>
<div class="avatars"> <div class="avatars">
{#each uniqueUsers as user, idx} {#each avatars as user}
<span style="z-index:{100 - idx};"> <span style="z-index:{user.zIndex};">
<UserAvatar {user} tooltipPosition={TooltipPosition.Bottom} /> {#if user._id === "overflow"}
<Avatar
{size}
initials={user.label}
color="var(--spectrum-global-color-gray-500)"
/>
{:else}
<UserAvatar {size} {user} tooltipPosition={TooltipPosition.Bottom} />
{/if}
</span> </span>
{/each} {/each}
</div> </div>
@ -27,10 +57,10 @@
.avatars { .avatars {
display: flex; display: flex;
} }
.avatars :global(> *:not(:first-child)) { span:not(:first-of-type) {
margin-left: -12px; margin-left: -6px;
} }
.avatars :global(.spectrum-Avatar) { .avatars :global(.spectrum-Avatar) {
border: 2px solid var(--background); border: 2px solid var(--avatars-background, var(--background));
} }
</style> </style>

View File

@ -172,7 +172,7 @@
</div> </div>
<div class="toprightnav"> <div class="toprightnav">
<span> <span>
<UserAvatars users={$userStore} /> <UserAvatars users={$userStore} order="rtl" />
</span> </span>
<AppActions {application} {loaded} /> <AppActions {application} {loaded} />
</div> </div>

View File

@ -3,7 +3,7 @@
import { helpers } from "@budibase/shared-core" import { helpers } from "@budibase/shared-core"
export let user export let user
export let size export let size = "S"
export let tooltipPosition = TooltipPosition.Top export let tooltipPosition = TooltipPosition.Top
export let showTooltip = true export let showTooltip = true
</script> </script>