refactor: workerIndex

This commit is contained in:
puriphatt 2024-10-10 17:49:28 +07:00
parent 85b108a9b2
commit 7760f0f15a
4 changed files with 88 additions and 12 deletions

View file

@ -1,7 +1,6 @@
<script lang="ts" setup>
import { computed, onMounted, ref, watch } from 'vue';
import { computed, ref, watch } from 'vue';
import { QTableProps } from 'quasar';
import ThaiBahtText from 'thai-baht-text';
import { toWords } from 'number-to-words';
import { storeToRefs } from 'pinia';
@ -9,14 +8,12 @@ import WorkerItem from './WorkerItem.vue';
import DeleteButton from '../button/DeleteButton.vue';
import { commaInput } from 'stores/utils';
import { precisionRound } from 'src/utils/arithmetic';
import TableComponents from 'components/TableComponents.vue';
import { QuotationPayload } from 'stores/quotations/types';
import { formatNumberDecimal } from 'stores/utils';
import { useConfigStore } from 'stores/config';
import { Product, Service, Work } from 'src/stores/product-service/types';
import { read } from 'fs';
defineProps<{
const props = defineProps<{
readonly?: boolean;
agentPrice: boolean;
employeeRows?: {
@ -250,10 +247,22 @@ function groupByServiceId() {
groupList.value = groupedItems;
}
function handleCheck(
index: number,
data: QuotationPayload['productServiceList'][number],
) {
const target = data.workerIndex.indexOf(index);
if (target > -1) {
data.workerIndex.splice(target, 1);
} else {
data.workerIndex.push(index);
}
}
watch(
() => rows.value,
() => {
groupByServiceId();
if (rows.value.length > 0) groupByServiceId();
},
);
@ -263,6 +272,19 @@ watch(
summaryPrice.value = summary.value;
},
);
watch(
() => props.employeeRows,
(a, b) => {
if (a === undefined || b === undefined) return;
if (a.length < b.length) {
rows.value.forEach((p) => {
const maxValue = Math.max(...p.workerIndex);
p.workerIndex = p.workerIndex.filter((i) => i !== maxValue);
});
}
},
);
</script>
<template>
<div class="column">
@ -278,7 +300,7 @@ watch(
style="background: var(--orange-5); color: var(--surface-1)"
size="sm"
>
{{ i + 1 }}
<q-icon size="xs" name="mdi-server-outline" />
</q-avatar>
{{ item.title }}
</div>
@ -419,9 +441,12 @@ watch(
>
<q-td colspan="100%" style="padding: 16px">
<WorkerItem
@check="(wokerIndex) => handleCheck(wokerIndex, props.row)"
checkable
fallback-img="/images/employee-avatar.png"
inTable
hideQuantity
:check-list="props.row.workerIndex"
:rows="employeeRows"
/>
</q-td>

View file

@ -1,9 +1,11 @@
<script lang="ts" setup>
import { QTableProps } from 'quasar';
import TableComponents from 'src/components/TableComponents.vue';
import { onMounted } from 'vue';
defineEmits<{
(e: 'delete', index: number): void;
(e: 'check', index: number): void;
}>();
withDefaults(
@ -12,6 +14,7 @@ withDefaults(
employeeAmount?: number;
fallbackImg?: string;
hideQuantity?: boolean;
checkable?: boolean;
inTable?: boolean;
rows: {
foreignRefNo: string;
@ -31,6 +34,8 @@ withDefaults(
},
);
const checkList = defineModel<number[]>('checkList', { default: [] });
const columns = [
{
name: 'order',
@ -87,13 +92,26 @@ const columns = [
<TableComponents
flat
bordered
button-delete
:button-delete="!checkable"
img-column="employeeName"
:readonly="readonly"
:inTable
:columns
:columns="
checkable
? [
{
name: 'check',
align: 'center',
label: '',
field: 'check',
},
...columns.filter((c) => c.name !== 'action'),
]
: columns
"
:rows
hidePagination
:customColumn="['check']"
@delete="(i) => $emit('delete', i)"
>
<template v-slot:img-column="{ props }">
@ -121,6 +139,20 @@ const columns = [
</div>
</q-avatar>
</template>
<template v-slot:body-cell-check="{ props }">
<q-td class="text-center">
<q-checkbox
size="xs"
@click.stop="
() => {
$emit('check', props.rowIndex);
}
"
:model-value="checkList.includes(props.rowIndex)"
></q-checkbox>
</q-td>
</template>
</TableComponents>
<div v-if="!hideQuantity" class="row q-pt-md items-center">

View file

@ -222,6 +222,7 @@ function mapNode() {
detail: p.product.detail,
remark: p.product.remark,
value: {
workerIndex: [],
vat: 0,
pricePerUnit,
discount: 0,
@ -258,6 +259,7 @@ function mapNode() {
subtitle: p.product.code || ' ',
checked: true,
value: {
workerIndex: [],
vat: 0,
pricePerUnit,
discount: 0,
@ -282,6 +284,7 @@ function mapNode() {
title: v.name,
subtitle: v.code,
value: {
workerIndex: [],
vat: 0,
pricePerUnit,
discount: 0,

View file

@ -52,7 +52,13 @@ import ToggleButton from 'components/button/ToggleButton.vue';
import FormAbout from 'components/05_quotation/FormAbout.vue';
import SelectZone from 'components/shared/SelectZone.vue';
import PersonCard from 'components/shared/PersonCard.vue';
import { AddButton, SaveButton, EditButton } from 'components/button';
import {
AddButton,
SaveButton,
EditButton,
UndoButton,
DeleteButton,
} from 'components/button';
import ProductServiceForm from './ProductServiceForm.vue';
import QuotationFormInfo from './QuotationFormInfo.vue';
import ProfileBanner from 'components/ProfileBanner.vue';
@ -250,7 +256,7 @@ async function assignToProductServiceList() {
}),
);
selectedProductGroup.value =
quotationFormData.value.productServiceList[0].product.productGroup?.id ||
quotationFormData.value.productServiceList[0]?.product.productGroup?.id ||
'';
}
}
@ -424,6 +430,9 @@ function convertToTable(nodes: Node[]) {
list.forEach((v) => {
v.amount = Math.max(selectedWorker.value.length, 1);
for (let i = 0; i < selectedWorker.value.length; i++) {
v.workerIndex.push(i);
}
});
productServiceList.value = list;
@ -437,6 +446,14 @@ function convertEmployeeToTable() {
v.amount + preSelectedWorker.value.length - selectedWorker.value.length,
1,
);
for (
let i = 0;
i < preSelectedWorker.value.length - selectedWorker.value.length;
i++
) {
v.workerIndex.push(selectedWorker.value.length + i);
}
return v;
});
refSelectZoneEmployee.value?.assignSelect(
@ -715,7 +732,6 @@ watch(
productGroup.find((g) => g.id === selectedProductGroup)
?.name || '-'
}}
<q-icon name="mdi-chevron-right" class="q-pl-sm" size="xs" />
</span>
<ProductItem