Compare commits

..

19 Commits

Author SHA1 Message Date
Tim Gröger 6737bd5b45 update to version 1.1.0 2024-10-08 14:53:22 +02:00
Tim Gröger aa3c172160 [feat] show names by display mode setting 2024-10-08 14:46:44 +02:00
Tim Gröger 923f5ec27c update version to 1.0.0 2024-01-16 19:54:07 +01:00
Tim Gröger 084ad8f945 fix correct datetimes in jobslots when change event start 2024-01-16 15:55:14 +01:00
Tim Gröger 7b1e37b3a7 fix correct datetimes in jobslots when come from template 2024-01-16 15:52:23 +01:00
Tim Gröger 9a648e8443 fix show january 2024-01-16 14:58:34 +01:00
Tim Gröger 38480a1eec update to v1.0.0-alpha.9 2023-05-16 00:04:42 +02:00
Tim Gröger f0e07138b1 fixed intput theming 2023-05-15 10:32:31 +02:00
Tim Gröger ba7013ac67 add show sended invitation to query 2023-05-13 00:06:27 +02:00
Tim Gröger 252072df57 (fix) #1 in frontend
required services have to be >= 1
2023-05-12 23:37:20 +02:00
Tim Gröger c5012c8431 update dependencies, new version 2023-05-08 21:40:52 +02:00
Tim Gröger 40148ba10f update version 2023-05-05 14:48:52 +02:00
Tim Gröger 3fbbacabca check has permission assign 2023-05-03 06:11:52 +02:00
Tim Gröger 6f6fca84ed fix load older events in listView 2023-05-03 00:19:09 +02:00
Tim Gröger b5d43bb1de fix editing ande remove events in listview 2023-05-03 00:09:21 +02:00
Tim Gröger 7ea5a8fac3 duty fix for listView in Overview 2023-05-02 23:17:45 +02:00
Tim Gröger 67d844d6e6 add on every page query for location 2023-05-02 23:15:32 +02:00
Tim Gröger 93f88792d0 update job start and end time when event time change 2023-05-02 22:40:54 +02:00
Tim Gröger 6ad340fe7c add query on agendaView 2023-05-02 15:00:39 +02:00
13 changed files with 247 additions and 61 deletions

View File

