feat: implement functionality to filter request list by same office area
Some checks failed
Spell Check / Spell Check with Typos (push) Failing after 10s

This commit is contained in:
puriphatt 2025-04-17 15:35:13 +07:00
parent 550ed55de0
commit d95d72806d
3 changed files with 80 additions and 9 deletions

View file

@ -1,5 +1,5 @@
<script setup lang="ts">
import { reactive, ref } from 'vue';
import { reactive, ref, watch } from 'vue';
import { RequestData } from 'src/stores/request-list';
import { DialogContainer, DialogHeader } from 'src/components/dialog';
import {
@ -8,12 +8,11 @@ import {
MainButton,
SaveButton,
} from 'src/components/button';
import TableProductAndService from 'src/components/shared/table/TableProductAndService.vue';
import { Product } from 'src/stores/product-service/types';
import FormResponsibleUser from './FormResponsibleUser.vue';
import FormGroupHead from './FormGroupHead.vue';
import TableRequestList from './TableRequestList.vue';
import { column } from './constants';
import useAddressStore from 'src/stores/address';
defineProps<{
requestList: RequestData[];
@ -37,6 +36,7 @@ enum Step {
const open = defineModel<boolean>({ default: false });
const step = ref<Step>(Step.RequestList);
const selected = ref<RequestData[]>([]);
const listSameArea = ref<string[]>([]);
const form = reactive({
responsibleUserLocal: false,
responsibleUserId: '',
@ -51,8 +51,18 @@ function reset() {
function prev() {
step.value = Step.RequestList;
console.log(selected.value[0]);
}
watch(
() => selected.value,
async () => {
if (selected.value.length === 1) {
const districtId = selected.value[0].quotation.customerBranch.districtId;
const ret = await useAddressStore().listSameOfficeArea(districtId);
if (ret) listSameArea.value = ret;
}
},
);
</script>
<template>
<DialogContainer v-model="open" :onOpen="reset">
@ -89,6 +99,7 @@ function prev() {
hide-action
hide-view
checkable
:list-same-area="listSameArea"
:columns="column"
:rows="requestList"
:visible-columns="[...column.map((col) => col.name)]"
@ -116,6 +127,7 @@ function prev() {
</FormGroupHead>
<FormResponsibleUser
:district-id="listSameArea[0]"
v-model:responsible-user-id="form.responsibleUserId"
v-model:responsible-user-local="form.responsibleUserLocal"
/>

View file

@ -24,6 +24,7 @@ const props = withDefaults(
hideAction?: boolean;
hideView?: boolean;
checkable?: boolean;
listSameArea?: string[];
}>(),
{
row: () => [],
@ -39,7 +40,7 @@ defineEmits<{
(e: 'rejectCancel', data: RequestData): void;
}>();
const selected = defineModel<unknown[]>('selected');
const selected = defineModel<RequestData[]>('selected');
function responsiblePerson(quotation: QuotationFull): CreatedBy[] | undefined {
const productServiceList = quotation.productServiceList;
@ -97,7 +98,7 @@ function getEmployeeName(
return (
{
['eng']: `${useOptionStore().mapOption(employee?.namePrefix || '')} ${employee?.firstNameEN} ${employee?.lastNameEN}`,
['tha']: `${useOptionStore().mapOption(employee?.namePrefix || '')} ${employee?.firstName} ${employee?.lastName}`,
['tha']: `${useOptionStore().mapOption(employee?.namePrefix || '')} ${employee?.firstName || employee?.firstNameEN} ${employee?.lastName || employee?.lastNameEN}`,
}[opts?.locale || 'eng'] || '-'
);
}
@ -119,6 +120,17 @@ function toEmployee(employee: RequestData['employee']) {
window.open(url.toString(), '_blank');
}
function handleCheckAll() {
const filteredRows = props.rows.filter((row) =>
props.listSameArea?.includes(row.quotation.customerBranch.districtId),
);
if (selected.value.length === filteredRows.length) {
selected.value = [];
} else {
selected.value = filteredRows;
}
}
</script>
<template>
<q-table
@ -146,7 +158,18 @@ function toEmployee(employee: RequestData['employee']) {
:props="props"
>
<q-th v-if="checkable">
<q-checkbox v-model="props.selected" size="sm" />
<q-checkbox
v-if="selected.length > 0"
:model-value="
selected.length ===
rows.filter((row) =>
listSameArea?.includes(row.quotation.customerBranch.districtId),
).length
"
size="sm"
@click="handleCheckAll"
/>
<div v-else style="width: 35px; height: 35px"></div>
</q-th>
<q-th v-for="col in props.cols" :key="col.name" :props="props">
{{ col.label && $t(col.label) }}
@ -161,11 +184,29 @@ function toEmployee(employee: RequestData['employee']) {
} & Omit<Parameters<QTableSlots['body']>[0], 'row'>"
>
<q-tr
:class="{ urgent: props.row.quotation.urgent, dark: $q.dark.isActive }"
:class="{
urgent: props.row.quotation.urgent,
dark: $q.dark.isActive,
'disabled-row':
selected &&
selected.length > 0 &&
!listSameArea.includes(
props.row.quotation.customerBranch.districtId,
),
}"
class="text-center"
>
<q-td v-if="checkable">
<q-checkbox v-model="props.selected" size="sm" />
<q-checkbox
:disable="
selected.length > 0 &&
!listSameArea.includes(
props.row.quotation.customerBranch.districtId,
)
"
v-model="props.selected"
size="sm"
/>
</q-td>
<q-td v-if="visibleColumns.includes('order')">
{{ props.rowIndex + 1 }}
@ -487,4 +528,9 @@ function toEmployee(employee: RequestData['employee']) {
text-decoration: underline;
cursor: pointer;
}
.disabled-row {
opacity: 0.3;
filter: grayscale(1);
}
</style>

View file

@ -102,12 +102,25 @@ const useAddressStore = defineStore('api-address', () => {
return subDistrict.value[districtId];
}
async function listSameOfficeArea(districtId: string) {
const res = await api.post<string[]>(
`/employment-office/list-same-office-area`,
{ districtId: districtId },
);
if (!res) return false;
return res.data;
}
return {
fetchOffice,
fetchOfficeById,
fetchProvince,
fetchDistrictByProvinceId,
fetchSubDistrictByProvinceId,
listSameOfficeArea,
};
});