targo-frontend/src/modules/timesheets/components/shift-list-day.vue

128 lines
4.6 KiB
Vue

<script
setup
lang="ts"
>
import ShiftListDayRow from 'src/modules/timesheets/components/shift-list-day-row.vue';
import ShiftListDayRowMobile from 'src/modules/timesheets/components/mobile/shift-list-day-row-mobile.vue';
import { inject, ref } from 'vue';
import { useTimesheetStore } from 'src/stores/timesheet-store';
import { useShiftApi } from 'src/modules/timesheets/composables/use-shift-api';
import { useTimesheetApi } from 'src/modules/timesheets/composables/use-timesheet-api';
import { isShiftOverlap } from 'src/modules/timesheets/utils/shift.util';
import type { Shift } from 'src/modules/timesheets/models/shift.models';
import type { TimesheetDay } from 'src/modules/timesheets/models/timesheet.models';
// ================== State ==================
const { timesheetId, weekDayIndex, day, dense = false, approved = false, holiday = false } = defineProps<{
timesheetId: number;
weekDayIndex: number;
day: TimesheetDay;
dense?: boolean;
approved?: boolean;
holiday?: boolean;
}>();
const emit = defineEmits<{
'deleteUnsavedShift': [void];
}>();
const shift_api = useShiftApi();
const timesheet_api = useTimesheetApi();
const timesheet_store = useTimesheetStore();
const preset_mouseover = ref(false);
const shift_error_message = ref<string | undefined>();
const employeeEmail = inject<string>('employeeEmail');
// ================== Methods ==================
const deleteCurrentShift = async (shift: Shift) => {
if (shift.id <= 0) {
shift.id = 0;
emit('deleteUnsavedShift');
} else {
await shift_api.deleteShiftById(shift.id, employeeEmail);
}
if (day.shifts.length < 2 && shift_error_message.value !== undefined) {
onTimeFieldBlur();
}
};
const onTimeFieldBlur = () => {
const is_error = isShiftOverlap(day.shifts);
day.shifts.map(shift => shift.has_error = is_error);
if (is_error)
shift_error_message.value = 'timesheet.errors.SHIFT_OVERLAP_SHORT';
else
shift_error_message.value = undefined;
}
const onClickApplyDailyPreset = async () => {
await timesheet_api.applyPreset(timesheetId, weekDayIndex, day.date, employeeEmail);
}
</script>
<template>
<div
class="column justify-center q-py-xs"
:class="approved ? '' : ''"
@mouseenter="preset_mouseover = true"
@mouseleave="preset_mouseover = false"
>
<!-- Button to apply preset to day -->
<transition
appear
enter-active-class="animated zoomIn fast"
leave-active-class="animated zoomOut fast"
>
<q-btn
v-if="!$q.platform.is.mobile && day.shifts.length < 1 && preset_mouseover && timesheet_store.has_timesheet_preset"
:disable="day.shifts.length > 0"
flat
dense
size="lg"
:label="$t('timesheet.apply_preset_day')"
class="text-uppercase text-weight-bold text-accent q-mx-lg q-py-none rounded-5"
style="opacity: 0.6;"
@click.stop="onClickApplyDailyPreset"
>
<q-icon
name="las la-calendar-day"
color="accent"
size="md"
/>
</q-btn>
</transition>
<div
v-for="shift, shift_index in day.shifts"
:key="shift_index"
class="col-auto"
>
<ShiftListDayRowMobile
v-if="$q.platform.is.mobile"
v-model:shift="day.shifts[shift_index]!"
:is-timesheet-approved="approved"
:error-message="shift_error_message"
:dense="dense"
:has-shift-after="shift_index < day.shifts.length - 1"
@request-delete="deleteCurrentShift(shift)"
@on-time-field-blur="onTimeFieldBlur()"
/>
<ShiftListDayRow
v-else
v-model:shift="day.shifts[shift_index]!"
:holiday="holiday"
:daily-hours="day.daily_hours"
:is-timesheet-approved="approved"
:error-message="shift_error_message"
@request-delete="deleteCurrentShift(shift)"
@on-time-field-blur="onTimeFieldBlur()"
/>
</div>
</div>
</template>