Skip to content

Commit

Permalink
[wip] feat(calendar): add dialog for meetings overview
Browse files Browse the repository at this point in the history
Signed-off-by: Maksim Sukharev <[email protected]>
  • Loading branch information
Antreesy committed Dec 16, 2024
1 parent 39eb211 commit 2986b59
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 1 deletion.
117 changes: 117 additions & 0 deletions src/components/CalendarEventsDialog.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
<!--
- SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
- SPDX-License-Identifier: AGPL-3.0-or-later
-->

<script setup lang="ts">
import { computed, onBeforeMount, ref } from 'vue'

import IconCalendarBlank from 'vue-material-design-icons/CalendarBlank.vue'

import { showError, showSuccess } from '@nextcloud/dialogs'
import { t, n } from '@nextcloud/l10n'

import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
import NcDateTimePickerNative from '@nextcloud/vue/dist/Components/NcDateTimePickerNative.js'
import NcDialog from '@nextcloud/vue/dist/Components/NcDialog.js'
import NcEmptyContent from '@nextcloud/vue/dist/Components/NcEmptyContent.js'
import NcLoadingIcon from '@nextcloud/vue/dist/Components/NcLoadingIcon.js'
import NcSelect from '@nextcloud/vue/dist/Components/NcSelect.js'
import usernameToColor from '@nextcloud/vue/dist/Functions/usernameToColor.js'

import { useGroupwareStore } from '../stores/groupware.ts'

const props = defineProps<{
token: string,
container?: string,
}>()
const emit = defineEmits<{
(event: 'close'): void,
}>()

const groupwareStore = useGroupwareStore()

const loading = ref(groupwareStore.calendars.length === 0)
const upcomingEvents = computed(() => {
return groupwareStore.getAllEvents(props.token)
})

const selectedCalendar = ref(null)
const calendarOptions = computed(() => {
return groupwareStore.calendars.map(calendar => {
return {
value: calendar.uri,
label: calendar.name,
style: `background-color: ${calendar.color ?? usernameToColor(calendar.uri).color}`,
}
})
})

onBeforeMount(() => {
getCalendars()
})

/**
*
*/
async function getCalendars() {
await groupwareStore.getPersonalCalendars()
loading.value = false
}
</script>

<template>
<NcDialog class="calendar-events"
:name="t('spreed', 'Upcoming events')"
size="normal"
close-on-click-outside
:container="container"
@update:open="emit('close')">
<template v-if="!loading && upcomingEvents.length">
<ul>
<li v-for="event in upcomingEvents" :key="event.uri">
<a :href="event.calendarAppUrl" target="_blank">{{ event.summary }}</a>
</li>
</ul>
</template>
<NcEmptyContent v-else>
<template #icon>
<NcLoadingIcon v-if="loading" />
<IconCalendarBlank v-else />
</template>

<template #description>
<p>{{ loading ? t('spreed', 'Loading …') : t('spreed', 'No upcoming events') }}</p>
</template>
</NcEmptyContent>
<NcSelect id="schedule_meeting_select"
v-model="selectedCalendar"
:options="calendarOptions"
:placeholder="t('spreed', 'Select calendar …')">
<template #option="option">
<span class="select-option_badge" :style="option.style" />
{{ option.label }}
</template>
</NcSelect>
<!-- <NcDateTimePickerNative id="schedule_meeting_input" ></NcDateTimePickerNative>-->

Check failure on line 96 in src/components/CalendarEventsDialog.vue

View workflow job for this annotation

GitHub Actions / NPM lint

Unexpected tab character
<template #actions>
<NcButton type="primary"
@click="emit('close')">
{{ t('spreed', 'Schedule a meeting') }}
</NcButton>
</template>
</NcDialog>
</template>

<style lang="scss" scoped>
.calendar-events {
}

.select-option_badge {
display: inline-block;
width: var(--default-font-size);
height: var(--default-font-size);
border-radius: 50%;
background-color: var(--primary-color);
}
</style>
9 changes: 9 additions & 0 deletions src/components/TopBar/TopBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
:show-actions="!isSidebar"
:is-sidebar="isSidebar"
:model="localMediaModel"
@open-calendar-events-dialog="showCalendarEventsDialog = true"
@open-breakout-rooms-editor="showBreakoutRoomsEditor = true" />

