Compare commits
No commits in common. "5b657f4bf046230bfb8f39a6490ebe6ae1d6c130" and "ea64568e2bfc6dd351dd7cae7fb8239e69f78828" have entirely different histories.
5b657f4bf0
...
ea64568e2b
|
@ -78,7 +78,12 @@
|
||||||
<q-btn color="primary" label="Schicht hinzufügen" @click="addJob()" />
|
<q-btn color="primary" label="Schicht hinzufügen" @click="addJob()" />
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
<q-card-section v-for="(job, index) in event.jobs" :key="index">
|
<q-card-section v-for="(job, index) in event.jobs" :key="index">
|
||||||
<edit-job-slot v-model="event.jobs[index]" @remove-job="removeJob(index)" />
|
<q-card class="q-my-auto">
|
||||||
|
<edit-job-slot
|
||||||
|
v-model="event.jobs[index]"
|
||||||
|
@remove-job="removeJob(index)"
|
||||||
|
/>
|
||||||
|
</q-card>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
<q-card-actions align="around">
|
<q-card-actions align="around">
|
||||||
<q-card-actions align="left">
|
<q-card-actions align="left">
|
||||||
|
@ -95,15 +100,11 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { computed, defineComponent, PropType, ref, onBeforeMount } from 'vue';
|
||||||
|
import { date, ModifyDateOptions } from 'quasar';
|
||||||
|
import { useEventStore } from '../../store';
|
||||||
import { notEmpty } from '@flaschengeist/api';
|
import { notEmpty } from '@flaschengeist/api';
|
||||||
import { IsoDateInput } from '@flaschengeist/api/components';
|
import { IsoDateInput } from '@flaschengeist/api/components';
|
||||||
|
|
||||||
import { useEventStore } from '../../store';
|
|
||||||
import { emptyEvent, emptyJob, EditableEvent } from '../../store/models';
|
|
||||||
|
|
||||||
import { date, ModifyDateOptions } from 'quasar';
|
|
||||||
import { computed, defineComponent, PropType, ref, onBeforeMount } from 'vue';
|
|
||||||
|
|
||||||
import EditJobSlot from './EditJobSlot.vue';
|
import EditJobSlot from './EditJobSlot.vue';
|
||||||
import RecurrenceRule from './RecurrenceRule.vue';
|
import RecurrenceRule from './RecurrenceRule.vue';
|
||||||
|
|
||||||
|
@ -119,8 +120,8 @@ export default defineComponent({
|
||||||
date: {
|
date: {
|
||||||
required: false,
|
required: false,
|
||||||
default: undefined,
|
default: undefined,
|
||||||
type: String as PropType<string | undefined>,
|
type: String as PropType<string|undefined>
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
emits: {
|
emits: {
|
||||||
done: (val: boolean) => typeof val === 'boolean',
|
done: (val: boolean) => typeof val === 'boolean',
|
||||||
|
@ -128,19 +129,33 @@ export default defineComponent({
|
||||||
setup(props, { emit }) {
|
setup(props, { emit }) {
|
||||||
const store = useEventStore();
|
const store = useEventStore();
|
||||||
const startDate = computed(() => {
|
const startDate = computed(() => {
|
||||||
const d = date.buildDate({ milliseconds: 0, seconds: 0, minutes: 0, hours: 0 });
|
const d = date.buildDate({milliseconds: 0, seconds: 0, minutes: 0, hours: 0})
|
||||||
if (!props.date || !date.isValid(props.date)) return d;
|
if (!props.date || !date.isValid(props.date)) return d
|
||||||
const split = props.date.split('-');
|
const split = props.date.split('-');
|
||||||
return date.adjustDate(d, {
|
return date.adjustDate(d, {year: parseInt(split[0]), month: parseInt(split[1]), date: parseInt(split[2])})
|
||||||
year: parseInt(split[0]),
|
})
|
||||||
month: parseInt(split[1]),
|
|
||||||
date: parseInt(split[2]),
|
|
||||||
});
|
const emptyJob = () => ({
|
||||||
|
id: NaN,
|
||||||
|
start: date.adjustDate(startDate.value, {hours: (new Date()).getHours()}, true),
|
||||||
|
end: date.addToDate(date.adjustDate(startDate.value, {hours: (new Date()).getHours()}, true), {hours: 1}),
|
||||||
|
services: [],
|
||||||
|
required_services: 2,
|
||||||
|
type: store.jobTypes[0],
|
||||||
|
});
|
||||||
|
|
||||||
|
const emptyEvent = () => ({
|
||||||
|
id: NaN,
|
||||||
|
start: new Date(startDate.value),
|
||||||
|
jobs: [emptyJob()],
|
||||||
|
type: store.eventTypes[0],
|
||||||
|
is_template: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
const templates = computed(() => store.templates);
|
const templates = computed(() => store.templates);
|
||||||
const template = ref<FG.Event | undefined>(undefined);
|
const template = ref<FG.Event | undefined>(undefined);
|
||||||
const event = ref<EditableEvent>(props.modelValue || emptyEvent(startDate.value));
|
const event = ref<FG.Event>(props.modelValue || emptyEvent());
|
||||||
const eventtypes = computed(() => store.eventTypes);
|
const eventtypes = computed(() => store.eventTypes);
|
||||||
const recurrent = ref(false);
|
const recurrent = ref(false);
|
||||||
const recurrenceRule = ref<FG.RecurrenceRule>({ frequency: 'daily', interval: 1 });
|
const recurrenceRule = ref<FG.RecurrenceRule>({ frequency: 'daily', interval: 1 });
|
||||||
|
@ -169,7 +184,7 @@ export default defineComponent({
|
||||||
|
|
||||||
event.value.is_template = template;
|
event.value.is_template = template;
|
||||||
try {
|
try {
|
||||||
if (event.value?.id !== undefined) {
|
if (!isNaN(event.value.id)) {
|
||||||
//fix
|
//fix
|
||||||
}
|
}
|
||||||
await store.addEvent(event.value);
|
await store.addEvent(event.value);
|
||||||
|
@ -224,8 +239,7 @@ export default defineComponent({
|
||||||
template.value = undefined;
|
template.value = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
const afterStart = (d: Date) =>
|
const afterStart = (d: Date) => !d || (event.value.start <= d || 'Das Veranstaltungsende muss vor dem Beginn liegen')
|
||||||
!d || event.value.start <= d || 'Das Veranstaltungsende muss vor dem Beginn liegen';
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
addJob,
|
addJob,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<q-card class="fit row justify-start content-center items-center">
|
<q-card-section class="fit row justify-start content-center items-center">
|
||||||
<q-card-section class="fit row justify-start content-center items-center">
|
<q-card-section class="fit row justify-start content-center items-center">
|
||||||
<IsoDateInput
|
<IsoDateInput
|
||||||
v-model="job.start"
|
v-model="job.start"
|
||||||
|
@ -45,10 +45,8 @@
|
||||||
filled
|
filled
|
||||||
/>
|
/>
|
||||||
</q-card-section>
|
</q-card-section>
|
||||||
<q-card-actions>
|
<q-btn label="Schicht löschen" color="negative" :disabled="jobCanDelete" @click="removeJob" />
|
||||||
<q-btn label="Schicht löschen" color="negative" :disabled="canDelete" @click="removeJob" />
|
</q-card-section>
|
||||||
</q-card-actions>
|
|
||||||
</q-card>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
@ -65,10 +63,10 @@ export default defineComponent({
|
||||||
required: true,
|
required: true,
|
||||||
type: Object as PropType<FG.Job>,
|
type: Object as PropType<FG.Job>,
|
||||||
},
|
},
|
||||||
canDelete: {
|
jobCanDelete: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
emits: {
|
emits: {
|
||||||
'remove-job': () => true,
|
'remove-job': () => true,
|
||||||
|
@ -84,7 +82,7 @@ export default defineComponent({
|
||||||
const job = new Proxy(props.modelValue, {
|
const job = new Proxy(props.modelValue, {
|
||||||
get(target, prop) {
|
get(target, prop) {
|
||||||
if (typeof prop === 'string') {
|
if (typeof prop === 'string') {
|
||||||
return (props.modelValue as unknown as Record<string, unknown>)[prop];
|
return ((props.modelValue as unknown) as Record<string, unknown>)[prop];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
set(obj, prop, value) {
|
set(obj, prop, value) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<q-page padding class="fit row justify-center content-start items-start q-gutter-sm">
|
<div>
|
||||||
<q-tabs v-if="$q.screen.gt.sm" v-model="tab">
|
<q-tabs v-if="$q.screen.gt.sm" v-model="tab">
|
||||||
<q-tab
|
<q-tab
|
||||||
v-for="(tabindex, index) in tabs"
|
v-for="(tabindex, index) in tabs"
|
||||||
|
@ -24,23 +24,25 @@
|
||||||
</q-item>
|
</q-item>
|
||||||
</q-list>
|
</q-list>
|
||||||
</q-drawer>
|
</q-drawer>
|
||||||
<q-tab-panels
|
<q-page padding class="fit row justify-center content-start items-start q-gutter-sm">
|
||||||
v-model="tab"
|
<q-tab-panels
|
||||||
style="background-color: transparent"
|
v-model="tab"
|
||||||
class="q-ma-none q-pa-none fit row justify-center content-start items-start"
|
style="background-color: transparent"
|
||||||
animated
|
class="q-ma-none q-pa-none fit row justify-center content-start items-start"
|
||||||
>
|
animated
|
||||||
<q-tab-panel name="create">
|
>
|
||||||
<EditEvent :date="date" />
|
<q-tab-panel name="create">
|
||||||
</q-tab-panel>
|
<EditEvent :date="date" />
|
||||||
<q-tab-panel name="eventtypes">
|
</q-tab-panel>
|
||||||
<ManageTypes title="Veranstaltungstyp" type="EventType" />
|
<q-tab-panel name="eventtypes">
|
||||||
</q-tab-panel>
|
<ManageTypes title="Veranstaltungstyp" type="EventType" />
|
||||||
<q-tab-panel name="jobtypes">
|
</q-tab-panel>
|
||||||
<ManageTypes title="Dienstart" type="JobType" />
|
<q-tab-panel name="jobtypes">
|
||||||
</q-tab-panel>
|
<ManageTypes title="Dienstart" type="JobType" />
|
||||||
</q-tab-panels>
|
</q-tab-panel>
|
||||||
</q-page>
|
</q-tab-panels>
|
||||||
|
</q-page>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
@ -58,16 +60,14 @@ export default defineComponent({
|
||||||
date: {
|
date: {
|
||||||
type: String,
|
type: String,
|
||||||
required: false,
|
required: false,
|
||||||
default: undefined,
|
default: undefined
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
const tabs = computed(() => [
|
const tabs = computed(() => [
|
||||||
{ name: 'create', label: 'Veranstaltungen' },
|
{ name: 'create', label: 'Veranstaltungen' },
|
||||||
...(hasPermission(PERMISSIONS.JOB_TYPE) ? [{ name: 'jobtypes', label: 'Dienstarten' }] : []),
|
...(hasPermission(PERMISSIONS.JOB_TYPE) ? [{ name: 'jobtypes', label: 'Dienstarten' }] : []),
|
||||||
...(hasPermission(PERMISSIONS.EVENT_TYPE)
|
...(hasPermission(PERMISSIONS.EVENT_TYPE) ? [{ name: 'eventtypes', label: 'Veranstaltungsarten' }] : [])
|
||||||
? [{ name: 'eventtypes', label: 'Veranstaltungsarten' }]
|
|
||||||
: []),
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const drawer = ref<boolean>(false);
|
const drawer = ref<boolean>(false);
|
||||||
|
@ -82,6 +82,7 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
showDrawer,
|
showDrawer,
|
||||||
tab,
|
tab,
|
|
@ -19,7 +19,7 @@ export const innerRoutes: FG_Plugin.MenuRoute[] = [
|
||||||
route: {
|
route: {
|
||||||
path: 'schedule-overview',
|
path: 'schedule-overview',
|
||||||
name: 'schedule-overview',
|
name: 'schedule-overview',
|
||||||
component: () => import('../pages/EventOverview.vue'),
|
component: () => import('../pages/Overview.vue'),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -30,7 +30,7 @@ export const innerRoutes: FG_Plugin.MenuRoute[] = [
|
||||||
route: {
|
route: {
|
||||||
path: 'schedule-management',
|
path: 'schedule-management',
|
||||||
name: 'schedule-management',
|
name: 'schedule-management',
|
||||||
component: () => import('../pages/EventManagement.vue'),
|
component: () => import('../pages/Management.vue'),
|
||||||
props: (route) => ({date: route.query.date}),
|
props: (route) => ({date: route.query.date}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -41,7 +41,7 @@ export const innerRoutes: FG_Plugin.MenuRoute[] = [
|
||||||
route: {
|
route: {
|
||||||
path: 'schedule-requests',
|
path: 'schedule-requests',
|
||||||
name: 'schedule-requests',
|
name: 'schedule-requests',
|
||||||
component: () => import('../pages/EventRequests.vue'),
|
component: () => import('../pages/Requests.vue'),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -57,6 +57,6 @@ export const privateRoutes: FG_Plugin.NamedRouteRecordRaw[] = [
|
||||||
{
|
{
|
||||||
name: 'events-edit',
|
name: 'events-edit',
|
||||||
path: 'schedule/:id/edit',
|
path: 'schedule/:id/edit',
|
||||||
component: () => import('../pages/EventPage.vue'),
|
component: () => import('../pages/Event.vue'),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
import { api, isAxiosError } from '@flaschengeist/api';
|
import { api, isAxiosError } from '@flaschengeist/api';
|
||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
import { EditableEvent } from './models';
|
|
||||||
|
interface UserService {
|
||||||
|
user: FG.Service;
|
||||||
|
}
|
||||||
|
|
||||||
function fixJob(job: FG.Job) {
|
function fixJob(job: FG.Job) {
|
||||||
job.start = new Date(job.start);
|
job.start = new Date(job.start);
|
||||||
|
@ -139,8 +142,8 @@ export const useEventStore = defineStore({
|
||||||
return api.post<FG.Job>(`/events/jobs/${jobId}/assign`, service);
|
return api.post<FG.Job>(`/events/jobs/${jobId}/assign`, service);
|
||||||
},
|
},
|
||||||
|
|
||||||
async addEvent(event: EditableEvent) {
|
async addEvent(event: FG.Event) {
|
||||||
if (event?.id === undefined) {
|
if (isNaN(event.id)) {
|
||||||
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);
|
||||||
return data;
|
return data;
|
||||||
|
@ -153,12 +156,10 @@ export const useEventStore = defineStore({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async sendInvite(job: FG.Job, invitees: FG.User[], isInvite = true) {
|
async sendInvite(job: FG.Job, invitees: FG.User[], transfer = false) {
|
||||||
return api.post<FG.Event>('/events/transfer', {
|
await Promise.resolve()
|
||||||
job: job.id,
|
console.log(job, invitees, transfer)
|
||||||
receiver: invitees,
|
return Promise.resolve()
|
||||||
is_invite: isInvite
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
|
@ -1,38 +0,0 @@
|
||||||
import { date } from 'quasar';
|
|
||||||
|
|
||||||
/** An new event does not contain an id and the type might be unset */
|
|
||||||
export type EditableEvent = Omit<Omit<Omit<FG.Event, 'jobs'>, 'type'>, 'id'> & {
|
|
||||||
type?: FG.EventType | number;
|
|
||||||
id?: number;
|
|
||||||
jobs: EditableJob[];
|
|
||||||
};
|
|
||||||
|
|
||||||
/** A new job does not have an id or type assigned */
|
|
||||||
export type EditableJob = Omit<Omit<FG.Job, 'type'>, 'id'> & {
|
|
||||||
type?: FG.EventType | number;
|
|
||||||
id?: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
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,
|
|
||||||
end: date.addToDate(start, { hours: 1 }),
|
|
||||||
services: [],
|
|
||||||
locked: false,
|
|
||||||
required_services: 2,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function emptyEvent(startDate?: Date): EditableEvent {
|
|
||||||
return {
|
|
||||||
start: startDate === undefined ? new Date() : new Date(startDate),
|
|
||||||
jobs: [emptyJob(startDate)],
|
|
||||||
is_template: false,
|
|
||||||
};
|
|
||||||
}
|
|
Loading…
Reference in New Issue