feat: show option propertie (service)

This commit is contained in:
puriphatt 2024-06-24 11:10:28 +00:00
parent 9ce656ae45
commit c240963512
5 changed files with 158 additions and 107 deletions

View file

@ -1,5 +1,9 @@
<script setup lang="ts">
import { Icon } from '@iconify/vue';
import { Attributes } from 'src/stores/product-service/types';
import useOptionStore from 'src/stores/options';
const optionStore = useOptionStore();
const remark = defineModel<string>('remark');
const detail = defineModel<string>('detail');
@ -9,6 +13,7 @@ const code = defineModel<string>('code');
const serviceCode = defineModel<string>('serviceCode');
const serviceName = defineModel<string>('serviceNameTh');
const serviceDescription = defineModel<string>('serviceDescription');
const serviceAttributes = defineModel<Attributes>('serviceAttributes');
defineProps<{
dense?: boolean;
@ -120,6 +125,16 @@ defineEmits<{
</q-btn>
</template>
</q-input>
<div v-if="readonly && serviceAttributes" class="col-12 q-gutter-x-md">
<span
v-for="(p, index) in serviceAttributes.additional"
:key="index"
class="bordered q-px-sm surface-tab"
style="border-radius: 6px"
>
{{ optionStore.mapOption(p.fieldName ?? '') }}
</span>
</div>
<q-input
id="input-service-description"
for="input-service-description"

View file

@ -5,10 +5,10 @@ import { moveItemUp, moveItemDown, deleteItem, dialog } from 'src/stores/utils';
import NoData from 'src/components/NoData.vue';
import WorkManagementComponent from './WorkManagementComponent.vue';
const { t } = useI18n();
import { WorkItems } from 'src/stores/product-service/types';
const { t } = useI18n();
const workItems = defineModel<WorkItems[]>('workItems', { default: [] });
defineProps<{
@ -75,6 +75,7 @@ function confirmDelete(items: unknown[], index: number) {
:readonly="readonly"
v-model:work-name="workItems[index].name"
v-model:product-items="work.product"
v-model:attributes="work.attributes"
@add-product="$emit('addProduct', index)"
@move-work-up="moveItemUp(workItems, index)"
@move-work-down="moveItemDown(workItems, index)"

View file

@ -3,10 +3,12 @@ import { Icon } from '@iconify/vue';
import { formatNumberDecimal } from 'src/stores/utils';
import useProductServiceStore from 'src/stores/product-service';
import { ProductList } from 'src/stores/product-service/types';
import useOptionStore from 'src/stores/options';
import { Attributes, ProductList } from 'src/stores/product-service/types';
import { storeToRefs } from 'pinia';
const productServiceStore = useProductServiceStore();
const optionStore = useOptionStore();
const { fetchListOfWork } = productServiceStore;
const { workNameItems } = storeToRefs(productServiceStore);
@ -19,6 +21,7 @@ defineProps<{
}>();
const workName = defineModel<string>('workName');
const attributes = defineModel<Attributes>('attributes');
const productItems = defineModel<(ProductList & { nameEn: string })[]>(
'productItems',
{
@ -50,119 +53,135 @@ defineEmits<{
header-style="border-top-left-radius: var(--radius-2); border-top-right-radius: var(--radius-2)"
>
<template v-slot:header>
<div class="row items-center q-py-sm full-width" @click.stop>
<q-btn
v-if="!readonly"
id="btn-work-up-product"
icon="mdi-arrow-up"
dense
flat
round
:disable="index === 0"
style="color: hsl(var(--text-mute-2))"
@click.stop="$emit('moveWorkUp')"
/>
<q-btn
v-if="!readonly"
id="btn-work-down-product"
icon="mdi-arrow-down"
dense
flat
round
class="q-mx-sm"
:disable="index === length - 1"
style="color: hsl(var(--text-mute-2))"
@click.stop="$emit('moveWorkDown')"
/>
<div
for="select-work-name"
class="col rounded q-py-sm q-px-md"
:class="{ bordered: !readonly }"
:style="`background-color:${readonly ? 'var(--surface-2)' : 'var(--surface-1); z-index: 2'}`"
@click="() => (readonly ? '' : fetchListOfWork())"
>
<div class="column full-width">
<div class="row items-center q-py-sm full-width" @click.stop>
<q-btn
v-if="!readonly"
id="btn-work-up-product"
icon="mdi-arrow-up"
dense
unelevated
flat
round
:disable="index === 0"
style="color: hsl(var(--text-mute-2))"
@click.stop="$emit('moveWorkUp')"
/>
<q-btn
v-if="!readonly"
id="btn-work-down-product"
icon="mdi-arrow-down"
dense
flat
round
class="q-mx-sm"
:disable="index === length - 1"
style="color: hsl(var(--text-mute-2))"
@click.stop="$emit('moveWorkDown')"
/>
<div
for="select-work-name"
class="col rounded q-py-sm q-px-md"
:class="{ bordered: !readonly }"
:style="`background-color:${readonly ? 'var(--surface-2)' : 'var(--surface-1); z-index: 2'}`"
@click="() => (readonly ? '' : fetchListOfWork())"
>
<q-btn
v-if="!readonly"
dense
unelevated
round
padding="0"
class="q-mr-sm"
style="background-color: var(--surface-tab)"
@click.stop="$emit('workProperties')"
>
<Icon
icon="basil:settings-adjust-solid"
width="24px"
style="color: var(--stone-7)"
/>
</q-btn>
<span class="text-body2" style="color: var(--foreground)">
{{ $t('workNo') }} {{ index + 1 }} :
<span class="app-text-muted-2">
{{ workName ? workName : $t('workName') }}
</span>
</span>
<q-menu v-if="!readonly" fit anchor="bottom left" self="top left">
<q-item>
<div class="full-width flex items-center justify-between">
{{ $t('workName') }}
<q-btn
dense
unelevated
class="bordered q-px-sm"
style="
border-radius: var(--radius-2);
color: hsl(var(--info-bg));
"
@click.stop="$emit('manageWorkName')"
>
<q-icon name="mdi-cog" size="xs" class="q-mr-sm" />
{{ $t('manage') }}
</q-btn>
</div>
</q-item>
<q-item
@click="workName = item.name"
clickable
v-for="(item, index) in workNameItems"
:key="index"
>
<div class="full-width flex items-center">
<q-icon
v-if="workName === item.name"
name="mdi-checkbox-marked"
size="xs"
color="primary"
class="q-mr-sm"
/>
<q-icon
v-else
name="mdi-checkbox-blank-outline"
size="xs"
style="color: hsl(var(--text-mute))"
class="q-mr-sm"
/>
{{ item.name }}
</div>
</q-item>
</q-menu>
</div>
<q-btn
v-if="!readonly"
id="btn-delete-work"
icon="mdi-trash-can-outline"
dense
flat
round
padding="0"
class="q-mr-sm"
style="background-color: var(--surface-tab)"
@click.stop="$emit('workProperties')"
color="negative"
class="q-ml-sm"
@click.stop="$emit('deleteWork')"
>
<Icon
icon="basil:settings-adjust-solid"
width="24px"
style="color: var(--stone-7)"
/>
<q-tooltip>{{ $t('delete') }}</q-tooltip>
</q-btn>
<span class="text-body2" style="color: var(--foreground)">
{{ $t('workNo') }} {{ index + 1 }} :
<span class="app-text-muted-2">
{{ workName ? workName : $t('workName') }}
</span>
</span>
<q-menu v-if="!readonly" fit anchor="bottom left" self="top left">
<q-item>
<div class="full-width flex items-center justify-between">
{{ $t('workName') }}
<q-btn
dense
unelevated
class="bordered q-px-sm"
style="
border-radius: var(--radius-2);
color: hsl(var(--info-bg));
"
@click.stop="$emit('manageWorkName')"
>
<q-icon name="mdi-cog" size="xs" class="q-mr-sm" />
{{ $t('manage') }}
</q-btn>
</div>
</q-item>
<q-item
@click="workName = item.name"
clickable
v-for="(item, index) in workNameItems"
:key="index"
>
<div class="full-width flex items-center">
<q-icon
v-if="workName === item.name"
name="mdi-checkbox-marked"
size="xs"
color="primary"
class="q-mr-sm"
/>
<q-icon
v-else
name="mdi-checkbox-blank-outline"
size="xs"
style="color: hsl(var(--text-mute))"
class="q-mr-sm"
/>
{{ item.name }}
</div>
</q-item>
</q-menu>
</div>
<q-btn
v-if="!readonly"
id="btn-delete-work"
icon="mdi-trash-can-outline"
dense
flat
round
padding="0"
color="negative"
class="q-ml-sm"
@click.stop="$emit('deleteWork')"
<div
v-if="readonly && attributes"
class="row q-pb-md q-px-md q-gutter-x-md"
>
<q-tooltip>{{ $t('delete') }}</q-tooltip>
</q-btn>
<span
v-for="(p, index) in attributes.additional"
:key="index"
class="bordered q-px-sm surface-tab"
style="border-radius: 6px"
>
{{ optionStore.mapOption(p.fieldName ?? '') }}
</span>
</div>
</div>
</template>
<div class="surface-2">
@ -318,7 +337,9 @@ defineEmits<{
:deep(
.q-item__section.column.q-item__section--side.justify-center.q-item__section--avatar.q-focusable.relative-position.cursor-pointer
) {
justify-content: start !important;
padding-right: 8px !important;
padding-top: 16px;
min-width: 0px;
}
</style>

View file

@ -1881,6 +1881,7 @@ watch(currentStatus, async () => {
openPropertiesDialog('service');
}
"
v-model:service-attributes="formDataProductService.attributes"
v-model:service-code="formDataProductService.code"
v-model:service-description="formDataProductService.detail"
v-model:service-name-th="formDataProductService.name"

View file

@ -4,8 +4,21 @@ import { defineStore } from 'pinia';
const useOptionStore = defineStore('optionStore', () => {
const globalOption = ref();
function mapOption(value: string) {
for (const category in globalOption.value) {
if (globalOption.value.hasOwnProperty(category)) {
const option = globalOption.value[category].find(
(opt: { value: string }) => opt.value === value,
);
if (option) return option.label;
}
}
}
return {
globalOption,
mapOption,
};
});