Rename accounts to users to be consistent with the new naming scheme where account only referes to the logged in user of the session and implement live updates of users via a user store which listens for updates from the event stream.
170 lines
4.1 KiB
Vue
170 lines
4.1 KiB
Vue
<template>
|
|
<main>
|
|
<h1>Edit</h1>
|
|
<label>
|
|
Crew Filter:
|
|
<select
|
|
v-model="crewFilter"
|
|
>
|
|
<option
|
|
:value="undefined"
|
|
:selected="crewFilter === undefined"
|
|
><All Crew></option>
|
|
<option
|
|
v-for="user in [...usersStore.users.values()].filter(a => a.type === 'crew' || a.type === 'admin')"
|
|
:key="user.id"
|
|
:value="String(user.id)"
|
|
:selected="crewFilter === String(user.id)"
|
|
>{{ user.name }}</option>
|
|
</select>
|
|
</label>
|
|
<Timetable :schedule :eventSlotFilter :shiftSlotFilter />
|
|
<Tabs
|
|
:tabs
|
|
default="locations"
|
|
>
|
|
<template #locations>
|
|
<TableScheduleLocations :edit="accountStore.canEditPublic" />
|
|
</template>
|
|
<template #events>
|
|
<TableScheduleEvents :edit="true" />
|
|
</template>
|
|
<template #eventSlots>
|
|
<label>
|
|
Location Filter:
|
|
<select
|
|
v-model="locationFilter"
|
|
>
|
|
<option
|
|
:value="undefined"
|
|
:selected="locationFilter === undefined"
|
|
><All locations></option>
|
|
<option
|
|
v-for="location in schedule.locations.values()"
|
|
:key="location.id"
|
|
:value="location.id"
|
|
:disabled="location.deleted"
|
|
:selected="locationFilter === location.id"
|
|
>{{ location.name }}</option>
|
|
</select>
|
|
</label>
|
|
<TableScheduleEventSlots :edit="true" :locationId="locationFilter" :eventSlotFilter />
|
|
</template>
|
|
<template #roles>
|
|
<TableScheduleRoles :edit="true" />
|
|
</template>
|
|
<template #shifts>
|
|
<TableScheduleShifts :edit="true" :roleId="roleFilter" />
|
|
</template>
|
|
<template #shiftSlots>
|
|
<label>
|
|
Role Filter:
|
|
<select
|
|
v-model="roleFilter"
|
|
>
|
|
<option
|
|
:value="undefined"
|
|
:selected="roleFilter === undefined"
|
|
><All roles></option>
|
|
<option
|
|
v-for="role in schedule.roles.values()"
|
|
:key="role.id"
|
|
:value="role.id"
|
|
:disabled="role.deleted"
|
|
:selected="roleFilter === role.id"
|
|
>{{ role.name }}</option>
|
|
</select>
|
|
</label>
|
|
<TableScheduleShiftSlots :edit="true" :roleId="roleFilter" :shiftSlotFilter />
|
|
</template>
|
|
</Tabs>
|
|
<p v-if="schedule.modified">
|
|
Changes are not saved yet.
|
|
<button
|
|
type="button"
|
|
@click="saveChanges"
|
|
>Save Changes</button>
|
|
</p>
|
|
</main>
|
|
</template>
|
|
|
|
<script lang="ts" setup>
|
|
definePageMeta({
|
|
middleware: ["authenticated"],
|
|
allowedAccountTypes: ["crew", "admin"],
|
|
});
|
|
|
|
const tabs = [
|
|
{ id: "locations", title: "Locations" },
|
|
{ id: "events", title: "Events" },
|
|
{ id: "eventSlots", title: "Event Slots" },
|
|
{ id: "roles", title: "Roles" },
|
|
{ id: "shifts", title: "Shifts" },
|
|
{ id: "shiftSlots", title: "Shifts Slots" },
|
|
];
|
|
|
|
const schedule = await useSchedule();
|
|
const usersStore = useUsersStore();
|
|
await usersStore.fetch();
|
|
const accountStore = useAccountStore();
|
|
|
|
const route = useRoute();
|
|
const crewFilter = computed({
|
|
get: () => queryToString(route.query.crew),
|
|
set: (value: string | undefined) => navigateTo({
|
|
path: route.path,
|
|
query: {
|
|
...route.query,
|
|
crew: value,
|
|
},
|
|
}),
|
|
});
|
|
const eventSlotFilter = computed(() => {
|
|
if (crewFilter.value === undefined || !accountStore.valid) {
|
|
return () => true;
|
|
}
|
|
const cid = parseInt(crewFilter.value);
|
|
return (slot: ClientScheduleEventSlot) => slot.assigned.has(cid);
|
|
});
|
|
const shiftSlotFilter = computed(() => {
|
|
if (crewFilter.value === undefined || !accountStore.valid) {
|
|
return () => true;
|
|
}
|
|
const cid = parseInt(crewFilter.value);
|
|
return (slot: ClientScheduleShiftSlot) => slot.assigned.has(cid);
|
|
});
|
|
|
|
const locationFilter = computed({
|
|
get: () => queryToNumber(route.query.location),
|
|
set: (value: number | undefined) => navigateTo({
|
|
path: route.path,
|
|
query: {
|
|
...route.query,
|
|
location: value !== undefined ? String(value) : undefined,
|
|
},
|
|
}),
|
|
});
|
|
|
|
const roleFilter = computed({
|
|
get: () => queryToNumber(route.query.role),
|
|
set: (value: string | undefined) => navigateTo({
|
|
path: route.path,
|
|
query: {
|
|
...route.query,
|
|
role: value,
|
|
},
|
|
}),
|
|
});
|
|
|
|
async function saveChanges() {
|
|
try {
|
|
await $fetch("/api/schedule", {
|
|
method: "PATCH",
|
|
body: schedule.value.toApi(true),
|
|
});
|
|
} catch (err: any) {
|
|
console.error(err);
|
|
alert(err?.data?.message ?? err.message);
|
|
}
|
|
}
|
|
</script>
|