Add assigment of crew to events and shifts

This commit is contained in:
Hornwitser 2025-03-15 18:18:08 +01:00
parent 0aff9cc94a
commit cef6b13dd1
7 changed files with 153 additions and 3 deletions

View file

@ -0,0 +1,62 @@
<template>
<div>
<template v-for="account in assigned">
{{ account.name }}
<button
v-if="edit"
type="button"
@click="assignedIds = assignedIds.filter(id => id !== account.id)"
>
x
</button>
{{ " " }}
</template>
<input
v-if="edit"
type="text"
@change="addCrew"
v-model="addName"
>
</div>
</template>
<script lang="ts" setup>
defineProps<{
edit?: boolean
}>();
const { data: accounts } = useAccounts();
const accountsById = computed(() => new Map(accounts.value?.map?.(a => [a.id, a])));
const assignedIds = defineModel<number[]>({ required: true });
const assigned = computed(
() => assignedIds.value.map(
id => accountsById.value.get(id) ?? { id, name: String(id) }
)
);
const crewByName = computed(() => new Map(
accounts.value
?.filter?.(a => a.type === "crew" || a.type === "admin")
?.map?.(a => [a.name, a])
));
const addName = ref("");
function addCrew() {
if (!addName.value)
return;
const account = crewByName.value.get(addName.value);
if (account) {
if (!assignedIds.value.some(id => id === account.id)) {
assignedIds.value = [...assignedIds.value, account.id];
} else {
alert(`${addName.value} has already been added`);
}
addName.value = "";
} else {
alert(`No crew account by the name ${addName.value}`);
}
}
</script>
<style scoped>
input {
width: 3em;
}
</style>

View file

