150 lines
5.9 KiB
Vue
150 lines
5.9 KiB
Vue
<script
|
|
setup
|
|
lang="ts"
|
|
>
|
|
import { date } from 'quasar';
|
|
import { computed, ref } from 'vue';
|
|
import { unwrapAndClone } from 'src/utils/unwrap-and-clone';
|
|
import { deepEqual } from 'src/utils/deep-equal';
|
|
import { useExpensesApi } from 'src/modules/timesheets/composables/use-expense-api';
|
|
import { useExpensesStore } from 'src/stores/expense-store';
|
|
import { getExpenseIcon } from 'src/modules/timesheets/utils/expense.util';
|
|
import { Expense } from 'src/modules/timesheets/models/expense.models';
|
|
import ExpenseDialogFormMobile from 'src/modules/timesheets/components/mobile/expense-dialog-form-mobile.vue';
|
|
|
|
const { expense, horizontal = false } = defineProps<{
|
|
expense: Expense;
|
|
index: number;
|
|
horizontal?: boolean;
|
|
}>();
|
|
|
|
const expenses_store = useExpensesStore();
|
|
const expenses_api = useExpensesApi();
|
|
|
|
const refresh_key = ref(1);
|
|
const background_class = computed(() => deepEqual(expense, expenses_store.current_expense) ? '' : '');
|
|
const approved_class = computed(() => expense.is_approved ? ' bg-accent text-white' : '')
|
|
const is_showing_update_form = ref(false);
|
|
|
|
const requestExpenseDeletion = async () => {
|
|
await expenses_api.deleteExpenseById(expense.id);
|
|
}
|
|
|
|
const onUpdateClicked = () => {
|
|
if (expense.is_approved) return;
|
|
|
|
if (deepEqual(expense, expenses_store.current_expense)) {
|
|
expenses_store.mode = 'create';
|
|
expenses_store.current_expense = new Expense(date.formatDate(new Date(), 'YYYY-MM-DD'));
|
|
is_showing_update_form.value = false;
|
|
return;
|
|
}
|
|
|
|
expenses_store.mode = 'update';
|
|
expenses_store.current_expense = expense;
|
|
expenses_store.initial_expense = unwrapAndClone(expense);
|
|
is_showing_update_form.value = true;
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="column bg-dark rounded-5 q-my-sm full-width">
|
|
<q-slide-item
|
|
right-color="negative"
|
|
class="rounded-5 bg-dark full-width"
|
|
@right="requestExpenseDeletion"
|
|
>
|
|
<template
|
|
#right
|
|
v-if="$q.screen.lt.md && !expenses_store.is_hiding_create_form && !expense.is_approved"
|
|
>
|
|
<q-icon name="delete" />
|
|
</template>
|
|
|
|
<q-item
|
|
:key="refresh_key"
|
|
clickable
|
|
class="row q-py-none q-pa-xs rounded-5 full-width"
|
|
:class="background_class + approved_class"
|
|
@click="onUpdateClicked"
|
|
>
|
|
<div class="column col">
|
|
<!-- date label -->
|
|
<div class="col-auto row items-center q-pl-xs">
|
|
<q-icon
|
|
name="calendar_month"
|
|
size="sm"
|
|
class="col-auto"
|
|
/>
|
|
|
|
<span
|
|
class="col text-uppercase text-weight-light full-width q-pl-sm text-h6"
|
|
:class="approved_class"
|
|
>
|
|
{{ $d(
|
|
date.extractDate(expense.date, 'YYYY-MM-DD'),
|
|
{ month: 'long', day: 'numeric' }
|
|
) }}
|
|
</span>
|
|
</div>
|
|
|
|
<div class="col row full-width items-center">
|
|
<!-- avatar type icon section -->
|
|
<q-icon
|
|
:name="getExpenseIcon(expense.type)"
|
|
:color="expense.is_approved ? 'white' : ($q.dark.isActive ? 'white' : 'primary')"
|
|
size="lg"
|
|
/>
|
|
|
|
<!-- amount or mileage section -->
|
|
<q-item-section class="col text-weight-bold text-h6">
|
|
<q-item-label v-if="expense.type === 'MILEAGE'">
|
|
{{ expense.mileage?.toFixed(1) }} km
|
|
</q-item-label>
|
|
<q-item-label v-else>
|
|
$ {{ expense.amount.toFixed(2) }}
|
|
</q-item-label>
|
|
</q-item-section>
|
|
|
|
<q-space v-if="horizontal" />
|
|
|
|
<!-- attachment file icon -->
|
|
<q-item-section avatar>
|
|
<q-btn
|
|
push
|
|
:color="expense.is_approved ? 'white' : 'accent'"
|
|
:text-color="expense.is_approved ? 'accent' : 'white'"
|
|
class="col-auto q-mx-sm q-px-sm q-pb-sm"
|
|
icon="attach_file"
|
|
/>
|
|
</q-item-section>
|
|
</div>
|
|
</div>
|
|
|
|
<div
|
|
class="col-auto q-px-sm"
|
|
:class="expense.is_approved ? '' : 'invisible'"
|
|
>
|
|
<q-icon
|
|
v-if="expense.is_approved"
|
|
name="verified"
|
|
color="white"
|
|
size="lg"
|
|
class="full-height"
|
|
/>
|
|
</div>
|
|
</q-item>
|
|
</q-slide-item>
|
|
|
|
<q-slide-transition
|
|
@hide="expenses_store.is_hiding_create_form = false"
|
|
:duration="200"
|
|
>
|
|
<ExpenseDialogFormMobile
|
|
v-if="is_showing_update_form && expenses_store.is_hiding_create_form"
|
|
class="q-mt-sm q-pa-sm"
|
|
@on-click-update-cancel="onUpdateClicked"
|
|
/>
|
|
</q-slide-transition>
|
|
</div>
|
|
</template> |