<CallButton shrink-on-mobile :hide-text="isSidebar" :is-screensharing="!!localMediaModel.attributes.localScreen" />
Expand All @@ -115,6 +116,11 @@
<BreakoutRoomsEditor v-if="showBreakoutRoomsEditor"
:token="token"
@close="showBreakoutRoomsEditor = false" />

<!-- Calendar events dialog -->
<CalendarEventsDialog v-if="showCalendarEventsDialog"
:token="token"
@close="showCalendarEventsDialog = false" />
</div>
</div>
</template>
Expand All @@ -139,6 +145,7 @@ import TasksCounter from './TasksCounter.vue'
import TopBarMediaControls from './TopBarMediaControls.vue'
import TopBarMenu from './TopBarMenu.vue'
import BreakoutRoomsEditor from '../BreakoutRoomsEditor/BreakoutRoomsEditor.vue'
import CalendarEventsDialog from '../CalendarEventsDialog.vue'
import ConversationIcon from '../ConversationIcon.vue'

import { useGetParticipants } from '../../composables/useGetParticipants.js'
Expand All @@ -155,6 +162,7 @@ export default {
components: {
// Components
BreakoutRoomsEditor,
CalendarEventsDialog,
CallButton,
CallTime,
ConversationIcon,
Expand Down Expand Up @@ -203,6 +211,7 @@ export default {
data: () => {
return {
showBreakoutRoomsEditor: false,
showCalendarEventsDialog: false,
boundaryElement: document.querySelector('.main-view'),
}
},
Expand Down
15 changes: 14 additions & 1 deletion src/components/TopBar/TopBarMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,17 @@
</NcActionButton>
</template>

<!-- Moderator actions -->
<template v-if="canFullModerate">
<NcActionButton close-after-click
@click="$emit('open-calendar-events-dialog')">
<template #icon>
<IconCalendarBlank :size="20" />
</template>
{{ t('spreed', 'Schedule a meeting') }}
</NcActionButton>
</template>

<!-- Fullscreen -->
<NcActionButton :aria-label="t('spreed', 'Toggle full screen')"
close-after-click
Expand Down Expand Up @@ -150,6 +161,7 @@
</template>

<script>
import IconCalendarBlank from 'vue-material-design-icons/CalendarBlank.vue'
import IconCog from 'vue-material-design-icons/Cog.vue'
import IconDotsCircle from 'vue-material-design-icons/DotsCircle.vue'
import IconDotsHorizontal from 'vue-material-design-icons/DotsHorizontal.vue'
Expand Down Expand Up @@ -208,6 +220,7 @@ export default {
NcButton,
NcLoadingIcon,
// Icons
IconCalendarBlank,
IconCog,
IconDotsCircle,
IconDotsHorizontal,
Expand Down Expand Up @@ -255,7 +268,7 @@ export default {
},
},

emits: ['open-breakout-rooms-editor'],
emits: ['open-breakout-rooms-editor', 'open-calendar-events-dialog'],

setup() {
return {
Expand Down
16 changes: 16 additions & 0 deletions src/stores/groupware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,28 @@ import type { AxiosError } from '@nextcloud/axios'
import { generateUrl, getBaseUrl } from '@nextcloud/router'

import {
getPersonalCalendars,
getUpcomingEvents,
getUserAbsence,
} from '../services/groupwareService.ts'
import type {
Calendar,
OutOfOfficeResult,
UpcomingEvent,
} from '../types/index.ts'

type State = {
absence: Record<string, OutOfOfficeResult>
calendars: Calendar[],
defaultCalendarUri: string | null,
upcomingEvents: Record<string, UpcomingEvent[]>
}

export const useGroupwareStore = defineStore('groupware', {
state: (): State => ({
absence: {},
calendars: [],
defaultCalendarUri: null,
upcomingEvents: {},
}),

Expand Down Expand Up @@ -73,6 +79,16 @@ export const useGroupwareStore = defineStore('groupware', {
}
},

async getPersonalCalendars() {
try {
const response = await getPersonalCalendars()
Vue.set(this, 'calendars', response.data.ocs.data.calendars)
Vue.set(this, 'defaultCalendarUri', response.data.ocs.data.defaultCalendarUri)
} catch (error) {
console.error(error)
}
},

/**
* Drop an absence status from the store
* @param {string} token The conversation token
Expand Down

0 comments on commit 2986b59

Please sign in to comment.