Skip to content

Commit

Permalink
Update backend: Implemented wrappers to wrap the event request, worki…
Browse files Browse the repository at this point in the history
…ng on the dialogs in the frontend.
  • Loading branch information
Mahmoud-Emad committed Mar 25, 2024
1 parent f64bdd8 commit ffc2449
Show file tree
Hide file tree
Showing 15 changed files with 359 additions and 201 deletions.
2 changes: 1 addition & 1 deletion client/src/clients/api/meeting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export class MeetingApi extends ApiClientBase {

list(query?: any) {
return this.unwrap(
() => this.$http.get<Api.Returns.List<Api.Meetings>>(this.getUrl('', query)),
() => this.$http.get<Api.Returns.List<Api.Meeting>>(this.getUrl('', query)),
{
transform: (d) => d.results
}
Expand Down
197 changes: 181 additions & 16 deletions client/src/components/CalenderComponent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
<v-divider class="d-flex mx-auto" style="width: 90%"></v-divider>

<div class="ma-7 px-7">
{{ isLoading }}
<div class="loading-container d-flex align-center justify-center my-5" v-if="isLoading">
<v-alert density="compact" class="pa-5" type="info" text="Events are loading..."></v-alert>
</div>
Expand All @@ -32,31 +31,54 @@
}"
>
</FullCalendar>

</div>

<!-- Dialogs -->

<v-dialog
v-if="selectedEventType.isNewEvent"
:routeQuery="dates?.startStr"
:modelValue="selectedEventType.isNewEvent"
@click:outside="closeDialog(CalendarEventSelection.NewEvent)"
>
<v-card>
<calenderRequest
:dates="dates"
@close-dialog="closeDialog(CalendarEventSelection.NewEvent)"
@create-vacation="createVacation(dates?.startStr, $event)"
/>
<!-- @create-event="createEvent(dates?.startStr, $event)" -->
<!-- @create-meeting="createMeeting(dates?.startStr, $event)" -->
</v-card>
</v-dialog>
</template>

<script lang="ts" setup>
import { reactive, ref, watch } from 'vue'
import { type CalendarOptions } from '@fullcalendar/core'
import { type CalendarApi, type CalendarOptions } from '@fullcalendar/core'
import { useApi } from '@/hooks'
import { useAsyncState } from '@vueuse/core'
import calenderRequest from '@/components/calenderRequest.vue'
import FullCalendar from '@fullcalendar/vue3'
import dayGridPlugin from '@fullcalendar/daygrid'
import timeGridPlugin from '@fullcalendar/timegrid'
import listPlugin from '@fullcalendar/list'
import interactionPlugin from '@fullcalendar/interaction'
import type { Api } from '@/types'
import { CalendarEventSelection, type Api } from '@/types'
import { normalizeEvent, normalizeVacation } from '@/utils/helpers'
import { normalizedBirthday, normalizeHoliday, normalizeMeeting } from '@/utils'
import { ApiClientBase } from '@/clients/api/base'
const homeEvents = ref<Api.Home[]>([])
const filteredEvents = ref<Api.Home[]>([])
const currentDate = ref<Date>(new Date())
const calendar = ref<CalendarApi>()
const isLoading = ref<boolean>(false)
const $api = useApi()
const dates = ref<any>()
const filters = reactive({
meeting: true,
event: true,
Expand All @@ -65,9 +87,32 @@ const filters = reactive({
birthday: true
})
const selectedEventType = reactive({
isMeeting: false,
isEvent: false,
isVacation: false,
isHoliday: false,
isBirthday: false,
isNewEvent: false
})
const meetings = ref<Api.Meeting[]>([])
const events = ref<Api.Event[]>([])
const vacations = ref<Api.Vacation[]>([])
const holidays = ref<Api.Holiday[]>([])
const birthdays = ref<Api.User[]>([])
const cached_users = new Map<number, Api.User>()
const selectedEvent = ref<Api.Meeting | Api.Inputs.Event | Api.Vacation | Api.Holiday | Api.User>()
const me = ApiClientBase.user.value?.fullUser
if (me) {
cached_users.set(me.id, me)
}
const loadEvents = async () => {
isLoading.value = true
useAsyncState(
await useAsyncState(
() =>
$api.home.list({
month: currentDate.value.getMonth() + 1,
Expand All @@ -76,13 +121,10 @@ const loadEvents = async () => {
[],
{
onSuccess(data) {
console.log("data", data);
for (const event of data) {
updateEventCalendarType(event)
}
filteredEvents.value = [...homeEvents.value]
console.log(filteredEvents.value);
}
}
)
Expand All @@ -93,40 +135,158 @@ const updateEventCalendarType = (event: any) => {
if (event.type === 'vacation') {
const vacationEvent = normalizeVacation(event) as any
homeEvents.value.push(vacationEvent)
vacations.value.push(event)
} else if (event.type === 'holiday') {
const publicHoliday = normalizeHoliday(event) as any
homeEvents.value.push(publicHoliday)
holidays.value.push(event)
} else if (event.type === 'meeting') {
const meeting = normalizeMeeting(event) as any
homeEvents.value.push(meeting)
meetings.value.push(event)
} else if (event.type === 'birthday') {
const birthday = normalizedBirthday(event) as any
homeEvents.value.push(birthday)
birthdays.value.push(event)
} else if (event.type === 'event') {
const _event = normalizeEvent(event) as any
homeEvents.value.push(_event)
events.value.push(event)
}
filteredEvents.value = [...homeEvents.value]
}
const filterEvents = () => {
console.log("events.value len 1", homeEvents.value.length);
filteredEvents.value = homeEvents.value.filter(event => {
const filterEvents = () => {
filteredEvents.value = homeEvents.value.filter((event) => {
return (
(event.type === 'meeting' && filters.meeting) ||
(event.type === 'event' && filters.event) ||
(event.type === 'vacation' && filters.vacation) ||
(event.type === 'holiday' && filters.holiday) ||
(event.type === 'birthday' && filters.birthday)
);
});
console.log("filteredEvents", filteredEvents.value.length);
)
})
}
function onSelect(arg: any) {
calendar.value = arg.view.calendar
dates.value = arg
openDialog(CalendarEventSelection.NewEvent)
}
function onClick(arg: any) {
selectedEvent.value = undefined
calendar.value = arg.view.calendar
const clickedEventTitle = arg.event.title as string
// We use a normalized event ID to avoid duplication. It's created by concatenating 'holiday', 'birthday', 'event', 'meeting', and 'vacation' with the event ID.
if (clickedEventTitle === CalendarEventSelection.PublicHoliday) {
selectedEvent.value = holidays.value.filter(
(holiday) => holiday.id === Number(arg.event.id.replace('holiday', ''))
)[0]
openDialog(CalendarEventSelection.PublicHoliday)
} else if (
clickedEventTitle
.toLocaleLowerCase()
.includes(CalendarEventSelection.Vacation.toLocaleLowerCase())
) {
selectedEvent.value = vacations.value.filter(
(vacation) => vacation.id === Number(arg.event.id.replace('vacation', ''))
)[0]
openDialog(CalendarEventSelection.Vacation)
} else if (clickedEventTitle === CalendarEventSelection.Birthday) {
selectedEvent.value = birthdays.value.filter(
(birthday) => birthday.id === Number(arg.event.id.replace('birthday', ''))
)[0]
openDialog(CalendarEventSelection.Birthday)
} else if (clickedEventTitle === CalendarEventSelection.Event) {
selectedEvent.value = events.value.filter(
(event) => event.id === Number(arg.event.id.replace('event', ''))
)[0]
openDialog(CalendarEventSelection.Event)
} else if (clickedEventTitle === CalendarEventSelection.Meeting) {
selectedEvent.value = meetings.value.filter(
(meeting) => meeting.id === Number(arg.event.id.replace('meeting', ''))
)[0]
openDialog(CalendarEventSelection.Meeting)
}
}
function openDialog(dialogType: string) {
console.log("Dates: ", dates.value);
switch (dialogType) {
case CalendarEventSelection.Birthday:
selectedEventType.isBirthday = true
break
case CalendarEventSelection.Event:
selectedEventType.isEvent = true
break
case CalendarEventSelection.Meeting:
selectedEventType.isMeeting = true
break
case CalendarEventSelection.PublicHoliday:
selectedEventType.isHoliday = true
break
case CalendarEventSelection.Vacation:
selectedEventType.isVacation = true
break
case CalendarEventSelection.NewEvent:
selectedEventType.isNewEvent = true
break
default:
break
}
}
function closeDialog(dialogType: string) {
switch (dialogType) {
case CalendarEventSelection.Birthday:
selectedEventType.isBirthday = false
break
case CalendarEventSelection.Event:
selectedEventType.isEvent = false
break
case CalendarEventSelection.Meeting:
selectedEventType.isMeeting = false
break
case CalendarEventSelection.PublicHoliday:
selectedEventType.isHoliday = false
break
case CalendarEventSelection.Vacation:
selectedEventType.isVacation = false
break
case CalendarEventSelection.NewEvent:
selectedEventType.isNewEvent = false
break
default:
selectedEventType.isNewEvent = false
break
}
}
async function createVacation(id: number, data: any) {
const vacation: Api.Vacation = data.vacation;
console.log("data: ", data);
if (cached_users.has(vacation.applying_user.id)) {
vacation.applying_user = cached_users.get(vacation.applying_user.id)
} else {
const user = await $api.users.getuser(vacation.applying_user.id, { disableNotify: true })
cached_users.set(vacation.applying_user.id, user)
vacation.applying_user = user
}
function onSelect() {}
function onClick() {}
vacations.value.push(vacation)
filteredEvents.value.push(vacation)
selectedEventType.isNewEvent = false
// return closeDialog(CalendarEventSelection.Vacation)
}
function createMeeting() {}
function createEvent() {}
const options = reactive<CalendarOptions>({
plugins: [dayGridPlugin, timeGridPlugin, listPlugin, interactionPlugin],
Expand Down Expand Up @@ -179,9 +339,14 @@ button {
text-transform: capitalize !important;
}
.fc-daygrid-event-harness {
cursor: pointer;
}
.fc-event-title {
font-weight: 500;
color: #131313 !important;
cursor: pointer;
}
.fc-popover {
Expand Down
16 changes: 11 additions & 5 deletions client/src/components/cards/vacationCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
<p>
Applying User :
<span color="warning" class="mx-2">{{
vacation.user.full_name
vacation.applying_user.full_name
}}</span>
</p>
</v-col>
Expand Down Expand Up @@ -80,10 +80,16 @@ import { computed, ref, watch } from 'vue';
import { useApi } from '@/hooks'
import { useAsyncState } from '@vueuse/core'
import { ApiClientBase } from '@/clients/api/base'
import type { PropType } from 'vue';
export default {
name: 'vacationCard',
props: ['vacation'],
props: {
vacation: {
type: Object as PropType<Api.Vacation>,
required: true,
}
},
emits: {
'close-dialog': (item: Boolean) => item,
'update-vacation': (item: any) => item,
Expand Down Expand Up @@ -154,12 +160,12 @@ export default {
user.value.fullUser.user_type === 'Admin' ||
user.value.fullUser.user_type === 'Supervisor'
) {
if (props.vacation.user.id == user.value.fullUser.id) {
if (props.vacation.applying_user.id == user.value.fullUser.id) {
return true
}
if (
props.vacation.user.reporting_to[0]?.id === props.vacation.user?.id &&
props.vacation.user.location.name === user.value.fullUser.location.name
props.vacation.applying_user.reporting_to[0]?.id === props.vacation.applying_user?.id &&
props.vacation.applying_user.location.name === user.value.fullUser.location.name
) {
return true
}
Expand Down
12 changes: 10 additions & 2 deletions client/src/types/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export module Api {
export interface Certificate {}

export interface Salary {}
export interface Meetings {
export interface Meeting {
type: string;
id: number
invited_users: any[]
Expand All @@ -71,6 +71,14 @@ export module Api {
}
location: string
}
export interface Event {
id: number
name: string
type: string;
description: string;
from_date: string;
end_date: string;
}
export interface User {
type: string;
id: number
Expand Down Expand Up @@ -146,7 +154,7 @@ export module Api {
export type Meeting = MsgRes<Meeting>

export type Profile = MsgRes<User>
export type AllMeetings = MsgRes<Meetings>
export type AllMeetings = MsgRes<Meeting>

export type Login = MsgRes<{
id: number
Expand Down
Loading

0 comments on commit ffc2449

Please sign in to comment.