119 lines
4.5 KiB
Vue
119 lines
4.5 KiB
Vue
<script
|
|
setup
|
|
lang="ts"
|
|
>
|
|
import ShiftListDay from 'src/modules/timesheets/components/shift-list-day.vue';
|
|
|
|
import { useQuasar } from 'quasar';
|
|
import { ref, computed, watch, inject, onMounted } from 'vue';
|
|
import { useTimesheetStore } from 'src/stores/timesheet-store';
|
|
import { useTimesheetApi } from 'src/modules/timesheets/composables/use-timesheet-api';
|
|
import { TimesheetDayDisplay } from 'src/modules/timesheets/models/timesheet.models';
|
|
|
|
// ========== constants ========================================
|
|
|
|
const CURRENT_DATE_STRING = new Date().toISOString().slice(0, 10);
|
|
|
|
// ========== state ========================================
|
|
|
|
const emit = defineEmits<{
|
|
'onCurrentDayComponentFound': [component: HTMLElement | undefined];
|
|
}>();
|
|
|
|
const q = useQuasar();
|
|
const timesheetApi = useTimesheetApi();
|
|
const timesheetStore = useTimesheetStore();
|
|
|
|
const currentDayComponent = ref<HTMLElement[] | null>(null);
|
|
const currentDayComponentWatcher = ref(currentDayComponent);
|
|
const employeeEmail = inject<string>('employeeEmail');
|
|
|
|
// ========== computed ========================================
|
|
|
|
const timesheetRows = computed(() => {
|
|
if (timesheetStore.is_loading) return [];
|
|
const rows: TimesheetDayDisplay[][] = Array.from({ length: 7 }, () => []);
|
|
timesheetStore.timesheets.flatMap(timesheet => timesheet.days.forEach((day, index) => {
|
|
rows[index]!.push(new TimesheetDayDisplay(timesheet, day));
|
|
}));
|
|
|
|
return rows;
|
|
});
|
|
|
|
const isShowingWeeklyPresets = computed(() => timesheetStore.timesheets.some(
|
|
timesheet => timesheet.days.every(day => day.shifts.length < 1)
|
|
) && timesheetStore.has_timesheet_preset);
|
|
|
|
// ========== methods ========================================
|
|
|
|
const onClickApplyWeeklyPreset = async (timesheet_id: number) => {
|
|
await timesheetApi.applyPreset(timesheet_id, undefined, undefined, employeeEmail);
|
|
}
|
|
|
|
onMounted(async () => {
|
|
await timesheetStore.getCurrentFederalHolidays();
|
|
});
|
|
|
|
watch(currentDayComponentWatcher, () => {
|
|
if (currentDayComponent.value && q.platform.is.mobile) {
|
|
emit('onCurrentDayComponentFound', currentDayComponent.value[0])
|
|
}
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<div
|
|
:key="timesheetStore.is_loading ? 0 : 1"
|
|
class="fit column no-wrap q-pb-lg"
|
|
:class="$q.platform.is.mobile ? '' : ''"
|
|
>
|
|
<div
|
|
v-if="isShowingWeeklyPresets"
|
|
class="row flex-center q-py-xs"
|
|
>
|
|
<div
|
|
v-for="timesheet, timesheetIndex in timesheetStore.timesheets"
|
|
:key="timesheetIndex"
|
|
class="col row flex-center full-width"
|
|
>
|
|
<q-btn
|
|
:disable="!timesheet.days.every(day => day.shifts.length < 1)"
|
|
outline
|
|
dense
|
|
color="accent"
|
|
icon="schedule_send"
|
|
:label="$t('timesheet.apply_preset_week')"
|
|
class="text-uppercase text-weight-bold q-px-xl q-py-xs rounded-50"
|
|
:class="timesheet.days.every(day => day.shifts.length < 1) ? '' : 'invisible'"
|
|
@click="onClickApplyWeeklyPreset(timesheet.timesheet_id)"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<transition-group
|
|
appear
|
|
enter-active-class="animated fadeInDown"
|
|
>
|
|
<div
|
|
v-for="row, rowIndex of timesheetRows"
|
|
:key="JSON.stringify(row)"
|
|
class="col-auto row items-stretch"
|
|
:style="`animation-delay: ${rowIndex / 10}s;`"
|
|
>
|
|
<div
|
|
v-for="day, dayIndex in row"
|
|
:key="day.day.date"
|
|
class="col row items-stretch q-pa-sm relative-position"
|
|
:class="day.day.date === CURRENT_DATE_STRING ? 'bg-info rounded-15 shadow-6' : ''"
|
|
>
|
|
<ShiftListDay
|
|
v-model="row[dayIndex]!.day"
|
|
:week-day-index="dayIndex"
|
|
:timesheet-id="day.timesheetId"
|
|
:timesheet-approved="day.isTimesheetApproved"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</transition-group>
|
|
</div>
|
|
</template> |