Compare commits

..

7 commits

Author SHA1 Message Date
Thanaphon Frappet
67a69b85e0 refactor: add ( ) ,
Some checks failed
Spell Check / Spell Check with Typos (push) Failing after 5s
2025-08-21 15:54:30 +07:00
Methapon2001
eb88cc4269 fix: duplicate value 2025-08-21 15:54:30 +07:00
Methapon2001
ec780f2018 chore: clean 2025-08-21 15:54:30 +07:00
Methapon2001
31b4daf42b feat(biz-type): add create button on empty 2025-08-21 15:54:30 +07:00
Methapon2001
5fad663a6e feat(biz-type): add response type and response data 2025-08-21 15:54:30 +07:00
Methapon2001
d4a9be9236 feat: add create slot for business type select 2025-08-21 15:54:30 +07:00
puriphatt
e33191dcd4 fix: business type display 2025-08-21 15:54:30 +07:00
8 changed files with 92 additions and 32 deletions

View file

@ -1,6 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted } from 'vue'; import { ref, onMounted } from 'vue';
import { getRole } from 'src/services/keycloak';
import { createSelect, SelectProps } from './select'; import { createSelect, SelectProps } from './select';
import SelectInput from '../SelectInput.vue'; import SelectInput from '../SelectInput.vue';
@ -95,6 +94,70 @@ function setDefaultValue() {
{{ (lang ?? $i18n.locale) !== 'eng' ? opt.name : opt.nameEN }} {{ (lang ?? $i18n.locale) !== 'eng' ? opt.name : opt.nameEN }}
</template> </template>
<template #no-option v-if="creatable">
<q-item
:disable="creatableDisabled"
clickable
v-close-popup
@click.stop="$emit('create')"
>
<q-item-section>
<span class="row items-center">
<q-icon
name="mdi-plus-circle-outline"
class="q-mr-sm"
style="color: hsl(var(--positive-bg))"
/>
<b>
{{ $t('general.add', { text: $t('businessType.title') }) }}
</b>
<span
v-if="creatableDisabled && creatableDisabledText"
class="app-text-muted q-pl-xs"
style="font-size: 80%"
>
{{ creatableDisabledText }}
</span>
</span>
</q-item-section>
</q-item>
<q-separator class="q-mx-sm" />
</template>
<template #before-options v-if="creatable">
<q-item
:disable="creatableDisabled"
clickable
v-close-popup
@click.stop="$emit('create')"
for="select-biz-type-add-new"
id="select-biz-type-add-new"
>
<q-item-section>
<span class="row items-center">
<q-icon
name="mdi-plus-circle-outline"
class="q-mr-sm"
style="color: hsl(var(--positive-bg))"
/>
<b>
{{ $t('general.add', { text: $t('businessType.title') }) }}
</b>
<span
v-if="creatableDisabled && creatableDisabledText"
class="app-text-muted q-pl-xs"
style="font-size: 80%"
>
{{ creatableDisabledText }}
</span>
</span>
</q-item-section>
</q-item>
<q-separator class="q-mx-sm" />
</template>
<template #option="{ opt, scope }"> <template #option="{ opt, scope }">
<q-item v-bind="scope.itemProps"> <q-item v-bind="scope.itemProps">
<span class="row items-center"> <span class="row items-center">

View file

@ -70,22 +70,25 @@ export const createSelect = <T extends Record<string, any>>(
if (!currentValue) return; if (!currentValue) return;
const option = selectOptions.value.find(
(v) => v[valueField] === currentValue,
);
if (option) {
valueOption.value = option;
return;
}
if (valueOption.value && valueOption.value[valueField] === currentValue) { if (valueOption.value && valueOption.value[valueField] === currentValue) {
return selectOptions.value.unshift(valueOption.value); selectOptions.value.unshift(valueOption.value);
selectOptions.value = selectOptions.value.filter((curr, idx, arr) => {
return (
arr.findIndex((item) => item[valueField] === curr[valueField]) === idx
);
});
return;
} }
const ret = await getByValue(currentValue); const ret = await getByValue(currentValue);
if (ret) { if (ret) {
selectOptions.value.unshift(ret); selectOptions.value.unshift(ret);
selectOptions.value = selectOptions.value.filter((curr, idx, arr) => {
return (
arr.findIndex((item) => item[valueField] === curr[valueField]) === idx
);
});
valueOption.value = ret; valueOption.value = ret;
} }
} }

View file

@ -340,7 +340,7 @@ export default {
requireLength: 'Please enter {msg} character', requireLength: 'Please enter {msg} character',
branchNameField: "Only letters, numbers, or the characters . , - ' &.", branchNameField: "Only letters, numbers, or the characters . , - ' &.",
branchNameENField: branchNameENField:
"Only English letters, numbers, or the characters . , - ' &.", "Only English letters, numbers, or the characters . , - ' &. ( )",
passportFormat: 'Please enter the passport number in the correct format.', passportFormat: 'Please enter the passport number in the correct format.',
}, },
warning: { warning: {

View file

@ -337,7 +337,7 @@ export default {
letterAndNumOnly: 'โปรดใช้เฉพาะ _ ตัวอักษรภาษาอังกฤษและตัวเลขเท่านั้น', letterAndNumOnly: 'โปรดใช้เฉพาะ _ ตัวอักษรภาษาอังกฤษและตัวเลขเท่านั้น',
numOnly: 'โปรดใช้เฉพาะตัวเลขเท่านั้น', numOnly: 'โปรดใช้เฉพาะตัวเลขเท่านั้น',
requireLength: 'กรุณากรอกให้ครบ {msg} หลัก', requireLength: 'กรุณากรอกให้ครบ {msg} หลัก',
branchNameField: "โปรดใช้ตัวอักษร ตัวเลข หรือ . , - ' & เท่านั้น", branchNameField: "โปรดใช้ตัวอักษร ตัวเลข หรือ . , - ' ( ) & เท่านั้น",
branchNameENField: branchNameENField:
"โปรดใช้ตัวอักษรภาษาอังกฤษ ตัวเลข หรือ . , - ' & เท่านั้น", "โปรดใช้ตัวอักษรภาษาอังกฤษ ตัวเลข หรือ . , - ' & เท่านั้น",
passportFormat: 'กรุณากรอกหมายเลขพาสปอร์ตให้ถูกต้องตามรูปแบบ', passportFormat: 'กรุณากรอกหมายเลขพาสปอร์ตให้ถูกต้องตามรูปแบบ',

View file

@ -4328,7 +4328,7 @@ const emptyCreateDialog = ref(false);
customerFormData.customerBranch[0].legalPersonNo customerFormData.customerBranch[0].legalPersonNo
" "
v-model:business-type=" v-model:business-type="
customerFormData.customerBranch[0].businessType customerFormData.customerBranch[0].businessTypeId
" "
v-model:job-position=" v-model:job-position="
customerFormData.customerBranch[0].jobPosition customerFormData.customerBranch[0].jobPosition

View file

@ -140,7 +140,7 @@ watch(
:rules="[ :rules="[
(val) => !!val || $t('form.error.required'), (val) => !!val || $t('form.error.required'),
(val) => (val) =>
/^[A-Za-z0-9ก-๙\s&.,'-]+$/.test(val) || /^[A-Za-z0-9ก-๙\s&.,'()-]+$/.test(val) ||
$t('form.error.branchNameField'), $t('form.error.branchNameField'),
]" ]"
/> />

View file

@ -2,6 +2,7 @@
import useOptionStore from 'stores/options'; import useOptionStore from 'stores/options';
import SelectBranch from 'src/components/shared/select/SelectBranch.vue'; import SelectBranch from 'src/components/shared/select/SelectBranch.vue';
import { isRoleInclude } from 'src/stores/utils'; import { isRoleInclude } from 'src/stores/utils';
import SelectBusinessType from 'src/components/shared/select/SelectBusinessType.vue';
withDefaults( withDefaults(
defineProps<{ defineProps<{
@ -142,15 +143,10 @@ const telephoneNo = defineModel<string>('telephoneNo', { default: '' });
for="input-tax" for="input-tax"
v-model="legalPersonNo" v-model="legalPersonNo"
/> />
<q-input <SelectBusinessType
dense
outlined
:readonly="readonly"
hide-bottom-space
class="col-6 col-md-3" class="col-6 col-md-3"
:label="$t('customer.table.businessTypePure')" v-model:value="businessType"
for="input-business-type" :readonly
:model-value="optionStore.mapOption(businessType)"
/> />
</div> </div>
@ -179,15 +175,10 @@ const telephoneNo = defineModel<string>('telephoneNo', { default: '' });
:label="$t('personnel.form.citizenId')" :label="$t('personnel.form.citizenId')"
for="input-citizen-id" for="input-citizen-id"
/> />
<q-input <SelectBusinessType
dense
outlined
:readonly="readonly"
hide-bottom-space
class="col-6 col-md-3" class="col-6 col-md-3"
:label="$t('customer.table.businessTypePure')" v-model:value="businessType"
for="input-first-name-en" :readonly
:model-value="optionStore.mapOption(businessType)"
/> />
</div> </div>

View file

@ -37,10 +37,13 @@ const useBusinessTypeStore = defineStore('business-type-store', () => {
return false; return false;
} }
async function create(data: BusinessTypePayLoad) { async function create(
const res = await api.post('/business-type', { data: BusinessTypePayLoad,
): Promise<BusinessType | null> {
const res = await api.post<BusinessType>('/business-type', {
...data, ...data,
}); });
if (res.status < 400) { if (res.status < 400) {
return res.data; return res.data;
} }