owltide/components/TableScheduleShifts.vue
Hornwitser b1053a95ba Fix import statements
Remove unused or unneeded imports and change imports of luxon APIs to
use the wrapper.
2025-06-23 12:54:09 +02:00

192 lines
4.3 KiB
Vue

<template>
<div>
<table>
<thead>
<tr>
<th>id</th>
<th>name</th>
<th>role</th>
<th>s</th>
<th>description</th>
<th v-if="edit"></th>
</tr>
</thead>
<tbody>
<template v-if="edit">
<tr
v-for="shift in schedule.shifts.values()"
:key="shift.id"
:class="{ removed: shift.deleted }"
>
<td>{{ shift.id }}</td>
<td>
<input
type="text"
:value="shift.name"
@input="editShift(shift, { name: ($event as any).target.value })"
>
</td>
<td>
<select
:value="shift.role.id"
@change="editShift(shift, { role: schedule.roles.get(parseInt(($event as any).target.value, 10)) })"
>
<option
v-for="role in schedule.roles.values()"
:key="role.id"
:value="role.id"
:disabled="shift.deleted"
:selected="shift.role.id === role.id"
>{{ role.name }}</option>
</select>
</td>
<td>{{ shift.slots.size ? shift.slots.size : "" }}</td>
<td>
<input
type="text"
:value="shift.description"
@input="editShift(shift, { description: ($event as any).target.value })"
>
</td>
<td>
<button
type="button"
:disabled="shift.deleted"
@click="editShift(shift, { deleted: true })"
>Delete</button>
<button
v-if="schedule.isModifiedShift(shift.id)"
type="button"
@click="revertShift(shift.id)"
>Revert</button>
</td>
</tr>
<tr>
<td>{{ schedule.nextClientId }}</td>
<td>
<input
type="text"
v-model="newShiftName"
>
</td>
<td>
<select v-model="newShiftRoleId">
<option
v-for="role in schedule.roles.values()"
:key="role.id"
:value="role.id"
:disabled="role.deleted"
:selected="role.id === newShiftRoleId"
>{{ role.name }}</option>
</select>
</td>
<td></td>
<td>
<input
type="text"
v-model="newShiftDescription"
>
</td>
<td>
<button
v-if="shiftExists(newShiftName)"
disabled
>Shift already exists</button>
<button
v-else
type="button"
@click="newShift"
>Add Shift</button>
</td>
</tr>
</template>
<template v-else>
<tr
v-for="shift in schedule.shifts.values()"
:key="shift.id"
>
<td>{{ shift.id }}</td>
<td>{{ shift.name }}</td>
<td>{{ shift.role.id }}</td>
<td>{{ shift.slots.size ? shift.slots.size : "" }}</td>
<td>{{ shift.description }}</td>
</tr>
</template>
</tbody>
</table>
</div>
</template>
<script lang="ts" setup>
import { DateTime } from '~/shared/utils/luxon';
import type { Id } from '~/shared/types/common';
import { toId } from '~/shared/utils/functions';
const props = defineProps<{
edit?: boolean,
roleId?: number,
}>();
const schedule = await useSchedule();
const newShiftName = ref("");
const newShiftRoleId = ref(props.roleId);
watch(() => props.roleId, () => {
newShiftRoleId.value = props.roleId;
});
const newShiftDescription = ref("");
function editShift(
shift: ClientScheduleShift,
edits: Parameters<ClientSchedule["editShift"]>[1],
) {
schedule.value.editShift(shift, edits);
}
function revertShift(id: Id) {
schedule.value.restoreShift(id);
}
function shiftExists(name: string) {
name = toId(name);
return (
[...schedule.value.shifts.values()].some(s => !s.deleted && toId(s.name) === name)
);
}
function newShift() {
if (shiftExists(newShiftName.value)) {
alert(`Shift ${newShiftName.value} already exists`);
return;
}
const role = schedule.value.roles.get(newShiftRoleId.value!);
if (!role) {
alert(`Invalid role`);
return;
}
const shift = new ClientScheduleShift(
schedule.value.nextClientId--,
DateTime.now(),
false,
role,
newShiftName.value,
newShiftDescription.value,
new Map(),
);
schedule.value.setShift(shift);
newShiftName.value = "";
newShiftDescription.value = "";
}
</script>
<style scoped>
table {
border-spacing: 0;
}
table th {
text-align: left;
border-bottom: 1px solid var(--foreground);
}
table :is(th, td) + :is(th, td) {
padding-inline-start: 0.4em;
}
.removed :is(td, input) {
text-decoration: line-through;
}
</style>