129 lines
4.7 KiB
Vue
129 lines
4.7 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"
|
|
:current-shifts="day.shifts"
|
|
: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"
|
|
:current-shifts="day.shifts"
|
|
:is-timesheet-approved="approved"
|
|
:error-message="shift_error_message"
|
|
@request-delete="deleteCurrentShift(shift)"
|
|
@on-time-field-blur="onTimeFieldBlur()"
|
|
/>
|
|
|
|
</div>
|
|
</div>
|
|
</template> |