fix(04): product service (unfinish)
This commit is contained in:
parent
485e0b82b2
commit
7cfc1ddee5
4 changed files with 342 additions and 165 deletions
|
|
@ -107,7 +107,7 @@ const branchFilter = selectFilterOptionRefMod(
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="service" class="col-9 row q-col-gutter-md">
|
<div v-if="service" class="col-12 row q-col-gutter-sm">
|
||||||
<q-input
|
<q-input
|
||||||
lazy-rules="ondemand"
|
lazy-rules="ondemand"
|
||||||
id="input-service-code"
|
id="input-service-code"
|
||||||
|
|
|
||||||
|
|
@ -18,46 +18,50 @@ defineEmits<{
|
||||||
}>();
|
}>();
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div class="col-3 app-text-muted">
|
<div class="full-width full-height">
|
||||||
• {{ $t(`properties`) }}
|
<div
|
||||||
<div>
|
class="text-weight-bold text-body1 flex items-center justify-between q-px-md q-py-sm"
|
||||||
|
style="background: hsla(var(--info-bg) / 0.1)"
|
||||||
|
>
|
||||||
|
{{ $t(`serviceProperties`) }}
|
||||||
|
|
||||||
<q-btn
|
<q-btn
|
||||||
:disable="readonly"
|
:disable="readonly"
|
||||||
dense
|
dense
|
||||||
|
flat
|
||||||
unelevated
|
unelevated
|
||||||
outline
|
class="q-px-sm"
|
||||||
class="q-mt-sm q-px-sm"
|
color="info"
|
||||||
color="primary"
|
|
||||||
@click="$emit('serviceProperties')"
|
@click="$emit('serviceProperties')"
|
||||||
>
|
>
|
||||||
<Icon
|
<Icon
|
||||||
icon="basil:settings-adjust-solid"
|
icon="basil:settings-adjust-solid"
|
||||||
width="24px"
|
width="24px"
|
||||||
class="q-mr-sm"
|
class="q-mr-sm"
|
||||||
style="color: var(--brand-1)"
|
style="color: hsl(var(--info-bg))"
|
||||||
/>
|
/>
|
||||||
{{ $t('properties') }}
|
{{ $t('serviceProperties') }}
|
||||||
</q-btn>
|
</q-btn>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-9 row">
|
<div class="col-12 row q-px-md q-py-xs items-center surface-1 scroll">
|
||||||
<div
|
|
||||||
v-if="serviceAttributes.additional.length > 0"
|
|
||||||
class="col q-gutter-sm row items-center"
|
|
||||||
>
|
|
||||||
<div
|
<div
|
||||||
v-for="(p, index) in serviceAttributes.additional"
|
v-if="serviceAttributes.additional.length > 0"
|
||||||
:key="index"
|
class="row items-center q-gutter-sm items-center"
|
||||||
class="bordered q-px-sm surface-3"
|
|
||||||
style="border-radius: 6px"
|
|
||||||
>
|
>
|
||||||
{{ optionStore.mapOption(p.fieldName ?? '') }}
|
<div
|
||||||
|
v-for="(p, index) in serviceAttributes.additional"
|
||||||
|
:key="index"
|
||||||
|
class="bordered q-px-sm surface-3"
|
||||||
|
style="border-radius: 6px"
|
||||||
|
>
|
||||||
|
{{ optionStore.mapOption(p.fieldName ?? '') }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div v-else class="col flex items-center app-text-muted">
|
<div v-else class="col flex items-center app-text-muted">
|
||||||
{{ $t('noProperties') }}
|
{{ $t('noProperties') }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -3,14 +3,15 @@ import { ref } from 'vue';
|
||||||
import ToggleButton from './button/ToggleButton.vue';
|
import ToggleButton from './button/ToggleButton.vue';
|
||||||
|
|
||||||
defineProps<{
|
defineProps<{
|
||||||
icon?: string;
|
|
||||||
fallbackCover?: string;
|
|
||||||
color?: string;
|
|
||||||
img?: string | null;
|
img?: string | null;
|
||||||
bgColor?: string;
|
icon?: string;
|
||||||
title?: string;
|
title?: string;
|
||||||
caption?: string;
|
caption?: string;
|
||||||
|
color?: string;
|
||||||
|
bgColor?: string;
|
||||||
toggleTitle?: string;
|
toggleTitle?: string;
|
||||||
|
fallbackImg?: string;
|
||||||
|
fallbackCover?: string;
|
||||||
|
|
||||||
hideFade?: boolean;
|
hideFade?: boolean;
|
||||||
hideActive?: boolean;
|
hideActive?: boolean;
|
||||||
|
|
@ -67,12 +68,6 @@ const showOverlay = ref(false);
|
||||||
class="surface-1"
|
class="surface-1"
|
||||||
style="border-radius: 50%; border: 4px solid var(--surface-1)"
|
style="border-radius: 50%; border: 4px solid var(--surface-1)"
|
||||||
>
|
>
|
||||||
<!-- <div
|
|
||||||
class="avatar__status"
|
|
||||||
style="z-index: 2"
|
|
||||||
:style="`${active ? 'background-color: hsla(var(--positive-bg) / 1)' : 'background-color: hsla(var(--text-mute) / 1)'}`"
|
|
||||||
></div> -->
|
|
||||||
|
|
||||||
<q-avatar
|
<q-avatar
|
||||||
size="6rem"
|
size="6rem"
|
||||||
font-size="3rem"
|
font-size="3rem"
|
||||||
|
|
@ -89,7 +84,26 @@ const showOverlay = ref(false);
|
||||||
>
|
>
|
||||||
<q-img id="profile-view" v-if="img" :src="img" :ratio="1">
|
<q-img id="profile-view" v-if="img" :src="img" :ratio="1">
|
||||||
<template #error>
|
<template #error>
|
||||||
|
<q-img
|
||||||
|
v-if="fallbackImg"
|
||||||
|
:src="fallbackImg"
|
||||||
|
:ratio="1"
|
||||||
|
style="background-color: transparent"
|
||||||
|
>
|
||||||
|
<template #error>
|
||||||
|
<div
|
||||||
|
class="full-width full-height flex items-center justify-center"
|
||||||
|
style="background-color: transparent"
|
||||||
|
:style="{
|
||||||
|
color: `${color || 'white'}`,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<q-icon :name="icon || 'mdi-account'" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</q-img>
|
||||||
<div
|
<div
|
||||||
|
v-else
|
||||||
class="full-width full-height flex items-center justify-center"
|
class="full-width full-height flex items-center justify-center"
|
||||||
style="background-color: transparent"
|
style="background-color: transparent"
|
||||||
:style="{
|
:style="{
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ import ProductCardComponent from 'components/04_product-service/ProductCardCompo
|
||||||
import StatCard from 'components/StatCardComponent.vue';
|
import StatCard from 'components/StatCardComponent.vue';
|
||||||
import DrawerInfo from 'components/DrawerInfo.vue';
|
import DrawerInfo from 'components/DrawerInfo.vue';
|
||||||
import BasicInformation from 'components/04_product-service/BasicInformation.vue';
|
import BasicInformation from 'components/04_product-service/BasicInformation.vue';
|
||||||
import FormDialog from 'components/FormDialog.vue';
|
|
||||||
import TooltipComponent from 'components/TooltipComponent.vue';
|
import TooltipComponent from 'components/TooltipComponent.vue';
|
||||||
import ButtonAddComponent from 'components/ButtonAddCompoent.vue';
|
import ButtonAddComponent from 'components/ButtonAddCompoent.vue';
|
||||||
import BasicInfoProduct from 'components/04_product-service/BasicInfoProduct.vue';
|
import BasicInfoProduct from 'components/04_product-service/BasicInfoProduct.vue';
|
||||||
|
|
@ -32,6 +31,7 @@ import DialogForm from 'components/DialogForm.vue';
|
||||||
import ProfileBanner from 'components/ProfileBanner.vue';
|
import ProfileBanner from 'components/ProfileBanner.vue';
|
||||||
import SideMenu from 'components/SideMenu.vue';
|
import SideMenu from 'components/SideMenu.vue';
|
||||||
import ImageUploadDialog from 'components/ImageUploadDialog.vue';
|
import ImageUploadDialog from 'components/ImageUploadDialog.vue';
|
||||||
|
import ToggleButton from 'src/components/button/ToggleButton.vue';
|
||||||
|
|
||||||
import useFlowStore from 'stores/flow';
|
import useFlowStore from 'stores/flow';
|
||||||
import useMyBranchStore from 'stores/my-branch';
|
import useMyBranchStore from 'stores/my-branch';
|
||||||
|
|
@ -134,7 +134,7 @@ const stat = ref<
|
||||||
color: 'orange',
|
color: 'orange',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: 'mdi-folder',
|
icon: 'mdi-shopping',
|
||||||
count: 0,
|
count: 0,
|
||||||
label: 'product',
|
label: 'product',
|
||||||
mode: 'product',
|
mode: 'product',
|
||||||
|
|
@ -185,6 +185,7 @@ const treeProductTypeAndGroup = computed(() => {
|
||||||
return tempValue;
|
return tempValue;
|
||||||
});
|
});
|
||||||
const profileFileImg = ref<File | null>(null);
|
const profileFileImg = ref<File | null>(null);
|
||||||
|
const refImageUpload = ref<InstanceType<typeof ImageUploadDialog>>();
|
||||||
|
|
||||||
const inputSearch = ref('');
|
const inputSearch = ref('');
|
||||||
const inputSearchProductAndService = ref('');
|
const inputSearchProductAndService = ref('');
|
||||||
|
|
@ -394,7 +395,7 @@ const workNameRef = ref();
|
||||||
const selectProduct = ref<ProductList[]>([]);
|
const selectProduct = ref<ProductList[]>([]);
|
||||||
const currentWorkIndex = ref<number>(0);
|
const currentWorkIndex = ref<number>(0);
|
||||||
|
|
||||||
const currentServiceTab = ref('serviceInformation');
|
const currentServiceTab = ref(1);
|
||||||
const propertiesDialog = ref<boolean>(false);
|
const propertiesDialog = ref<boolean>(false);
|
||||||
|
|
||||||
const totalProduct = ref<number>(0);
|
const totalProduct = ref<number>(0);
|
||||||
|
|
@ -964,6 +965,7 @@ const prevProduct = ref<ProductCreate>({
|
||||||
function assignFormDataProduct(data: ProductList) {
|
function assignFormDataProduct(data: ProductList) {
|
||||||
statusToggle.value = data.status === 'INACTIVE' ? false : true;
|
statusToggle.value = data.status === 'INACTIVE' ? false : true;
|
||||||
profileUrl.value = `${baseUrl.value}/product/${data?.id}/image`;
|
profileUrl.value = `${baseUrl.value}/product/${data?.id}/image`;
|
||||||
|
|
||||||
profileSubmit.value = true;
|
profileSubmit.value = true;
|
||||||
|
|
||||||
prevProduct.value = {
|
prevProduct.value = {
|
||||||
|
|
@ -1089,8 +1091,9 @@ async function submitService() {
|
||||||
|
|
||||||
async function submitProduct() {
|
async function submitProduct() {
|
||||||
formDataProduct.value.productTypeId = currentIdType.value;
|
formDataProduct.value.productTypeId = currentIdType.value;
|
||||||
if (profileSubmit.value) {
|
if (profileFileImg.value) {
|
||||||
formDataProduct.value.image = imageProduct.value;
|
formDataProduct.value.image = profileFileImg.value;
|
||||||
|
// formDataProduct.value.image = imageProduct.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dialogProduct.value) {
|
if (dialogProduct.value) {
|
||||||
|
|
@ -1282,6 +1285,18 @@ function handleHold(node: ProductGroup) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function handleImageUpload(file: File | null, url: string | null) {
|
||||||
|
// if (!infoProductEdit.value && !dialogProductEdit.value) {
|
||||||
|
// infoProductEdit.value = true;
|
||||||
|
// await submitProduct();
|
||||||
|
// infoProductEdit.value = false;
|
||||||
|
// }
|
||||||
|
// if (infoProductEdit.value && !dialogProductEdit.value) {
|
||||||
|
// await submitProduct();
|
||||||
|
// }
|
||||||
|
// imageDialog.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
utilsStore.currentTitle.title = 'mainProductTitle';
|
utilsStore.currentTitle.title = 'mainProductTitle';
|
||||||
utilsStore.currentTitle.path = [
|
utilsStore.currentTitle.path = [
|
||||||
|
|
@ -1310,6 +1325,7 @@ watch(productMode, () => {
|
||||||
const tmp: typeof utilsStore.currentTitle.path = [
|
const tmp: typeof utilsStore.currentTitle.path = [
|
||||||
{
|
{
|
||||||
text: 'manage',
|
text: 'manage',
|
||||||
|
i18n: true,
|
||||||
handler: () => {
|
handler: () => {
|
||||||
productMode.value = 'group';
|
productMode.value = 'group';
|
||||||
expandedTree.value = [];
|
expandedTree.value = [];
|
||||||
|
|
@ -1322,6 +1338,7 @@ watch(productMode, () => {
|
||||||
if (productMode.value === 'type' || productMode.value === 'service') {
|
if (productMode.value === 'type' || productMode.value === 'service') {
|
||||||
tmp.push({
|
tmp.push({
|
||||||
text: 'productGroup',
|
text: 'productGroup',
|
||||||
|
i18n: true,
|
||||||
argsi18n: { name: pathGroupName.value },
|
argsi18n: { name: pathGroupName.value },
|
||||||
handler: () => {
|
handler: () => {
|
||||||
productMode.value = 'type';
|
productMode.value = 'type';
|
||||||
|
|
@ -1332,7 +1349,11 @@ watch(productMode, () => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (productMode.value === 'service') {
|
if (productMode.value === 'service') {
|
||||||
tmp.push({ text: 'productType', argsi18n: { name: pathTypeName.value } });
|
tmp.push({
|
||||||
|
text: 'productType',
|
||||||
|
i18n: true,
|
||||||
|
argsi18n: { name: pathTypeName.value },
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
utilsStore.currentTitle.path = tmp;
|
utilsStore.currentTitle.path = tmp;
|
||||||
|
|
@ -1435,7 +1456,7 @@ watch(
|
||||||
clearFormGroup();
|
clearFormGroup();
|
||||||
clearFormService();
|
clearFormService();
|
||||||
await fetchListOfOptionBranch();
|
await fetchListOfOptionBranch();
|
||||||
currentServiceTab = 'serviceInformation';
|
currentServiceTab = 1;
|
||||||
dialogService = true;
|
dialogService = true;
|
||||||
}
|
}
|
||||||
"
|
"
|
||||||
|
|
@ -1447,7 +1468,7 @@ watch(
|
||||||
{{ $t('dataSum') }}
|
{{ $t('dataSum') }}
|
||||||
<q-btn
|
<q-btn
|
||||||
class="q-ml-xs"
|
class="q-ml-xs"
|
||||||
icon="mdi-pin"
|
icon="mdi-pin-outline"
|
||||||
color="primary"
|
color="primary"
|
||||||
size="sm"
|
size="sm"
|
||||||
flat
|
flat
|
||||||
|
|
@ -2349,16 +2370,14 @@ watch(
|
||||||
|
|
||||||
<q-item dense>
|
<q-item dense>
|
||||||
<q-item-section class="q-py-sm">
|
<q-item-section class="q-py-sm">
|
||||||
<div class="q-pa-sm surface-2 rounded">
|
<div
|
||||||
<q-toggle
|
class="q-pa-sm surface-2 rounded flex items-center"
|
||||||
color="positive"
|
>
|
||||||
|
<ToggleButton
|
||||||
|
two-way
|
||||||
:id="`view-detail-btn-${props.row.name}-status`"
|
:id="`view-detail-btn-${props.row.name}-status`"
|
||||||
dense
|
:model-value="
|
||||||
size="sm"
|
|
||||||
:label="
|
|
||||||
props.row.status !== 'INACTIVE'
|
props.row.status !== 'INACTIVE'
|
||||||
? $t('switchOnLabel')
|
|
||||||
: $t('switchOffLabel')
|
|
||||||
"
|
"
|
||||||
@click="
|
@click="
|
||||||
async () => {
|
async () => {
|
||||||
|
|
@ -2368,10 +2387,14 @@ watch(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
"
|
"
|
||||||
:model-value="
|
|
||||||
props.row.status !== 'INACTIVE'
|
|
||||||
"
|
|
||||||
/>
|
/>
|
||||||
|
<span class="q-pl-md">
|
||||||
|
{{
|
||||||
|
props.row.status !== 'INACTIVE'
|
||||||
|
? $t('switchOnLabel')
|
||||||
|
: $t('switchOffLabel')
|
||||||
|
}}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</q-item-section>
|
</q-item-section>
|
||||||
</q-item>
|
</q-item>
|
||||||
|
|
@ -2896,15 +2919,27 @@ watch(
|
||||||
class="table__icon"
|
class="table__icon"
|
||||||
:class="`icon-color-${productAndServiceTab === 'product' ? 'green' : 'orange'}`"
|
:class="`icon-color-${productAndServiceTab === 'product' ? 'green' : 'orange'}`"
|
||||||
>
|
>
|
||||||
<q-icon
|
<q-avatar size="md">
|
||||||
size="md"
|
<q-img
|
||||||
style="scale: 0.8"
|
class="text-center"
|
||||||
:name="
|
:ratio="1"
|
||||||
productAndServiceTab === 'product'
|
:src="`
|
||||||
? 'mdi-folder'
|
${props.row.imageUrl ?? null}
|
||||||
: 'mdi-server-network'
|
`"
|
||||||
"
|
>
|
||||||
/>
|
<template #error>
|
||||||
|
<q-icon
|
||||||
|
size="sm"
|
||||||
|
:name="
|
||||||
|
productAndServiceTab === 'product'
|
||||||
|
? 'mdi-shopping'
|
||||||
|
: 'mdi-server-network'
|
||||||
|
"
|
||||||
|
style="color: var(--teal-10); top: 10%"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</q-img>
|
||||||
|
</q-avatar>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div class="col">
|
||||||
|
|
@ -3170,16 +3205,15 @@ watch(
|
||||||
|
|
||||||
<q-item dense>
|
<q-item dense>
|
||||||
<q-item-section class="q-py-sm">
|
<q-item-section class="q-py-sm">
|
||||||
<div class="q-pa-sm surface-2 rounded">
|
<div
|
||||||
<q-toggle
|
class="q-pa-sm surface-2 rounded flex items-center"
|
||||||
color="positive"
|
>
|
||||||
|
<ToggleButton
|
||||||
|
two-way
|
||||||
:id="`view-detail-btn-${props.row.name}-status`"
|
:id="`view-detail-btn-${props.row.name}-status`"
|
||||||
dense
|
:model-value="
|
||||||
size="sm"
|
props.row.status === 'CREATED' ||
|
||||||
:label="
|
props.row.status === 'ACTIVE'
|
||||||
props.row.status !== 'INACTIVE'
|
|
||||||
? $t('switchOnLabel')
|
|
||||||
: $t('switchOffLabel')
|
|
||||||
"
|
"
|
||||||
@click="
|
@click="
|
||||||
() => {
|
() => {
|
||||||
|
|
@ -3190,11 +3224,14 @@ watch(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
"
|
"
|
||||||
:model-value="
|
|
||||||
props.row.status === 'CREATED' ||
|
|
||||||
props.row.status === 'ACTIVE'
|
|
||||||
"
|
|
||||||
/>
|
/>
|
||||||
|
<span class="q-pl-md">
|
||||||
|
{{
|
||||||
|
props.row.status !== 'INACTIVE'
|
||||||
|
? $t('switchOnLabel')
|
||||||
|
: $t('switchOffLabel')
|
||||||
|
}}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</q-item-section>
|
</q-item-section>
|
||||||
</q-item>
|
</q-item>
|
||||||
|
|
@ -3351,8 +3388,9 @@ watch(
|
||||||
hideFade
|
hideFade
|
||||||
hideActive
|
hideActive
|
||||||
useToggle
|
useToggle
|
||||||
|
:img="`/images/product-service-${productMode}-avatar-add${productMode === 'type' ? ($q.dark.isActive ? '-d' : '-l') : ''}.png`"
|
||||||
:toggleTitle="$t('formDialogTitleUseStatus')"
|
:toggleTitle="$t('formDialogTitleUseStatus')"
|
||||||
:icon="productMode === 'group' ? 'mdi-folder' : 'mdi-folder-table'"
|
:icon="productMode === 'group' ? 'mdi-folder-plus' : 'mdi-folder-table'"
|
||||||
:title="formDataGroup.name"
|
:title="formDataGroup.name"
|
||||||
:caption="formDataGroup.code"
|
:caption="formDataGroup.code"
|
||||||
:menu="[
|
:menu="[
|
||||||
|
|
@ -3428,9 +3466,7 @@ watch(
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</DialogForm>
|
</DialogForm>
|
||||||
|
|
||||||
<DrawerInfo
|
<DrawerInfo
|
||||||
:hideAction="!currentStatusProduct"
|
|
||||||
ref="formDialogRef"
|
ref="formDialogRef"
|
||||||
v-model:drawerOpen="drawerInfo"
|
v-model:drawerOpen="drawerInfo"
|
||||||
:title="
|
:title="
|
||||||
|
|
@ -3559,7 +3595,7 @@ watch(
|
||||||
</InfoForm>
|
</InfoForm>
|
||||||
</DrawerInfo>
|
</DrawerInfo>
|
||||||
|
|
||||||
<FormDialog
|
<DialogForm
|
||||||
v-model:modal="dialogProductServiceType"
|
v-model:modal="dialogProductServiceType"
|
||||||
:title="'สร้างสินค้าและบริการ'"
|
:title="'สร้างสินค้าและบริการ'"
|
||||||
no-footer
|
no-footer
|
||||||
|
|
@ -3585,9 +3621,9 @@ watch(
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</FormDialog>
|
</DialogForm>
|
||||||
|
|
||||||
<FormDialog
|
<DialogForm
|
||||||
v-model:modal="dialogTotalProduct"
|
v-model:modal="dialogTotalProduct"
|
||||||
noAddress
|
noAddress
|
||||||
noAppBox
|
noAppBox
|
||||||
|
|
@ -3704,7 +3740,7 @@ watch(
|
||||||
</AppBox>
|
</AppBox>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</FormDialog>
|
</DialogForm>
|
||||||
|
|
||||||
<!-- Add Product -->
|
<!-- Add Product -->
|
||||||
<DialogForm
|
<DialogForm
|
||||||
|
|
@ -3737,7 +3773,7 @@ watch(
|
||||||
useToggle
|
useToggle
|
||||||
hideActive
|
hideActive
|
||||||
:toggleTitle="$t('formDialogTitleUseStatus')"
|
:toggleTitle="$t('formDialogTitleUseStatus')"
|
||||||
img="/images/product-avatar.png"
|
:img="profileUrl || '/images/product-avatar-add.png'"
|
||||||
fallbackCover="/images/product-banner.png"
|
fallbackCover="/images/product-banner.png"
|
||||||
bgColor="#ebf1ee"
|
bgColor="#ebf1ee"
|
||||||
:menu="[
|
:menu="[
|
||||||
|
|
@ -3747,6 +3783,8 @@ watch(
|
||||||
bgColor: 'var(--surface-1)',
|
bgColor: 'var(--surface-1)',
|
||||||
},
|
},
|
||||||
]"
|
]"
|
||||||
|
@view="imageDialog = true"
|
||||||
|
@edit="refImageUpload && refImageUpload.browse()"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -3773,7 +3811,7 @@ watch(
|
||||||
>
|
>
|
||||||
<span class="full-width q-py-sm" style="padding-inline: 20px">
|
<span class="full-width q-py-sm" style="padding-inline: 20px">
|
||||||
{{
|
{{
|
||||||
v === 0
|
v === 1
|
||||||
? $t('formDialogTitleInformation')
|
? $t('formDialogTitleInformation')
|
||||||
: $t('priceInformation')
|
: $t('priceInformation')
|
||||||
}}
|
}}
|
||||||
|
|
@ -3810,7 +3848,7 @@ watch(
|
||||||
</DialogForm>
|
</DialogForm>
|
||||||
|
|
||||||
<!-- edit product -->
|
<!-- edit product -->
|
||||||
<FormDialog
|
<DialogForm
|
||||||
:edit="!(formDataProduct.status === 'INACTIVE')"
|
:edit="!(formDataProduct.status === 'INACTIVE')"
|
||||||
:isEdit="infoProductEdit"
|
:isEdit="infoProductEdit"
|
||||||
v-model:modal="dialogProductEdit"
|
v-model:modal="dialogProductEdit"
|
||||||
|
|
@ -3836,12 +3874,98 @@ watch(
|
||||||
"
|
"
|
||||||
:close="
|
:close="
|
||||||
() => {
|
() => {
|
||||||
|
infoProductEdit = false;
|
||||||
dialogProductEdit = false;
|
dialogProductEdit = false;
|
||||||
flowStore.rotate();
|
flowStore.rotate();
|
||||||
}
|
}
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<template #prepend>
|
<div class="q-mx-lg q-mt-lg">
|
||||||
|
<ProfileBanner
|
||||||
|
active
|
||||||
|
hideFade
|
||||||
|
useToggle
|
||||||
|
hideActive
|
||||||
|
icon="mdi-shopping"
|
||||||
|
fallbackImg="/images/product-avatar.png"
|
||||||
|
color="var(--teal-10)"
|
||||||
|
:readonly="!infoProductEdit"
|
||||||
|
:toggleTitle="$t('formDialogTitleUseStatus')"
|
||||||
|
:img="profileUrl || '/images/product-avatar.png'"
|
||||||
|
fallbackCover="/images/product-banner.png"
|
||||||
|
bgColor="#ebf1ee"
|
||||||
|
:menu="[
|
||||||
|
{
|
||||||
|
icon: 'mdi-office-building-outline',
|
||||||
|
color: 'hsl(var(--info-bg))',
|
||||||
|
bgColor: 'var(--surface-1)',
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
@view="imageDialog = true"
|
||||||
|
@edit="refImageUpload && refImageUpload.browse()"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="col surface-1 q-ma-lg rounded bordered scroll row relative-position"
|
||||||
|
id="group-form"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="col"
|
||||||
|
style="height: 100%; max-height: 100; overflow-y: auto"
|
||||||
|
v-if="$q.screen.gt.sm"
|
||||||
|
>
|
||||||
|
<div class="q-py-md q-pl-md q-pr-sm">
|
||||||
|
<q-item
|
||||||
|
v-for="v in 2"
|
||||||
|
:key="v"
|
||||||
|
dense
|
||||||
|
clickable
|
||||||
|
class="no-padding items-center rounded full-width"
|
||||||
|
:class="{ 'q-mt-xs': v > 1 }"
|
||||||
|
active-class="product-form-active"
|
||||||
|
:active="productTab === v"
|
||||||
|
@click="productTab = v"
|
||||||
|
>
|
||||||
|
<span class="full-width q-py-sm" style="padding-inline: 20px">
|
||||||
|
{{
|
||||||
|
v === 1
|
||||||
|
? $t('formDialogTitleInformation')
|
||||||
|
: $t('priceInformation')
|
||||||
|
}}
|
||||||
|
</span>
|
||||||
|
</q-item>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="col-12 col-md-10 q-py-md q-pr-md q-pl-sm"
|
||||||
|
id="customer-form-content"
|
||||||
|
style="height: 100%; max-height: 100%; overflow-y: auto"
|
||||||
|
>
|
||||||
|
<BasicInfoProduct
|
||||||
|
v-if="productTab === 1"
|
||||||
|
:readonly="!infoProductEdit"
|
||||||
|
v-model:options-branch="branchOption"
|
||||||
|
v-model:registered-branch-id="formDataProduct.registeredBranchId"
|
||||||
|
v-model:detail="formDataProduct.detail"
|
||||||
|
v-model:remark="formDataProduct.remark"
|
||||||
|
v-model:name="formDataProduct.name"
|
||||||
|
v-model:code="formDataProduct.code"
|
||||||
|
v-model:process="formDataProduct.process"
|
||||||
|
dense
|
||||||
|
separator
|
||||||
|
/>
|
||||||
|
<PriceDataComponent
|
||||||
|
v-if="productTab === 2"
|
||||||
|
:readonly="!infoProductEdit"
|
||||||
|
v-model:price="formDataProduct.price"
|
||||||
|
v-model:agent-price="formDataProduct.agentPrice"
|
||||||
|
v-model:service-charge="formDataProduct.serviceCharge"
|
||||||
|
dense
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- <template #prepend>
|
||||||
<ProfileUpload
|
<ProfileUpload
|
||||||
prefix-id="form-dialog-product"
|
prefix-id="form-dialog-product"
|
||||||
isProduct
|
isProduct
|
||||||
|
|
@ -3876,18 +4000,16 @@ watch(
|
||||||
v-model:service-charge="formDataProduct.serviceCharge"
|
v-model:service-charge="formDataProduct.serviceCharge"
|
||||||
dense
|
dense
|
||||||
/>
|
/>
|
||||||
</template>
|
</template> -->
|
||||||
</FormDialog>
|
</DialogForm>
|
||||||
|
|
||||||
<!-- add service -->
|
<!-- add service -->
|
||||||
<FormDialog
|
<DialogForm
|
||||||
no-address
|
no-address
|
||||||
no-app-box
|
no-app-box
|
||||||
height="95vh"
|
height="95vh"
|
||||||
:title="$t('addService')"
|
:title="$t('addService')"
|
||||||
v-model:modal="dialogService"
|
v-model:modal="dialogService"
|
||||||
:tabs-list="serviceTab"
|
|
||||||
v-model:current-tab="currentServiceTab"
|
|
||||||
:submit="
|
:submit="
|
||||||
() => {
|
() => {
|
||||||
submitService();
|
submitService();
|
||||||
|
|
@ -3901,8 +4023,8 @@ watch(
|
||||||
}
|
}
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<template #prepend>
|
<!-- :tabs-list="serviceTab" -->
|
||||||
<ProfileUpload
|
<!-- <ProfileUpload
|
||||||
prefix-id="form-dialog-service"
|
prefix-id="form-dialog-service"
|
||||||
isService
|
isService
|
||||||
v-model:url-profile="profileUrl"
|
v-model:url-profile="profileUrl"
|
||||||
|
|
@ -3910,15 +4032,62 @@ watch(
|
||||||
v-model:profile-submit="profileSubmit"
|
v-model:profile-submit="profileSubmit"
|
||||||
@cancel-file="inputFile.value = ''"
|
@cancel-file="inputFile.value = ''"
|
||||||
@input-file="inputFile.click()"
|
@input-file="inputFile.click()"
|
||||||
|
/> -->
|
||||||
|
<div class="q-mx-lg q-mt-lg">
|
||||||
|
<ProfileBanner
|
||||||
|
hideFade
|
||||||
|
useToggle
|
||||||
|
hideActive
|
||||||
|
:toggleTitle="$t('formDialogTitleUseStatus')"
|
||||||
|
:img="profileUrl || '/images/product-avatar-add.png'"
|
||||||
|
fallbackCover="/images/product-banner.png"
|
||||||
|
bgColor="#ebf1ee"
|
||||||
|
:menu="[
|
||||||
|
{
|
||||||
|
icon: 'mdi-office-building-outline',
|
||||||
|
color: 'hsl(var(--info-bg))',
|
||||||
|
bgColor: 'var(--surface-1)',
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
@view="imageDialog = true"
|
||||||
|
@edit="refImageUpload && refImageUpload.browse()"
|
||||||
/>
|
/>
|
||||||
</template>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="currentServiceTab === 'serviceInformation'"
|
class="col surface-1 q-mx-lg q-mt-lg q-mb-md rounded bordered scroll row relative-position"
|
||||||
class="col-md-10 col-sm-12"
|
id="group-form"
|
||||||
>
|
>
|
||||||
<div class="surface-1 rounded bordered q-pa-lg full-width row">
|
<div
|
||||||
|
class="col"
|
||||||
|
style="height: 100%; max-height: 100; overflow-y: auto"
|
||||||
|
v-if="$q.screen.gt.sm"
|
||||||
|
>
|
||||||
|
<div class="q-py-md q-pl-md q-pr-sm">
|
||||||
|
<q-item
|
||||||
|
v-for="v in 2"
|
||||||
|
:key="v"
|
||||||
|
dense
|
||||||
|
clickable
|
||||||
|
class="no-padding items-center rounded full-width"
|
||||||
|
:class="{ 'q-mt-xs': v > 1 }"
|
||||||
|
active-class="product-form-active"
|
||||||
|
:active="currentServiceTab === v"
|
||||||
|
@click="currentServiceTab = v"
|
||||||
|
>
|
||||||
|
<span class="full-width q-py-sm" style="padding-inline: 20px">
|
||||||
|
{{ v === 1 ? $t('serviceInformation') : $t('workInformation') }}
|
||||||
|
</span>
|
||||||
|
</q-item>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="col-12 col-md-10 q-py-md q-pr-md q-pl-sm"
|
||||||
|
id="customer-form-content"
|
||||||
|
style="height: 100%; max-height: 100%; overflow-y: auto"
|
||||||
|
>
|
||||||
<BasicInformation
|
<BasicInformation
|
||||||
|
v-if="currentServiceTab === 1"
|
||||||
dense
|
dense
|
||||||
service
|
service
|
||||||
v-model:options-branch="branchOption"
|
v-model:options-branch="branchOption"
|
||||||
|
|
@ -3929,52 +4098,51 @@ watch(
|
||||||
v-model:service-description="formDataProductService.detail"
|
v-model:service-description="formDataProductService.detail"
|
||||||
v-model:service-name-th="formDataProductService.name"
|
v-model:service-name-th="formDataProductService.name"
|
||||||
/>
|
/>
|
||||||
</div>
|
|
||||||
<div class="surface-1 rounded bordered q-mt-md q-pa-lg row">
|
<FormServiceWork
|
||||||
<FormServiceProperties
|
v-if="currentServiceTab === 2"
|
||||||
v-model:service-attributes="formDataProductService.attributes"
|
v-model:work-items="workItems"
|
||||||
@service-properties="
|
dense
|
||||||
|
@addProduct="
|
||||||
|
async (index) => {
|
||||||
|
await fetchListOfProductIsAdd(currentIdType);
|
||||||
|
currentWorkIndex = index;
|
||||||
|
dialogTotalProduct = true;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
@manage-work-name="
|
||||||
() => {
|
() => {
|
||||||
tempValueProperties = formDataProductService.attributes;
|
manageWorkNameDialog = true;
|
||||||
openPropertiesDialog('service');
|
}
|
||||||
|
"
|
||||||
|
@work-properties="
|
||||||
|
(index) => {
|
||||||
|
currentWorkIndex = index;
|
||||||
|
tempValueProperties = workItems[index].attributes;
|
||||||
|
openPropertiesDialog('work');
|
||||||
}
|
}
|
||||||
"
|
"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="currentServiceTab === 'workInformation'"
|
class="col-2 surface-1 q-mx-lg q-mb-lg rounded bordered row"
|
||||||
class="surface-1 rounded bordered col-md-10 col-sm-12 q-pa-lg"
|
v-if="currentServiceTab === 1"
|
||||||
>
|
>
|
||||||
<FormServiceWork
|
<FormServiceProperties
|
||||||
v-model:work-items="workItems"
|
v-model:service-attributes="formDataProductService.attributes"
|
||||||
dense
|
@service-properties="
|
||||||
@addProduct="
|
|
||||||
async (index) => {
|
|
||||||
await fetchListOfProductIsAdd(currentIdType);
|
|
||||||
currentWorkIndex = index;
|
|
||||||
dialogTotalProduct = true;
|
|
||||||
}
|
|
||||||
"
|
|
||||||
@manage-work-name="
|
|
||||||
() => {
|
() => {
|
||||||
manageWorkNameDialog = true;
|
tempValueProperties = formDataProductService.attributes;
|
||||||
}
|
openPropertiesDialog('service');
|
||||||
"
|
|
||||||
@work-properties="
|
|
||||||
(index) => {
|
|
||||||
currentWorkIndex = index;
|
|
||||||
tempValueProperties = workItems[index].attributes;
|
|
||||||
openPropertiesDialog('work');
|
|
||||||
}
|
}
|
||||||
"
|
"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</FormDialog>
|
</DialogForm>
|
||||||
|
|
||||||
<!-- service properties -->
|
<!-- service properties -->
|
||||||
<FormDialog
|
<DialogForm
|
||||||
no-address
|
no-address
|
||||||
no-app-box
|
no-app-box
|
||||||
height="75vh"
|
height="75vh"
|
||||||
|
|
@ -4003,10 +4171,10 @@ watch(
|
||||||
v-model:properties-option="propertiesOption"
|
v-model:properties-option="propertiesOption"
|
||||||
v-model:form-service-properties="tempValueProperties"
|
v-model:form-service-properties="tempValueProperties"
|
||||||
/>
|
/>
|
||||||
</FormDialog>
|
</DialogForm>
|
||||||
|
|
||||||
<!-- manage work name -->
|
<!-- manage work name -->
|
||||||
<FormDialog
|
<DialogForm
|
||||||
no-address
|
no-address
|
||||||
no-app-box
|
no-app-box
|
||||||
no-footer
|
no-footer
|
||||||
|
|
@ -4023,19 +4191,17 @@ watch(
|
||||||
@edit="editWork"
|
@edit="editWork"
|
||||||
@add="createWork"
|
@add="createWork"
|
||||||
/>
|
/>
|
||||||
</FormDialog>
|
</DialogForm>
|
||||||
|
|
||||||
<!-- edit service -->
|
<!-- edit service -->
|
||||||
<FormDialog
|
<DialogForm
|
||||||
no-address
|
no-address
|
||||||
:no-app-box="currentServiceTab !== 'workInformation'"
|
|
||||||
:edit="!(formDataProductService.status === 'INACTIVE')"
|
:edit="!(formDataProductService.status === 'INACTIVE')"
|
||||||
height="95vh"
|
height="95vh"
|
||||||
:isEdit="infoServiceEdit"
|
:isEdit="infoServiceEdit"
|
||||||
:title="$t('service')"
|
:title="$t('service')"
|
||||||
:tabs-list="serviceTab"
|
:tabs-list="serviceTab"
|
||||||
v-model:modal="dialogServiceEdit"
|
v-model:modal="dialogServiceEdit"
|
||||||
v-model:current-tab="currentServiceTab"
|
|
||||||
:submit="
|
:submit="
|
||||||
() => {
|
() => {
|
||||||
submitService();
|
submitService();
|
||||||
|
|
@ -4076,14 +4242,11 @@ watch(
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<div
|
<div v-if="currentServiceTab === 1" class="col-md-10 col-sm-12">
|
||||||
v-if="currentServiceTab === 'serviceInformation'"
|
|
||||||
class="col-md-10 col-sm-12"
|
|
||||||
>
|
|
||||||
<div class="surface-1 rounded bordered q-pa-lg full-width row">
|
<div class="surface-1 rounded bordered q-pa-lg full-width row">
|
||||||
<BasicInformation
|
<BasicInformation
|
||||||
:readonly="!infoServiceEdit"
|
:readonly="!infoServiceEdit"
|
||||||
v-if="currentServiceTab === 'serviceInformation'"
|
v-if="currentServiceTab === 1"
|
||||||
dense
|
dense
|
||||||
service
|
service
|
||||||
v-model:options-branch="branchOption"
|
v-model:options-branch="branchOption"
|
||||||
|
|
@ -4113,7 +4276,7 @@ watch(
|
||||||
<FormServiceWork
|
<FormServiceWork
|
||||||
:readonly="!infoServiceEdit"
|
:readonly="!infoServiceEdit"
|
||||||
v-model:work-items="workItems"
|
v-model:work-items="workItems"
|
||||||
v-if="currentServiceTab === 'workInformation'"
|
v-if="currentServiceTab === 2"
|
||||||
dense
|
dense
|
||||||
@addProduct="
|
@addProduct="
|
||||||
async (index) => {
|
async (index) => {
|
||||||
|
|
@ -4132,7 +4295,7 @@ watch(
|
||||||
"
|
"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</FormDialog>
|
</DialogForm>
|
||||||
|
|
||||||
<q-dialog v-model="holdDialog" position="bottom">
|
<q-dialog v-model="holdDialog" position="bottom">
|
||||||
<div class="surface-1 full-width rounded column q-pb-md">
|
<div class="surface-1 full-width rounded column q-pb-md">
|
||||||
|
|
@ -4248,12 +4411,11 @@ watch(
|
||||||
|
|
||||||
<q-item clickable v-ripple>
|
<q-item clickable v-ripple>
|
||||||
<q-item-section avatar>
|
<q-item-section avatar>
|
||||||
<q-toggle
|
<ToggleButton
|
||||||
color="positive"
|
two-way
|
||||||
dense
|
|
||||||
:id="`view-detail-btn-${currentNode.name}-status`"
|
:id="`view-detail-btn-${currentNode.name}-status`"
|
||||||
size="sm"
|
:model-value="currentNode.status !== 'INACTIVE'"
|
||||||
@click.stop="
|
@click="
|
||||||
async () => {
|
async () => {
|
||||||
if (!currentNode) return;
|
if (!currentNode) return;
|
||||||
if (currentNode.type === 'type') {
|
if (currentNode.type === 'type') {
|
||||||
|
|
@ -4278,7 +4440,6 @@ watch(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"
|
"
|
||||||
:model-value="currentNode.status !== 'INACTIVE'"
|
|
||||||
/>
|
/>
|
||||||
</q-item-section>
|
</q-item-section>
|
||||||
<q-item-section>
|
<q-item-section>
|
||||||
|
|
@ -4297,31 +4458,22 @@ watch(
|
||||||
ref="refImageUpload"
|
ref="refImageUpload"
|
||||||
v-model:dialogState="imageDialog"
|
v-model:dialogState="imageDialog"
|
||||||
v-model:file="profileFileImg"
|
v-model:file="profileFileImg"
|
||||||
|
v-model:image-url="profileUrl"
|
||||||
|
:hidden-footer="!infoProductEdit"
|
||||||
clearButton
|
clearButton
|
||||||
|
@save="handleImageUpload"
|
||||||
>
|
>
|
||||||
<template #error>
|
<template #error>
|
||||||
<div class="full-height full-width" style="background: white">
|
<div class="full-height full-width" style="background: white">
|
||||||
<div
|
<div
|
||||||
class="full-height full-width flex justify-center items-center"
|
class="full-height full-width flex justify-center items-center"
|
||||||
:style="`background: hsla(var(${
|
style="background: #ebf1ee"
|
||||||
productMode === 'group'
|
|
||||||
? '--pink-6'
|
|
||||||
: $q.dark.isActive
|
|
||||||
? '--violet-10'
|
|
||||||
: '--violet-11'
|
|
||||||
}-hsl)/0.1)`"
|
|
||||||
>
|
>
|
||||||
<q-icon
|
<q-img
|
||||||
size="15rem"
|
src="/images/product-avatar.png"
|
||||||
:name="productMode === 'group' ? 'mdi-folder' : 'mdi-folder-table'"
|
fit="contain"
|
||||||
:style="`color: hsla(var(${
|
style="height: 100%"
|
||||||
productMode === 'group'
|
/>
|
||||||
? '--pink-6'
|
|
||||||
: $q.dark.isActive
|
|
||||||
? '--violet-10'
|
|
||||||
: '--violet-11'
|
|
||||||
}-hsl)/1)`"
|
|
||||||
></q-icon>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -4386,7 +4538,6 @@ watch(
|
||||||
color: hsla(var(--_color) / 1);
|
color: hsla(var(--_color) / 1);
|
||||||
|
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
padding: var(--size-1);
|
|
||||||
position: relative;
|
position: relative;
|
||||||
transform: rotate(45deg);
|
transform: rotate(45deg);
|
||||||
|
|
||||||
|
|
@ -4407,6 +4558,14 @@ watch(
|
||||||
transform: rotate(-45deg);
|
transform: rotate(-45deg);
|
||||||
color: hsla(var(--_branch-card-bg) / 1);
|
color: hsla(var(--_branch-card-bg) / 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:deep(.q-img) {
|
||||||
|
transform: rotate(-45deg);
|
||||||
|
|
||||||
|
&:deep(.q-icon) {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.tags {
|
.tags {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue