Compare commits

..

10 Commits

8 changed files with 73 additions and 21 deletions

View File

@ -1,6 +1,6 @@
[metadata] [metadata]
license = MIT license = MIT
version = 1.0.0-alpha.8 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,7 @@ python_requires = >=3.8
packages = packages =
flaschengeist_events flaschengeist_events
install_requires = install_requires =
flaschengeist >= 2.0.0.dev0 flaschengeist >= 2.0.0
[options.package_data] [options.package_data]
* = *.toml, script.py.mako, *.ini, migrations/*.py * = *.toml, script.py.mako, *.ini, migrations/*.py

View File

@ -1,6 +1,6 @@
{ {
"license": "MIT", "license": "MIT",
"version": "1.0.0-alpha.8", "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,8 +22,8 @@
"@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.8", "@flaschengeist/api": "^1.0.0",
"@flaschengeist/types": "^1.0.0-alpha.10", "@flaschengeist/types": "^1.0.0",
"@quasar/app-webpack": "^3.7.2", "@quasar/app-webpack": "^3.7.2",
"@typescript-eslint/eslint-plugin": "^5.8.0", "@typescript-eslint/eslint-plugin": "^5.8.0",
"@typescript-eslint/parser": "^5.8.0", "@typescript-eslint/parser": "^5.8.0",
@ -38,8 +38,8 @@
"typescript": "^4.5.4" "typescript": "^4.5.4"
}, },
"peerDependencies": { "peerDependencies": {
"@flaschengeist/api": "^1.0.0-alpha.8", "@flaschengeist/api": "^1.0.0",
"@flaschengeist/users": "^1.0.0-alpha.4" "@flaschengeist/users": "^1.0.0"
}, },
"prettier": { "prettier": {
"singleQuote": true, "singleQuote": true,

View File

@ -183,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 });
@ -199,9 +199,16 @@ export default defineComponent({
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 = []; event.value.jobs = [];
tpl.jobs.forEach((job) => { tpl.jobs.forEach((job) => {
const copied_job: FG.Job = Object.assign({}, job, { id: NaN }); const copied_job: FG.Job = Object.assign({}, job, {
copied_job.start.setTime(copied_job.start.getTime() + diff); id: NaN,
if (copied_job.end) copied_job.end.setTime(copied_job.end.getTime() + diff); 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); event.value.jobs.push(<Job>copied_job);
}); });
} }
@ -292,6 +299,7 @@ export default defineComponent({
const diff = newValue.getTime() - oldValue.getTime(); const diff = newValue.getTime() - oldValue.getTime();
event.value?.jobs.forEach((job) => { event.value?.jobs.forEach((job) => {
job.start.setTime(job.start.getTime() + diff); job.start.setTime(job.start.getTime() + diff);
job.end?.setTime(job.end.getTime() + diff);
}); });
computed_end.value?.setTime(computed_end.value?.getTime() + diff); computed_end.value?.setTime(computed_end.value?.getTime() + diff);
setTimeout(() => { setTimeout(() => {

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

@ -235,7 +235,7 @@ 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() || '-';

View File

@ -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;
} }

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) {