parent
9f29ce7887
commit
3d89ce5a88
2 changed files with 135 additions and 35 deletions
124
src/components/shared/select/SelectProductGroup.vue
Normal file
124
src/components/shared/select/SelectProductGroup.vue
Normal file
|
|
@ -0,0 +1,124 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, onMounted } from 'vue';
|
||||||
|
|
||||||
|
import { createSelect, SelectProps } from './select';
|
||||||
|
import SelectInput from '../SelectInput.vue';
|
||||||
|
|
||||||
|
import { ProductGroup } from 'stores/product-service/types';
|
||||||
|
|
||||||
|
import useStore from 'stores/product-service';
|
||||||
|
|
||||||
|
type SelectOption = ProductGroup;
|
||||||
|
|
||||||
|
const value = defineModel<string | null | undefined>('value', {
|
||||||
|
required: true,
|
||||||
|
});
|
||||||
|
const valueOption = defineModel<SelectOption>('valueOption', {
|
||||||
|
required: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const selectOptions = ref<SelectOption[]>([]);
|
||||||
|
|
||||||
|
const { fetchProductGroup: getList, fetchProductGroupById: getById } =
|
||||||
|
useStore();
|
||||||
|
|
||||||
|
defineEmits<{
|
||||||
|
(e: 'create'): void;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
type ExclusiveProps = {
|
||||||
|
selectFirstValue?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
const props = defineProps<SelectProps<typeof getList> & ExclusiveProps>();
|
||||||
|
|
||||||
|
const { getOptions, setFirstValue, getSelectedOption, filter } =
|
||||||
|
createSelect<SelectOption>(
|
||||||
|
{
|
||||||
|
value,
|
||||||
|
valueOption,
|
||||||
|
selectOptions,
|
||||||
|
getList: async (query) => {
|
||||||
|
const ret = await getList({
|
||||||
|
query,
|
||||||
|
...props.params,
|
||||||
|
activeOnly: true,
|
||||||
|
});
|
||||||
|
if (ret) return ret.result;
|
||||||
|
},
|
||||||
|
getByValue: async (id) => {
|
||||||
|
const ret = await getById(id);
|
||||||
|
if (ret) return ret;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ valueField: 'id' },
|
||||||
|
);
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
await getOptions();
|
||||||
|
|
||||||
|
if (props.autoSelectOnSingle && selectOptions.value.length === 1) {
|
||||||
|
setFirstValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (props.selectFirstValue) {
|
||||||
|
setDefaultValue();
|
||||||
|
} else await getSelectedOption();
|
||||||
|
});
|
||||||
|
|
||||||
|
function setDefaultValue() {
|
||||||
|
setFirstValue();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<SelectInput
|
||||||
|
v-model="value"
|
||||||
|
incremental
|
||||||
|
option-label="code"
|
||||||
|
option-value="id"
|
||||||
|
:label
|
||||||
|
:placeholder
|
||||||
|
:readonly
|
||||||
|
:disable="disabled"
|
||||||
|
:option="selectOptions"
|
||||||
|
:hide-selected="false"
|
||||||
|
:fill-input="false"
|
||||||
|
:rules="[
|
||||||
|
(v: string) => !props.required || !!v || $t('form.error.required'),
|
||||||
|
]"
|
||||||
|
@filter="filter"
|
||||||
|
>
|
||||||
|
<template #append v-if="clearable">
|
||||||
|
<q-icon
|
||||||
|
v-if="!readonly && value"
|
||||||
|
name="mdi-close-circle"
|
||||||
|
@click.stop="value = ''"
|
||||||
|
class="cursor-pointer clear-btn"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #option="{ scope }">
|
||||||
|
<q-item
|
||||||
|
v-if="scope.opt"
|
||||||
|
v-bind="scope.itemProps"
|
||||||
|
class="row items-center"
|
||||||
|
>
|
||||||
|
<q-item-section>
|
||||||
|
{{ scope.opt.name }}
|
||||||
|
<span class="app-text-muted text-caption">
|
||||||
|
{{ scope.opt.code }}
|
||||||
|
</span>
|
||||||
|
</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #selected-item="{ opt }">
|
||||||
|
<q-item-section v-if="opt">
|
||||||
|
{{ opt.name }}
|
||||||
|
<span class="app-text-muted text-caption">
|
||||||
|
{{ opt.code }}
|
||||||
|
</span>
|
||||||
|
</q-item-section>
|
||||||
|
</template>
|
||||||
|
</SelectInput>
|
||||||
|
</template>
|
||||||
|
|
@ -7,6 +7,7 @@ import DialogForm from 'src/components/DialogForm.vue';
|
||||||
import TreeView from 'src/components/shared/TreeView.vue';
|
import TreeView from 'src/components/shared/TreeView.vue';
|
||||||
import SelectZone from 'src/components/shared/SelectZone.vue';
|
import SelectZone from 'src/components/shared/SelectZone.vue';
|
||||||
import SelectInput from 'src/components/shared/SelectInput.vue';
|
import SelectInput from 'src/components/shared/SelectInput.vue';
|
||||||
|
import SelectProductGroup from 'src/components/shared/select/SelectProductGroup.vue';
|
||||||
import TotalProductCardComponent from 'src/components/04_product-service/TotalProductCardComponent.vue';
|
import TotalProductCardComponent from 'src/components/04_product-service/TotalProductCardComponent.vue';
|
||||||
import DeleteButton from 'src/components/button/DeleteButton.vue';
|
import DeleteButton from 'src/components/button/DeleteButton.vue';
|
||||||
import { isRoleInclude } from 'src/stores/utils';
|
import { isRoleInclude } from 'src/stores/utils';
|
||||||
|
|
@ -839,8 +840,13 @@ watch(
|
||||||
<template #top>
|
<template #top>
|
||||||
<div class="row items-center app-text-muted">
|
<div class="row items-center app-text-muted">
|
||||||
{{ $t('productService.group.title') }}
|
{{ $t('productService.group.title') }}
|
||||||
<SelectInput
|
|
||||||
|
<SelectProductGroup
|
||||||
|
class="q-pl-sm col-5"
|
||||||
id="product-group-select"
|
id="product-group-select"
|
||||||
|
style="min-height: 50px"
|
||||||
|
clearable
|
||||||
|
v-model:value="selectedProductGroup"
|
||||||
:placeholder="
|
:placeholder="
|
||||||
!selectedProductGroup
|
!selectedProductGroup
|
||||||
? $t('general.select', {
|
? $t('general.select', {
|
||||||
|
|
@ -848,40 +854,10 @@ watch(
|
||||||
})
|
})
|
||||||
: ''
|
: ''
|
||||||
"
|
"
|
||||||
v-model="selectedProductGroup"
|
:params="{
|
||||||
clearable
|
activeOnly: true,
|
||||||
optionLabel="name"
|
}"
|
||||||
optionValue="id"
|
/>
|
||||||
class="q-pl-sm col-5"
|
|
||||||
:fillInput="false"
|
|
||||||
:hide-selected="false"
|
|
||||||
:option="productGroup"
|
|
||||||
style="min-height: 50px"
|
|
||||||
>
|
|
||||||
<template #option="{ scope }">
|
|
||||||
<q-item
|
|
||||||
v-if="scope.opt"
|
|
||||||
v-bind="scope.itemProps"
|
|
||||||
class="row items-center"
|
|
||||||
>
|
|
||||||
<q-item-section>
|
|
||||||
{{ scope.opt.name }}
|
|
||||||
<span class="app-text-muted text-caption">
|
|
||||||
{{ scope.opt.code }}
|
|
||||||
</span>
|
|
||||||
</q-item-section>
|
|
||||||
</q-item>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template #selected-item="{ scope }">
|
|
||||||
<q-item-section v-if="scope.opt">
|
|
||||||
{{ scope.opt.name }}
|
|
||||||
<span class="app-text-muted text-caption">
|
|
||||||
{{ scope.opt.code }}
|
|
||||||
</span>
|
|
||||||
</q-item-section>
|
|
||||||
</template>
|
|
||||||
</SelectInput>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue