targo-frontend/src/modules/timesheets/components/expense-dialog-list-item.vue

217 lines
8.5 KiB
Vue

<script
setup
lang="ts"
>
import ExpenseDialogForm from 'src/modules/timesheets/components/expense-dialog-form.vue';
import { ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { date, Notify } from 'quasar';
import { unwrapAndClone } from 'src/utils/unwrap-and-clone';
import { useExpensesStore } from 'src/stores/expense-store';
import { useTimesheetStore } from 'src/stores/timesheet-store';
import { useExpensesApi } from 'src/modules/timesheets/composables/use-expense-api';
import { getExpenseIcon } from 'src/modules/timesheets/utils/expense.util';
import type { Expense } from 'src/modules/timesheets/models/expense.models';
const { t } = useI18n();
const expense = defineModel<Expense>({ required: true });
const expenses_api = useExpensesApi();
const expenses_store = useExpensesStore();
const timesheet_store = useTimesheetStore();
const is_showing_update_form = ref(false);
const { mode = 'normal' } = defineProps<{
mode?: 'approval' | 'normal';
}>();
const requestExpenseDeletion = async () => {
await expenses_api.deleteExpenseById(expense.value.id);
}
const onClickExpenseUpdate = () => {
if (expense.value.is_approved) return;
expenses_store.mode = 'update';
expenses_store.current_expense = expense.value;
expenses_store.initial_expense = unwrapAndClone(expense.value);
}
const onClickApproval = async () => {
expenses_store.current_expense = unwrapAndClone(expense.value);
expenses_store.current_expense.is_approved = !expenses_store.current_expense.is_approved;
const success = await expenses_store.upsertExpense(expenses_store.current_expense, timesheet_store.current_pay_period_overview?.email);
if (success) {
expense.value.is_approved = !expense.value.is_approved;
} else {
expenses_store.current_expense.is_approved = !expenses_store.current_expense.is_approved;
Notify.create({
message: t('timesheet.errors.UPDATE_ERROR'),
color: "negative"
});
}
}
</script>
<template>
<q-expansion-item
v-model="is_showing_update_form"
hide-expand-icon
dense
group="expenses"
class="shadow-3 rounded-5 bg-dark q-my-sm"
:class="expense.is_approved ? ' bg-accent text-white' : ''"
@before-show="onClickExpenseUpdate()"
>
<template #header>
<div class="col row items-center full-width">
<!-- avatar type icon section -->
<div class="col-auto">
<q-icon
:name="getExpenseIcon(expense.type)"
:color="expense.is_approved ? 'white' : ($q.dark.isActive ? 'white' : 'blue-grey-8')"
size="lg"
class="q-pr-md"
/>
<q-tooltip
anchor="top middle"
self="center middle"
:offset="[0, 20]"
class="bg-accent text-uppercase text-weight-bold"
>
{{ $t(`timesheet.expense.types.${expense.type}`) }}
</q-tooltip>
</div>
<!-- amount or mileage section -->
<div class="col column">
<span
class="text-weight-bolder"
:class="expense.is_approved ? ' bg-accent text-white' : ''"
style="font-size: 1.3em;"
>
{{ expense.type === 'MILEAGE' ? `${Number(expense.mileage).toFixed(1)} km` : `$
${Number(expense.amount).toFixed(2)}` }}
</span>
<!-- date label -->
<span
class="text-uppercase text-weight-light text-caption"
:class="expense.is_approved ? ' bg-accent text-white' : ''"
>
{{ $d(date.extractDate(expense.date, 'YYYY-MM-DD'), {
month: 'short', day: 'numeric', weekday:
'long'
}) }}
</span>
</div>
<!-- attachment file icon -->
<div class="col row items-center justify-start">
<q-btn
push
:color="expense.is_approved ? 'white' : 'accent'"
:text-color="expense.is_approved ? 'accent' : 'white'"
class="col-auto q-px-sm q-mr-sm"
icon="attach_file"
/>
<q-item-label class="col">
attachment_name.jpg
</q-item-label>
</div>
<!-- comment section -->
<div class="col column no-wrap">
<span class="col-auto text-weight-bold text-accent text-uppercase text-caption">
{{ $t('timesheet.expense.employee_comment') }}
</span>
<span
class="col ellipsis"
:class="expense.is_approved ? ' bg-accent text-white' : ''"
style="font-size: 1em;"
>
{{ expense.comment }}
</span>
<q-tooltip
anchor="top middle"
self="center middle"
:offset="[0, 20]"
class="bg-accent text-uppercase text-weight-bold"
>
{{ expense.comment }}
</q-tooltip>
</div>
<!-- supervisor comment section -->
<div
v-if="expense.supervisor_comment"
class="col column"
>
<span class="col-auto text-weight-bold text-accent text-uppercase text-caption">
{{ $t('timesheet.expense.supervisor_comment') }}
</span>
<span
class="col"
:class="expense.is_approved ? ' bg-accent text-white' : ''"
style="font-size: 1.3em;"
>
{{ expense.supervisor_comment }}
</span>
</div>
<div class="col-auto">
<q-btn
v-if="mode === 'approval'"
flat
size="lg"
:icon="expense.is_approved ? 'lock' : 'lock_open'"
:color="expense.is_approved ? 'white' : 'accent'"
class="relative-position"
@click.stop="onClickApproval"
>
<q-tooltip
anchor="top middle"
self="center middle"
:offset="[0, 20]"
class="bg-accent text-uppercase text-weight-bold"
>
{{ expense.is_approved ? $t('timesheet_approvals.tooltip.unapprove') :
$t('timesheet_approvals.tooltip.approve') }}
</q-tooltip>
</q-btn>
<q-icon
v-if="expense.is_approved"
name="verified"
color="white"
size="2.5em"
class="q-px-sm"
/>
<q-btn
v-else-if="!expense.is_approved && mode === 'normal'"
flat
dense
size="lg"
icon="close"
color="negative"
class="q-py-xs q-px-sm"
@click.stop="requestExpenseDeletion"
/>
</div>
</div>
</template>
<ExpenseDialogForm v-model="expense" />
</q-expansion-item>
</template>