Add first version of ListView
This commit is contained in:
parent
70545c3dda
commit
ba697e1d1a
|
@ -80,11 +80,12 @@
|
||||||
</q-menu>
|
</q-menu>
|
||||||
</template>
|
</template>
|
||||||
<template #day="{ scope: { timestamp } }">
|
<template #day="{ scope: { timestamp } }">
|
||||||
<div itemref="" class="q-pb-sm" style="min-height: 200px">
|
<div itemref="" class="q-pa-sm" style="min-height: 200px">
|
||||||
<event-slot
|
<event-slot
|
||||||
v-for="(agenda, index) in events[timestamp.weekday]"
|
v-for="(agenda, index) in events[timestamp.weekday]"
|
||||||
:key="index"
|
:key="index"
|
||||||
v-model="events[timestamp.weekday][index]"
|
v-model="events[timestamp.weekday][index]"
|
||||||
|
class="q-mb-sm"
|
||||||
@remove-event="remove"
|
@remove-event="remove"
|
||||||
@edit-event="edit"
|
@edit-event="edit"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -0,0 +1,183 @@
|
||||||
|
<template>
|
||||||
|
<q-dialog
|
||||||
|
:model-value="editor !== undefined"
|
||||||
|
persistent
|
||||||
|
transition-show="scale"
|
||||||
|
transition-hide="scale"
|
||||||
|
>
|
||||||
|
<q-card>
|
||||||
|
<div class="column">
|
||||||
|
<div class="col" align="right" style="position: sticky; top: 0; z-index: 999">
|
||||||
|
<q-btn round color="negative" icon="close" dense rounded @click="editDone(false)" />
|
||||||
|
</div>
|
||||||
|
<div class="col" style="margin: 0; padding: 0; margin-top: -2.4em">
|
||||||
|
<edit-event v-model="editor" @done="editDone" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</q-card>
|
||||||
|
</q-dialog>
|
||||||
|
<div class="q-pa-md">
|
||||||
|
<q-card style="height: 70vh; max-width: 1800px" class="q-pa-md">
|
||||||
|
<div class="scroll" ref="scrollDiv" style="height: 100%">
|
||||||
|
<q-infinite-scroll :offset="250" @load="load">
|
||||||
|
<q-list>
|
||||||
|
<q-item id="bbb">
|
||||||
|
<q-btn label="Ältere Veranstaltungen laden" @click="load(-1)" />
|
||||||
|
</q-item>
|
||||||
|
<template v-for="(events, index) in agendas" :key="index">
|
||||||
|
<q-separator />
|
||||||
|
<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
|
||||||
|
>
|
||||||
|
</template>
|
||||||
|
</q-list>
|
||||||
|
<template #loading>
|
||||||
|
<div class="row justify-center q-my-md">
|
||||||
|
<q-spinner-dots color="primary" size="40px" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</q-infinite-scroll>
|
||||||
|
</div>
|
||||||
|
</q-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { computed, defineComponent, onBeforeMount, ref } from 'vue';
|
||||||
|
import { useScheduleStore } from '../../store';
|
||||||
|
import { date, scroll } from 'quasar';
|
||||||
|
import EditEvent from '../management/EditEvent.vue';
|
||||||
|
import EventSlot from '../overview/slots/EventSlot.vue';
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'ListView',
|
||||||
|
components: { EditEvent, EventSlot },
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
interface Agendas {
|
||||||
|
[index: string]: FG.Event[];
|
||||||
|
}
|
||||||
|
|
||||||
|
const store = useScheduleStore();
|
||||||
|
|
||||||
|
const editor = ref<FG.Event | undefined>(undefined);
|
||||||
|
const events = ref<FG.Event[]>([]);
|
||||||
|
const scrollDiv = ref<Element>()
|
||||||
|
|
||||||
|
const agendas = computed<Agendas>(() => {
|
||||||
|
const ag = {} as Agendas;
|
||||||
|
events.value?.forEach((event) => {
|
||||||
|
const day = date.formatDate(event.start, 'YYYYMMDD');
|
||||||
|
|
||||||
|
if (!ag[day]) {
|
||||||
|
ag[day] = [];
|
||||||
|
}
|
||||||
|
ag[day].push(event);
|
||||||
|
});
|
||||||
|
return ag;
|
||||||
|
});
|
||||||
|
|
||||||
|
onBeforeMount(async () => {
|
||||||
|
//await loadAgendas();
|
||||||
|
});
|
||||||
|
|
||||||
|
async function edit(id: number) {
|
||||||
|
editor.value = await store.getEvent(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
function editDone(changed: boolean) {
|
||||||
|
//if (changed) void loadAgendas();
|
||||||
|
editor.value = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 })));
|
||||||
|
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 }))
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
if (done) return done(true);
|
||||||
|
} else if (done) done(false);
|
||||||
|
}
|
||||||
|
if (index <= 1) {
|
||||||
|
window.setTimeout(() => {(<Element>scrollDiv.value).scrollTop = document.getElementById("bbb")?.scrollHeight || 0}, 150);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function remove(id: number) {
|
||||||
|
if (await store.removeEvent(id)) {
|
||||||
|
// Successfull removed
|
||||||
|
for (const idx in agendas.value) {
|
||||||
|
const i = agendas.value[idx].findIndex((event) => event.id === id);
|
||||||
|
if (i !== -1) {
|
||||||
|
agendas.value[idx].splice(i, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Not found, this means our eventa are outdated
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function asMonth(value: string) {
|
||||||
|
if (value) {
|
||||||
|
return date.formatDate(new Date(value), 'MMMM', {
|
||||||
|
months: [
|
||||||
|
'Januar',
|
||||||
|
'Februar',
|
||||||
|
'März',
|
||||||
|
'April',
|
||||||
|
'Mai',
|
||||||
|
'Juni',
|
||||||
|
'Juli',
|
||||||
|
'August',
|
||||||
|
'September',
|
||||||
|
'Oktober',
|
||||||
|
'November',
|
||||||
|
'Dezember',
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function asYear(value: string) {
|
||||||
|
if (value) {
|
||||||
|
return date.formatDate(new Date(value), 'YYYY');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
agendas,
|
||||||
|
asYear,
|
||||||
|
asMonth,
|
||||||
|
edit,
|
||||||
|
editor,scrollDiv,
|
||||||
|
editDone,
|
||||||
|
load,
|
||||||
|
remove,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
@import '@quasar/quasar-ui-qcalendar/dist/index.css';
|
||||||
|
|
||||||
|
/* Fill full height of card */
|
||||||
|
.q-calendar-agenda__pane {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Same as Qcard */
|
||||||
|
.q-calendar {
|
||||||
|
--calendar-background-dark: --q-dark;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,6 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<q-card
|
<q-card
|
||||||
class="q-mx-xs q-mt-sm justify-start content-center items-center rounded-borders shadow-5"
|
style="width: 100%"
|
||||||
|
class="justify-start content-center items-center rounded-borders shadow-5"
|
||||||
bordered
|
bordered
|
||||||
>
|
>
|
||||||
<q-card-section class="text-primary q-pa-xs">
|
<q-card-section class="text-primary q-pa-xs">
|
||||||
|
@ -95,5 +96,3 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped></style>
|
|
||||||
|
|
|
@ -32,9 +32,10 @@
|
||||||
animated
|
animated
|
||||||
>
|
>
|
||||||
<q-tab-panel name="agendaView">
|
<q-tab-panel name="agendaView">
|
||||||
<AgendaView />
|
<agenda-view />
|
||||||
</q-tab-panel>
|
</q-tab-panel>
|
||||||
<q-tab-panel name="listView">
|
<q-tab-panel name="listView">
|
||||||
|
<list-view />
|
||||||
</q-tab-panel>
|
</q-tab-panel>
|
||||||
</q-tab-panels>
|
</q-tab-panels>
|
||||||
</q-page>
|
</q-page>
|
||||||
|
@ -43,12 +44,13 @@
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { computed, defineComponent, ref } from 'vue';
|
import { computed, defineComponent, ref } from 'vue';
|
||||||
import AgendaView from '../components/overview/AgendaView.vue';
|
|
||||||
import { useQuasar } from 'quasar';
|
import { useQuasar } from 'quasar';
|
||||||
|
import AgendaView from '../components/overview/AgendaView.vue';
|
||||||
|
import ListView from '../components/overview/ListView.vue';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'EventOverview',
|
name: 'EventOverview',
|
||||||
components: { AgendaView },
|
components: { AgendaView, ListView },
|
||||||
setup() {
|
setup() {
|
||||||
const quasar = useQuasar();
|
const quasar = useQuasar();
|
||||||
|
|
||||||
|
|
|
@ -120,7 +120,7 @@ export const useScheduleStore = defineStore({
|
||||||
return this.templates;
|
return this.templates;
|
||||||
},
|
},
|
||||||
|
|
||||||
async getEvents(filter: { from?: Date; to?: Date } | undefined = undefined) {
|
async getEvents(filter: { from?: Date; to?: Date, limit?: number, offset?: number, descending?: boolean } | undefined = undefined) {
|
||||||
try {
|
try {
|
||||||
const { data } = await api.get<FG.Event[]>('/events', { params: filter });
|
const { data } = await api.get<FG.Event[]>('/events', { params: filter });
|
||||||
data.forEach((element) => fixEvent(element));
|
data.forEach((element) => fixEvent(element));
|
||||||
|
|
Loading…
Reference in New Issue