jws-frontend/src/components/05_quotation/TableQuotation.vue
2024-12-02 10:38:28 +07:00

201 lines
5.3 KiB
Vue

<script lang="ts" setup>
import { QTableProps } from 'quasar';
import { dateFormat } from 'src/utils/datetime';
import { formatNumberDecimal, commaInput } from 'stores/utils';
import BadgeComponent from 'components/BadgeComponent.vue';
import KebabAction from 'components/shared/KebabAction.vue';
import { hslaColors } from 'src/pages/05_quotation/constants';
const props = withDefaults(
defineProps<{
rows: QTableProps['rows'];
columns: QTableProps['columns'];
grid?: boolean;
visibleColumns?: string[];
hideEdit?: boolean;
}>(),
{
row: () => [],
column: () => [],
grid: false,
visibleColumns: () => [],
},
);
function payCondition(value: string) {
if (value === 'Full') return 'quotation.type.fullAmountCash';
if (value === 'Split') return 'quotation.type.installmentsCash';
if (value === 'SplitCustom') return 'quotation.type.installmentsCustomCash';
return '';
}
function quotationStatus(value: string) {
if (value === 'Issued') return 'quotation.status.Issued';
if (value === 'Accepted') return 'quotation.status.Accepted';
if (value === 'Expired') return 'quotation.status.Expired';
if (value === 'PaymentInProcess') return 'quotation.status.Invoice';
if (value === 'PaymentSuccess') return 'quotation.status.PaymentSuccess';
if (value === 'ProcessComplete') return 'quotation.status.ProcessComplete';
return '';
}
defineEmits<{
(e: 'preview', data: any): void;
(e: 'view', data: any): void;
(e: 'edit', data: any): void;
(e: 'delete', data: any): void;
}>();
</script>
<template>
<q-table
v-bind="props"
flat
hide-pagination
card-container-class="q-col-gutter-sm"
:rows-per-page-options="[0]"
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 props.cols" :key="col.name" :props="props">
{{ col.label && $t(col.label) }}
</q-th>
</q-tr>
</template>
<template v-slot:body="props">
<q-tr :class="{ urgent: props.row.urgent }">
<q-td v-if="visibleColumns.includes('order')">
{{ props.rowIndex + 1 }}
</q-td>
<q-td v-if="visibleColumns.includes('workName')">
<div class="column">
<div class="col-6">{{ props.row.workName }}</div>
<div class="col-6 app-text-muted">{{ props.row.code }}</div>
</div>
</q-td>
<q-td v-if="visibleColumns.includes('createdAt')">
{{ dateFormat(props.row.createdAt) }}
</q-td>
<q-td v-if="visibleColumns.includes('dueDate')">
{{ dateFormat(props.row.dueDate) }}
</q-td>
<q-td v-if="visibleColumns.includes('contactName')">
{{ props.row.contactName }}
</q-td>
<q-td v-if="visibleColumns.includes('actor')">
{{ props.row.createdBy.firstName }}
</q-td>
<q-td v-if="visibleColumns.includes('summaryPrice')">
{{ formatNumberDecimal(props.row.finalPrice, 2) }}
</q-td>
<q-td v-if="visibleColumns.includes('payCondition')">
{{ $t(payCondition(props.row.payCondition)) }}
</q-td>
<q-td v-if="visibleColumns.includes('status')">
<div class="row" style="min-width: 150px">
<BadgeComponent
:title="$t(quotationStatus(props.row.quotationStatus))"
:hsla-color="hslaColors[props.row.quotationStatus] || ''"
/>
<div v-if="props.row.urgent" class="q-ml-sm" style="font-size: 90%">
<BadgeComponent
icon="mdi-fire"
:title="$t('general.urgent2')"
hsla-color="--gray-1-hsl"
hsla-background="--red-8-hsl"
solid
/>
</div>
</div>
</q-td>
<q-td class="text-right">
<q-btn
:id="`btn-eye-${props.row.firstName}`"
icon="mdi-play-box-outline"
size="sm"
dense
round
flat
@click.stop="$emit('preview', props.row.id)"
/>
<q-btn
:id="`btn-eye-${props.row.firstName}`"
icon="mdi-eye-outline"
size="sm"
dense
round
flat
@click.stop="$emit('view', props.row)"
/>
<KebabAction
:idName="`btn-kebab-${props.row.firstName}`"
status="'ACTIVE'"
hide-toggle
:hide-edit="hideEdit"
@view="$emit('view', props.row)"
@edit="$emit('edit', props.row)"
@delete="$emit('delete', props.row.id)"
/>
</q-td>
</q-tr>
</template>
<template v-slot:item="props">
<slot name="grid" :item="props" />
</template>
</q-table>
</template>
<style scoped>
.q-table tr.urgent {
background: hsla(var(--red-6-hsl) / 0.03);
}
.q-table tr.urgent td:first-child {
&::after {
content: ' ';
display: block;
position: absolute;
left: 0;
top: 15%;
bottom: 15%;
background: var(--red-8);
width: 4px;
border-radius: 99rem;
animation: blink 1s infinite;
}
}
@keyframes blink {
0% {
background: var(--red-8);
}
50% {
background: var(--red-3);
}
100% {
background: var(--red-8);
}
}
</style>