@ -10,6 +10,7 @@
<th>event</th>
<th>s</th>
<th>location</th>
<th>assigned</th>
<th v-if="edit"></th>
</tr>
</thead>
@ -53,6 +54,7 @@
>{{ location.name }}</option>
</select>
</td>
<td></td>
<td>
Add at
<button
@ -108,6 +110,13 @@
>{{ location.name }}</option>
</select>
</td>
<td>
<AssignedCrew
:edit="true"
:modelValue="es.assigned"
@update:modelValue="editEventSlot(es, { assigned: $event })"
/>
</td>
<td>
<button
:disabled="removed.has(es.id)"
@ -147,6 +156,8 @@
v-model="newEventName"
>
</td>
<td></td>
<td></td>
<td colspan="2">
<button
type="button"
@ -176,6 +187,7 @@
<td>{{ es.name }}</td>
<td>{{ status(es) }}</td>
<td>{{ es.location }}</td>
<td><AssignedCrew :modelValue="es.assigned" :edit="false" /></td>
</template>
</tr>
</template>
@ -225,6 +237,7 @@ interface EventSlot {
origLocation: string,
name: string,
location: string,
assigned: number[],
start: DateTime,
end: DateTime,
}
@ -332,6 +345,7 @@ function mergeSlot(event: ScheduleEvent, eventSlot: EventSlot): ScheduleEvent {
return {
...s,
locations: [...locations],
assigned: eventSlot.assigned.length ? eventSlot.assigned : undefined,
start,
end,
};
@ -349,6 +363,7 @@ function mergeSlot(event: ScheduleEvent, eventSlot: EventSlot): ScheduleEvent {
slots: [...event.slots, {
id: oldSlot ? oldSlot.id : `${event.id}-${nextId}`,
locations: [eventSlot.location],
assigned: eventSlot.assigned.length ? eventSlot.assigned : undefined,
start,
end,
}],
@ -487,6 +502,7 @@ function editEventSlot(
duration?: string,
name?: string,
location?: string,
assigned?: number[],
}
) {
if (edits.start) {
@ -522,6 +538,12 @@ function editEventSlot(
location: edits.location,
};
}
if (edits.assigned !== undefined) {
eventSlot = {
...eventSlot,
assigned: edits.assigned,
};
}
const change = { op: "set" as const, data: eventSlot };
changes.value = replaceChange(change, changes.value);
}
@ -568,6 +590,7 @@ function newEventSlot(options: { start?: DateTime, end?: DateTime } = {}) {
name,
origLocation: location,
location,
assigned: [],
start,
end,
},
@ -612,6 +635,7 @@ const eventSlots = computed(() => {
slot,
name: event.name,
location,
assigned: slot.assigned ?? [],
origLocation: location,
start: DateTime.fromISO(slot.start, { zone: timezone.value }),
end: DateTime.fromISO(slot.end, { zone: timezone.value }),

View file

@ -10,6 +10,7 @@
<th>shift</th>
<th>s</th>
<th>role</th>
<th>assigned</th>
<th v-if="edit"></th>
</tr>
</thead>
@ -53,6 +54,7 @@
>{{ role.name }}</option>
</select>
</td>
<td></td>
<td>
Add at
<button
@ -108,6 +110,13 @@
>{{ role.name }}</option>
</select>
</td>
<td>
<AssignedCrew
:edit="true"
:modelValue="ss.assigned"
@update:modelValue="editShiftSlot(ss, { assigned: $event })"
/>
</td>
<td>
<button
:disabled="removed.has(ss.id)"
@ -147,7 +156,7 @@
v-model="newShiftName"
>
</td>
<td colspan="2">
<td colspan="3">
<button
type="button"
@click="newShiftSlot()"
@ -176,6 +185,7 @@
<td>{{ ss.name }}</td>
<td>{{ status(ss) }}</td>
<td>{{ ss.role }}</td>
<td><AssignedCrew :modelValue="ss.assigned" :edit="false" /></td>
</template>
</tr>
</template>
@ -225,6 +235,7 @@ interface ShiftSlot {
origRole: string,
name: string,
role: string,
assigned: number[],
start: DateTime,
end: DateTime,
}
@ -299,6 +310,7 @@ function mergeSlot(shift: Shift, shiftSlot: ShiftSlot): Shift {
})) + 1;
const start = shiftSlot.start.toUTC().toISO({ suppressSeconds: true })!;
const end = shiftSlot.end.toUTC().toISO({ suppressSeconds: true })!;
const assigned = shiftSlot.assigned.length ? shiftSlot.assigned : undefined;
if (shift.role !== shiftSlot.role) {
console.warn(`Attempt to add slot id=${shiftSlot.id} role=${shiftSlot.role} to shift id=${shift.id} role=${shift.role}`);
@ -308,7 +320,7 @@ function mergeSlot(shift: Shift, shiftSlot: ShiftSlot): Shift {
if (oldSlot && oldSlot.id === shiftSlot.id) {
return {
...shift,
slots: shift.slots.map(s => s.id !== oldSlot.id ? s : { ...s, start, end, }),
slots: shift.slots.map(s => s.id !== oldSlot.id ? s : { ...s, assigned, start, end, }),
};
}
@ -317,6 +329,7 @@ function mergeSlot(shift: Shift, shiftSlot: ShiftSlot): Shift {
...shift,
slots: [...(oldSlot ? shift.slots.filter(s => s.id !== oldSlot.id) : shift.slots), {
id: oldSlot ? oldSlot.id : `${shift.id}-${nextId}`,
assigned,
start,
end,
}],
@ -459,6 +472,7 @@ function editShiftSlot(
duration?: string,
name?: string,
role?: string,
assigned?: number[],
}
) {
if (edits.start) {
@ -505,6 +519,12 @@ function editShiftSlot(
changes.value = changesCopy;
return;
}
if (edits.assigned !== undefined) {
shiftSlot = {
...shiftSlot,
assigned: edits.assigned,
};
}
const change = { op: "set" as const, data: shiftSlot };
changes.value = replaceChange(change, changes.value);
}
@ -551,6 +571,7 @@ function newShiftSlot(options: { start?: DateTime, end?: DateTime } = {}) {
name,
origRole: role,
role,
assigned: [],
start,
end,
},
@ -594,6 +615,7 @@ const shiftSlots = computed(() => {
slot,
name: shift.name,
role: shift.role,
assigned: slot.assigned ?? [],
origRole: shift.role,
start: DateTime.fromISO(slot.start, { zone: timezone.value }),
end: DateTime.fromISO(slot.end, { zone: timezone.value }),