targo-frontend/src/modules/timesheets/pages/timesheet-details-overview.vue

188 lines
7.9 KiB
Vue

<script setup lang="ts">
import { date } from 'quasar';
import { computed, onMounted } from 'vue';
import { useI18n } from 'vue-i18n';
import { useAuthStore } from 'src/stores/auth-store';
import { useExpensesStore } from 'src/stores/expense-store';
import { useShiftStore } from 'src/stores/shift-store';
import { useTimesheetStore } from 'src/stores/timesheet-store';
import { useTimesheetApi } from '../composables/api/use-timesheet-api';
import { buildShiftOptions } from '../utils/shift.util';
import { formatPayPeriodLabel } from '../utils/timesheet-format.util';
import TimesheetNavigation from '../components/timesheet/timesheet-navigation.vue';
import ShiftsLegend from '../components/shift/shifts-legend.vue';
import ShiftCrudDialog from '../components/shift/shift-crud-dialog.vue';
import TimesheetDetailsExpenses from '../components/expenses/timesheet-details-expenses.vue';
import { SHIFT_KEY } from '../types/shift.types';
import type { TimesheetExpense } from '../types/expense.interfaces';
import DetailedShiftList from '../components/shift/detailed-shift-list.vue';
/* eslint-disable */
//------------------- stores -------------------
const { locale, t } = useI18n();
const auth_store = useAuthStore();
const expenses_store = useExpensesStore();
const shift_store = useShiftStore();
const timesheet_store = useTimesheetStore();
const timesheet_api = useTimesheetApi();
//------------------- expenses -------------------
const openExpensesDialog = () => expenses_store.openDialog({
email: auth_store.user.email,
pay_year: timesheet_store.current_pay_period.pay_year,
pay_period_no: timesheet_store.current_pay_period.pay_period_no,
t,
});
const onSaveExpenses = async ( payload: { email: string; pay_year: number; pay_period_no: number; expenses: TimesheetExpense[] }) => {
await expenses_store.saveExpenses({...payload, t});
await timesheet_store.refreshCurrentPeriodForUser(auth_store.user.email);
};
const onCloseExpenses = () => expenses_store.closeDialog();
//------------------- pay-period format label -------------------
const date_options: Intl.DateTimeFormatOptions = { day: 'numeric', month: 'long', year: 'numeric' };
const pay_period_label = computed(() => formatPayPeriodLabel(
timesheet_store.current_pay_period?.label,
locale.value,
date.extractDate,
date_options
)
);
//------------------- q-select Shift options -------------------
const shift_options = computed(() => buildShiftOptions(SHIFT_KEY, t));
//------------------- navigation by date -------------------
const onDateSelected = async (date_string: string) => {
await timesheet_store.loadByIsoDate(date_string, auth_store.user.email);
};
onMounted(async () => {
await timesheet_store.loadToday(auth_store.user.email);
});
// ------------------- shifts -------------------
const onRequestAdd = ({ date }: { date: string }) => shift_store.openCreate(date);
const onRequestEdit = ({ date, shift }: { date: string; shift: any }) => shift_store.openEdit(date, shift);
const onRequestDelete = async ({ date, shift }: { date: string; shift: any }) => shift_store.openDelete(date, shift);
const onShiftSaved = async () => {
await timesheet_store.refreshCurrentPeriodForUser(auth_store.user.email);
};
</script>
<template>
<q-page padding class="q-pa-md bg-secondary" >
<!-- title and dates -->
<div class="text-h4 row justify-center text-center q-mt-lg text-uppercase text-weight-bolder text-grey-8">
{{ $t('timesheet.title') }}
</div>
<div class="row items-center justify-center q-py-none q-my-none">
<div
class="text-primary text-uppercase text-weight-bold"
:class="$q.screen.lt.md ? '' : 'text-h6'"
>
{{ pay_period_label.start_date }}
</div>
<div
class="text-grey-8 text-uppercase q-mx-md"
:class="$q.screen.lt.md ? 'text-weight-medium text-caption' : 'text-weight-bold'"
>
{{ $t('timesheet.date_ranges_to') }}
</div>
<div
class="text-primary text-uppercase text-center text-weight-bold"
:class="$q.screen.lt.md ? '' : 'text-h6'"
>
{{ pay_period_label.end_date }}
</div>
</div>
<div>
<q-card flat class=" col q-mt-md bg-secondary">
<!-- navigation btn -->
<q-card-section horizontal>
<q-btn
color="primary"
unelevated
icon="receipt_long"
:label="$t('timesheet.expense.open_btn')"
@click="openExpensesDialog"
/>
</q-card-section>
<q-card-section class="row items-center justify-between q-px-md q-pb-none">
<TimesheetNavigation
:is-disabled="timesheet_store.is_loading"
:is-previous-limit="timesheet_store.is_calendar_limit"
@date-selected="onDateSelected"
@pressed-previous-button="timesheet_api.getPreviousPeriodForUser(auth_store.user.email)"
@pressed-next-button="timesheet_api.getNextPeriodForUser(auth_store.user.email)"
/>
</q-card-section>
<!-- shift's colored legend -->
<ShiftsLegend
:is-loading="false"
/>
<q-card-section horizontal>
<!-- display of shifts for 2 timesheets -->
<DetailedShiftList
:raw-data="timesheet_store.pay_period_employee_details"
:current-pay-period="timesheet_store.current_pay_period"
@request-add="onRequestAdd"
@request-edit="onRequestEdit"
@request-delete="onRequestDelete"
/>
<q-inner-loading :showing="timesheet_store.is_loading" color="primary"/>
</q-card-section>
</q-card>
</div>
<!-- read/edit/create/delete expense dialog -->
<q-dialog
v-model="expenses_store.is_dialog_open"
persistent
>
<q-card
class="q-pa-md column"
style=" min-width: 70vw;"
>
<q-inner-loading :showing="expenses_store.is_loading">
<q-spinner size="32px"/>
</q-inner-loading>
<!-- <q-banner
v-if="expenses_error"
dense
class="bg-red-2 col-auto text-negative q-mt-sm"
>
{{ expenses_error }}
</q-banner> -->
<TimesheetDetailsExpenses
v-if="expenses_store.data"
:pay_period_no="expenses_store.data.pay_period_no"
:pay_year="expenses_store.data.pay_year"
:email="expenses_store.data.employee_email"
:is_approved="expenses_store.data.is_approved"
:initial_expenses="expenses_store.data.expenses"
@save="onSaveExpenses"
@close="onCloseExpenses"
@error=" "
/>
</q-card>
</q-dialog>
<!-- shift crud dialog -->
<ShiftCrudDialog
v-model="shift_store.is_open"
:mode="shift_store.mode"
:date-iso="shift_store.date_iso"
:email="auth_store.user.email"
:initial-shift="shift_store.initial_shift"
:shift-options="shift_options"
@close="shift_store.close"
@saved="onShiftSaved"
/>
</q-page>
</template>