@ -197,9 +197,9 @@ def get_events(
if not with_backup: if not with_backup:
for event in events: for event in events:
clear_backup(event) clear_backup(event)
logger.debug(end) # logger.debug(end)
for event in events: # for event in events:
logger.debug(f"{event.start} < {end} = {event.start < end}") # logger.debug(f"{event.start} < {end} = {event.start < end}")
return count, events return count, events

View File

@ -1,6 +1,6 @@
[metadata] [metadata]
license = MIT license = MIT
version = 0.0.1-dev.1 version = 1.0.0
name = flaschengeist-events name = flaschengeist-events
description = Events plugin for Flaschengeist description = Events plugin for Flaschengeist
url = https://flaschengeist.dev/Flaschengeist/flaschengeist-schedule url = https://flaschengeist.dev/Flaschengeist/flaschengeist-schedule
@ -24,7 +24,10 @@ python_requires = >=3.8
packages = packages =
flaschengeist_events flaschengeist_events
install_requires = install_requires =
flaschengeist == 2.0.* flaschengeist >= 2.0.0
[options.package_data]
* = *.toml, script.py.mako, *.ini, migrations/*.py
[options.entry_points] [options.entry_points]
flaschengeist.plugins = flaschengeist.plugins =

View File

@ -1,6 +1,6 @@
{ {
"license": "MIT", "license": "MIT",
"version": "1.0.0-alpha.6", "version": "1.1.0",
"name": "@flaschengeist/schedule", "name": "@flaschengeist/schedule",
"author": "Ferdinand Thiessen <rpm@fthiessen.de>", "author": "Ferdinand Thiessen <rpm@fthiessen.de>",
"homepage": "https://flaschengeist.dev/Flaschengeist", "homepage": "https://flaschengeist.dev/Flaschengeist",
@ -22,24 +22,24 @@
"@quasar/quasar-ui-qcalendar": "^4.0.0-beta.11" "@quasar/quasar-ui-qcalendar": "^4.0.0-beta.11"
}, },
"devDependencies": { "devDependencies": {
"@flaschengeist/api": "^1.0.0-alpha.7", "@flaschengeist/api": "^1.0.0",
"@flaschengeist/types": "^1.0.0-alpha.10", "@flaschengeist/types": "^1.0.0",
"@quasar/app": "^3.2.5", "@quasar/app-webpack": "^3.7.2",
"@typescript-eslint/eslint-plugin": "^5.6.0", "@typescript-eslint/eslint-plugin": "^5.8.0",
"@typescript-eslint/parser": "^5.6.0", "@typescript-eslint/parser": "^5.8.0",
"axios": "^0.24.0", "axios": "^0.24.0",
"eslint": "^8.4.1", "eslint": "^8.5.0",
"eslint-config-prettier": "^8.3.0", "eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.0.0", "eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-vue": "^8.2.0", "eslint-plugin-vue": "^8.2.0",
"pinia": "^2.0.6", "pinia": "^2.0.8",
"prettier": "^2.5.1", "prettier": "^2.5.1",
"quasar": "^2.3.4", "quasar": "^2.11.10",
"typescript": "^4.5.2" "typescript": "^4.5.4"
}, },
"peerDependencies": { "peerDependencies": {
"@flaschengeist/api": "^1.0.0-alpha.7", "@flaschengeist/api": "^1.0.0",
"@flaschengeist/users": "^1.0.0-alpha.3" "@flaschengeist/users": "^1.0.0"
}, },
"prettier": { "prettier": {
"singleQuote": true, "singleQuote": true,

View File

@ -52,6 +52,7 @@
class="col-xs-12 col-sm-6 q-pa-sm" class="col-xs-12 col-sm-6 q-pa-sm"
label="Veranstaltungsende" label="Veranstaltungsende"
:rules="[afterStart]" :rules="[afterStart]"
:key="update_time"
/> />
<q-input <q-input
v-model="event.description" v-model="event.description"
@ -61,7 +62,7 @@
filled filled
/> />
</q-card-section> </q-card-section>
<q-card-section v-if="event.is_template !== true && modelValue === undefined"> <q-card-section v-if="modelValue === undefined">
<q-btn-toggle <q-btn-toggle
v-model="recurrent" v-model="recurrent"
spread spread
@ -81,8 +82,7 @@
<q-btn color="primary" label="Schicht hinzufügen" @click="addJob()" /> <q-btn color="primary" label="Schicht hinzufügen" @click="addJob()" />
</div> </div>
</div> </div>
<template v-for="(job, index) in event.jobs" :key="index"> <template v-for="(job, index) in event.jobs" :key="index + update_time">
<!--:ref="active === index ? 'activeJob' : undefined"-->
<edit-job-slot <edit-job-slot
ref="activeJob" ref="activeJob"
v-model="event.jobs[index]" v-model="event.jobs[index]"
@ -138,6 +138,7 @@ export default defineComponent({
}, },
emits: { emits: {
done: (val: boolean) => typeof val === 'boolean', done: (val: boolean) => typeof val === 'boolean',
'update:modelValue': (val?: FG.Event) => typeof val === 'object',
}, },
setup(props, { emit }) { setup(props, { emit }) {
const store = useEventStore(); const store = useEventStore();
@ -182,7 +183,7 @@ export default defineComponent({
} }
function fromTemplate(tpl: FG.Event) { function fromTemplate(tpl: FG.Event) {
const today = new Date(); const today = props.modelValue?.start || new Date();
template.value = tpl; template.value = tpl;
event.value = Object.assign({}, tpl, { id: undefined }); event.value = Object.assign({}, tpl, { id: undefined });
@ -196,16 +197,27 @@ export default defineComponent({
const diff = event.value.start.getTime() - tpl.start.getTime(); const diff = event.value.start.getTime() - tpl.start.getTime();
// Adjust end of event and all jobs // Adjust end of event and all jobs
if (event.value.end) event.value.end.setTime(event.value.end.getTime() + diff); if (event.value.end) event.value.end.setTime(event.value.end.getTime() + diff);
event.value.jobs.forEach((job) => { event.value.jobs = [];
job.start.setTime(job.start.getTime() + diff); tpl.jobs.forEach((job) => {
if (job.end) job.end.setTime(job.end.getTime() + diff); const copied_job: FG.Job = Object.assign({}, job, {
id: NaN,
start: new Date(),
end: undefined,
});
copied_job.start.setTime(job.start.getTime() + diff);
if (job.end) {
copied_job.end = new Date();
copied_job.end.setTime(job.end.getTime() + diff);
}
event.value.jobs.push(<Job>copied_job);
}); });
} }
async function save(template = false) { async function save(is_template = false) {
event.value.is_template = template; event.value.is_template = is_template;
try { try {
await store.addEvent(event.value); const _event = await store.addEvent(event.value);
emit('update:modelValue', _event);
if (props.modelValue === undefined && recurrent.value && !event.value.is_template) { if (props.modelValue === undefined && recurrent.value && !event.value.is_template) {
let count = 0; let count = 0;
@ -267,7 +279,55 @@ export default defineComponent({
}); });
} }
const computed_start = computed({
get: () => event.value?.start,
set: (value) => {
event.value.start = value;
},
});
const computed_end = computed({
get: () => event.value?.end,
set: (value) => {
event.value.end = value;
},
});
const update_time = ref(false);
watch(computed_start, (newValue, oldValue) => {
update_time.value = true;
const diff = newValue.getTime() - oldValue.getTime();
event.value?.jobs.forEach((job) => {
job.start.setTime(job.start.getTime() + diff);
job.end?.setTime(job.end.getTime() + diff);
});
computed_end.value?.setTime(computed_end.value?.getTime() + diff);
setTimeout(() => {
update_time.value = false;
}, 0);
});
watch(computed_end, (newValue, oldValue) => {
if (newValue && oldValue) {
update_time.value = true;
if (!newValue || !oldValue) return;
const diff = newValue.getTime() - oldValue.getTime();
event.value?.jobs.forEach((job) => {
if (job.end) job.end.setTime(job.end.getTime() + diff);
else job.end = new Date(newValue.getTime());
});
} else if (newValue && !oldValue) {
event.value?.jobs.forEach((job) => {
if (!job.end) job.end = new Date(newValue.getTime());
});
}
setTimeout(() => {
update_time.value = false;
}, 0);
});
return { return {
update_time,
activate, activate,
active, active,
addJob, addJob,

View File

@ -40,12 +40,12 @@
:rules="[notEmpty]" :rules="[notEmpty]"
/> />
<q-input <q-input
v-model="job.required_services" v-model.number="job.required_services"
filled filled
class="col-xs-12 col-sm-6 q-pa-sm" class="col-xs-12 col-sm-6 q-pa-sm"
label="Dienstanzahl" label="Dienstanzahl"
type="number" type="number"
:rules="[notEmpty]" :rules="[minOneService, notEmpty]"
/> />
<q-input <q-input
v-model="job.comment" v-model="job.comment"
@ -134,6 +134,10 @@ export default defineComponent({
validate: () => form.value?.validate() || Promise.resolve(true), validate: () => form.value?.validate() || Promise.resolve(true),
}); });
function minOneService(val: number) {
return parseInt(val) > 0 || 'Mindestens ein Dienst nötig';
}
return { return {
form, form,
formatStartEnd, formatStartEnd,
@ -141,6 +145,7 @@ export default defineComponent({
job, job,
jobtypes, jobtypes,
notEmpty, notEmpty,
minOneService,
typeName, typeName,
}; };
}, },

View File

@ -30,10 +30,17 @@
<q-table :title="title" :rows="rows" row-key="id" :columns="columns"> <q-table :title="title" :rows="rows" row-key="id" :columns="columns">
<template #top-right> <template #top-right>
<q-input ref="input" v-model="actualType.name" :rules="rules" dense placeholder="Neuer Typ"> <q-input
<slot name="after" ref="input"
><q-btn color="primary" icon="mdi-plus" title="Hinzufügen" @click="addType" v-model="actualType.name"
/></slot> :rules="rules"
dense
filled
placeholder="Neuer Typ"
>
<template #after
><q-btn color="primary" icon="mdi-plus" title="Hinzufügen" round @click="addType"
/></template>
</q-input> </q-input>
</template> </template>
<template #body-cell-actions="props"> <template #body-cell-actions="props">

View File

@ -88,9 +88,10 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { ComponentPublicInstance, computed, defineComponent, onBeforeMount, ref } from 'vue'; import { ComponentPublicInstance, computed, defineComponent, onBeforeMount, ref, watch } from 'vue';
import { QCalendarAgenda } from '@quasar/quasar-ui-qcalendar'; import { QCalendarAgenda } from '@quasar/quasar-ui-qcalendar';
import { date, QDate, QPopupProxy, useQuasar } from 'quasar'; import { date, QDate, QPopupProxy, useQuasar } from 'quasar';
import { useRoute, useRouter } from 'vue-router';
import { EditableEvent, emptyEvent } from '../../store/models'; import { EditableEvent, emptyEvent } from '../../store/models';
import { startOfWeek } from '@flaschengeist/api'; import { startOfWeek } from '@flaschengeist/api';
import { useEventStore } from '../../store'; import { useEventStore } from '../../store';
@ -105,6 +106,8 @@ export default defineComponent({
setup() { setup() {
const store = useEventStore(); const store = useEventStore();
const quasar = useQuasar(); const quasar = useQuasar();
const route = useRoute();
const router = useRouter();
const datepicker = ref<QDate>(); const datepicker = ref<QDate>();
const proxy = ref<QPopupProxy>(); const proxy = ref<QPopupProxy>();
@ -141,6 +144,19 @@ export default defineComponent({
} }
onBeforeMount(async () => { onBeforeMount(async () => {
await router.replace({ query: { ...route.query, q_tab: 'agendaView' } });
if (!Object.keys(route.query).includes('q_date')) {
const q_date = date.formatDate(selectedDate.value, 'YYYY-MM-DD');
await router.replace({ query: { ...route.query, q_date } });
} else {
selectedDate.value = date.extractDate(route.query.q_date as string, 'YYYY-MM-DD');
}
if (!Object.keys(route.query).includes('q_view')) {
const q_view = calendarView.value;
await router.replace({ query: { ...route.query, q_view } });
} else {
calendarView.value = route.query.q_view as string;
}
await loadAgendas(); await loadAgendas();
}); });
@ -171,7 +187,11 @@ export default defineComponent({
} }
} }
const loading = ref(false);
async function loadAgendas() { async function loadAgendas() {
if (loading.value) return;
loading.value = true;
const from = const from =
calendarView.value === 'day' ? selectedDate.value : startOfWeek(selectedDate.value); calendarView.value === 'day' ? selectedDate.value : startOfWeek(selectedDate.value);
const to = date.addToDate(from, { days: calendarView.value === 'day' ? 1 : 7 }); const to = date.addToDate(from, { days: calendarView.value === 'day' ? 1 : 7 });
@ -184,8 +204,11 @@ export default defineComponent({
if (!events.value[day]) { if (!events.value[day]) {
events.value[day] = []; events.value[day] = [];
} }
events.value[day].push(event); const idx = events.value[day].findIndex((e) => e.id === event.id);
if (idx === -1) events.value[day].push(event);
else events.value[day][idx] = event;
}); });
loading.value = false;
} }
function addDays(reverse: boolean) { function addDays(reverse: boolean) {
@ -212,12 +235,24 @@ export default defineComponent({
'November', 'November',
'Dezember', 'Dezember',
'-', '-',
][value?.getMonth() || 12]; ][value?.getMonth() === 0 ? 0 : value?.getMonth() || 12];
} }
function asYear(value?: Date) { function asYear(value?: Date) {
return value?.getFullYear() || '-'; return value?.getFullYear() || '-';
} }
watch(selectedDate, async (newValue) => {
const q_date = date.formatDate(newValue, 'YYYY-MM-DD');
await router.replace({ query: { ...route.query, q_date } });
await loadAgendas();
});
watch(calendarView, async (newValue) => {
const q_view = newValue;
await router.replace({ query: { ...route.query, q_view } });
await loadAgendas();
});
return { return {
asYear, asYear,
asMonth, asMonth,

View File

@ -28,7 +28,7 @@
<q-separator /> <q-separator />
<q-item-label header>{{ asDate(index) }}</q-item-label> <q-item-label header>{{ asDate(index) }}</q-item-label>
<q-item v-for="(event, idx) in events" :key="idx"> <q-item v-for="(event, idx) in events" :key="idx">
<event-slot :model-value="event" /> <event-slot v-model="events[idx]" @edit-event="edit" @remove-event="remove" />
</q-item> </q-item>
</template> </template>
</q-list> </q-list>
@ -88,6 +88,10 @@ export default defineComponent({
function editDone(changed: boolean) { function editDone(changed: boolean) {
//if (changed) void loadAgendas(); //if (changed) void loadAgendas();
const idx = events.value.findIndex((event) => event.id === editor.value?.id);
if (idx >= 0) {
events.value[idx] = editor.value as FG.Event;
}
editor.value = undefined; editor.value = undefined;
} }
@ -95,7 +99,12 @@ export default defineComponent({
const start = new Date(); const start = new Date();
if (index < 0) { if (index < 0) {
const { result } = await store.getEvents({ to: start, limit: 5, descending: true }); const { result } = await store.getEvents({ to: start, limit: 5, descending: true });
events.value.unshift(...result); //events.value.unshift(...result);
for (const event of result) {
const idx = events.value.findIndex((e) => e.id === event.id);
if (idx === -1) events.value.unshift(event);
else events.value[idx] = event;
}
if (done) done(false); if (done) done(false);
} else { } else {
const len = events.value.length; const len = events.value.length;
@ -104,7 +113,12 @@ export default defineComponent({
offset: (index - 1) * 10, offset: (index - 1) * 10,
limit: 10, limit: 10,
}); });
if (len == events.value.push(...result)) { for (const event of result) {
const idx = events.value.findIndex((e) => e.id === event.id);
if (idx === -1) events.value.unshift(event);
else events.value[idx] = event;
}
if (len == events.value.length) {
if (done) return done(true); if (done) return done(true);
} else if (done) done(false); } else if (done) done(false);
} }
@ -117,17 +131,11 @@ export default defineComponent({
async function remove(id: number) { async function remove(id: number) {
if (await store.removeEvent(id)) { if (await store.removeEvent(id)) {
// Successfull removed const idx = events.value.findIndex((event) => event.id === id);
for (const idx in agendas.value) { if (idx !== -1) {
const i = agendas.value[idx].findIndex((event) => event.id === id); events.value.splice(idx, 1);
if (i !== -1) {
agendas.value[idx].splice(i, 1);
break;
} }
} }
} else {
// Not found, this means our eventa are outdated
}
} }
function asMonth(value: string) { function asMonth(value: string) {

View File

@ -54,7 +54,7 @@
</q-select> </q-select>
<div class="row col-12 justify-end"> <div class="row col-12 justify-end">
<q-btn <q-btn
v-if="!modelValue.locked && !isEnrolled && !isFull" v-if="!modelValue.locked && !isEnrolled && !isFull && canAssign"
flat flat
color="primary" color="primary"
label="Eintragen" label="Eintragen"
@ -101,6 +101,7 @@ import { PERMISSIONS } from '../../../permissions';
import TransferInviteDialog from './TransferInviteDialog.vue'; import TransferInviteDialog from './TransferInviteDialog.vue';
import ServiceUserChip from './ServiceUserChip.vue'; import ServiceUserChip from './ServiceUserChip.vue';
import { UserAvatar } from '@flaschengeist/api/components'; import { UserAvatar } from '@flaschengeist/api/components';
import { DisplayNameMode } from '@flaschengeist/users';
export default defineComponent({ export default defineComponent({
name: 'JobSlot', name: 'JobSlot',
@ -123,11 +124,34 @@ export default defineComponent({
const quasar = useQuasar(); const quasar = useQuasar();
// Make sure users are loaded if we can assign them // Make sure users are loaded if we can assign them
onBeforeMount(() => void userStore.getUsers()); onBeforeMount(() => {
void userStore.getUsers();
void userStore.getDisplayNameModeSetting(true);
});
/* Stuff used for general display */ /* Stuff used for general display */
// Get displayname of user // Get displayname of user
function userDisplay(id: string) { function userDisplay(id: string) {
switch (userStore.userSettings.display_name) {
case DisplayNameMode.FIRSTNAME:
return userStore.findUser(id)?.firstname || id;
case DisplayNameMode.LASTNAME:
return userStore.findUser(id)?.lastname || id;
case DisplayNameMode.DISPLAYNAME:
return userStore.findUser(id)?.display_name || id;
case DisplayNameMode.FIRSTNAME_LASTNAME:
return (
`${<string>userStore.findUser(id)?.firstname} ${<string>(
userStore.findUser(id)?.lastname
)}` || id
);
case DisplayNameMode.LASTNAME_FIRSTNAME:
return (
`${<string>userStore.findUser(id)?.lastname}, ${<string>(
userStore.findUser(id)?.firstname
)}` || id
);
}
return userStore.findUser(id)?.display_name || id; return userStore.findUser(id)?.display_name || id;
} }
@ -205,6 +229,8 @@ export default defineComponent({
// Current user can assign other users // Current user can assign other users
const canAssignOther = computed(() => hasPermission(PERMISSIONS.ASSIGN_OTHER)); const canAssignOther = computed(() => hasPermission(PERMISSIONS.ASSIGN_OTHER));
const canAssign = computed(() => hasPermission(PERMISSIONS.ASSIGN));
// options shown in the select // options shown in the select
const options = ref([] as FG.Service[]); const options = ref([] as FG.Service[]);
@ -257,6 +283,7 @@ export default defineComponent({
unassign: (s?: FG.Service) => assign(Object.assign({}, s || service.value, { value: -1 })), unassign: (s?: FG.Service) => assign(Object.assign({}, s || service.value, { value: -1 })),
backup: (is_backup: boolean) => assign(Object.assign({}, service.value, { is_backup })), backup: (is_backup: boolean) => assign(Object.assign({}, service.value, { is_backup })),
canAssignOther, canAssignOther,
canAssign,
canInvite, canInvite,
filterUsers, filterUsers,
isBackup, isBackup,

View File

@ -44,7 +44,8 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { computed, defineComponent, ref } from 'vue'; import { computed, defineComponent, ref, onBeforeMount, watch } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import ManageTypes from '../components/management/ManageTypes.vue'; import ManageTypes from '../components/management/ManageTypes.vue';
import EditEvent from '../components/management/EditEvent.vue'; import EditEvent from '../components/management/EditEvent.vue';
import { hasPermission } from '@flaschengeist/api'; import { hasPermission } from '@flaschengeist/api';
@ -70,6 +71,21 @@ export default defineComponent({
: []), : []),
]); ]);
const route = useRoute();
const router = useRouter();
onBeforeMount(async () => {
if (
(route.query.q_tab && route.query.q_tab === 'create') ||
route.query.q_tab === 'jobtypes' ||
route.query.q_tab === 'eventtypes'
) {
tab.value = route.query.q_tab;
} else {
await router.replace({ query: { q_tab: tab.value } });
}
});
const drawer = ref<boolean>(false); const drawer = ref<boolean>(false);
const tab = ref<string>('create'); const tab = ref<string>('create');
@ -82,6 +98,10 @@ export default defineComponent({
}, },
}); });
watch(tab, async (val) => {
await router.replace({ query: { q_tab: val } });
});
return { return {
showDrawer, showDrawer,
tab, tab,

View File

@ -43,7 +43,8 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { computed, defineComponent, ref, onBeforeMount } from 'vue'; import { computed, defineComponent, ref, onBeforeMount, watch } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { useQuasar } from 'quasar'; import { useQuasar } from 'quasar';
import AgendaView from '../components/overview/AgendaView.vue'; import AgendaView from '../components/overview/AgendaView.vue';
import ListView from '../components/overview/ListView.vue'; import ListView from '../components/overview/ListView.vue';
@ -55,8 +56,19 @@ export default defineComponent({
components: { AgendaView, ListView }, components: { AgendaView, ListView },
setup() { setup() {
const store = useEventStore(); const store = useEventStore();
onBeforeMount(() => { const route = useRoute();
const router = useRouter();
const tab = ref<string>('agendaView');
onBeforeMount(async () => {
void store.getJobTypes(); void store.getJobTypes();
if (
Object.keys(route.query).includes('q_tab') &&
(route.query.q_tab === 'listView' || route.query.q_tab === 'agendaView')
) {
tab.value = route.query.q_tab as string;
} else {
await router.replace({ query: { ...route.query, q_tab: tab.value } });
}
}); });
const quasar = useQuasar(); const quasar = useQuasar();
@ -74,7 +86,10 @@ export default defineComponent({
}, },
}); });
const tab = ref<string>('agendaView'); watch(tab, async (val) => {
console.log(val);
await router.replace({ query: { ...route.query, q_tab: val } });
});
return { return {
showDrawer, showDrawer,

View File

@ -56,6 +56,7 @@
<script lang="ts"> <script lang="ts">
import { formatStartEnd, useMainStore, useUserStore } from '@flaschengeist/api'; import { formatStartEnd, useMainStore, useUserStore } from '@flaschengeist/api';
import { computed, defineComponent, ref, onBeforeMount, watch } from 'vue'; import { computed, defineComponent, ref, onBeforeMount, watch } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { QTableProps } from 'quasar'; import { QTableProps } from 'quasar';
import { Job } from '../store/models'; import { Job } from '../store/models';
import { useEventStore } from '../store'; import { useEventStore } from '../store';
@ -67,6 +68,8 @@ export default defineComponent({
const store = useEventStore(); const store = useEventStore();
const userStore = useUserStore(); const userStore = useUserStore();
const mainStore = useMainStore(); const mainStore = useMainStore();
const router = useRouter();
const route = useRoute();
interface RowData extends FG.Invitation { interface RowData extends FG.Invitation {
inviter: FG.User; inviter: FG.User;
@ -155,7 +158,11 @@ export default defineComponent({
.finally(() => (loading.value = false)); .finally(() => (loading.value = false));
}; };
onBeforeMount(() => { onBeforeMount(async () => {
if (route.query.sent === 'true') {
showSent.value = true;
}
void Promise.allSettled([ void Promise.allSettled([
userStore.getUsers(), userStore.getUsers(),
store.getInvitations(), store.getInvitations(),
@ -165,8 +172,9 @@ export default defineComponent({
); );
}); });
watch(showSent, () => { watch(showSent, async () => {
onRequest({ pagination: pagination.value, filter: () => [], getCellValue: () => [] }); onRequest({ pagination: pagination.value, filter: () => [], getCellValue: () => [] });
await router.replace({ query: { sent: showSent.value ? 'true' : 'false' } });
}); });
function getType(row: RowData) { function getType(row: RowData) {

View File

@ -150,15 +150,13 @@ export const useEventStore = defineStore({
if (event?.id === undefined) { if (event?.id === undefined) {
const { data } = await api.post<FG.Event>('/events', event); const { data } = await api.post<FG.Event>('/events', event);
if (data.is_template) this.templates.push(data); if (data.is_template) this.templates.push(data);
fixEvent(data);
return data; return data;
} else { } else {
if (typeof event.type === 'object') event.type = event.type.id; if (typeof event.type === 'object') event.type = event.type.id;
const { data } = await api.put<FG.Event>( const { data } = await api.put<FG.Event>(`/events/${event.id}`, event);
`/events/${event.id}`,
// Object.assign(event, { jobs: undefined })
event
);
if (data.is_template) this.templates.push(data); if (data.is_template) this.templates.push(data);
fixEvent(data);
return data; return data;
} }
}, },