owltide/components/DiffScheduleShift.vue

101 lines
2.5 KiB
Vue
Raw Permalink Normal View History

<!--
SPDX-FileCopyrightText: © 2025 Hornwitser <code@hornwitser.no>
SPDX-License-Identifier: AGPL-3.0-or-later
-->
<template>
<div>
<h4>{{ state }} {{ shift.name }}</h4>
<DiffFieldString
title="Name"
:before="shift.serverName"
:after="shift.name"
:state
/>
<DiffFieldEntityId
title="Role"
:before="shift.serverRoleId"
:after="shift.roleId"
:entities="schedule.roles"
:state
/>
<DiffFieldString
title="Description"
:before="shift.serverDescription"
:after="shift.description"
:state
/>
<DiffScheduleShiftSlot
v-for="[state, slot] in slots"
:key="slot.id"
:slot
:schedule
:state
/>
</div>
</template>
<script lang="ts" setup>
const props = defineProps<{
shift: ClientScheduleShift,
schedule: ClientSchedule,
}>();
const state = computed(() => {
if (props.shift.deleted) return "deleted";
if (props.shift.isNew()) return "created";
return "modified";
});
const slots = computed((): [
"deleted" | "created" | "modified", ClientScheduleShiftSlot
][] => {
const afterIds = props.shift.slotIds;
const beforeIds = props.shift.serverSlotIds;
if (state.value === "deleted") {
return (
[...beforeIds]
.map(id => props.schedule.shiftSlots.get(id))
.filter(slot => slot !== undefined)
.map(slot => ["deleted", slot] as ["deleted", ClientScheduleShiftSlot])
);
}
if (state.value === "created") {
return (
[...afterIds]
.map(id => props.schedule.shiftSlots.get(id))
.filter(slot => slot !== undefined)
.map(slot => ["created", slot] as ["created", ClientScheduleShiftSlot])
);
}
const added = [...toRaw(afterIds).difference(beforeIds)]
.map(id => props.schedule.shiftSlots.get(id))
.filter(slot => slot !== undefined)
.filter(slot => !slot.deleted)
.map(slot => ["created", slot] as ["created", ClientScheduleShiftSlot])
;
const removed = [...new Set(
[...toRaw(beforeIds).difference(afterIds)]
.map(id => props.schedule.shiftSlots.get(id))
.filter(slot => slot !== undefined)
).union(
new Set(
[...afterIds]
.map(id => props.schedule.shiftSlots.get(id))
.filter(slot => slot !== undefined)
.filter(slot => slot.deleted)
)
)]
.map(slot => ["deleted", slot] as ["deleted", ClientScheduleShiftSlot])
;
const modified = [...toRaw(afterIds).intersection(beforeIds)]
.map(id => props.schedule.shiftSlots.get(id))
.filter(slot => slot !== undefined)
.filter(slot => slot.isModified() && !slot.deleted)
.map(slot => ["modified", slot] as ["modified", ClientScheduleShiftSlot])
;
return [
...added,
...removed,
...modified,
];
});
</script>