jws-frontend/src/pages/10_invoice/TableInvoice.vue
Thanaphon Frappet 87de5b48ac
Some checks failed
Spell Check / Spell Check with Typos (push) Failing after 8s
fix: installment force push
2025-03-06 11:14:11 +07:00

148 lines
4 KiB
Vue

<script setup lang="ts" generic="T">
import { QTableSlots } from 'quasar';
import { columns } from './constants';
import BadgeComponent from 'src/components/BadgeComponent.vue';
import { Invoice, PaymentDataStatus } from 'src/stores/payment/types';
import { ViewButton } from 'components/button';
import { useInvoice } from 'src/stores/payment';
const invoiceStore = useInvoice();
withDefaults(
defineProps<{
rows: T[];
readonly?: boolean;
flat?: boolean;
bordered?: boolean;
grid?: boolean;
hideHeader?: boolean;
buttonDownload?: boolean;
buttonDelete?: boolean;
hidePagination?: boolean;
inTable?: boolean;
hideView?: boolean;
btnSelected?: boolean;
imgColumn?: string;
customColumn?: string[];
}>(),
{
row: () => [],
flat: false,
bordered: false,
grid: false,
hideHeader: false,
buttonDownload: false,
imgColumn: '',
customColumn: () => [],
},
);
defineEmits<{
(e: 'view', id: string): void;
(e: 'preview', data: Invoice): void;
(e: 'edit', data: T, index: number): void;
(e: 'delete', data: T, index: number): void;
(e: 'download', data: T, index: number): void;
}>();
</script>
<template>
<q-table
:rows-per-page-options="[0]"
:rows="rows.map((data, i) => ({ ...data, _index: i }))"
:columns
:grid
hide-bottom
bordered
flat
hide-pagination
selection="multiple"
card-container-class="q-col-gutter-sm"
class="full-width"
>
<template v-slot:header="props">
<q-tr
style="background-color: hsla(var(--info-bg) / 0.07)"
:props="props"
>
<q-th v-for="col in columns" :key="col.name" :props="props">
{{ $t(col.label) }}
</q-th>
</q-tr>
</template>
<template
v-slot:body="props: {
row: Invoice & { _index: number };
} & Omit<Parameters<QTableSlots['body']>[0], 'row'>"
>
<q-tr :class="{ dark: $q.dark.isActive }" class="text-center">
<q-td v-for="col in columns" :align="col.align" :key="col.name">
<!-- NOTE: custom column will starts with # -->
<template v-if="!col.name.startsWith('#')">
<span>
{{
typeof col.field === 'string'
? props.row[col.field as keyof Invoice]
: col.field(props.row)
}}
</span>
</template>
<template v-if="col.name === '#order'">
{{
$q.screen.xs
? props.rowIndex + 1
: col.field(props.row) +
(invoiceStore.page - 1) * invoiceStore.pageSize
}}
</template>
<template v-if="col.name === '#status'">
<BadgeComponent
:hsla-color="
{
[PaymentDataStatus.Success]: '--green-8-hsl',
[PaymentDataStatus.Wait]: '--orange-5-hsl',
}[props.row.payment.paymentStatus]
"
:title="$t(`invoice.status.${props.row.payment.paymentStatus}`)"
/>
</template>
<template v-if="col.name === '#action'">
<q-btn
:id="`btn-preview-${props.row.quotation.workName}`"
flat
dense
rounded
icon="mdi-play-box-outline"
size="12px"
:title="$t('preview.doc')"
@click.stop="$emit('preview', props.row)"
/>
<q-btn
:id="`btn-eye-${props.row.quotation.workName}`"
icon="mdi-eye-outline"
size="sm"
dense
round
flat
@click.stop="$emit('view', props.row.quotation.id)"
/>
</template>
</q-td>
</q-tr>
</template>
<template v-slot:item="props: { row: Invoice }">
<slot name="grid" :item="props" />
</template>
</q-table>
</template>
<style lang="scss" scoped>
:deep(i.q-icon.mdi.mdi-alert.q-table__bottom-nodata-icon) {
color: #ffc224 !important;
}
</style>