Add some checks
This commit is contained in:
@@ -116,11 +116,30 @@
|
|||||||
color="accent"
|
color="accent"
|
||||||
icon="save"
|
icon="save"
|
||||||
label="Save"
|
label="Save"
|
||||||
@click="save($event, template)"
|
@click="saveTemplate($event, template)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</q-card> </q-expansion-item
|
</q-card> </q-expansion-item
|
||||||
></q-list>
|
></q-list>
|
||||||
|
<q-dialog v-model="alert">
|
||||||
|
<q-card>
|
||||||
|
<q-card-section>
|
||||||
|
<div class="text-h6">Overlapped blocks!</div>
|
||||||
|
</q-card-section>
|
||||||
|
<q-card-section class="q-pt-none">
|
||||||
|
<q-chip
|
||||||
|
square
|
||||||
|
icon="schedule"
|
||||||
|
v-for="item in overlapped"
|
||||||
|
:key="item.start"
|
||||||
|
>
|
||||||
|
{{ item.start }}-{{ item.end }}</q-chip
|
||||||
|
>
|
||||||
|
</q-card-section>
|
||||||
|
<q-card-actions align="right">
|
||||||
|
<q-btn flat label="OK" color="primary" v-close-popup />
|
||||||
|
</q-card-actions> </q-card
|
||||||
|
></q-dialog>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -132,7 +151,11 @@ import {
|
|||||||
today,
|
today,
|
||||||
} from '@quasar/quasar-ui-qcalendar';
|
} from '@quasar/quasar-ui-qcalendar';
|
||||||
import { Boat, useBoatStore } from 'src/stores/boat';
|
import { Boat, useBoatStore } from 'src/stores/boat';
|
||||||
import { buildTimeBlock, useScheduleStore } from 'src/stores/schedule';
|
import {
|
||||||
|
buildTimeBlock,
|
||||||
|
timeTuplesOverlapped,
|
||||||
|
useScheduleStore,
|
||||||
|
} from 'src/stores/schedule';
|
||||||
import { onMounted, ref } from 'vue';
|
import { onMounted, ref } from 'vue';
|
||||||
import type { TimeBlockTemplate, TimeTuple } from 'src/stores/schedule.types';
|
import type { TimeBlockTemplate, TimeTuple } from 'src/stores/schedule.types';
|
||||||
import { date } from 'quasar';
|
import { date } from 'quasar';
|
||||||
@@ -143,11 +166,8 @@ const boatStore = useBoatStore();
|
|||||||
const resources = boatStore.boats;
|
const resources = boatStore.boats;
|
||||||
const timeblockTemplates = scheduleStore.timeblockTemplates;
|
const timeblockTemplates = scheduleStore.timeblockTemplates;
|
||||||
const editable = ref(false);
|
const editable = ref(false);
|
||||||
|
const alert = ref(false);
|
||||||
const save = (evt: Event, template: TimeBlockTemplate) => {
|
const overlapped = ref<{ start: string; end: string }[]>();
|
||||||
editable.value = false;
|
|
||||||
console.log(evt, template);
|
|
||||||
};
|
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await boatStore.fetchBoats();
|
await boatStore.fetchBoats();
|
||||||
@@ -155,6 +175,21 @@ onMounted(async () => {
|
|||||||
await scheduleStore.fetchTimeBlockTemplates();
|
await scheduleStore.fetchTimeBlockTemplates();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const saveTemplate = (evt: Event, template: TimeBlockTemplate) => {
|
||||||
|
overlapped.value = timeTuplesOverlapped(template.timeTuples);
|
||||||
|
console.log(overlapped.value);
|
||||||
|
alert.value = overlapped.value.length > 0;
|
||||||
|
editable.value = false;
|
||||||
|
console.log(evt, template);
|
||||||
|
};
|
||||||
|
|
||||||
|
function createTimeblock(boat: Boat, templateId: string, date: string) {
|
||||||
|
const timeBlock = timeblockTemplates.find((t) => t.$id === templateId);
|
||||||
|
timeBlock?.timeTuples.map((tb: TimeTuple) =>
|
||||||
|
scheduleStore.createTimeblock(buildTimeBlock(boat, tb, date))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function onDragStart(e: DragEvent, template: TimeBlockTemplate) {
|
function onDragStart(e: DragEvent, template: TimeBlockTemplate) {
|
||||||
if (e.dataTransfer) {
|
if (e.dataTransfer) {
|
||||||
console.log('Drag start: ', e);
|
console.log('Drag start: ', e);
|
||||||
@@ -191,13 +226,6 @@ function onDragLeave(e: DragEvent, type: string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function createTimeblock(boat: Boat, templateId: string, date: string) {
|
|
||||||
const timeBlock = timeblockTemplates.find((t) => t.$id === templateId);
|
|
||||||
timeBlock?.timeTuples.map((tb: TimeTuple) =>
|
|
||||||
scheduleStore.createTimeblock(buildTimeBlock(boat, tb, date))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onDrop(
|
function onDrop(
|
||||||
e: DragEvent,
|
e: DragEvent,
|
||||||
type: string,
|
type: string,
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<q-item v-for="link in navlinks" :key="link.label">
|
<q-item v-for="link in navlinks" :key="link.label">
|
||||||
<q-btn
|
<q-btn
|
||||||
:icon="link.icon"
|
:icon="link.icon"
|
||||||
color="primary"
|
:color="link.color"
|
||||||
size="1.25em"
|
size="1.25em"
|
||||||
:to="link.to"
|
:to="link.to"
|
||||||
:label="link.label"
|
:label="link.label"
|
||||||
@@ -21,8 +21,19 @@ const navlinks = [
|
|||||||
icon: 'more_time',
|
icon: 'more_time',
|
||||||
to: '/schedule/book',
|
to: '/schedule/book',
|
||||||
label: 'Create a Reservation',
|
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',
|
||||||
},
|
},
|
||||||
{ icon: 'calendar_month', to: '/schedule/view', label: 'View Schedule' },
|
|
||||||
{ icon: 'edit_calendar', to: '/schedule/manage', label: 'Manage Calendar' },
|
|
||||||
];
|
];
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ const routes: RouteRecordRaw[] = [
|
|||||||
path: 'manage',
|
path: 'manage',
|
||||||
component: () => import('src/pages/schedule/ManageCalendar.vue'),
|
component: () => import('src/pages/schedule/ManageCalendar.vue'),
|
||||||
name: 'manage-schedule',
|
name: 'manage-schedule',
|
||||||
|
meta: { requiresScheduleAdmin: true },
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -101,6 +102,7 @@ const routes: RouteRecordRaw[] = [
|
|||||||
{
|
{
|
||||||
path: '/admin',
|
path: '/admin',
|
||||||
component: () => import('layouts/AdminLayout.vue'),
|
component: () => import('layouts/AdminLayout.vue'),
|
||||||
|
meta: { requiresAdmin: true },
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: '/user',
|
path: '/user',
|
||||||
|
|||||||
@@ -17,6 +17,11 @@ import {
|
|||||||
import { AppwriteIds, databases } from 'src/boot/appwrite';
|
import { AppwriteIds, databases } from 'src/boot/appwrite';
|
||||||
import { ID, Models } from 'appwrite';
|
import { ID, Models } from 'appwrite';
|
||||||
|
|
||||||
|
export type Interval = {
|
||||||
|
start: string;
|
||||||
|
end: string;
|
||||||
|
};
|
||||||
|
|
||||||
export function arrayToTimeTuples(arr: string[]) {
|
export function arrayToTimeTuples(arr: string[]) {
|
||||||
const timeTuples: TimeTuple[] = [];
|
const timeTuples: TimeTuple[] = [];
|
||||||
for (let i = 0; i < arr.length; i += 2) {
|
for (let i = 0; i < arr.length; i += 2) {
|
||||||
@@ -25,6 +30,33 @@ export function arrayToTimeTuples(arr: string[]) {
|
|||||||
return timeTuples;
|
return timeTuples;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function timeTuplesOverlapped(tuples: TimeTuple[]): Interval[] {
|
||||||
|
return blocksOverlapped(
|
||||||
|
tuples.map((tuples) => {
|
||||||
|
return {
|
||||||
|
start: '01/01/2001 ' + tuples[0],
|
||||||
|
end: '01/01/2001 ' + tuples[1],
|
||||||
|
};
|
||||||
|
})
|
||||||
|
).map((t) => {
|
||||||
|
return { start: t.start.split(' ')[1], end: t.end.split(' ')[1] };
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function blocksOverlapped(blocks: Timeblock[] | Interval[]): Interval[] {
|
||||||
|
return Array.from(
|
||||||
|
new Set(
|
||||||
|
blocks
|
||||||
|
.sort((a, b) => Date.parse(a.start) - Date.parse(b.start))
|
||||||
|
.reduce((acc: Interval[], block, i, arr) => {
|
||||||
|
if (i > 0 && block.start < arr[i - 1].end)
|
||||||
|
acc.push(arr[i - 1], block);
|
||||||
|
return acc;
|
||||||
|
}, [])
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export function buildTimeBlock(
|
export function buildTimeBlock(
|
||||||
resource: Boat,
|
resource: Boat,
|
||||||
time: TimeTuple,
|
time: TimeTuple,
|
||||||
|
|||||||
Reference in New Issue
Block a user