Skip to content

Commit

Permalink
fix(meetings): show selected attendees in bubbles and hint
Browse files Browse the repository at this point in the history
Signed-off-by: Maksim Sukharev <[email protected]>
  • Loading branch information
Antreesy committed Jan 16, 2025
1 parent 04fb3cd commit fe7db75
Showing 1 changed file with 76 additions and 3 deletions.
79 changes: 76 additions & 3 deletions src/components/CalendarEventsDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,16 @@ import { useIsMobile } from '@nextcloud/vue/dist/Composables/useIsMobile.js'
import usernameToColor from '@nextcloud/vue/dist/Functions/usernameToColor.js'

import SelectableParticipant from './BreakoutRoomsEditor/SelectableParticipant.vue'
import ContactSelectionBubble from './UIShared/ContactSelectionBubble.vue'
import SearchBox from './UIShared/SearchBox.vue'
import TransitionWrapper from './UIShared/TransitionWrapper.vue'

import { useStore } from '../composables/useStore.js'
import { ATTENDEE } from '../constants.js'
import { hasTalkFeature } from '../services/CapabilitiesManager.ts'
import { useGroupwareStore } from '../stores/groupware.ts'
import type { Conversation, Participant } from '../types/index.ts'
import { getDisplayNameWithFallback } from '../utils/getDisplayName.ts'

const props = defineProps<{
token: string,
Expand Down Expand Up @@ -111,9 +114,34 @@ const invalidHint = computed(() => {
const selectAll = ref(true)
const selectedAttendeeIds = ref<number[]>([])
const attendeeHint = computed(() => {
return selectedAttendeeIds.value?.length
? n('spreed', 'Sending %n invitation', 'Sending %n invitations', selectedAttendeeIds.value.length)
: t('spreed', 'Sending no invitations')
if (!selectedAttendeeIds.value?.length) {
return t('spreed', 'Sending no invitations')
}

const list: Participant[] = selectedParticipants.value.slice(0, 2)
const remainingCount = selectedParticipants.value.length - list.length
const summary = list.map(participant => getDisplayNameWithFallback(participant.displayName, participant.actorType))

if (remainingCount === 0) {
// Amount is 2 or less
switch (summary.length) {
case 1: {
return t('spreed', '{participant0} will receive an invitation', { participant0: summary[0] })
}
case 2: {
return t('spreed', '{participant0} and {participant1} will receive invitations',
{ participant0: summary[0], participant1: summary[1] })
}
case 0:
default: {
return ''
}
}
} else {
return n('spreed', '{participant0}, {participant1} and %n other will receive invitations',
'{participant0}, {participant1} and %n others will receive invitations', remainingCount,
{ participant0: summary[0], participant1: summary[1] })
}
})

const searchText = ref('')
Expand All @@ -131,6 +159,20 @@ const filteredParticipants = computed(() => participants.value.filter((participa
|| (participant.actorType === ATTENDEE.ACTOR_TYPE.USERS && isMatch(participant.actorId))
|| (participant.actorType === ATTENDEE.ACTOR_TYPE.EMAILS && isMatch(participant.invitedActorId))
}))
const selectedParticipants = computed(() => participants.value
.filter((participant: Participant) => selectedAttendeeIds.value.includes(participant.attendeeId))
.sort((a: Participant, b: Participant) => {
if (a.actorType === ATTENDEE.ACTOR_TYPE.USERS && b.actorType === ATTENDEE.ACTOR_TYPE.EMAILS) {
return -1
} else if (a.actorType === ATTENDEE.ACTOR_TYPE.EMAILS && b.actorType === ATTENDEE.ACTOR_TYPE.USERS) {
return 1
} else if (a.actorType === ATTENDEE.ACTOR_TYPE.EMAILS && b.actorType === ATTENDEE.ACTOR_TYPE.EMAILS
&& (!a.displayName || !b.displayName)) {
return a.displayName ? -1 : 1
}
return 0
})
)

onBeforeMount(() => {
getCalendars()
Expand Down Expand Up @@ -171,6 +213,14 @@ function toggleAll(value: boolean) {
selectedAttendeeIds.value = value ? participants.value.map((participant: Participant) => participant.attendeeId) : []
}

/**
* Remove selected attendee from contact bubble
* @param value switch value
*/
function removeSelectedParticipant(value: Participant) {
selectedAttendeeIds.value = selectedAttendeeIds.value.filter(id => value.attendeeId !== id)
}

/**
* Check selected attendees
* @param value array of ids
Expand Down Expand Up @@ -374,6 +424,17 @@ async function submitNewMeeting() {
is-focused
:placeholder-text="t('spreed', 'Search participants')"
@abort-search="searchText = ''" />
<!-- Selected results -->
<TransitionWrapper v-if="selectedAttendeeIds.length"
class="calendar-meeting__attendees-selected"
name="zoom"
tag="div"
group>
<ContactSelectionBubble v-for="participant in selectedParticipants"
:key="participant.actorType + participant.actorId"
:participant="participant"
@update="removeSelectedParticipant" />
</TransitionWrapper>
<ul v-if="filteredParticipants.length" class="calendar-meeting__attendees">
<SelectableParticipant v-for="participant in filteredParticipants"
:key="participant.attendeeId"
Expand Down Expand Up @@ -508,6 +569,18 @@ async function submitNewMeeting() {
overflow-y: auto;
}

&__attendees-selected {
display: flex;
flex-wrap: wrap;
gap: var(--default-grid-baseline);
border-bottom: 1px solid var(--color-background-darker);
padding: var(--default-grid-baseline) 0;
max-height: 97px;
overflow-y: auto;
flex: 1 0 auto;
align-content: flex-start;
}

// Overwrite default NcDateTimePickerNative styles
:deep(.native-datetime-picker) {
width: calc(50% - var(--default-grid-baseline));
Expand Down

0 comments on commit fe7db75

Please sign in to comment.