148 lines
4 KiB
Vue
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>
|