Refactor ClientSchedule to mutable types
Use a single mutable location, event, slot, etc, for each unique resource that keeps track of the local editable client copy and the server copy of the data contained in it. This makes it much simpler to update these data structures as I can take advantage of the v-model bindings in Vue.js and work with the system instead of against it.
This commit is contained in:
parent
d48fb035b4
commit
e3ff872b5c
16 changed files with 1213 additions and 1125 deletions
|
@ -92,42 +92,39 @@
|
|||
<td>
|
||||
<input
|
||||
type="text"
|
||||
:value="ss.name"
|
||||
@input="editShift(ss, { name: ($event as any).target.value })"
|
||||
v-model="ss.name"
|
||||
>
|
||||
</td>
|
||||
<td>{{ status(ss) }}</td>
|
||||
<td>
|
||||
<select
|
||||
:value="ss.role.id"
|
||||
@change="editShift(ss, { role: schedule.roles.get(parseInt(($event as any).target.value)) })"
|
||||
v-model="ss.shift.roleId"
|
||||
>
|
||||
<option
|
||||
v-for="role in schedule.roles.values()"
|
||||
:key="role.id"
|
||||
:value="role.id"
|
||||
:disabled="role.deleted"
|
||||
:selected="role.id === ss.role.id"
|
||||
:selected="role.id === ss.shift.roleId"
|
||||
>{{ role.name }}</option>
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<AssignedCrew
|
||||
:edit="true"
|
||||
:modelValue="ss.assigned"
|
||||
@update:modelValue="editShiftSlot(ss, { assigned: $event })"
|
||||
v-model="ss.slot.assigned"
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<button
|
||||
:disabled="ss.deleted"
|
||||
type="button"
|
||||
@click="editShiftSlot(ss, { deleted: true })"
|
||||
@click="ss.slot.deleted = true"
|
||||
>Remove</button>
|
||||
<button
|
||||
v-if="schedule.isModifiedShiftSlot(ss.slot.id)"
|
||||
v-if="ss.slot.isModified()"
|
||||
type="button"
|
||||
@click="revertShiftSlot(ss.id)"
|
||||
@click="ss.shift.discardSlot(ss.slot.id)"
|
||||
>Revert</button>
|
||||
</td>
|
||||
</template>
|
||||
|
@ -185,7 +182,7 @@
|
|||
<td>{{ ss.end.diff(ss.start).toFormat('hh:mm') }}</td>
|
||||
<td>{{ ss.name }}</td>
|
||||
<td>{{ status(ss) }}</td>
|
||||
<td>{{ ss.role.id }}</td>
|
||||
<td>{{ ss.roleId }}</td>
|
||||
<td><AssignedCrew :modelValue="ss.assigned" :edit="false" /></td>
|
||||
</template>
|
||||
</tr>
|
||||
|
@ -213,7 +210,7 @@ interface ShiftSlot {
|
|||
shift: ClientScheduleShift,
|
||||
slot: ClientScheduleShiftSlot,
|
||||
name: string,
|
||||
role: ClientScheduleRole,
|
||||
roleId: Id,
|
||||
assigned: Set<Id>,
|
||||
start: DateTime,
|
||||
end: DateTime,
|
||||
|
@ -290,42 +287,26 @@ function durationFromTime(time: string) {
|
|||
return duration;
|
||||
}
|
||||
const newShiftName = ref("");
|
||||
function editShift(
|
||||
shiftSlot: ShiftSlot,
|
||||
edits: Parameters<ClientSchedule["editShift"]>[1],
|
||||
) {
|
||||
schedule.value.editShift(shiftSlot.shift, edits);
|
||||
}
|
||||
|
||||
function editShiftSlot(
|
||||
shiftSlot: ShiftSlot,
|
||||
edits: {
|
||||
deleted?: boolean,
|
||||
start?: string,
|
||||
end?: string,
|
||||
duration?: string,
|
||||
assigned?: Set<Id>,
|
||||
}
|
||||
) {
|
||||
const computedEdits: Parameters<ClientSchedule["editShiftSlot"]>[1] = {
|
||||
deleted: edits.deleted,
|
||||
assigned: edits.assigned,
|
||||
};
|
||||
if (edits.start) {
|
||||
const start = DateTime.fromISO(edits.start, { zone: accountStore.activeTimezone, locale: accountStore.activeLocale });
|
||||
computedEdits.start = start;
|
||||
computedEdits.end = start.plus(shiftSlot.slot.end.diff(shiftSlot.slot.start));
|
||||
shiftSlot.start = start;
|
||||
shiftSlot.end = start.plus(shiftSlot.slot.end.diff(shiftSlot.slot.start));
|
||||
}
|
||||
if (edits.end !== undefined) {
|
||||
computedEdits.end = endFromTime(shiftSlot.start, edits.end);
|
||||
shiftSlot.end = endFromTime(shiftSlot.start, edits.end);
|
||||
}
|
||||
if (edits.duration !== undefined) {
|
||||
computedEdits.end = shiftSlot.start.plus(durationFromTime(edits.duration));
|
||||
shiftSlot.end = shiftSlot.start.plus(durationFromTime(edits.duration));
|
||||
}
|
||||
schedule.value.editShiftSlot(shiftSlot.slot, computedEdits);
|
||||
}
|
||||
function revertShiftSlot(id: Id) {
|
||||
schedule.value.restoreShiftSlot(id);
|
||||
}
|
||||
function newShiftSlot(options: { start?: DateTime, end?: DateTime } = {}) {
|
||||
const name = newShiftName.value;
|
||||
|
@ -361,15 +342,16 @@ function newShiftSlot(options: { start?: DateTime, end?: DateTime } = {}) {
|
|||
alert("Invalid start and/or end time");
|
||||
return;
|
||||
}
|
||||
const slot = new ClientScheduleShiftSlot(
|
||||
const slot = ClientScheduleShiftSlot.create(
|
||||
schedule.value,
|
||||
schedule.value.nextClientId--,
|
||||
false,
|
||||
shift.id,
|
||||
start,
|
||||
end,
|
||||
new Set(),
|
||||
);
|
||||
schedule.value.setShiftSlot(slot);
|
||||
schedule.value.shiftSlots.set(slot.id, slot);
|
||||
shift.slotIds.add(slot.id);
|
||||
newShiftName.value = "";
|
||||
}
|
||||
|
||||
|
@ -386,7 +368,7 @@ function gapFormat(gap: Gap) {
|
|||
const shiftSlots = computed(() => {
|
||||
const data: (ShiftSlot | Gap)[] = [];
|
||||
for (const shift of schedule.value.shifts.values()) {
|
||||
if (props.roleId !== undefined && shift.role.id !== props.roleId)
|
||||
if (props.roleId !== undefined && shift.roleId !== props.roleId)
|
||||
continue;
|
||||
for (const slot of shift.slots.values()) {
|
||||
if (props.shiftSlotFilter && !props.shiftSlotFilter(slot))
|
||||
|
@ -398,7 +380,7 @@ const shiftSlots = computed(() => {
|
|||
shift,
|
||||
slot,
|
||||
name: shift.name,
|
||||
role: shift.role,
|
||||
roleId: shift.roleId,
|
||||
assigned: slot.assigned,
|
||||
start: slot.start,
|
||||
end: slot.end,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue