Merge branch 'alpha' into devel

This commit is contained in:
2026-03-14 23:25:03 -04:00
15 changed files with 433 additions and 89 deletions

View File

@@ -11,7 +11,7 @@
<q-toolbar-title>{{ pageTitle }}</q-toolbar-title>
<q-space />
<div>v{{ VERSION }}</div>
<div>v{{ APP_VERSION }}</div>
</q-toolbar>
</q-header>
<LeftDrawer
@@ -22,8 +22,7 @@
<script setup lang="ts">
import { ref } from 'vue';
import LeftDrawer from 'components/LeftDrawer.vue';
const VERSION = process.env.VUE_APP_VERSION;
import { APP_VERSION } from 'src/version';
const leftDrawerOpen = ref(false);
function toggleLeftDrawer() {

View File

@@ -1,9 +1,11 @@
<template>
<div v-if="boats">
<div
v-if="boats"
class="row">
<q-card
v-for="boat in boats"
:key="boat.id"
class="q-ma-sm">
class="q-ma-sm col-xs-12 col-sm-6 col-xl-3">
<q-card-section>
<q-img
:src="boat.imgSrc"

View File

@@ -83,13 +83,14 @@ import { Dialog, Notify } from 'quasar';
import { useAuthStore } from 'src/stores/auth';
import { useRouter } from 'vue-router';
import { AppwriteException } from 'appwrite';
import { APP_VERSION } from 'src/version.js';
const email = ref('');
const token = ref('');
const userId = ref();
const router = useRouter();
console.log('version:' + process.env.VUE_APP_VERSION);
console.log('version:' + APP_VERSION);
const doTokenLogin = async () => {
const authStore = useAuthStore();

View File

@@ -61,12 +61,13 @@ import { useAuthStore } from 'src/stores/auth';
import NewPasswordComponent from 'src/components/NewPasswordComponent.vue';
import { Dialog } from 'quasar';
import { useRouter } from 'vue-router';
import { APP_VERSION } from 'src/version.js';
const email = ref('');
const password = ref('');
const router = useRouter();
console.log('version:' + process.env.VUE_APP_VERSION);
console.log('version:' + APP_VERSION);
const doRegister = async () => {
if (email.value && password.value) {

View File

@@ -1,9 +1,7 @@
<template>
<q-page class="fit row wrap justify-start items-start content-start">
<div class="fit row">
<div class="q-pa-md">
<div
class="scheduler"
style="max-width: 1200px">
<div class="scheduler col-12">
<NavigationBar
@next="onNext"
@today="onToday"
@@ -128,31 +126,31 @@
:model-value="template" />
</q-list>
</div>
<q-dialog v-model="alert">
<q-card>
<q-card-section>
<div class="text-h6">Warning!</div>
</q-card-section>
<q-card-section class="q-pt-none">
Conflicting times! Please delete overlapped items!
<q-chip
v-for="item in overlapped"
:key="item.index">
{{ boats.find((b) => b.$id === item.boatId)?.name }}:
{{ date.formatDate(item.start, 'hh:mm') }} -
{{ date.formatDate(item.end, 'hh:mm') }}
</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>
</q-page>
<q-dialog v-model="alert">
<q-card>
<q-card-section>
<div class="text-h6">Warning!</div>
</q-card-section>
<q-card-section class="q-pt-none">
Conflicting times! Please delete overlapped items!
<q-chip
v-for="item in overlapped"
:key="item.index">
{{ boats.find((b) => b.$id === item.boatId)?.name }}:
{{ date.formatDate(item.start, 'hh:mm') }} -
{{ date.formatDate(item.end, 'hh:mm') }}
</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>
</template>
<script setup lang="ts">
@@ -210,8 +208,8 @@ const filteredIntervals = (date: Timestamp, boat: Boat) => {
const sortedIntervals = (date: Timestamp, boat: Boat) => {
return computed(() =>
filteredIntervals(date, boat).value.sort(
(a, b) => Date.parse(a.start) - Date.parse(b.start)
)
(a, b) => Date.parse(a.start) - Date.parse(b.start),
),
);
};
@@ -237,14 +235,14 @@ function getIntervals(date: Timestamp, boat: Boat) {
function intervalsFromTemplate(
boat: Boat,
templateId: string,
date: string
date: string,
): Interval[] {
const template = intervalTemplateStore
.getIntervalTemplates()
.value.find((t) => t.$id === templateId);
return template
? template.timeTuples.map((timeTuple: TimeTuple) =>
buildInterval(boat, timeTuple, date)
buildInterval(boat, timeTuple, date),
)
: [];
}
@@ -281,7 +279,7 @@ function onDrop(
//TODO: Move all overlap checking to the store. This is too messy right now.
e: DragEvent,
type: string,
scope: { resource: Boat; timestamp: Timestamp }
scope: { resource: Boat; timestamp: Timestamp },
) {
if (e.target instanceof HTMLDivElement)
e.target.classList.remove('bg-secondary');
@@ -296,9 +294,9 @@ function onDrop(
.map((boat) =>
intervalsOverlapped(
existingIntervals.value.concat(
intervalsFromTemplate(boat, templateId, date)
)
)
intervalsFromTemplate(boat, templateId, date),
),
),
)
.flat(1);
if (overlapped.value.length === 0) {

View File

@@ -61,15 +61,6 @@ export const links = <Link[]>[
front_links: false,
enabled: true,
},
{
name: 'Manage',
to: '/schedule/manage',
icon: 'edit_calendar',
front_links: false,
enabled: true,
color: 'accent',
requiredRoles: ['Schedule Admins'],
},
],
},
{
@@ -100,6 +91,24 @@ export const links = <Link[]>[
front_links: true,
enabled: false,
},
{
name: 'Manage',
icon: 'tune',
enabled: true,
requiredRoles: ['Schedule Admins'],
color: 'negative',
sublinks: [
{
name: 'Schedule',
to: '/schedule/manage',
icon: 'edit_calendar',
front_links: false,
enabled: true,
color: 'accent',
requiredRoles: ['Schedule Admins'],
},
],
},
];
const authStore = useAuthStore();

1
src/version.js Normal file
View File

@@ -0,0 +1 @@
export const APP_VERSION = '0.0.0';