Added arrow navigation on calendar page
This commit is contained in:
@@ -8,8 +8,8 @@ import CenturyLayout from "./state/centennially/Layout.vue"
|
|||||||
import DecadeLayout from "./state/decennially/Layout.vue"
|
import DecadeLayout from "./state/decennially/Layout.vue"
|
||||||
import YearLayout from "./state/yearly/Layout.vue"
|
import YearLayout from "./state/yearly/Layout.vue"
|
||||||
|
|
||||||
const { currentConfig, jumpToDate, selectedDate } = useCalendar()
|
const { currentConfig, jumpToDate, selectedDate, toPastFar, toPastNear, toFutureNear, toFutureFar } = useCalendar()
|
||||||
const { isReadOnly } = storeToRefs(useCalendar())
|
const { isReadOnly, calendarState } = storeToRefs(useCalendar())
|
||||||
|
|
||||||
const currentViewComponent: ComputedRef<Component> = computed<Component>(() => {
|
const currentViewComponent: ComputedRef<Component> = computed<Component>(() => {
|
||||||
switch (currentConfig.viewType) {
|
switch (currentConfig.viewType) {
|
||||||
@@ -31,6 +31,34 @@ const currentViewComponent: ComputedRef<Component> = computed<Component>(() => {
|
|||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
jumpToDate(selectedDate)
|
jumpToDate(selectedDate)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Key combos to navigate
|
||||||
|
const { arrowUp, arrowLeft, pageUp } = useMagicKeys()
|
||||||
|
const { arrowDown, arrowRight, pageDown } = useMagicKeys()
|
||||||
|
|
||||||
|
watch([arrowUp, arrowLeft], (k) => {
|
||||||
|
if (calendarState.value === 'active' && k[0] || k[1]) {
|
||||||
|
toPastNear()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
watch([arrowDown, arrowRight], (k) => {
|
||||||
|
if (calendarState.value === 'active' && k[0] || k[1]) {
|
||||||
|
toFutureNear()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(pageUp!, (k) => {
|
||||||
|
if (calendarState.value === 'active' && k) {
|
||||||
|
toPastFar()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(pageDown!, (k) => {
|
||||||
|
if (calendarState.value === 'active' && k) {
|
||||||
|
toFutureFar()
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|||||||
@@ -3,20 +3,8 @@ import { breakpointsTailwind, useBreakpoints } from "@vueuse/core"
|
|||||||
import { PhPlus } from "@phosphor-icons/vue";
|
import { PhPlus } from "@phosphor-icons/vue";
|
||||||
import { VisuallyHidden } from "radix-vue";
|
import { VisuallyHidden } from "radix-vue";
|
||||||
|
|
||||||
const isDialogOpen = ref<boolean>(false);
|
const { isCreatingEventModalOpen } = storeToRefs(useCalendar());
|
||||||
const { resetSkeleton } = useCalendar();
|
const { resetSkeleton, toggleCreatingEventModal } = useCalendar();
|
||||||
|
|
||||||
// Watch the popover state
|
|
||||||
watch(isDialogOpen, (hasOpened, _o) => {
|
|
||||||
if (hasOpened) {
|
|
||||||
resetSkeleton()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// Toggles the dialog
|
|
||||||
function toggleDialog() {
|
|
||||||
isDialogOpen.value = !isDialogOpen.value;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prevents the modal from closing if's still loading
|
* Prevents the modal from closing if's still loading
|
||||||
@@ -36,7 +24,7 @@ const breakpoints = useBreakpoints(
|
|||||||
<UiButton
|
<UiButton
|
||||||
class="max-md:fixed max-md:bottom-8 max-md:right-8 max-md:z-50 max-md:size-14 max-md:rounded-xl"
|
class="max-md:fixed max-md:bottom-8 max-md:right-8 max-md:z-50 max-md:size-14 max-md:rounded-xl"
|
||||||
:size="breakpoints.md.value ? 'default' : 'icon'"
|
:size="breakpoints.md.value ? 'default' : 'icon'"
|
||||||
@click="toggleDialog"
|
@click="toggleCreatingEventModal"
|
||||||
>
|
>
|
||||||
<PhPlus :size="breakpoints.md.value ? 18 : 24" weight="bold" />
|
<PhPlus :size="breakpoints.md.value ? 18 : 24" weight="bold" />
|
||||||
|
|
||||||
@@ -47,7 +35,7 @@ const breakpoints = useBreakpoints(
|
|||||||
</Transition>
|
</Transition>
|
||||||
</ClientOnly>
|
</ClientOnly>
|
||||||
|
|
||||||
<UiDialog v-model:open="isDialogOpen">
|
<UiDialog v-model:open="isCreatingEventModalOpen">
|
||||||
<UiDialogContent
|
<UiDialogContent
|
||||||
class="max-md:translate-0 max-md:inset-0 max-md:w-full max-md:block"
|
class="max-md:translate-0 max-md:inset-0 max-md:w-full max-md:block"
|
||||||
:trap-focus="true"
|
:trap-focus="true"
|
||||||
@@ -64,7 +52,7 @@ const breakpoints = useBreakpoints(
|
|||||||
</UiDialogDescription>
|
</UiDialogDescription>
|
||||||
</VisuallyHidden>
|
</VisuallyHidden>
|
||||||
|
|
||||||
<CalendarFormCreateEvent @event-created="toggleDialog" />
|
<CalendarFormCreateEvent @event-created="toggleCreatingEventModal" />
|
||||||
</UiDialogContent>
|
</UiDialogContent>
|
||||||
</UiDialog>
|
</UiDialog>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ interface DirectionLabels {
|
|||||||
futureFar: string
|
futureFar: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const { currentConfig, decrementViewMonth, incrementViewMonth, decrementViewYear, incrementViewYear } =
|
const { currentConfig, toPastFar, toPastNear, toFutureNear, toFutureFar } =
|
||||||
useCalendar()
|
useCalendar()
|
||||||
|
|
||||||
const activeDirectionLabels: ComputedRef<DirectionLabels> = computed(() => {
|
const activeDirectionLabels: ComputedRef<DirectionLabels> = computed(() => {
|
||||||
@@ -51,90 +51,6 @@ const activeDirectionLabels: ComputedRef<DirectionLabels> = computed(() => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
function toPastFar(): void {
|
|
||||||
switch (currentConfig.viewType) {
|
|
||||||
case "month":
|
|
||||||
decrementViewYear()
|
|
||||||
break
|
|
||||||
|
|
||||||
case "year":
|
|
||||||
decrementViewYear(10)
|
|
||||||
break
|
|
||||||
|
|
||||||
case "decade":
|
|
||||||
decrementViewYear(100)
|
|
||||||
break
|
|
||||||
|
|
||||||
case "century":
|
|
||||||
default:
|
|
||||||
decrementViewYear(1000)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function toPastNear(): void {
|
|
||||||
switch (currentConfig.viewType) {
|
|
||||||
case "month":
|
|
||||||
decrementViewMonth()
|
|
||||||
break
|
|
||||||
|
|
||||||
case "year":
|
|
||||||
decrementViewYear()
|
|
||||||
break
|
|
||||||
|
|
||||||
case "decade":
|
|
||||||
decrementViewYear(10)
|
|
||||||
break
|
|
||||||
|
|
||||||
case "century":
|
|
||||||
default:
|
|
||||||
decrementViewYear(100)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function toFutureNear(): void {
|
|
||||||
switch (currentConfig.viewType) {
|
|
||||||
case "month":
|
|
||||||
incrementViewMonth()
|
|
||||||
break
|
|
||||||
|
|
||||||
case "year":
|
|
||||||
incrementViewYear()
|
|
||||||
break
|
|
||||||
|
|
||||||
case "decade":
|
|
||||||
incrementViewYear(10)
|
|
||||||
break
|
|
||||||
|
|
||||||
case "century":
|
|
||||||
default:
|
|
||||||
incrementViewYear(100)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function toFutureFar(): void {
|
|
||||||
switch (currentConfig.viewType) {
|
|
||||||
case "month":
|
|
||||||
incrementViewYear()
|
|
||||||
break
|
|
||||||
|
|
||||||
case "year":
|
|
||||||
incrementViewYear(10)
|
|
||||||
break
|
|
||||||
|
|
||||||
case "decade":
|
|
||||||
incrementViewYear(100)
|
|
||||||
break
|
|
||||||
|
|
||||||
case "century":
|
|
||||||
default:
|
|
||||||
incrementViewYear(1000)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ import type { CalendarEvent } from "@@/models/CalendarEvent"
|
|||||||
import type { CalendarMonth } from "@@/models/CalendarMonth"
|
import type { CalendarMonth } from "@@/models/CalendarMonth"
|
||||||
import type { Category } from "@@/models/Category"
|
import type { Category } from "@@/models/Category"
|
||||||
|
|
||||||
|
type CalendarState = "active" | "idle"
|
||||||
|
|
||||||
type CalendarViewType = "month" | "year" | "decade" | "century"
|
type CalendarViewType = "month" | "year" | "decade" | "century"
|
||||||
|
|
||||||
type CalendarCurrentConfig = {
|
type CalendarCurrentConfig = {
|
||||||
@@ -668,6 +670,90 @@ export const useCalendar = defineStore("calendar", () => {
|
|||||||
currentEvents.value = computeCurrentEvents()
|
currentEvents.value = computeCurrentEvents()
|
||||||
}, { deep: true, immediate: true })
|
}, { deep: true, immediate: true })
|
||||||
|
|
||||||
|
function toPastFar(): void {
|
||||||
|
switch (currentConfig.value.viewType) {
|
||||||
|
case "month":
|
||||||
|
decrementViewYear()
|
||||||
|
break
|
||||||
|
|
||||||
|
case "year":
|
||||||
|
decrementViewYear(10)
|
||||||
|
break
|
||||||
|
|
||||||
|
case "decade":
|
||||||
|
decrementViewYear(100)
|
||||||
|
break
|
||||||
|
|
||||||
|
case "century":
|
||||||
|
default:
|
||||||
|
decrementViewYear(1000)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function toPastNear(): void {
|
||||||
|
switch (currentConfig.value.viewType) {
|
||||||
|
case "month":
|
||||||
|
decrementViewMonth()
|
||||||
|
break
|
||||||
|
|
||||||
|
case "year":
|
||||||
|
decrementViewYear()
|
||||||
|
break
|
||||||
|
|
||||||
|
case "decade":
|
||||||
|
decrementViewYear(10)
|
||||||
|
break
|
||||||
|
|
||||||
|
case "century":
|
||||||
|
default:
|
||||||
|
decrementViewYear(100)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function toFutureNear(): void {
|
||||||
|
switch (currentConfig.value.viewType) {
|
||||||
|
case "month":
|
||||||
|
incrementViewMonth()
|
||||||
|
break
|
||||||
|
|
||||||
|
case "year":
|
||||||
|
incrementViewYear()
|
||||||
|
break
|
||||||
|
|
||||||
|
case "decade":
|
||||||
|
incrementViewYear(10)
|
||||||
|
break
|
||||||
|
|
||||||
|
case "century":
|
||||||
|
default:
|
||||||
|
incrementViewYear(100)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function toFutureFar(): void {
|
||||||
|
switch (currentConfig.value.viewType) {
|
||||||
|
case "month":
|
||||||
|
incrementViewYear()
|
||||||
|
break
|
||||||
|
|
||||||
|
case "year":
|
||||||
|
incrementViewYear(10)
|
||||||
|
break
|
||||||
|
|
||||||
|
case "decade":
|
||||||
|
incrementViewYear(100)
|
||||||
|
break
|
||||||
|
|
||||||
|
case "century":
|
||||||
|
default:
|
||||||
|
incrementViewYear(1000)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines if the event can appear in the front end
|
* Determines if the event can appear in the front end
|
||||||
*
|
*
|
||||||
@@ -805,6 +891,22 @@ export const useCalendar = defineStore("calendar", () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* State for event modal creation
|
||||||
|
*/
|
||||||
|
const isCreatingEventModalOpen = ref<boolean>(false)
|
||||||
|
|
||||||
|
// Watch the popover state
|
||||||
|
watch(isCreatingEventModalOpen, (hasOpened, _o) => {
|
||||||
|
if (hasOpened) {
|
||||||
|
resetSkeleton()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
function toggleCreatingEventModal() {
|
||||||
|
isCreatingEventModalOpen.value = !isCreatingEventModalOpen.value
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* State for event modal edition
|
* State for event modal edition
|
||||||
*/
|
*/
|
||||||
@@ -936,6 +1038,19 @@ export const useCalendar = defineStore("calendar", () => {
|
|||||||
isCategoriesModalOpen.value = state
|
isCategoriesModalOpen.value = state
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the state of the active calendar for UI interactions
|
||||||
|
*/
|
||||||
|
const calendarState = ref<CalendarState>("active")
|
||||||
|
|
||||||
|
watch([isCategoriesModalOpen, isCreatingEventModalOpen, isDeleteEventModalOpen, isEditEventModalOpen, isAdvancedSearchOpen, isDraggingEvent], (values) => {
|
||||||
|
if (values.every(v => !v)) {
|
||||||
|
calendarState.value = 'active'
|
||||||
|
} else {
|
||||||
|
calendarState.value = 'idle'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
isReadOnly,
|
isReadOnly,
|
||||||
setReadStatus,
|
setReadStatus,
|
||||||
@@ -975,10 +1090,15 @@ export const useCalendar = defineStore("calendar", () => {
|
|||||||
areDatesIdentical,
|
areDatesIdentical,
|
||||||
compareDates,
|
compareDates,
|
||||||
getRelativeString,
|
getRelativeString,
|
||||||
|
toPastFar,
|
||||||
|
toPastNear,
|
||||||
|
toFutureNear,
|
||||||
|
toFutureFar,
|
||||||
baseEvents,
|
baseEvents,
|
||||||
allEvents,
|
allEvents,
|
||||||
categories,
|
categories,
|
||||||
currentEvents,
|
currentEvents,
|
||||||
|
calendarState,
|
||||||
getRelativeEventFromDate,
|
getRelativeEventFromDate,
|
||||||
getRelativeEventFromEvent,
|
getRelativeEventFromEvent,
|
||||||
cancelLatestRequest,
|
cancelLatestRequest,
|
||||||
@@ -993,6 +1113,8 @@ export const useCalendar = defineStore("calendar", () => {
|
|||||||
lastActiveEvent,
|
lastActiveEvent,
|
||||||
updateEventFromSkeleton,
|
updateEventFromSkeleton,
|
||||||
deleteEventFromSkeleton,
|
deleteEventFromSkeleton,
|
||||||
|
isCreatingEventModalOpen,
|
||||||
|
toggleCreatingEventModal,
|
||||||
isEditEventModalOpen,
|
isEditEventModalOpen,
|
||||||
revealEditEventModal,
|
revealEditEventModal,
|
||||||
isDeleteEventModalOpen,
|
isDeleteEventModalOpen,
|
||||||
|
|||||||
Reference in New Issue
Block a user