More work on timeblocks
All checks were successful
Build BAB Application Deployment Artifact / build (push) Successful in 2m0s

This commit is contained in:
2024-04-29 21:14:02 -04:00
parent 43e68c8ae7
commit c297f1f287
6 changed files with 153 additions and 179 deletions

View File

@@ -3,108 +3,13 @@
Use the calendar to pick a date. Select an available boat and timeslot
below.
</q-banner>
<BoatScheduleTableComponent />
<BoatScheduleTableComponent v-model="reservation" />
</template>
<script setup lang="ts">
import { ref } from 'vue';
import {
today,
parseTimestamp,
addToDate,
Timestamp,
} from '@quasar/quasar-ui-qcalendar';
import { Boat, useBoatStore } from 'src/stores/boat';
import { useScheduleStore, Timeblock } from 'src/stores/schedule';
import { computed } from 'vue';
import { date } from 'quasar';
import BoatScheduleTableComponent from './boat/BoatScheduleTableComponent.vue';
import { Reservation } from 'src/stores/schedule.types';
interface EventData {
event: object;
scope: {
timestamp: object;
columnindex: number;
activeDate: boolean;
droppable: boolean;
};
}
const calendar = ref();
const scheduleStore = useScheduleStore();
const selectedDate = ref(today());
const selectedBoatTime = ref();
const disabledBefore = computed(() => {
const todayTs = parseTimestamp(today()) as Timestamp;
return addToDate(todayTs, { day: -1 }).date;
});
function monthFormatter() {
try {
return new Intl.DateTimeFormat('en-CA' || undefined, {
month: 'long',
timeZone: 'UTC',
});
} catch (e) {
//
}
}
const disabledDays = () => {
// Placeholder. This should actually compute days when boats aren't available.
const days = [];
const todayTs = parseTimestamp(today()) as Timestamp;
days.push(addToDate(todayTs, { day: 2 }).date);
return days;
};
const boatoptions = (boat: Boat) => {
const options = useScheduleStore()
.getTimeblocksForDate(date.extractDate(selectedDate.value, 'YYYY-MM-DD'))
.map((x: Timeblock) => {
const conflicts = getConflicts(x, boat);
return {
label: x.start.time + ' to ' + x.end.time,
value: boat.id + ':' + x.start.time,
disable: conflicts.length > 0,
user: conflicts[0]?.user,
boat: boat,
timeblock: x,
};
});
return options;
};
const emit = defineEmits(['onClickTime', 'onUpdateDuration']);
function onPrev() {
calendar.value.prev();
}
function onNext() {
calendar.value.next();
}
function onClickDate(data: EventData) {
return data;
}
function onChange(data: EventData) {
return data;
}
const getConflicts = (timeblock: Timeblock, boat: Boat) => {
const start = date.buildDate({
hour: timeblock.start.hour,
minute: timeblock.start.minute,
second: 0,
millisecond: 0,
});
const end = date.buildDate({
hour: timeblock.end.hour,
minute: timeblock.end.minute,
second: 0,
millisecond: 0,
});
return scheduleStore.getConflictingReservations(boat, start, end);
};
const reservation = ref<Reservation | null>(null);
</script>

View File

@@ -14,18 +14,21 @@
interval-start="06:00"
:short-interval-label="true"
v-model="selectedDate"
:column-count="boats.length"
@change="scrollToEvent()"
:column-count="boatData.length"
@change="changeEvent"
v-touch-swipe.left.right="handleSwipe"
>
<template #head-day="{ scope }">
<div style="text-align: center; font-weight: 800">
{{ boats[scope.columnIndex].displayName }}
{{ boatData[scope.columnIndex].displayName }}
</div>
</template>
<template #day-body="{ scope }">
<div v-for="block in blocklist" :key="block.id">
<div
v-for="block in boatData[scope.columnIndex].blocks"
:key="block.id"
>
<div
class="timeblock"
:style="
@@ -54,24 +57,26 @@ import {
} from '@quasar/quasar-ui-qcalendar';
import CalendarHeaderComponent from './CalendarHeaderComponent.vue';
import { ref, reactive, computed } from 'vue';
import { useBoatStore } from 'src/stores/boat';
import { Timeblock, useScheduleStore } from 'src/stores/schedule';
import { TouchSwipeValue } from 'quasar';
import { ref, computed } from 'vue';
import { Boat, useBoatStore } from 'src/stores/boat';
import { useScheduleStore } from 'src/stores/schedule';
import { Reservation, Timeblock } from 'src/stores/schedule.types';
interface BoatData extends Boat {
blocks?: Timeblock[];
}
const scheduleStore = useScheduleStore();
const boatStore = useBoatStore();
const selectedBlock = ref<Timeblock | null>(null);
const selectedDate = ref(today());
const reservation = ref<Reservation | null>(null);
const blocklist = reactive<Timeblock[]>(
scheduleStore.getTimeblocksForDate(parsed(today()) as Timestamp)
);
const boats = boatStore.boats;
const boatData = ref<BoatData[]>(boatStore.boats);
const calendar = ref<QCalendarDay | null>(null);
function handleSwipe(event: Event) {
function handleSwipe({ ...event }) {
event.direction === 'right' ? calendar.value?.prev() : calendar.value?.next();
}
function blockStyles(
@@ -84,16 +89,26 @@ function blockStyles(
height: '',
opacity: '',
};
if (timeStartPos && timeDurationHeight) {
s.top = timeStartPos(block.start.time) + 'px';
if (block && timeStartPos && timeDurationHeight) {
s.top = timeStartPos(parsed(block.start)?.time || '00:00') + 'px';
s.height =
timeDurationHeight(
diffTimestamp(block.start, block.end, false) / 1000 / 60
) + 'px';
}
if (selectedBlock.value?.id === block.id) {
s.opacity = '1.0';
parseInt(
timeDurationHeight(
diffTimestamp(
parsed(block.start) as Timestamp,
parsed(block.end) as Timestamp,
false
) /
1000 /
60
)
) -
1 +
'px';
}
// if (selectedBlock.value?.id === block.id) {
// s.opacity = '1.0';
// }
return s;
}
@@ -109,38 +124,42 @@ function selectBlock(event: MouseEvent, scope: DayBodyScope, block: Timeblock) {
selectedBlock.value = block;
}
function scrollToEvent() {
function changeEvent({ start }: { start: string }) {
const newBlocks = scheduleStore.getTimeblocksForDate(start);
boatData.value.map((b) => {
return (b.blocks = newBlocks.filter((block) => block.boatId === b.$id));
});
setTimeout(() => calendar.value?.scrollToTime('09:00'), 10); // Should figure out why we need this setTimeout...
}
const disabledBefore = computed(() => {
let ts = parseTimestamp(today());
ts = addToDate(ts, { day: -1 });
return ts.date;
const todayTs = parseTimestamp(today()) as Timestamp;
return addToDate(todayTs, { day: -1 }).date;
});
</script>
<style lang="sass">
.boat-schedule-table-component
display: flex
height: 60vh
max-height: 60vh
.timeblock
display: flex
position: absolute
justify-content: center
align-items: center
width: 100%
opacity: 0.25
margin: 0 1px
width: 99%
opacity: 0.5
margin: 0px
text-overflow: ellipsis
overflow: hidden
font-size: 0.8em
cursor: pointer
background: $primary
color: white
border: 2px solid black
border: 1px solid black
.selected
opacity: 1 !important
.q-calendar-day__interval--text
font-size: 0.8em
.q-calendar-day__day.q-current-day
padding: 1px
</style>