Add a save dialog at the bottom of the screen that is present whenever there are unsaved changes. This dialog provides a diff between the client and server state so that the user can easily confirm the changes they are about to make are the correct changes before applying them to the server.
96 lines
2.4 KiB
Vue
96 lines
2.4 KiB
Vue
<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>
|