refactor(04): service new img dialog

This commit is contained in:
puriphatt 2024-09-12 11:22:11 +07:00
parent f1168c781f
commit 21ac39d538
4 changed files with 296 additions and 92 deletions

View file

@ -490,6 +490,15 @@ const branchOption = ref<{ id: string; name: string }[]>([]);
const currentStatus = ref<Status | 'All'>('All');
// img
const isImageEdit = ref<boolean>(false);
const refreshImageState = ref(false);
const imageList = ref<{ selectedImage: string; list: string[] }>();
const onCreateImageList = ref<{
selectedImage: string;
list: { url: string; imgFile: File | null; name: string }[];
}>({ selectedImage: '', list: [] });
async function searchProduct(isAdd: boolean = true) {
const res = await fetchListProduct({
query: inputSearchProductAndService.value,
@ -869,9 +878,10 @@ async function assignFormDataProductService(id: string) {
const res = await fetchListServiceById(id);
if (res) {
await fetchImageList(res.id, res.selectedImage || '', 'service');
serviceTab.value = 1;
statusToggle.value = res.status === 'INACTIVE' ? false : true;
profileUrl.value = res.imageUrl;
profileUrl.value = `${baseUrl.value}/service/${res.id}/image/${res.selectedImage}`;
profileSubmit.value = true;
currentService.value = JSON.parse(JSON.stringify(res));
@ -884,6 +894,7 @@ async function assignFormDataProductService(id: string) {
work: [],
status: res.status,
productGroupId: res.productGroupId,
selectedImage: res.selectedImage,
};
formDataProductService.value = { ...prevService.value };
@ -932,12 +943,13 @@ const prevProduct = ref<ProductCreate>({
image: undefined,
});
function assignFormDataProduct(data: ProductList) {
async function assignFormDataProduct(data: ProductList) {
productTab.value = 1;
statusToggle.value = data.status === 'INACTIVE' ? false : true;
profileUrl.value = `${baseUrl.value}/product/${data?.id}/image`;
profileUrl.value = `${baseUrl.value}/product/${data?.id}/image/${data?.selectedImage}`;
profileSubmit.value = true;
await fetchImageList(data.id, data.selectedImage || '', 'product');
// profileSubmit.value = true;
prevProduct.value = {
productGroupId: data.productGroupId,
@ -953,8 +965,8 @@ function assignFormDataProduct(data: ProductList) {
status: data.status,
expenseType: data.expenseType,
vatIncluded: data.vatIncluded,
selectedImage: data.selectedImage,
};
formDataProduct.value = { ...prevProduct.value };
}
@ -1028,7 +1040,7 @@ function assignFormDataProductServiceCreate() {
});
}
async function submitService() {
async function submitService(notClose = false) {
assignFormDataProductServiceCreate();
formDataProductService.value.productGroupId = currentIdGrop.value;
@ -1045,7 +1057,10 @@ async function submitService() {
return;
}
const res = await createService(formDataProductService.value);
const res = await createService(
formDataProductService.value,
onCreateImageList.value,
);
if (res) {
allStat.value[1].count = allStat.value[1].count + 1;
stat.value[1].count = stat.value[1].count + 1;
@ -1063,15 +1078,16 @@ async function submitService() {
});
}
if (!notClose) clearFormService();
if (productAndServiceTab.value === 'service') {
await fetchListOfService();
}
flowStore.rotate();
clearFormService();
}
async function submitProduct() {
async function submitProduct(notClose = false) {
formDataProduct.value.productGroupId = currentIdGrop.value;
if (profileFileImg.value) {
formDataProduct.value.image = profileFileImg.value;
@ -1085,7 +1101,10 @@ async function submitProduct() {
productTab.value = 1;
return;
}
const res = await createProduct(formDataProduct.value);
const res = await createProduct(
formDataProduct.value,
onCreateImageList.value,
);
if (res) {
allStat.value[2].count = allStat.value[2].count + 1;
@ -1102,7 +1121,7 @@ async function submitProduct() {
});
}
totalProduct.value = totalProduct.value + 1;
clearFormProduct();
if (!notClose) clearFormProduct();
if (productAndServiceTab.value === 'product') {
await fetchListOfProduct();
@ -1234,12 +1253,14 @@ async function alternativeFetch() {
}
}
function cloneData() {
function cloneServiceData() {
if (!currentService.value) return;
const currentSelectedImage = formDataProductService.value.selectedImage;
formDataProductService.value = {
...prevService.value,
attributes: JSON.parse(JSON.stringify(currentService.value.attributes)),
};
formDataProductService.value.selectedImage = currentSelectedImage;
workItems.value = currentService.value.work.map((item) => {
return {
@ -1317,6 +1338,19 @@ function handleHold(node: ProductGroup & { type: string }) {
currentNode.value = node;
}
async function fetchImageList(
id: string,
selectedName: string,
type: 'product' | 'service',
) {
const res = await productServiceStore.fetchImageListById(id, type);
imageList.value = {
selectedImage: selectedName,
list: res.map((n: string) => `${type}/${id}/image/${n}`),
};
return res;
}
onMounted(async () => {
utilsStore.currentTitle.title = 'productService.title';
utilsStore.currentTitle.path = [
@ -1442,6 +1476,13 @@ watch(productMode, async () => {
await calculateStats({ type: 'product' });
}
});
watch(
() => profileFileImg.value,
() => {
if (profileFileImg.value !== null) isImageEdit.value = true;
},
);
</script>
<template>
@ -2430,9 +2471,7 @@ watch(productMode, async () => {
<q-img
class="text-center"
:ratio="1"
:src="`
${props.row.imageUrl ?? null}
`"
:src="`${baseUrl}/${productAndServiceTab}/${props.row.id}/image/${props.row.selectedImage}`"
>
<template #error>
<q-icon
@ -3336,6 +3375,7 @@ watch(productMode, async () => {
:close="
() => {
dialogProduct = false;
onCreateImageList = { selectedImage: '', list: [] };
flowStore.rotate();
}
"
@ -3356,8 +3396,13 @@ watch(productMode, async () => {
bgColor: 'var(--surface-1)',
},
]"
@view="imageDialog = true"
@edit="refImageUpload && refImageUpload.browse()"
@view="
() => {
imageDialog = true;
isImageEdit = false;
}
"
@edit="imageDialog = isImageEdit = true"
v-model:toggle-status="formDataProduct.status"
@update:toggle-status="
() => {
@ -3449,15 +3494,6 @@ watch(productMode, async () => {
v-model:modal="dialogProductEdit"
noAddress
:title="$t('productService.product.title')"
:editData="() => (infoProductEdit = true)"
:undo="
() => {
formDataProduct = { ...prevProduct };
infoProductEdit = false;
flowStore.rotate();
}
"
:deleteData="() => deleteProductConfirm()"
:submit="() => submitProduct()"
:close="
() => {
@ -3478,9 +3514,12 @@ watch(productMode, async () => {
icon="mdi-shopping-outline"
fallbackImg="/images/product-avatar.png"
color="var(--teal-10)"
:readonly="!infoProductEdit"
:toggleTitle="$t('status.title')"
:img="profileUrl || '/images/product-avatar.png'"
:img="
`${baseUrl}/product/${currentIdProduct}/image/${formDataProduct.selectedImage}`.concat(
refreshImageState ? `?ts=${Date.now()}` : '',
) || '/images/product-avatar.png'
"
fallbackCover="/images/product-banner.png"
:bgColor="`hsla(var(--teal-${$q.dark.isActive ? '8' : '10'}-hsl)/0.15)`"
:menu="[
@ -3491,8 +3530,13 @@ watch(productMode, async () => {
},
]"
v-model:toggle-status="formDataProduct.status"
@view="imageDialog = true"
@edit="refImageUpload && refImageUpload.browse()"
@view="
() => {
imageDialog = true;
isImageEdit = false;
}
"
@edit="imageDialog = isImageEdit = true"
@update:toggle-status="
async () => {
if (formDataProduct.status)
@ -3639,6 +3683,7 @@ watch(productMode, async () => {
() => {
clearFormService();
dialogService = false;
onCreateImageList = { selectedImage: '', list: [] };
flowStore.rotate();
}
"
@ -3664,8 +3709,13 @@ watch(productMode, async () => {
bgColor: 'var(--surface-1)',
},
]"
@view="imageDialog = true"
@edit="refImageUpload && refImageUpload.browse()"
@view="
() => {
imageDialog = true;
isImageEdit = false;
}
"
@edit="imageDialog = isImageEdit = true"
v-model:toggle-status="formDataProductService.status"
@update:toggle-status="
() => {
@ -3879,20 +3929,6 @@ watch(productMode, async () => {
dialogServiceEdit = false;
}
"
:edit-data="
() => {
infoServiceEdit = true;
}
"
:undo="
() => {
infoServiceEdit = false;
cloneData();
statusToggle = prevService.status === 'INACTIVE' ? false : true;
flowStore.rotate();
}
"
:delete-data="() => deleteServiceConfirm()"
>
<div class="q-mx-lg q-mt-lg">
<ProfileBanner
@ -3901,9 +3937,13 @@ watch(productMode, async () => {
:title="formDataProductService.name"
:caption="formDataProductService.code"
:active="formDataProductService.status !== 'INACTIVE'"
:readonly="!infoServiceEdit"
:toggleTitle="$t('status.title')"
:img="profileUrl || '/images/service-avatar.png'"
:img="
`${baseUrl}/service/${currentIdService}/image/${formDataProductService.selectedImage}`.concat(
refreshImageState ? `?ts=${Date.now()}` : '',
) || '/images/service-avatar.png'
"
fallbackImg="/images/service-avatar.png"
fallbackCover="/images/service-banner.png"
:bgColor="`hsla(var(--orange-${$q.dark.isActive ? '6' : '5'}-hsl)/0.15)`"
:menu="[
@ -3919,8 +3959,13 @@ watch(productMode, async () => {
},
]"
v-model:toggle-status="formDataProductService.status"
@view="imageDialog = true"
@edit="refImageUpload && refImageUpload.browse()"
@view="
() => {
imageDialog = true;
isImageEdit = false;
}
"
@edit="imageDialog = isImageEdit = true"
@update:toggle-status="
async () => {
if (formDataProductService.status)
@ -3965,7 +4010,7 @@ watch(productMode, async () => {
@click="
() => {
infoServiceEdit = false;
cloneData();
cloneServiceData();
statusToggle = prevService.status === 'INACTIVE' ? false : true;
flowStore.rotate();
}
@ -4225,10 +4270,91 @@ watch(productMode, async () => {
v-model:dialogState="imageDialog"
v-model:file="profileFileImg"
v-model:image-url="profileUrl as string"
:hidden-footer="!profileUrl && !dialogService && !dialogProduct"
clearButton
v-model:data-list="imageList"
v-model:on-create-data-list="onCreateImageList"
:hidden-footer="!isImageEdit"
:on-create="dialogProduct || dialogService"
:change-disabled="!actionDisplay"
@add-image="
async (v) => {
if (!v) return;
if (!currentIdProduct) return;
const res = await productServiceStore.addImageList(
v,
currentIdProduct,
Date.now(),
dialogProductEdit ? 'product' : 'service',
);
await fetchImageList(
currentIdProduct,
res,
dialogProductEdit ? 'product' : 'service',
);
}
"
@remove-image="
async (v) => {
if (!v) return;
if (!currentIdProduct && !currentIdService) return;
const name = v.split('/').pop() || '';
const type = dialogProductEdit ? 'product' : 'service';
await productServiceStore.deleteImageByName(
dialogProductEdit ? currentIdProduct : currentIdService,
name,
type,
);
await fetchImageList(
dialogProductEdit ? currentIdProduct : currentIdService,
name,
type,
);
}
"
@submit="
async (v) => {
if (dialogProduct || dialogService) {
profileUrl = v;
imageDialog = false;
} else {
const type = dialogProductEdit ? 'product' : 'service';
const id = dialogProductEdit ? currentIdProduct : currentIdService;
refreshImageState = true;
type === 'product'
? (formDataProduct.selectedImage = v)
: (formDataProductService.selectedImage = v);
imageList ? (imageList.selectedImage = v) : '';
profileUrl = `${baseUrl}/${type}/${id}/image/${v}`;
if (type === 'product') {
const { selectedImage, ...data } = prevProduct;
formDataProduct = {
selectedImage: formDataProduct.selectedImage,
...data,
};
await submitProduct(true);
} else {
cloneServiceData();
await submitService(true);
}
imageDialog = false;
refreshImageState = false;
infoProductEdit = false;
infoServiceEdit = false;
}
}
"
>
<template #title>
<span
v-if="!dialogProduct || !dialogService"
class="justify-center flex text-bold"
>
{{ $t('general.image') }}
{{
dialogProductEdit ? formDataProduct.name : formDataProductService.name
}}
</span>
</template>
<template #error>
<div class="full-height full-width" style="background: var(--surface-1)">
<div