Compare commits
6 Commits
512e68f1ed
...
f539d2c386
Author | SHA1 | Date |
---|---|---|
Ferdinand Thiessen | f539d2c386 | |
Ferdinand Thiessen | f87c691f61 | |
Ferdinand Thiessen | 7b622f96ea | |
Ferdinand Thiessen | 7eb0074111 | |
Ferdinand Thiessen | f79823531d | |
Ferdinand Thiessen | 4c92fb0ff7 |
|
@ -1,25 +1,53 @@
|
|||
<template>
|
||||
<q-card class="row justify-center content-center" style="text-align: center">
|
||||
<q-card-section>
|
||||
<div class="text-h6 col-12">Dienste diesen Monat: {{ jobs }}</div>
|
||||
<!--TODO: Filters are deprecated! -->
|
||||
<!--<div class="text-h6 col-12">Nächster Dienst: {{ nextJob | date }}</div>-->
|
||||
<q-card style="text-align: center">
|
||||
<q-card-section class="row justify-center items-center content-center">
|
||||
<div class="col-5">
|
||||
<q-icon :name="jobs == 0 ? 'mdi-calendar-blank' : 'mdi-calendar-alert'" :size="divHeight" />
|
||||
</div>
|
||||
<div v-if="(jobs || 0) > 0" ref="div" class="col-7">
|
||||
<div class="text-h6">Anstehende Dienste</div>
|
||||
<div class="text-body1">{{ jobs }}</div>
|
||||
<div class="text-h6">Nächster Dienst</div>
|
||||
<div class="text-body1">{{ formatDate(nextJob) }}</div>
|
||||
</div>
|
||||
<div v-else ref="div" class="col-7">
|
||||
<div class="text-subtitle1">Keine anstehenden Dienste</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { date } from 'quasar';
|
||||
import { computed, defineComponent, onBeforeMount, ref } from 'vue';
|
||||
import { asHour, formatDateTime } from '@flaschengeist/api';
|
||||
|
||||
import { useEventStore } from '../store';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'EventsWidget',
|
||||
setup() {
|
||||
function randomNumber(start: number, end: number) {
|
||||
return start + Math.floor(Math.random() * Math.floor(end));
|
||||
const store = useEventStore();
|
||||
|
||||
const jobs = ref<number>();
|
||||
const nextJob = ref<Date>();
|
||||
const div = ref<HTMLElement>();
|
||||
const divHeight = computed(() => `${div.value?.scrollHeight || '100'}px`);
|
||||
|
||||
onBeforeMount(() => {
|
||||
void store.getJobs({ limit: 1, from: new Date() }).then(({ count, result }) => {
|
||||
jobs.value = count;
|
||||
nextJob.value = count > 0 ? result[0].start : undefined;
|
||||
});
|
||||
});
|
||||
|
||||
function formatDate(d?: Date) {
|
||||
if (d === undefined) return '-';
|
||||
if (date.isSameDate(d, new Date(), 'day')) return `Heute ${asHour(d)} Uhr`;
|
||||
return formatDateTime(d, true, true, false, true) + ' Uhr';
|
||||
}
|
||||
const jobs = randomNumber(0, 5);
|
||||
const nextJob = new Date(2021, randomNumber(1, 12), randomNumber(1, 31));
|
||||
return { jobs, nextJob };
|
||||
|
||||
return { div, divHeight, formatDate, jobs, nextJob };
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -64,7 +64,7 @@
|
|||
{{ timestamp.day }}
|
||||
<q-menu>
|
||||
<q-list style="min-width: 100px">
|
||||
<q-item exact :to="{ name: 'new-event', query: { date: timestamp.date } }">
|
||||
<q-item exact clickable @click="create(timestamp.date)">
|
||||
<q-item-section>Neue Veranstaltung</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
|
@ -95,6 +95,7 @@ import { date, QDate, QPopupProxy, useQuasar } from 'quasar';
|
|||
import { startOfWeek } from '@flaschengeist/api';
|
||||
import EditEvent from '../management/EditEvent.vue';
|
||||
import { QCalendarAgenda } from '@quasar/quasar-ui-qcalendar';
|
||||
import { EditableEvent, emptyEvent } from '../../store/models';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'AgendaView',
|
||||
|
@ -115,7 +116,7 @@ export default defineComponent({
|
|||
calendarView.value == 'day' || quasar.screen.xs ? 1 : quasar.screen.sm ? 3 : 7
|
||||
);
|
||||
const events = ref<Agendas>({});
|
||||
const editor = ref<FG.Event | undefined>(undefined);
|
||||
const editor = ref<EditableEvent>();
|
||||
|
||||
interface Agendas {
|
||||
[index: number]: FG.Event[];
|
||||
|
@ -125,6 +126,9 @@ export default defineComponent({
|
|||
await loadAgendas();
|
||||
});
|
||||
|
||||
function create(ds: string) {
|
||||
editor.value = emptyEvent(date.extractDate(ds, 'YYYY-MM-DD'));
|
||||
}
|
||||
async function edit(id: number) {
|
||||
editor.value = await store.getEvent(id);
|
||||
}
|
||||
|
@ -156,12 +160,12 @@ export default defineComponent({
|
|||
minutes: 0,
|
||||
hours: 0,
|
||||
});
|
||||
const start = calendarRealView.value === 'day' ? selected : startOfWeek(selected);
|
||||
const start = calendarView.value === 'day' ? selected : startOfWeek(selected);
|
||||
const end = date.addToDate(start, { days: calendarDays.value });
|
||||
|
||||
events.value = {};
|
||||
const list = await store.getEvents({ from: start, to: end });
|
||||
list.forEach((event) => {
|
||||
const { result } = await store.getEvents({ from: start, to: end });
|
||||
result.forEach((event) => {
|
||||
const day = event.start.getDay();
|
||||
|
||||
if (!events.value[day]) {
|
||||
|
@ -221,6 +225,7 @@ export default defineComponent({
|
|||
calendarPrev,
|
||||
calendarRealView,
|
||||
calendarView,
|
||||
create,
|
||||
edit,
|
||||
editor,
|
||||
editDone,
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
</q-item>
|
||||
<template v-for="(events, index) in agendas" :key="index">
|
||||
<q-separator />
|
||||
<q-item-label overline>{{index}}</q-item-label>
|
||||
<q-item-label overline>{{ index }}</q-item-label>
|
||||
<q-item v-for="(event, idx) in events" :key="idx"
|
||||
><event-slot :model-value="event" />{{ idx }}</q-item
|
||||
>
|
||||
|
@ -63,7 +63,7 @@ export default defineComponent({
|
|||
|
||||
const editor = ref<FG.Event | undefined>(undefined);
|
||||
const events = ref<FG.Event[]>([]);
|
||||
const scrollDiv = ref<Element>()
|
||||
const scrollDiv = ref<Element>();
|
||||
|
||||
const agendas = computed<Agendas>(() => {
|
||||
const ag = {} as Agendas;
|
||||
|
@ -94,21 +94,24 @@ export default defineComponent({
|
|||
async function load(index: number, done?: (stop: boolean) => void) {
|
||||
const start = new Date();
|
||||
if (index < 0) {
|
||||
events.value.unshift(...(await store.getEvents({ to: start, limit: 5, descending: true })));
|
||||
const { result } = await store.getEvents({ to: start, limit: 5, descending: true });
|
||||
events.value.unshift(...result);
|
||||
if (done) done(false);
|
||||
} else {
|
||||
const len = events.value.length;
|
||||
if (
|
||||
len ==
|
||||
events.value.push(
|
||||
...(await store.getEvents({ from: start, offset: (index - 1) * 10, limit: 10 }))
|
||||
)
|
||||
) {
|
||||
const { result } = await store.getEvents({
|
||||
from: start,
|
||||
offset: (index - 1) * 10,
|
||||
limit: 10,
|
||||
});
|
||||
if (len == events.value.push(...result)) {
|
||||
if (done) return done(true);
|
||||
} else if (done) done(false);
|
||||
} else if (done) done(false);
|
||||
}
|
||||
if (index <= 1) {
|
||||
window.setTimeout(() => {(<Element>scrollDiv.value).scrollTop = document.getElementById("bbb")?.scrollHeight || 0}, 150);
|
||||
window.setTimeout(() => {
|
||||
(<Element>scrollDiv.value).scrollTop = document.getElementById('bbb')?.scrollHeight || 0;
|
||||
}, 150);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -159,7 +162,8 @@ export default defineComponent({
|
|||
asYear,
|
||||
asMonth,
|
||||
edit,
|
||||
editor,scrollDiv,
|
||||
editor,
|
||||
scrollDiv,
|
||||
editDone,
|
||||
load,
|
||||
remove,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { FG_Plugin } from "@flaschengeist/types";
|
||||
import { FG_Plugin } from '@flaschengeist/types';
|
||||
|
||||
export interface RecurrenceRule {
|
||||
frequency: string;
|
||||
|
@ -13,13 +13,13 @@ interface InvitationData {
|
|||
}
|
||||
|
||||
interface InvitationResponseData {
|
||||
event: number,
|
||||
job: number,
|
||||
invitee: string
|
||||
event: number;
|
||||
job: number;
|
||||
invitee: string;
|
||||
}
|
||||
|
||||
export interface EventNotification extends FG_Plugin.Notification {
|
||||
data: {
|
||||
type: number
|
||||
type: number;
|
||||
} & (InvitationData | InvitationResponseData);
|
||||
}
|
||||
|
|
|
@ -30,7 +30,10 @@ function transpile(msg: FG_Plugin.Notification) {
|
|||
|
||||
message.link = { name: 'events-requests' };
|
||||
} else if ((message.data.type & EventTypes._mask_) === EventTypes.invitation_response) {
|
||||
message.link = {name: 'events-single-view', params: {id: (<InvitationResponseData>message.data).event}}
|
||||
message.link = {
|
||||
name: 'events-single-view',
|
||||
params: { id: (<InvitationResponseData>message.data).event },
|
||||
};
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ export const privateRoutes: FG_Plugin.NamedRouteRecordRaw[] = [
|
|||
name: 'events-single-view',
|
||||
path: 'events/:id',
|
||||
component: () => import('../pages/EventPage.vue'),
|
||||
props: true
|
||||
props: true,
|
||||
},
|
||||
{
|
||||
name: 'events-edit',
|
||||
|
|
|
@ -107,13 +107,15 @@ export const useEventStore = defineStore({
|
|||
},
|
||||
|
||||
async getEvents(
|
||||
filter:
|
||||
| { from?: Date; to?: Date; limit?: number; offset?: number; descending?: boolean }
|
||||
| undefined = undefined
|
||||
filter?: FG.PaginationFilter & {
|
||||
user?: string;
|
||||
}
|
||||
) {
|
||||
try {
|
||||
const { data } = await api.get<FG.Event[]>('/events', { params: filter });
|
||||
data.forEach((element) => fixEvent(element));
|
||||
const { data } = await api.get<FG.PaginationResponse<FG.Event>>('/events', {
|
||||
params: <unknown>filter,
|
||||
});
|
||||
data.result.forEach((element) => fixEvent(element));
|
||||
return data;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
|
@ -166,6 +168,15 @@ export const useEventStore = defineStore({
|
|||
.then(({ data }) => fixJob(data));
|
||||
},
|
||||
|
||||
async getJobs(filter?: FG.PaginationFilter) {
|
||||
return api
|
||||
.get<FG.PaginationResponse<FG.Job>>('/events/jobs', { params: <unknown>filter })
|
||||
.then(({ data }) => {
|
||||
data.result.forEach((j) => fixJob(j));
|
||||
return data;
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Send invite to job or transfer to other user
|
||||
* @param job Job to invite to
|
||||
|
|
|
@ -16,9 +16,6 @@ export type EditableJob = Omit<Omit<FG.Job, 'type'>, 'id'> & {
|
|||
export function emptyJob(startDate = new Date()): EditableJob {
|
||||
const start = date.adjustDate(startDate, {
|
||||
hours: new Date().getHours(),
|
||||
minutes: 0,
|
||||
seconds: 0,
|
||||
milliseconds: 0,
|
||||
});
|
||||
return {
|
||||
start: start,
|
||||
|
@ -29,9 +26,9 @@ export function emptyJob(startDate = new Date()): EditableJob {
|
|||
};
|
||||
}
|
||||
|
||||
export function emptyEvent(startDate?: Date): EditableEvent {
|
||||
export function emptyEvent(startDate: Date = new Date()): EditableEvent {
|
||||
return {
|
||||
start: startDate === undefined ? new Date() : new Date(startDate),
|
||||
start: date.adjustDate(startDate, { hours: 0, minutes: 0, seconds: 0, milliseconds: 0 }),
|
||||
jobs: [emptyJob(startDate)],
|
||||
is_template: false,
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue