refactor: api select value (#69)
* feat: add file * fix: wrong type * feat: select customer component * fixup! feat: select customer component * fix: char case * refactor: fn alias * chore: add space * feat: accept fetch parameter * refactor: naming * feat: add emit event create * fix: add suffix to add text * feat: add before options slot for select input comp * fix: error when label not found * fix: value type * feat: add required param * fix: wording * refactor: fix customer * feat: use new select component * chore: add note * feat: add decoration for select with creatable * feat: emit event * feat: close popup on click * feat: adjust alignment * feat: add readonly params * feat: add select branch option * feat: use new select component * feat: add disabled params * feat: adjust internal search and select * refactor: props type * feat: use new select component * feat: add lib for select component * refactor: use factory function instead * refactor: merge two lines of code * refactor: move watch inside * refactor: fix value not in list check * chore: cleanup * fix: remove test page size * chore: remove unused * feat: use new select component * fix: typo * fix: error * refactor: extract type * refactor: change ref var to normal var * refactor: force overwrite params to prevent error on render * feat: add clearable parameter * feat: make clearable
This commit is contained in:
parent
a227744131
commit
d414685fe7
13 changed files with 500 additions and 319 deletions
|
|
@ -1,30 +1,12 @@
|
|||
<script setup lang="ts">
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import useBranchStore from 'src/stores/branch';
|
||||
import useCustomerStore from 'src/stores/customer';
|
||||
import SelectInput from '../shared/SelectInput.vue';
|
||||
import { QSelect } from 'quasar';
|
||||
import { Branch } from 'src/stores/branch/types';
|
||||
import { CustomerBranch } from 'src/stores/customer/types';
|
||||
import useOptionStore from 'stores/options';
|
||||
import SelectCustomer from '../shared/select/SelectCustomer.vue';
|
||||
import SelectBranch from '../shared/select/SelectBranch.vue';
|
||||
|
||||
const { locale } = useI18n({ useScope: 'global' });
|
||||
const branchStore = useBranchStore();
|
||||
const customerStore = useCustomerStore();
|
||||
|
||||
const optionStore = useOptionStore();
|
||||
const branchId = defineModel<string>('branchId');
|
||||
const customerBranchId = defineModel<string>('customerBranchId');
|
||||
const agentPrice = defineModel<boolean>('agentPrice');
|
||||
const special = defineModel<boolean>('special');
|
||||
|
||||
const branchOption = ref<{ value: string; label: string; labelEN: string }[]>();
|
||||
const customerOption =
|
||||
ref<
|
||||
{ value: string; label: string; labelEN: string; namePrefix: string }[]
|
||||
>();
|
||||
|
||||
defineProps<{
|
||||
outlined?: boolean;
|
||||
readonly?: boolean;
|
||||
|
|
@ -40,103 +22,6 @@ defineProps<{
|
|||
defineEmits<{
|
||||
(e: 'addCustomer'): void;
|
||||
}>();
|
||||
|
||||
async function filter(
|
||||
val: string,
|
||||
update: (...args: unknown[]) => void,
|
||||
type: 'branch' | 'customer',
|
||||
) {
|
||||
update(
|
||||
async () => {
|
||||
await init(val, type);
|
||||
},
|
||||
|
||||
(ref: QSelect) => {
|
||||
if (val !== '' && ref.options && ref.options?.length > 0) {
|
||||
ref.setOptionIndex(-1);
|
||||
ref.moveOptionSelection(1, true);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
const currentSelectedBranchOption =
|
||||
ref<NonNullable<typeof branchOption.value>[number]>();
|
||||
const currentSelectedCustomerOption =
|
||||
ref<NonNullable<typeof customerOption.value>[number]>();
|
||||
|
||||
async function init(val: string, type: 'branch' | 'customer') {
|
||||
const res =
|
||||
type === 'branch'
|
||||
? await branchStore.fetchList({
|
||||
query: val,
|
||||
pageSize: 30,
|
||||
})
|
||||
: await customerStore.fetchListCustomerBranch({
|
||||
query: val,
|
||||
pageSize: 30,
|
||||
company: true,
|
||||
});
|
||||
if (res) {
|
||||
if (type === 'branch') {
|
||||
const mapped = (res.result as Branch[]).map((v: Branch) => ({
|
||||
value: v.id,
|
||||
label: v.name,
|
||||
labelEN: v.nameEN,
|
||||
}));
|
||||
|
||||
if (!mapped.find((v) => v.value === branchId.value) && branchId.value) {
|
||||
if (currentSelectedBranchOption.value?.value !== branchId.value) {
|
||||
const v = await branchStore.fetchById(branchId.value);
|
||||
if (v) {
|
||||
mapped.unshift({
|
||||
value: v.id,
|
||||
label: v.name,
|
||||
labelEN: v.nameEN,
|
||||
});
|
||||
currentSelectedBranchOption.value = mapped.at(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
branchOption.value = mapped;
|
||||
} else if (type === 'customer') {
|
||||
const mapped = (res.result as CustomerBranch[]).map(
|
||||
(v: CustomerBranch) => ({
|
||||
value: v.id,
|
||||
label: v.registerName || `${v.firstName} ${v.lastName}` || '-',
|
||||
labelEN:
|
||||
v.registerNameEN || `${v.firstNameEN} ${v.lastNameEN}` || '-',
|
||||
namePrefix: v.namePrefix,
|
||||
}),
|
||||
);
|
||||
|
||||
if (
|
||||
!mapped.find((v) => v.value === customerBranchId.value) &&
|
||||
customerBranchId.value
|
||||
) {
|
||||
const v = await customerStore.fetchListCustomerBranchById(
|
||||
customerBranchId.value,
|
||||
);
|
||||
|
||||
if (v) {
|
||||
mapped.unshift({
|
||||
value: v.id,
|
||||
label: v.registerName || `${v.firstName} ${v.lastName}` || '-',
|
||||
labelEN:
|
||||
v.registerNameEN || `${v.firstNameEN} ${v.lastNameEN}` || '-',
|
||||
namePrefix: v.namePrefix,
|
||||
});
|
||||
}
|
||||
}
|
||||
customerOption.value = mapped;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await init('', 'branch');
|
||||
await init('', 'customer');
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<div class="row">
|
||||
|
|
@ -170,62 +55,24 @@ onMounted(async () => {
|
|||
</div>
|
||||
</div>
|
||||
<div class="col-12 row q-col-gutter-sm">
|
||||
<SelectInput
|
||||
:readonly
|
||||
incremental
|
||||
v-model="branchId"
|
||||
id="quotation-branch"
|
||||
class="col-md col-12"
|
||||
:option="branchOption"
|
||||
<SelectBranch
|
||||
v-model:value="branchId"
|
||||
:label="$t('quotation.branch')"
|
||||
:option-label="locale === 'eng' ? 'labelEN' : 'label'"
|
||||
:rules="[(val: string) => !!val || $t('form.error.required')]"
|
||||
@filter="(val: string, update) => filter(val, update, 'branch')"
|
||||
/>
|
||||
|
||||
<SelectInput
|
||||
class="col-md-6 col-12"
|
||||
simple
|
||||
required
|
||||
:readonly
|
||||
incremental
|
||||
v-model="customerBranchId"
|
||||
class="col-md col-12"
|
||||
id="quotation-customer"
|
||||
:option="customerOption"
|
||||
/>
|
||||
<SelectCustomer
|
||||
v-model:value="customerBranchId"
|
||||
:label="$t('quotation.customer')"
|
||||
:option-label="locale === 'eng' ? 'labelEN' : 'label'"
|
||||
:rules="[(val: string) => !!val || $t('form.error.required')]"
|
||||
@filter="(val: string, update) => filter(val, update, 'customer')"
|
||||
>
|
||||
<template #option="{ scope }">
|
||||
<q-item
|
||||
clickable
|
||||
v-if="scope.index === 0 && !hideAdd"
|
||||
@click.stop="$emit('addCustomer')"
|
||||
>
|
||||
<q-item-section>
|
||||
{{ $t('general.add', { text: $t('quotation.newCustomer') }) }}
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-separator v-if="scope.index === 0" />
|
||||
|
||||
<q-item clickable v-bind="scope.itemProps">
|
||||
<q-item-section>
|
||||
{{
|
||||
optionStore.mapOption(scope.opt.namePrefix) ||
|
||||
$t('general.company')
|
||||
}}
|
||||
{{ locale === 'eng' ? scope.opt.labelEN : scope.opt.label }}
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</template>
|
||||
|
||||
<template #noOption>
|
||||
<q-item clickable @click.stop="$emit('addCustomer')">
|
||||
<q-item-section>
|
||||
{{ $t('general.add', { text: $t('quotation.newCustomer') }) }}
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</template>
|
||||
</SelectInput>
|
||||
@create="$emit('addCustomer')"
|
||||
class="col-md-6 col-12"
|
||||
creatable
|
||||
simple
|
||||
required
|
||||
:readonly
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue