owltide/components/DiffScheduleEvent.vue
Hornwitser a32a49b281
All checks were successful
/ build (push) Successful in 1m35s
/ deploy (push) Successful in 16s
Add UI for setting cancelled status
Add indications in event cards, event slot cards and the timetable for
an event or event slot being cancelled by striking it through and
dimming the text colour.  And a checkbox in the event and event slot
list to edit the cancelled status.  And a diff entry for the cancelled
status on events and event slots.
2025-09-21 23:15:10 +02:00

123 lines
3 KiB
Vue

<!--
SPDX-FileCopyrightText: © 2025 Hornwitser <code@hornwitser.no>
SPDX-License-Identifier: AGPL-3.0-or-later
-->
<template>
<div>
<h4>{{ state }} {{ event.name }}</h4>
<DiffFieldString
title="Name"
:before="event.serverName"
:after="event.name"
:state
/>
<DiffFieldString
title="Timetable Name"
:before="event.serverTimetableName"
:after="event.timetableName"
:state
/>
<DiffFieldString
title="Host"
:before="event.serverHost"
:after="event.host"
:state
/>
<DiffFieldString
title="Public"
:before='event.serverCrew ? "No" : "Yes"'
:after='event.crew ? "No" : "Yes"'
:state
/>
<DiffFieldString
title="Cancelled"
:before='event.serverCancelled ? "Yes" : "No"'
:after='event.cancelled ? "Yes" : "No"'
:state
/>
<DiffFieldString
title="Notice"
:before="event.serverNotice"
:after="event.notice"
:state
/>
<DiffFieldString
title="Description"
:before="event.serverDescription"
:after="event.description"
:state
/>
<DiffScheduleEventSlot
v-for="[state, slot] in slots"
:key="slot.id"
:slot
:schedule
:state
/>
</div>
</template>
<script lang="ts" setup>
const props = defineProps<{
event: ClientScheduleEvent,
schedule: ClientSchedule,
}>();
const state = computed(() => {
if (props.event.deleted) return "deleted";
if (props.event.isNew()) return "created";
return "modified";
});
const slots = computed((): [
"deleted" | "created" | "modified", ClientScheduleEventSlot
][] => {
const afterIds = props.event.slotIds;
const beforeIds = props.event.serverSlotIds;
if (state.value === "deleted") {
return (
[...beforeIds]
.map(id => props.schedule.eventSlots.get(id))
.filter(slot => slot !== undefined)
.map(slot => ["deleted", slot] as ["deleted", ClientScheduleEventSlot])
);
}
if (state.value === "created") {
return (
[...afterIds]
.map(id => props.schedule.eventSlots.get(id))
.filter(slot => slot !== undefined)
.map(slot => ["created", slot] as ["created", ClientScheduleEventSlot])
);
}
const added = [...toRaw(afterIds).difference(beforeIds)]
.map(id => props.schedule.eventSlots.get(id))
.filter(slot => slot !== undefined)
.filter(slot => !slot.deleted)
.map(slot => ["created", slot] as ["created", ClientScheduleEventSlot])
;
const removed = [...new Set(
[...toRaw(beforeIds).difference(afterIds)]
.map(id => props.schedule.eventSlots.get(id))
.filter(slot => slot !== undefined)
).union(
new Set(
[...afterIds]
.map(id => props.schedule.eventSlots.get(id))
.filter(slot => slot !== undefined)
.filter(slot => slot.deleted)
)
)]
.map(slot => ["deleted", slot] as ["deleted", ClientScheduleEventSlot])
;
const modified = [...toRaw(afterIds).intersection(beforeIds)]
.map(id => props.schedule.eventSlots.get(id))
.filter(slot => slot !== undefined)
.filter(slot => slot.isModified() && !slot.deleted)
.map(slot => ["modified", slot] as ["modified", ClientScheduleEventSlot])
;
return [
...added,
...removed,
...modified,
];
});
</script>