refactor: show mode list

This commit is contained in:
Thanaphon Frappet 2025-01-27 15:20:02 +07:00
parent 18d0aca1de
commit a4bc6e4884
2 changed files with 118 additions and 169 deletions

View file

@ -23,6 +23,8 @@ import PersonCard from 'src/components/shared/PersonCard.vue';
import { QuotationFull } from 'src/stores/quotations/types';
import { Lang } from 'src/utils/ui';
import NoData from 'src/components/NoData.vue';
import TableWorker from 'src/components/shared/table/TableWorker.vue';
import ToggleView from 'src/components/shared/ToggleView.vue';
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL;
@ -104,6 +106,7 @@ const employeeStore = useEmployeeStore();
const quotationStore = useQuotationStore();
const open = defineModel<boolean>('open', { default: false });
const viewMode = ref<boolean>(false);
const workerSelected = ref<Employee[]>([]);
const workerList = ref<Employee[]>([]);
const importWorkerCriteria = ref<{
@ -314,6 +317,8 @@ watch(() => state.search, getWorkerList);
<q-tab-panel class="q-pa-none" :name="1">
<div class="column q-pa-md full-height">
<section class="row justify-end q-mb-md">
<ToggleView v-model="viewMode" class="q-mr-sm" />
<q-input
for="input-search"
outlined
@ -340,55 +345,59 @@ watch(() => state.search, getWorkerList);
>
<NoData :not-found="!!state.search" />
</div>
<div
:key="emp.id"
v-for="(emp, index) in workerList.map((data) => ({
...data,
_selectedIndex: selectedIndex(data),
}))"
class="col-md-2 col-sm-6 col-12"
<TableWorker
v-model:selected="workerSelected"
:rows="workerList"
:disabledWorkerId
:grid="viewMode"
>
<button
class="selectable-item full-width"
:class="{
['selectable-item__selected']: emp._selectedIndex !== -1,
['selectable-item__disabled']: disabledWorkerId?.some(
(id) => id === emp.id,
),
}"
@click="toggleSelect(emp)"
>
<span class="selectable-item__pos">
{{ emp._selectedIndex + 1 }}
</span>
<PersonCard
no-action
class="full-width"
:prefix-id="'employee-' + index"
:data="{
name:
locale === Lang.English
? `${emp.firstNameEN} ${emp.lastNameEN}`
: `${emp.firstName} ${emp.lastName}`,
code: emp.employeePassport?.at(0)?.number || '-',
female: emp.gender === 'female',
male: emp.gender === 'male',
img: getEmployeeImageUrl(emp),
fallbackImg: `/images/employee-avatar-${emp.gender}.png`,
detail: [
{
icon: 'mdi-passport',
value: optionStore.mapOption(emp.nationality),
},
{
icon: 'mdi-clock-outline',
value: calculateAge(emp.dateOfBirth),
},
],
}"
/>
</button>
</div>
<template #grid="{ item: emp, index }">
<div :key="emp.id" class="col-md-2 col-sm-6 col-12">
<button
class="selectable-item full-width"
:class="{
['selectable-item__selected']:
emp._selectedIndex !== -1,
['selectable-item__disabled']: disabledWorkerId?.some(
(id) => id === emp.id,
),
}"
@click="toggleSelect(emp)"
>
<span class="selectable-item__pos">
{{ (emp._selectedIndex || 0) + 1 }}
</span>
<PersonCard
no-action
class="full-width"
:prefix-id="'employee-' + index"
:data="{
name:
locale === Lang.English
? `${emp.firstNameEN} ${emp.lastNameEN}`
: `${emp.firstName} ${emp.lastName}`,
code: emp.employeePassport?.at(0)?.number || '-',
female: emp.gender === 'female',
male: emp.gender === 'male',
img: getEmployeeImageUrl(emp),
fallbackImg: `/images/employee-avatar-${emp.gender}.png`,
detail: [
{
icon: 'mdi-passport',
value: optionStore.mapOption(emp.nationality),
},
{
icon: 'mdi-clock-outline',
value: calculateAge(emp.dateOfBirth),
},
],
}"
/>
</button>
</div>
</template>
</TableWorker>
</section>
</div>
</div>
@ -457,86 +466,15 @@ watch(() => state.search, getWorkerList);
</template>
<div class="q-pa-md surface-1">
<q-table
<TableWorker
v-model:selected="productWorkerMap[id]"
:rows-per-page-options="[0]"
:rows="
workerSelected.map((data, i) => ({
...data,
_index: i,
}))
"
:columns
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"
>
<template v-if="!col.name.startsWith('#')">
{{ $t(col.label) }}
</template>
<template v-if="col.name === '#check'">
<q-checkbox v-model="props.selected" size="sm" />
</template>
</q-th>
</q-tr>
</template>
<template
v-slot:body="props: {
row: Employee & { _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('#')">
<q-avatar
v-if="col.name === 'employeeName'"
class="q-mr-sm"
size="md"
>
<q-img
:src="getEmployeeImageUrl(props.row)"
:ratio="1"
class="text-center"
/>
</q-avatar>
<span>
{{
typeof col.field === 'string'
? props.row[col.field as keyof Employee]
: col.field(props.row)
}}
</span>
</template>
<template v-if="col.name === '#check'">
<q-checkbox v-model="props.selected" size="sm" />
</template>
</q-td>
</q-tr>
</template>
</q-table>
/>
</div>
</q-expansion-item>
</div>

View file

@ -46,6 +46,8 @@ import {
columnsAttachment,
} from 'src/pages/03_customer-management/constant';
import { storeToRefs } from 'pinia';
import ToggleView from 'src/components/shared/ToggleView.vue';
import TableWorker from 'src/components/shared/table/TableWorker.vue';
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL;
@ -55,6 +57,8 @@ const quotationForm = useQuotationForm();
const { locale } = useI18n();
const ocrStore = useOcrStore();
const viewMode = ref<boolean>(false);
const { state: employeeFormState, currentFromDataEmployee } =
storeToRefs(employeeFormStore);
@ -329,14 +333,15 @@ watch(() => state.search, getWorkerList);
<div class="column full-height no-wrap surface-2">
<section class="row q-mb-md">
<header
class="row items-center q-py-sm q-px-md justify-between full-width surface-3 bordered-b no-wrap"
class="row items-center q-py-sm q-px-md justify-end full-width surface-3 bordered-b no-wrap"
>
<ToggleView v-model="viewMode" class="q-mr-sm full-height" />
<q-input
for="input-search"
outlined
dense
:label="$t('general.search')"
class="q-mr-md col-md-4"
:bg-color="$q.dark.isActive ? 'dark' : 'white'"
v-model="state.search"
debounce="500"
@ -447,7 +452,7 @@ watch(() => state.search, getWorkerList);
<div class="full-width q-pt-md">
<section
:class="{ ['items-center']: workerList.length === 0 }"
class="row q-col-gutter-md scroll"
class="row scroll"
>
<div
style="display: inline-block; margin-inline: auto"
@ -455,52 +460,58 @@ watch(() => state.search, getWorkerList);
>
<NoData :not-found="!!state.search" />
</div>
<div
:key="emp.id"
v-for="(emp, index) in workerList.map((data) => ({
...data,
_selectedIndex: selectedIndex(data),
}))"
class="col-md-2 col-sm-6 col-12"
<TableWorker
v-model:selected="workerSelected"
:rows="workerList"
:disabledWorkerId
:grid="viewMode"
>
<button
class="selectable-item full-width"
:class="{
['selectable-item__selected']: emp._selectedIndex !== -1,
['selectable-item__disabled']: disabledWorkerId?.some(
(id) => id === emp.id,
),
}"
@click="toggleSelect(emp)"
>
<PersonCard
no-action
class="full-width"
:prefix-id="'employee-' + index"
:data="{
name:
locale === Lang.English
? `${emp.firstNameEN} ${emp.lastNameEN}`
: `${emp.firstName} ${emp.lastName}`,
code: emp.employeePassport?.at(0)?.number || '-',
female: emp.gender === 'female',
male: emp.gender === 'male',
img: getEmployeeImageUrl(emp),
fallbackImg: `/images/employee-avatar-${emp.gender}.png`,
detail: [
{
icon: 'mdi-passport',
value: optionStore.mapOption(emp.nationality),
},
{
icon: 'mdi-clock-outline',
value: calculateAge(emp.dateOfBirth),
},
],
}"
/>
</button>
</div>
<template #grid="{ item: emp, index }">
<div :key="emp.id" class="col-md-2 col-sm-6 col-12">
<button
class="selectable-item full-width"
:class="{
['selectable-item__selected']:
emp._selectedIndex !== -1,
['selectable-item__disabled']: disabledWorkerId?.some(
(id) => id === emp.id,
),
}"
@click="toggleSelect(emp)"
>
<span class="selectable-item__pos">
{{ (emp._selectedIndex || 0) + 1 }}
</span>
<PersonCard
no-action
class="full-width"
:prefix-id="'employee-' + index"
:data="{
name:
locale === Lang.English
? `${emp.firstNameEN} ${emp.lastNameEN}`
: `${emp.firstName} ${emp.lastName}`,
code: emp.employeePassport?.at(0)?.number || '-',
female: emp.gender === 'female',
male: emp.gender === 'male',
img: getEmployeeImageUrl(emp),
fallbackImg: `/images/employee-avatar-${emp.gender}.png`,
detail: [
{
icon: 'mdi-passport',
value: optionStore.mapOption(emp.nationality),
},
{
icon: 'mdi-clock-outline',
value: calculateAge(emp.dateOfBirth),
},
],
}"
/>
</button>
</div>
</template>
</TableWorker>
</section>
</div>
</q-expansion-item>