Navigation Tweaks
This commit is contained in:
@@ -9,13 +9,28 @@
|
||||
<q-scroll-area class="fit">
|
||||
<q-list padding class="menu-list">
|
||||
<template v-for="link in enabledLinks" :key="link.name">
|
||||
<q-item clickable v-ripple :to="link.to">
|
||||
<!-- TODO: Template this to be DRY --><q-item
|
||||
clickable
|
||||
v-ripple
|
||||
:to="link.to"
|
||||
>
|
||||
<q-item-section avatar>
|
||||
<q-icon :name="link.icon" />
|
||||
</q-item-section>
|
||||
|
||||
<q-item-section> {{ link.name }} </q-item-section>
|
||||
</q-item>
|
||||
<q-list v-if="link.sublinks">
|
||||
<div v-for="sublink in link.sublinks" :key="sublink.name">
|
||||
<q-item clickable v-ripple :to="sublink.to" class="q-ml-md">
|
||||
<q-item-section avatar>
|
||||
<q-icon :name="sublink.icon" />
|
||||
</q-item-section>
|
||||
|
||||
<q-item-section> {{ sublink.name }} </q-item-section>
|
||||
</q-item>
|
||||
</div></q-list
|
||||
>
|
||||
</template>
|
||||
<q-item clickable v-ripple @click="logout()">
|
||||
<q-item-section avatar><q-icon name="logout" /></q-item-section
|
||||
|
||||
@@ -7,11 +7,13 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import BoatPreviewComponent from 'src/components/boat/BoatPreviewComponent.vue';
|
||||
import { ref } from 'vue';
|
||||
import { onMounted } from 'vue';
|
||||
import { useBoatStore } from 'src/stores/boat';
|
||||
import ToolbarComponent from 'src/components/ToolbarComponent.vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
|
||||
const boatStore = useBoatStore();
|
||||
boatStore.fetchBoats();
|
||||
const boats = ref(useBoatStore().boats);
|
||||
const { boats } = storeToRefs(boatStore);
|
||||
|
||||
onMounted(() => boatStore.fetchBoats());
|
||||
</script>
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
<template>
|
||||
<q-page padding>
|
||||
<div class="subcontent">
|
||||
<!-- <navigation-bar @today="onToday" @prev="onPrev" @next="onNext" /> -->
|
||||
|
||||
<navigation-bar @today="onToday" @prev="onPrev" @next="onNext" />
|
||||
<div class="row justify-center">
|
||||
<q-calendar-day
|
||||
<q-calendar-scheduler
|
||||
ref="calendar"
|
||||
v-model="selectedDate"
|
||||
view="day"
|
||||
:max-days="3"
|
||||
v-model:model-resources="boatStore.boats"
|
||||
resource-key="$id"
|
||||
resource-label="displayName"
|
||||
:weekdays="[1, 2, 3, 4, 5, 6, 0]"
|
||||
view="week"
|
||||
bordered
|
||||
animated
|
||||
transition-next="slide-left"
|
||||
transition-prev="slide-right"
|
||||
cell-width="150px"
|
||||
day-min-height="50px"
|
||||
@change="onChange"
|
||||
@moved="onMoved"
|
||||
@click-date="onClickDate"
|
||||
@@ -20,22 +22,11 @@
|
||||
@click-interval="onClickInterval"
|
||||
@click-head-day="onClickHeadDay"
|
||||
>
|
||||
<template
|
||||
#day-body="{
|
||||
scope: { timestamp, timeStartPos, timeDurationHeight },
|
||||
}"
|
||||
>
|
||||
<template
|
||||
v-for="event in reservationEvents(timestamp)"
|
||||
:key="event.id"
|
||||
>
|
||||
<div
|
||||
v-if="event.start !== undefined"
|
||||
class="booking-event"
|
||||
:style="slotStyle(event, timeStartPos, timeDurationHeight)"
|
||||
>
|
||||
<template #day="{ scope }">
|
||||
<div v-for="event in boatReservationEvents(scope)" :key="event.id">
|
||||
<div v-if="event.start !== undefined" class="booking-event">
|
||||
<span class="title q-calendar__ellipsis">
|
||||
{{ event.user }}
|
||||
{{ useAuthStore().getUserNameById(event.user) }}
|
||||
<q-tooltip>{{
|
||||
event.start +
|
||||
' - ' +
|
||||
@@ -43,9 +34,9 @@
|
||||
}}</q-tooltip>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</q-calendar-day>
|
||||
</q-calendar-scheduler>
|
||||
</div>
|
||||
</div>
|
||||
</q-page>
|
||||
@@ -53,46 +44,57 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useReservationStore } from 'src/stores/reservation';
|
||||
import { Reservation } from 'src/stores/schedule.types';
|
||||
import { ref } from 'vue';
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { useAuthStore } from 'src/stores/auth';
|
||||
|
||||
const reservationStore = useReservationStore();
|
||||
import {
|
||||
TimestampOrNull,
|
||||
getDate,
|
||||
parsed,
|
||||
today,
|
||||
} from '@quasar/quasar-ui-qcalendar';
|
||||
import { QCalendarDay } from '@quasar/quasar-ui-qcalendar';
|
||||
import { date } from 'quasar';
|
||||
import { getDate, today } from '@quasar/quasar-ui-qcalendar';
|
||||
import { QCalendarScheduler } from '@quasar/quasar-ui-qcalendar';
|
||||
import { Timestamp } from '@quasar/quasar-ui-qcalendar';
|
||||
import { useBoatStore } from 'src/stores/boat';
|
||||
import { Boat, useBoatStore } from 'src/stores/boat';
|
||||
import NavigationBar from 'src/components/scheduling/NavigationBar.vue';
|
||||
|
||||
const selectedDate = ref(today());
|
||||
const boatStore = useBoatStore();
|
||||
const calendar = ref();
|
||||
|
||||
// Method declarations
|
||||
|
||||
function slotStyle(
|
||||
event: Reservation,
|
||||
timeStartPos: (time: TimestampOrNull) => string,
|
||||
timeDurationHeight: (minutes: number) => string
|
||||
) {
|
||||
const s = {
|
||||
top: '',
|
||||
height: '',
|
||||
'align-items': 'flex-start',
|
||||
};
|
||||
if (timeStartPos && timeDurationHeight) {
|
||||
s.top = timeStartPos(parsed(event.start)) + 'px';
|
||||
s.height =
|
||||
timeDurationHeight(date.getDateDiff(event.end, event.start, 'minutes')) +
|
||||
'px';
|
||||
}
|
||||
return s;
|
||||
interface DayScope {
|
||||
timestamp: Timestamp;
|
||||
columnIndex: number;
|
||||
resource: object;
|
||||
resourceIndex: number;
|
||||
indentLevel: number;
|
||||
activeDate: boolean;
|
||||
droppable: boolean;
|
||||
}
|
||||
|
||||
function reservationEvents(timestamp: Timestamp) {
|
||||
return reservationStore.getReservationsByDate(getDate(timestamp));
|
||||
onMounted(() => boatStore.fetchBoats());
|
||||
// Method declarations
|
||||
|
||||
// function slotStyle(
|
||||
// event: Reservation,
|
||||
// timeStartPos: (time: TimestampOrNull) => string,
|
||||
// timeDurationHeight: (minutes: number) => string
|
||||
// ) {
|
||||
// const s = {
|
||||
// top: '',
|
||||
// height: '',
|
||||
// 'align-items': 'flex-start',
|
||||
// };
|
||||
// if (timeStartPos && timeDurationHeight) {
|
||||
// s.top = timeStartPos(parsed(event.start)) + 'px';
|
||||
// s.height =
|
||||
// timeDurationHeight(date.getDateDiff(event.end, event.start, 'minutes')) +
|
||||
// 'px';
|
||||
// }
|
||||
// return s;
|
||||
// }
|
||||
|
||||
function boatReservationEvents({ timestamp, resource }: DayScope) {
|
||||
return reservationStore.getReservationsByDate(
|
||||
getDate(timestamp),
|
||||
(resource as Boat).$id
|
||||
);
|
||||
}
|
||||
function onMoved(data: Event) {
|
||||
console.log('onMoved', data);
|
||||
@@ -112,6 +114,15 @@ function onClickInterval(data: Event) {
|
||||
function onClickHeadDay(data: Event) {
|
||||
console.log('onClickHeadDay', data);
|
||||
}
|
||||
function onToday() {
|
||||
calendar.value.moveToToday();
|
||||
}
|
||||
function onPrev() {
|
||||
calendar.value.prev();
|
||||
}
|
||||
function onNext() {
|
||||
calendar.value.next();
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="sass" scoped>
|
||||
|
||||
@@ -17,9 +17,8 @@
|
||||
:drag-over-func="onDragOver"
|
||||
:drag-leave-func="onDragLeave"
|
||||
:drop-func="onDrop"
|
||||
:day-min-height="50"
|
||||
:cell-width="150"
|
||||
:day-height="0"
|
||||
day-min-height="50px"
|
||||
cell-width="150px"
|
||||
>
|
||||
<template #day="{ scope }">
|
||||
<div
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<q-page padding>
|
||||
<q-item v-for="link in navlinks" :key="link.label">
|
||||
<q-item v-for="link in navlinks" :key="link.name">
|
||||
<q-btn
|
||||
:icon="link.icon"
|
||||
:color="link.color"
|
||||
color="primary"
|
||||
size="1.25em"
|
||||
:to="link.to"
|
||||
:label="link.label"
|
||||
:label="link.name"
|
||||
rounded
|
||||
class="full-width"
|
||||
align="left"
|
||||
@@ -16,24 +16,9 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const navlinks = [
|
||||
{
|
||||
icon: 'more_time',
|
||||
to: '/schedule/book',
|
||||
label: 'Create a Reservation',
|
||||
color: 'primary',
|
||||
},
|
||||
{
|
||||
icon: 'calendar_month',
|
||||
to: '/schedule/view',
|
||||
label: 'View Schedule',
|
||||
color: 'primary',
|
||||
},
|
||||
{
|
||||
icon: 'edit_calendar',
|
||||
to: '/schedule/manage',
|
||||
label: 'Manage Calendar',
|
||||
color: 'accent',
|
||||
},
|
||||
];
|
||||
import { enabledLinks } from 'src/router/navlinks';
|
||||
|
||||
const navlinks = enabledLinks.find(
|
||||
(link) => link.name === 'Schedule'
|
||||
)?.sublinks;
|
||||
</script>
|
||||
|
||||
@@ -26,6 +26,29 @@ export const links = [
|
||||
icon: 'calendar_month',
|
||||
front_links: true,
|
||||
enabled: true,
|
||||
sublinks: [
|
||||
{
|
||||
name: 'Book',
|
||||
to: '/schedule/book',
|
||||
icon: 'more_time',
|
||||
front_links: false,
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
name: 'View',
|
||||
to: '/schedule/view',
|
||||
icon: 'calendar_month',
|
||||
front_links: false,
|
||||
enabled: true,
|
||||
},
|
||||
{
|
||||
name: 'Manage',
|
||||
to: '/schedule/manage',
|
||||
icon: 'edit_calendar',
|
||||
front_links: false,
|
||||
enabled: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Certifications',
|
||||
@@ -57,4 +80,11 @@ export const links = [
|
||||
},
|
||||
];
|
||||
|
||||
export const enabledLinks = links.filter((link) => link.enabled);
|
||||
export const enabledLinks = links
|
||||
.filter((link) => link.enabled)
|
||||
.map((link) => {
|
||||
if (link.sublinks) {
|
||||
link.sublinks = link.sublinks.filter((sublink) => sublink.enabled);
|
||||
}
|
||||
return link;
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user