refactor: show mode list
This commit is contained in:
parent
18d0aca1de
commit
a4bc6e4884
2 changed files with 118 additions and 169 deletions
|
|
@ -23,6 +23,8 @@ import PersonCard from 'src/components/shared/PersonCard.vue';
|
||||||
import { QuotationFull } from 'src/stores/quotations/types';
|
import { QuotationFull } from 'src/stores/quotations/types';
|
||||||
import { Lang } from 'src/utils/ui';
|
import { Lang } from 'src/utils/ui';
|
||||||
import NoData from 'src/components/NoData.vue';
|
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;
|
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL;
|
||||||
|
|
||||||
|
|
@ -104,6 +106,7 @@ const employeeStore = useEmployeeStore();
|
||||||
const quotationStore = useQuotationStore();
|
const quotationStore = useQuotationStore();
|
||||||
|
|
||||||
const open = defineModel<boolean>('open', { default: false });
|
const open = defineModel<boolean>('open', { default: false });
|
||||||
|
const viewMode = ref<boolean>(false);
|
||||||
const workerSelected = ref<Employee[]>([]);
|
const workerSelected = ref<Employee[]>([]);
|
||||||
const workerList = ref<Employee[]>([]);
|
const workerList = ref<Employee[]>([]);
|
||||||
const importWorkerCriteria = ref<{
|
const importWorkerCriteria = ref<{
|
||||||
|
|
@ -314,6 +317,8 @@ watch(() => state.search, getWorkerList);
|
||||||
<q-tab-panel class="q-pa-none" :name="1">
|
<q-tab-panel class="q-pa-none" :name="1">
|
||||||
<div class="column q-pa-md full-height">
|
<div class="column q-pa-md full-height">
|
||||||
<section class="row justify-end q-mb-md">
|
<section class="row justify-end q-mb-md">
|
||||||
|
<ToggleView v-model="viewMode" class="q-mr-sm" />
|
||||||
|
|
||||||
<q-input
|
<q-input
|
||||||
for="input-search"
|
for="input-search"
|
||||||
outlined
|
outlined
|
||||||
|
|
@ -340,55 +345,59 @@ watch(() => state.search, getWorkerList);
|
||||||
>
|
>
|
||||||
<NoData :not-found="!!state.search" />
|
<NoData :not-found="!!state.search" />
|
||||||
</div>
|
</div>
|
||||||
<div
|
|
||||||
:key="emp.id"
|
<TableWorker
|
||||||
v-for="(emp, index) in workerList.map((data) => ({
|
v-model:selected="workerSelected"
|
||||||
...data,
|
:rows="workerList"
|
||||||
_selectedIndex: selectedIndex(data),
|
:disabledWorkerId
|
||||||
}))"
|
:grid="viewMode"
|
||||||
class="col-md-2 col-sm-6 col-12"
|
|
||||||
>
|
>
|
||||||
<button
|
<template #grid="{ item: emp, index }">
|
||||||
class="selectable-item full-width"
|
<div :key="emp.id" class="col-md-2 col-sm-6 col-12">
|
||||||
:class="{
|
<button
|
||||||
['selectable-item__selected']: emp._selectedIndex !== -1,
|
class="selectable-item full-width"
|
||||||
['selectable-item__disabled']: disabledWorkerId?.some(
|
:class="{
|
||||||
(id) => id === emp.id,
|
['selectable-item__selected']:
|
||||||
),
|
emp._selectedIndex !== -1,
|
||||||
}"
|
['selectable-item__disabled']: disabledWorkerId?.some(
|
||||||
@click="toggleSelect(emp)"
|
(id) => id === emp.id,
|
||||||
>
|
),
|
||||||
<span class="selectable-item__pos">
|
}"
|
||||||
{{ emp._selectedIndex + 1 }}
|
@click="toggleSelect(emp)"
|
||||||
</span>
|
>
|
||||||
<PersonCard
|
<span class="selectable-item__pos">
|
||||||
no-action
|
{{ (emp._selectedIndex || 0) + 1 }}
|
||||||
class="full-width"
|
</span>
|
||||||
:prefix-id="'employee-' + index"
|
<PersonCard
|
||||||
:data="{
|
no-action
|
||||||
name:
|
class="full-width"
|
||||||
locale === Lang.English
|
:prefix-id="'employee-' + index"
|
||||||
? `${emp.firstNameEN} ${emp.lastNameEN}`
|
:data="{
|
||||||
: `${emp.firstName} ${emp.lastName}`,
|
name:
|
||||||
code: emp.employeePassport?.at(0)?.number || '-',
|
locale === Lang.English
|
||||||
female: emp.gender === 'female',
|
? `${emp.firstNameEN} ${emp.lastNameEN}`
|
||||||
male: emp.gender === 'male',
|
: `${emp.firstName} ${emp.lastName}`,
|
||||||
img: getEmployeeImageUrl(emp),
|
code: emp.employeePassport?.at(0)?.number || '-',
|
||||||
fallbackImg: `/images/employee-avatar-${emp.gender}.png`,
|
female: emp.gender === 'female',
|
||||||
detail: [
|
male: emp.gender === 'male',
|
||||||
{
|
img: getEmployeeImageUrl(emp),
|
||||||
icon: 'mdi-passport',
|
fallbackImg: `/images/employee-avatar-${emp.gender}.png`,
|
||||||
value: optionStore.mapOption(emp.nationality),
|
detail: [
|
||||||
},
|
{
|
||||||
{
|
icon: 'mdi-passport',
|
||||||
icon: 'mdi-clock-outline',
|
value: optionStore.mapOption(emp.nationality),
|
||||||
value: calculateAge(emp.dateOfBirth),
|
},
|
||||||
},
|
{
|
||||||
],
|
icon: 'mdi-clock-outline',
|
||||||
}"
|
value: calculateAge(emp.dateOfBirth),
|
||||||
/>
|
},
|
||||||
</button>
|
],
|
||||||
</div>
|
}"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</TableWorker>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -457,86 +466,15 @@ watch(() => state.search, getWorkerList);
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<div class="q-pa-md surface-1">
|
<div class="q-pa-md surface-1">
|
||||||
<q-table
|
<TableWorker
|
||||||
v-model:selected="productWorkerMap[id]"
|
v-model:selected="productWorkerMap[id]"
|
||||||
:rows-per-page-options="[0]"
|
|
||||||
:rows="
|
:rows="
|
||||||
workerSelected.map((data, i) => ({
|
workerSelected.map((data, i) => ({
|
||||||
...data,
|
...data,
|
||||||
_index: i,
|
_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>
|
</div>
|
||||||
</q-expansion-item>
|
</q-expansion-item>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,8 @@ import {
|
||||||
columnsAttachment,
|
columnsAttachment,
|
||||||
} from 'src/pages/03_customer-management/constant';
|
} from 'src/pages/03_customer-management/constant';
|
||||||
import { storeToRefs } from 'pinia';
|
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;
|
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL;
|
||||||
|
|
||||||
|
|
@ -55,6 +57,8 @@ const quotationForm = useQuotationForm();
|
||||||
const { locale } = useI18n();
|
const { locale } = useI18n();
|
||||||
const ocrStore = useOcrStore();
|
const ocrStore = useOcrStore();
|
||||||
|
|
||||||
|
const viewMode = ref<boolean>(false);
|
||||||
|
|
||||||
const { state: employeeFormState, currentFromDataEmployee } =
|
const { state: employeeFormState, currentFromDataEmployee } =
|
||||||
storeToRefs(employeeFormStore);
|
storeToRefs(employeeFormStore);
|
||||||
|
|
||||||
|
|
@ -329,14 +333,15 @@ watch(() => state.search, getWorkerList);
|
||||||
<div class="column full-height no-wrap surface-2">
|
<div class="column full-height no-wrap surface-2">
|
||||||
<section class="row q-mb-md">
|
<section class="row q-mb-md">
|
||||||
<header
|
<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
|
<q-input
|
||||||
for="input-search"
|
for="input-search"
|
||||||
outlined
|
outlined
|
||||||
dense
|
dense
|
||||||
:label="$t('general.search')"
|
:label="$t('general.search')"
|
||||||
class="q-mr-md col-md-4"
|
|
||||||
:bg-color="$q.dark.isActive ? 'dark' : 'white'"
|
:bg-color="$q.dark.isActive ? 'dark' : 'white'"
|
||||||
v-model="state.search"
|
v-model="state.search"
|
||||||
debounce="500"
|
debounce="500"
|
||||||
|
|
@ -447,7 +452,7 @@ watch(() => state.search, getWorkerList);
|
||||||
<div class="full-width q-pt-md">
|
<div class="full-width q-pt-md">
|
||||||
<section
|
<section
|
||||||
:class="{ ['items-center']: workerList.length === 0 }"
|
:class="{ ['items-center']: workerList.length === 0 }"
|
||||||
class="row q-col-gutter-md scroll"
|
class="row scroll"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
style="display: inline-block; margin-inline: auto"
|
style="display: inline-block; margin-inline: auto"
|
||||||
|
|
@ -455,52 +460,58 @@ watch(() => state.search, getWorkerList);
|
||||||
>
|
>
|
||||||
<NoData :not-found="!!state.search" />
|
<NoData :not-found="!!state.search" />
|
||||||
</div>
|
</div>
|
||||||
<div
|
<TableWorker
|
||||||
:key="emp.id"
|
v-model:selected="workerSelected"
|
||||||
v-for="(emp, index) in workerList.map((data) => ({
|
:rows="workerList"
|
||||||
...data,
|
:disabledWorkerId
|
||||||
_selectedIndex: selectedIndex(data),
|
:grid="viewMode"
|
||||||
}))"
|
|
||||||
class="col-md-2 col-sm-6 col-12"
|
|
||||||
>
|
>
|
||||||
<button
|
<template #grid="{ item: emp, index }">
|
||||||
class="selectable-item full-width"
|
<div :key="emp.id" class="col-md-2 col-sm-6 col-12">
|
||||||
:class="{
|
<button
|
||||||
['selectable-item__selected']: emp._selectedIndex !== -1,
|
class="selectable-item full-width"
|
||||||
['selectable-item__disabled']: disabledWorkerId?.some(
|
:class="{
|
||||||
(id) => id === emp.id,
|
['selectable-item__selected']:
|
||||||
),
|
emp._selectedIndex !== -1,
|
||||||
}"
|
['selectable-item__disabled']: disabledWorkerId?.some(
|
||||||
@click="toggleSelect(emp)"
|
(id) => id === emp.id,
|
||||||
>
|
),
|
||||||
<PersonCard
|
}"
|
||||||
no-action
|
@click="toggleSelect(emp)"
|
||||||
class="full-width"
|
>
|
||||||
:prefix-id="'employee-' + index"
|
<span class="selectable-item__pos">
|
||||||
:data="{
|
{{ (emp._selectedIndex || 0) + 1 }}
|
||||||
name:
|
</span>
|
||||||
locale === Lang.English
|
<PersonCard
|
||||||
? `${emp.firstNameEN} ${emp.lastNameEN}`
|
no-action
|
||||||
: `${emp.firstName} ${emp.lastName}`,
|
class="full-width"
|
||||||
code: emp.employeePassport?.at(0)?.number || '-',
|
:prefix-id="'employee-' + index"
|
||||||
female: emp.gender === 'female',
|
:data="{
|
||||||
male: emp.gender === 'male',
|
name:
|
||||||
img: getEmployeeImageUrl(emp),
|
locale === Lang.English
|
||||||
fallbackImg: `/images/employee-avatar-${emp.gender}.png`,
|
? `${emp.firstNameEN} ${emp.lastNameEN}`
|
||||||
detail: [
|
: `${emp.firstName} ${emp.lastName}`,
|
||||||
{
|
code: emp.employeePassport?.at(0)?.number || '-',
|
||||||
icon: 'mdi-passport',
|
female: emp.gender === 'female',
|
||||||
value: optionStore.mapOption(emp.nationality),
|
male: emp.gender === 'male',
|
||||||
},
|
img: getEmployeeImageUrl(emp),
|
||||||
{
|
fallbackImg: `/images/employee-avatar-${emp.gender}.png`,
|
||||||
icon: 'mdi-clock-outline',
|
detail: [
|
||||||
value: calculateAge(emp.dateOfBirth),
|
{
|
||||||
},
|
icon: 'mdi-passport',
|
||||||
],
|
value: optionStore.mapOption(emp.nationality),
|
||||||
}"
|
},
|
||||||
/>
|
{
|
||||||
</button>
|
icon: 'mdi-clock-outline',
|
||||||
</div>
|
value: calculateAge(emp.dateOfBirth),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</TableWorker>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</q-expansion-item>
|
</q-expansion-item>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue