-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Additional Stores #215
Additional Stores #215
Changes from 4 commits
c4d0333
5c7d1ab
a4d4aa6
8dd4f0f
b7cb014
47aefc5
b8d0ce6
5eae328
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -151,7 +151,6 @@ | |
|
||
<script setup> | ||
import { ref, inject, onMounted, computed } from 'vue'; | ||
import { useAuth0 } from '@auth0/auth0-vue'; | ||
import { useI18n } from 'vue-i18n'; | ||
import { useRouter } from 'vue-router'; | ||
import { useUserStore } from '@/stores/user-store'; | ||
|
@@ -164,17 +163,18 @@ import TextButton from '@/elements/TextButton.vue'; | |
// icons | ||
import { IconExternalLink } from '@tabler/icons-vue'; | ||
|
||
// stores | ||
import { useExternalConnectionsStore } from '@/stores/external-connections-store'; | ||
|
||
// component constants | ||
const { t } = useI18n({ useScope: 'global' }); | ||
const call = inject('call'); | ||
const refresh = inject('refresh'); | ||
const router = useRouter(); | ||
const user = useUserStore(); | ||
const logout = inject('logout'); | ||
const externalConnectionsStore = useExternalConnectionsStore(); | ||
|
||
const externalConnections = ref({}); | ||
const hasZoomAccountConnected = computed(() => (externalConnections.value?.zoom?.length ?? []) > 0); | ||
const zoomAccountName = computed(() => (externalConnections.value?.zoom[0].name ?? null)); | ||
const hasZoomAccountConnected = computed(() => (externalConnectionsStore.zoom.length) > 0); | ||
const zoomAccountName = computed(() => (externalConnectionsStore.zoom[0].name ?? null)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since we only allow one zoom connection, any objection to the zoom getter just grabbing the first item? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, I think this is fine. Maybe adding a comment indication that we currently only handle one zoom connection would make things clearer here. Is |
||
|
||
const activeUsername = ref(user.data.username); | ||
const activeDisplayName = ref(user.data.name); | ||
|
@@ -205,15 +205,9 @@ const getSignedUserUrl = async () => { | |
signedUserUrl.value = data.value.url; | ||
}; | ||
|
||
const getExternalConnections = async () => { | ||
const { data } = await call('account/external-connections').get().json(); | ||
externalConnections.value = data.value; | ||
}; | ||
|
||
const refreshData = async () => Promise.all([ | ||
getSignedUserUrl(), | ||
getExternalConnections(), | ||
refresh(), | ||
externalConnectionsStore.fetch(call), | ||
]); | ||
|
||
// save user data | ||
|
@@ -261,6 +255,7 @@ const connectZoom = async () => { | |
}; | ||
const disconnectZoom = async () => { | ||
await call('zoom/disconnect').post(); | ||
await useExternalConnectionsStore().reset(); | ||
await refreshData(); | ||
}; | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,7 +8,7 @@ | |
<calendar-management | ||
:title="t('heading.calendarsUnconnected')" | ||
:type="calendarManagementType.connect" | ||
:calendars="calendars" | ||
:calendars="calendarStore.unconnectedCalendars" | ||
:loading="loading" | ||
@sync="syncCalendars" | ||
@modify="connectCalendar" | ||
|
@@ -18,7 +18,7 @@ | |
<calendar-management | ||
:title="t('heading.calendarsConnected')" | ||
:type="calendarManagementType.edit" | ||
:calendars="calendars" | ||
:calendars="calendarStore.connectedCalendars" | ||
:loading="loading" | ||
@remove="deleteCalendar" | ||
@modify="editCalendar" | ||
|
@@ -199,7 +199,9 @@ | |
<script setup> | ||
import { calendarManagementType } from '@/definitions'; | ||
import { IconArrowRight } from '@tabler/icons-vue'; | ||
import { ref, reactive, inject, onMounted, computed } from 'vue'; | ||
import { | ||
ref, reactive, inject, onMounted, computed, | ||
} from 'vue'; | ||
import { useI18n } from 'vue-i18n'; | ||
import { useRoute, useRouter } from 'vue-router'; | ||
import AlertBox from '@/elements/AlertBox'; | ||
|
@@ -208,12 +210,14 @@ import GoogleSignInBtn from '@/assets/img/google/1x/btn_google_signin_light_norm | |
import GoogleSignInBtn2x from '@/assets/img/google/2x/[email protected]'; | ||
import PrimaryButton from '@/elements/PrimaryButton'; | ||
import SecondaryButton from '@/elements/SecondaryButton'; | ||
import ConfirmationModal from "@/components/ConfirmationModal.vue"; | ||
import ConfirmationModal from '@/components/ConfirmationModal.vue'; | ||
import { useCalendarStore } from '@/stores/calendar-store'; | ||
|
||
// component constants | ||
const { t } = useI18n({ useScope: 'global' }); | ||
const call = inject('call'); | ||
const refresh = inject('refresh'); | ||
const calendarStore = useCalendarStore(); | ||
|
||
const calendarConnectError = ref(''); | ||
|
||
|
@@ -223,11 +227,6 @@ const deleteCalendarModalTarget = ref(null); | |
// Temp until we get a store solution rolling | ||
const loading = ref(false); | ||
|
||
// view properties | ||
defineProps({ | ||
calendars: Array, // list of calendars from db | ||
}); | ||
|
||
// handle calendar user input to add or edit calendar connections | ||
const inputModes = { | ||
hidden: 0, | ||
|
@@ -264,7 +263,9 @@ const closeModals = async () => { | |
}; | ||
|
||
const refreshData = async () => { | ||
await refresh({ onlyConnectedCalendars: false }); | ||
// Invalidate our calendar store | ||
await calendarStore.reset(); | ||
await refresh(); | ||
loading.value = false; | ||
}; | ||
|
||
|
@@ -391,7 +392,5 @@ onMounted(async () => { | |
calendarConnectError.value = route.query.error; | ||
await router.replace(route.path); | ||
} | ||
|
||
await refreshData(); | ||
}); | ||
</script> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import { defineStore } from 'pinia'; | ||
import { appointmentState } from '@/definitions'; | ||
import { useUserStore } from '@/stores/user-store'; | ||
import dj from 'dayjs'; | ||
|
||
const initialData = { | ||
appointments: [], | ||
isInit: false, | ||
}; | ||
|
||
// eslint-disable-next-line import/prefer-default-export | ||
export const useAppointmentStore = defineStore('appointments', { | ||
state: () => ({ | ||
data: structuredClone(initialData), | ||
}), | ||
getters: { | ||
isLoaded() { | ||
return this.data.isInit; | ||
}, | ||
appointments() { | ||
return this.data.appointments; | ||
}, | ||
pendingAppointments() { | ||
return this.data.appointments.filter((a) => a.status === appointmentState.pending); | ||
}, | ||
}, | ||
actions: { | ||
status(appointment) { | ||
// check past events | ||
if (appointment.slots.filter((s) => dj(s.start).isAfter(dj())).length === 0) { | ||
return appointmentState.past; | ||
} | ||
// check booked events | ||
if (appointment.slots.filter((s) => s.attendee_id != null).length > 0) { | ||
return appointmentState.booked; | ||
} | ||
// else event is still wating to be booked | ||
return appointmentState.pending; | ||
}, | ||
reset() { | ||
this.$patch({ data: structuredClone(initialData) }); | ||
}, | ||
async mergeCalendarInfo(calendarsById) { | ||
const userStore = useUserStore(); | ||
|
||
this.data.appointments.forEach((a) => { | ||
a.calendar_title = calendarsById[a.calendar_id]?.title; | ||
a.calendar_color = calendarsById[a.calendar_id]?.color; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. At some point we can improve this by appending the corresponding calendar object to the appointment. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And done! |
||
a.status = this.status(a); | ||
a.active = a.status !== appointmentState.past; // TODO | ||
// convert start dates from UTC back to users timezone | ||
a.slots.forEach((s) => { | ||
s.start = dj.utc(s.start).tz(userStore.data.timezone ?? dj.tz.guess()); | ||
}); | ||
}); | ||
}, | ||
async fetch(call) { | ||
const { data, error } = await call('me/appointments').get().json(); | ||
if (!error.value) { | ||
if (data.value === null || typeof data.value === 'undefined') return; | ||
this.data.appointments = data.value; | ||
this.data.isInit = true; | ||
} | ||
}, | ||
}, | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you use a line length limitation < 120? Just wondering about the line breaks here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I need to fix this up as my ide is at odds with eslint. 😵