Squashed commit of the following:
commit eb6c7b164a9f182f8d1ce73cc5354866c6d6b10e
Author: puriphatt <puriphat@frappet.com>
Date: Wed Sep 11 11:29:44 2024 +0700
refactor: no img close to default on create
commit eae9eb26071cc2985624bb1c6ce551bf5eb6eb8b
Author: puriphatt <puriphat@frappet.com>
Date: Wed Sep 11 11:04:04 2024 +0700
refactor/feat: save => apply, disabled selected img, no img close to default
commit ccbf80fc53db3144873c049bd6dbd37b4e2e9ff3
Author: puriphatt <puriphat@frappet.com>
Date: Wed Sep 11 09:31:32 2024 +0700
fix(01): use submit function
commit 36b4f6ca15e5966f37dfefc9fdb744feec60dd27
Author: puriphatt <puriphat@frappet.com>
Date: Tue Sep 10 17:45:19 2024 +0700
fix: imgList error
commit bac0eaf3ab955672ae0c78d3295b4a839827c5f2
Author: puriphatt <puriphat@frappet.com>
Date: Tue Sep 10 17:18:03 2024 +0700
refactor(03): customer new upload img dialog
commit 9d7398e9613a738c33e265482cdb7d7bb250ea9f
Author: puriphatt <puriphat@frappet.com>
Date: Tue Sep 10 15:40:39 2024 +0700
refactor(02): new upload dialog
commit 8b91d43f41eae3ba2442f6c742d617c25ee180cb
Author: puriphatt <puriphat@frappet.com>
Date: Tue Sep 10 15:25:21 2024 +0700
refactor(01): new upload dialog, confirm remove, individual action
commit 61caf1919168bc5635568d7ca246574fdc43cd04
Author: puriphatt <puriphat@frappet.com>
Date: Mon Sep 9 17:08:42 2024 +0700
refactor(01): branch new img upload
commit e791b7316d001d839c8afb1950f7331c62d9e81a
Author: puriphatt <puriphat@frappet.com>
Date: Mon Sep 9 17:08:42 2024 +0700
refactor(02): personnel new img upload
commit af4d11312b9cb666338901efa9971117cb7738c4
Author: puriphatt <puriphat@frappet.com>
Date: Mon Sep 9 17:08:42 2024 +0700
feat(02): new image upload
commit e4d7afdb8c74d65a550644f2c60f70909d51d4a8
Author: puriphatt <puriphat@frappet.com>
Date: Mon Sep 9 17:08:41 2024 +0700
refactor: mock select image function
commit 5ab3f045b9c7d2c821920c12114da15eed09655a
Author: puriphatt <puriphat@frappet.com>
Date: Mon Sep 9 17:08:41 2024 +0700
refactor: mock new image preview
This commit is contained in:
parent
ab0b3bb4f3
commit
62fc7055dd
13 changed files with 925 additions and 254 deletions
|
|
@ -47,7 +47,6 @@ import {
|
|||
UndoButton,
|
||||
} from 'components/button';
|
||||
|
||||
const apiBaseUrl = import.meta.env.VITE_API_BASE_URL;
|
||||
const $q = useQuasar();
|
||||
const { t } = useI18n();
|
||||
const utilsStore = useUtilsStore();
|
||||
|
|
@ -160,12 +159,18 @@ const refQrCodeUpload = ref();
|
|||
const refImageUpload = ref();
|
||||
const isImageEdit = ref(false);
|
||||
const isQrCodeEdit = ref(false);
|
||||
const profileFile = ref<File | undefined>(undefined);
|
||||
const profileFile = ref<File | null>(null);
|
||||
const qrCodeFile = ref<File | undefined>(undefined);
|
||||
const imageUrl = ref<string>('');
|
||||
const prevImageUrl = ref<string>('');
|
||||
const currentNode = ref<BranchWithChildren>();
|
||||
const imageDialog = ref(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: [] });
|
||||
const qrCodeDialog = ref(false);
|
||||
|
||||
const qrCodeimageUrl = ref<string>('');
|
||||
|
|
@ -335,6 +340,7 @@ const defaultFormData = {
|
|||
lineId: '',
|
||||
webUrl: '',
|
||||
virtual: false,
|
||||
selectedImage: '',
|
||||
};
|
||||
|
||||
const formDialogRef = ref();
|
||||
|
|
@ -350,11 +356,11 @@ const currentEdit = ref<{ id: string; code: string }>({
|
|||
code: '',
|
||||
});
|
||||
const formData = ref<
|
||||
Omit<BranchCreate & { codeHeadOffice?: string }, 'qrCodeImage' | 'imageUrl'>
|
||||
Omit<BranchCreate & { codeHeadOffice?: string }, 'qrCodeImage'>
|
||||
>(structuredClone(defaultFormData));
|
||||
|
||||
const prevFormData = ref<
|
||||
Omit<BranchCreate & { codeHeadOffice?: string }, 'qrCodeImage' | 'imageUrl'>
|
||||
Omit<BranchCreate & { codeHeadOffice?: string }, 'qrCodeImage'>
|
||||
>(structuredClone(defaultFormData));
|
||||
|
||||
const modalDrawer = ref<boolean>(false);
|
||||
|
|
@ -383,8 +389,8 @@ async function selectedSubBranche(id: string) {
|
|||
async function fetchBranchById(id: string) {
|
||||
const res = await branchStore.fetchById(id, { includeContact: true });
|
||||
if (res) {
|
||||
qrCodeimageUrl.value = `${apiBaseUrl}/branch/${res.id}/line-image?ts=${Date.now()}`;
|
||||
imageUrl.value = `${apiBaseUrl}/branch/${res.id}/branch-image`;
|
||||
qrCodeimageUrl.value = `${baseUrl}/branch/${res.id}/image?ts=${Date.now()}`;
|
||||
imageUrl.value = `${baseUrl}/branch/${res.id}/image/${res.selectedImage}`;
|
||||
prevImageUrl.value = res.imageUrl;
|
||||
formBankBook.value = res.bank;
|
||||
|
||||
|
|
@ -417,6 +423,7 @@ async function fetchBranchById(id: string) {
|
|||
status: res.status,
|
||||
webUrl: res.webUrl,
|
||||
virtual: res.virtual,
|
||||
selectedImage: res.selectedImage,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -447,8 +454,9 @@ async function undo() {
|
|||
isQrCodeEdit.value = false;
|
||||
isImageEdit.value = false;
|
||||
formType.value = 'view';
|
||||
imageUrl.value = prevImageUrl.value;
|
||||
formData.value = prevFormData.value;
|
||||
const tempSelectedImage = formData.value.selectedImage;
|
||||
formData.value = JSON.parse(JSON.stringify(prevFormData.value));
|
||||
formData.value.selectedImage = tempSelectedImage;
|
||||
}
|
||||
|
||||
watch(expandedTree, async () => {
|
||||
|
|
@ -501,9 +509,7 @@ function drawerEdit() {
|
|||
isQrCodeEdit.value = true;
|
||||
isImageEdit.value = true;
|
||||
formType.value = 'edit';
|
||||
prevFormData.value = {
|
||||
...formData.value,
|
||||
};
|
||||
prevFormData.value = JSON.parse(JSON.stringify(formData.value));
|
||||
}
|
||||
|
||||
const currentBranchAdmin = ref<User | null>(null);
|
||||
|
|
@ -514,6 +520,8 @@ async function triggerEdit(
|
|||
code?: string,
|
||||
) {
|
||||
await fetchBranchById(id);
|
||||
await fetchImageList(id, formData.value.selectedImage || '');
|
||||
|
||||
if (openFormType === 'form') {
|
||||
formType.value = 'edit';
|
||||
openDialog();
|
||||
|
|
@ -675,12 +683,12 @@ async function triggerChangeStatus(
|
|||
});
|
||||
}
|
||||
|
||||
async function onSubmit() {
|
||||
if (formType.value === 'edit') {
|
||||
async function onSubmit(submitSelectedItem?: boolean) {
|
||||
if (formType.value === 'edit' || submitSelectedItem) {
|
||||
delete formData.value['codeHeadOffice'];
|
||||
delete formData.value['code'];
|
||||
|
||||
await branchStore.editById(
|
||||
const res = await branchStore.editById(
|
||||
currentEdit.value.id,
|
||||
{
|
||||
...formData.value,
|
||||
|
|
@ -695,8 +703,12 @@ async function onSubmit() {
|
|||
},
|
||||
);
|
||||
|
||||
formData.value.codeHeadOffice = formData.value.code = res.code;
|
||||
imageUrl.value = `${baseUrl}/branch/${res.id}/image/${res.selectedImage}`;
|
||||
|
||||
await fetchList({ pageSize: 99999 });
|
||||
if (!imageDialog.value) modalDrawer.value = false;
|
||||
|
||||
if (!imageDialog.value) modalDrawer.value = submitSelectedItem || false;
|
||||
modal.value = false;
|
||||
}
|
||||
|
||||
|
|
@ -709,6 +721,7 @@ async function onSubmit() {
|
|||
imageUrl: profileFile.value,
|
||||
},
|
||||
formBankBook.value,
|
||||
onCreateImageList.value,
|
||||
);
|
||||
|
||||
await fetchList({ pageSize: 99999 });
|
||||
|
|
@ -801,6 +814,15 @@ function handleHold(node: BranchWithChildren) {
|
|||
// };
|
||||
}
|
||||
|
||||
async function fetchImageList(id: string, selectedName: string) {
|
||||
const res = await branchStore.fetchImageListById(id);
|
||||
imageList.value = {
|
||||
selectedImage: selectedName,
|
||||
list: res.map((n: string) => `branch/${id}/image/${n}`),
|
||||
};
|
||||
return res;
|
||||
}
|
||||
|
||||
watch(
|
||||
() => profileFile.value,
|
||||
() => {
|
||||
|
|
@ -1291,7 +1313,11 @@ watch(currentHq, () => {
|
|||
:ratio="1"
|
||||
:src="
|
||||
baseUrl +
|
||||
`/branch/${props.row.id}/branch-image?ts=${Date.now()}`
|
||||
`/branch/${props.row.id}/image/${props.row.selectedImage}`.concat(
|
||||
refreshImageState
|
||||
? `?ts=${Date.now()}`
|
||||
: '',
|
||||
)
|
||||
"
|
||||
>
|
||||
<template #error>
|
||||
|
|
@ -1392,6 +1418,7 @@ watch(currentHq, () => {
|
|||
'subBranch',
|
||||
);
|
||||
}
|
||||
await drawerEdit();
|
||||
formType = 'edit';
|
||||
}
|
||||
"
|
||||
|
|
@ -1465,7 +1492,7 @@ watch(currentHq, () => {
|
|||
$i18n.locale === 'eng'
|
||||
? `${props.row.addressEN || ''} ${props.row.subDistrict?.nameEN || ''} ${props.row.district?.nameEN || ''} ${props.row.province?.nameEN || ''}`
|
||||
: `${props.row.address || ''} ${props.row.subDistrict?.name || ''} ${props.row.district?.name || ''} ${props.row.province?.name || ''}`,
|
||||
branchImgUrl: `/branch/${props.row.id}/branch-image`,
|
||||
branchImgUrl: `/branch/${props.row.id}/branch`,
|
||||
}"
|
||||
:field-selected="fieldSelected"
|
||||
:badge-field="['branchLabelStatus']"
|
||||
|
|
@ -1517,6 +1544,7 @@ watch(currentHq, () => {
|
|||
'subBranch',
|
||||
);
|
||||
}
|
||||
await drawerEdit();
|
||||
formType = 'edit';
|
||||
}
|
||||
"
|
||||
|
|
@ -1556,13 +1584,15 @@ watch(currentHq, () => {
|
|||
}
|
||||
"
|
||||
:close="
|
||||
() => (
|
||||
(formLastSubBranch = 0),
|
||||
(modal = false),
|
||||
(profileFile = undefined),
|
||||
(isImageEdit = false),
|
||||
(isSubCreate = false)
|
||||
)
|
||||
() => {
|
||||
formLastSubBranch = 0;
|
||||
modal = false;
|
||||
profileFile = null;
|
||||
isImageEdit = false;
|
||||
isSubCreate = false;
|
||||
imageList = { selectedImage: '', list: [] };
|
||||
onCreateImageList = { selectedImage: '', list: [] };
|
||||
}
|
||||
"
|
||||
>
|
||||
<div class="q-mx-lg q-mt-lg">
|
||||
|
|
@ -1604,8 +1634,13 @@ watch(currentHq, () => {
|
|||
: '--violet-11'
|
||||
}-hsl)/${imageUrl ? '0' : '0.15'})`"
|
||||
:menu="formMenuIcon"
|
||||
@view="imageDialog = true"
|
||||
@edit="refImageUpload && refImageUpload.browse()"
|
||||
@view="
|
||||
() => {
|
||||
imageDialog = true;
|
||||
isImageEdit = false;
|
||||
}
|
||||
"
|
||||
@edit="imageDialog = isImageEdit = true"
|
||||
@update:toggle-status="
|
||||
() => {
|
||||
formData.status =
|
||||
|
|
@ -1769,21 +1804,18 @@ watch(currentHq, () => {
|
|||
<DrawerInfo
|
||||
ref="formDialogRef"
|
||||
v-model:drawer-open="modalDrawer"
|
||||
:submit="() => onSubmit()"
|
||||
:category="changeTitle(formType, formTypeBranch)"
|
||||
:title="$i18n.locale === 'eng' ? formData.nameEN : formData.name"
|
||||
:address-separator="true"
|
||||
:undo="() => undo()"
|
||||
:is-edit="formType === 'edit'"
|
||||
:edit-data="() => drawerEdit()"
|
||||
:submit="() => onSubmit()"
|
||||
:delete-data="() => triggerDelete(currentEdit.id)"
|
||||
:close="
|
||||
() => (
|
||||
(modalDrawer = false),
|
||||
flowStore.rotate(),
|
||||
(isImageEdit = false),
|
||||
resetScrollBar('branch-info')
|
||||
)
|
||||
() => {
|
||||
modalDrawer = false;
|
||||
isImageEdit = false;
|
||||
imageList = { selectedImage: '', list: [] };
|
||||
onCreateImageList = { selectedImage: '', list: [] };
|
||||
flowStore.rotate();
|
||||
resetScrollBar('branch-info');
|
||||
}
|
||||
"
|
||||
:statusBranch="formData.status"
|
||||
hide-action
|
||||
|
|
@ -1796,8 +1828,11 @@ watch(currentHq, () => {
|
|||
v-model:cover-url="imageUrl"
|
||||
:toggleTitle="$t('status.title')"
|
||||
:hideFade="imageUrl === '' || imageUrl === null"
|
||||
:img="imageUrl || null"
|
||||
:cover="imageUrl || null"
|
||||
:img="
|
||||
`${baseUrl}/branch/${currentId}/image/${formData.selectedImage}`.concat(
|
||||
refreshImageState ? `?ts=${Date.now()}` : '',
|
||||
) || null
|
||||
"
|
||||
:title="formData.name"
|
||||
:caption="formData.code"
|
||||
icon="mdi-office-building-outline"
|
||||
|
|
@ -1820,10 +1855,15 @@ watch(currentHq, () => {
|
|||
: $q.dark.isActive
|
||||
? '--violet-10'
|
||||
: '--violet-11'
|
||||
}-hsl)/${imageUrl ? '0' : '0.15'})`"
|
||||
}-hsl)/${imageUrl ? '0' : '0.1'})`"
|
||||
v-model:toggle-status="formData.status"
|
||||
@view="imageDialog = true"
|
||||
@edit="refImageUpload && refImageUpload.browse()"
|
||||
@view="
|
||||
() => {
|
||||
imageDialog = true;
|
||||
isImageEdit = false;
|
||||
}
|
||||
"
|
||||
@edit="imageDialog = isImageEdit = true"
|
||||
@update:toggle-status="
|
||||
async (v) => {
|
||||
const res = await triggerChangeStatus(currentId, v);
|
||||
|
|
@ -1836,7 +1876,6 @@ watch(currentHq, () => {
|
|||
await fetchList({ pageSize: 99999 });
|
||||
}
|
||||
"
|
||||
:readonly="formType === 'view'"
|
||||
:menu="formMenuIcon"
|
||||
/>
|
||||
</div>
|
||||
|
|
@ -2200,12 +2239,53 @@ watch(currentHq, () => {
|
|||
<ImageUploadDialog
|
||||
ref="refImageUpload"
|
||||
v-model:dialogState="imageDialog"
|
||||
v-model:file="profileFile as File"
|
||||
v-model:file="profileFile"
|
||||
v-model:image-url="imageUrl"
|
||||
:hiddenFooter="!isImageEdit && !modal"
|
||||
@save="imageDialog = false"
|
||||
clearButton
|
||||
v-model:data-list="imageList"
|
||||
v-model:on-create-data-list="onCreateImageList"
|
||||
:on-create="modal"
|
||||
:hiddenFooter="!isImageEdit"
|
||||
@add-image="
|
||||
async (v) => {
|
||||
if (!v) return;
|
||||
if (!currentId) return;
|
||||
await branchStore.addImageList(v, currentId, Date.now());
|
||||
await fetchImageList(currentId, formData.selectedImage || '');
|
||||
}
|
||||
"
|
||||
@remove-image="
|
||||
async (v) => {
|
||||
if (!v) return;
|
||||
if (!currentId) return;
|
||||
const name = v.split('/').pop() || '';
|
||||
await branchStore.deleteImageByName(currentId, name);
|
||||
await fetchImageList(currentId, name);
|
||||
}
|
||||
"
|
||||
@submit="
|
||||
async (v) => {
|
||||
if (modal) {
|
||||
imageUrl = v;
|
||||
imageDialog = false;
|
||||
} else {
|
||||
refreshImageState = true;
|
||||
formData.selectedImage = v;
|
||||
imageList ? (imageList.selectedImage = v) : '';
|
||||
imageUrl = `${baseUrl}/branch/${currentId && currentId}/image/${v}`;
|
||||
await onSubmit(true);
|
||||
imageDialog = false;
|
||||
refreshImageState = false;
|
||||
}
|
||||
}
|
||||
"
|
||||
>
|
||||
<template #title>
|
||||
<span v-if="!modal" class="justify-center flex text-bold">
|
||||
{{ $t('general.image') }}
|
||||
{{ changeTitle(formType, formTypeBranch) }}
|
||||
{{ $i18n.locale === 'eng' ? formData.nameEN : formData.name }}
|
||||
</span>
|
||||
</template>
|
||||
<template #error>
|
||||
<div class="full-height full-width" style="background: white">
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, onMounted, watch, computed } from 'vue';
|
||||
import useUtilsStore, { dialog } from 'stores/utils';
|
||||
import useUtilsStore, { dialog, baseUrl } from 'stores/utils';
|
||||
import { calculateAge } from 'src/utils/datetime';
|
||||
import { useQuasar, type QTableProps } from 'quasar';
|
||||
import { storeToRefs } from 'pinia';
|
||||
|
|
@ -59,7 +59,6 @@ const adrressStore = useAddressStore();
|
|||
const useMyBranchStore = useMyBranch();
|
||||
const { data: userData } = storeToRefs(userStore);
|
||||
const { myBranch } = storeToRefs(useMyBranchStore);
|
||||
const apiBaseUrl = import.meta.env.VITE_API_BASE_URL;
|
||||
|
||||
const defaultFormData = {
|
||||
provinceId: null,
|
||||
|
|
@ -87,7 +86,6 @@ const defaultFormData = {
|
|||
firstName: '',
|
||||
userRole: '',
|
||||
userType: '',
|
||||
profileImage: null,
|
||||
birthDate: null,
|
||||
responsibleArea: null,
|
||||
username: '',
|
||||
|
|
@ -178,7 +176,6 @@ const userCode = ref<string>();
|
|||
const currentUser = ref<User>();
|
||||
const infoDrawerEdit = ref(false);
|
||||
const infoPersonId = ref<string>('');
|
||||
const infoPersonCard = ref();
|
||||
const infoDrawer = ref(false);
|
||||
const profileSubmit = ref(false);
|
||||
const urlProfile = ref<string>();
|
||||
|
|
@ -198,6 +195,7 @@ const typeStats = ref<UserTypeStats>();
|
|||
const agencyFile = ref<File[]>([]);
|
||||
const agencyFileList = ref<{ name: string; url: string }[]>([]);
|
||||
const formData = ref<UserCreate>({
|
||||
selectedImage: '',
|
||||
branchId: '',
|
||||
provinceId: null,
|
||||
districtId: null,
|
||||
|
|
@ -227,7 +225,6 @@ const formData = ref<UserCreate>({
|
|||
namePrefix: null,
|
||||
userRole: '',
|
||||
userType: '',
|
||||
profileImage: null,
|
||||
birthDate: null,
|
||||
responsibleArea: null,
|
||||
checkpoint: null,
|
||||
|
|
@ -240,12 +237,18 @@ const isImageEdit = ref<boolean>(false);
|
|||
const imageUrl = ref<string>('');
|
||||
const profileFileImg = ref<File | null>(null);
|
||||
const imageDialog = ref(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: [] });
|
||||
|
||||
// const inputFile = document.createElement('input');
|
||||
// inputFile.type = 'file';
|
||||
// inputFile.accept = 'image/*';
|
||||
|
||||
const reader = new FileReader();
|
||||
// const reader = new FileReader();
|
||||
|
||||
const columns = [
|
||||
{
|
||||
|
|
@ -357,23 +360,6 @@ async function openDialog(
|
|||
|
||||
infoDrawerEdit.value = isPersonEdit ? true : false;
|
||||
infoDrawer.value = true;
|
||||
const user = userData.value.result.find((x) => x.id === id);
|
||||
infoPersonCard.value = user
|
||||
? [
|
||||
{
|
||||
id: user.id,
|
||||
img: `${user.profileImageUrl}`,
|
||||
name:
|
||||
locale.value === 'eng'
|
||||
? `${user.firstNameEN} ${user.lastNameEN}`
|
||||
: `${user.firstName} ${user.lastName}`,
|
||||
male: user.gender === 'male',
|
||||
female: user.gender === 'female',
|
||||
badge: user.code,
|
||||
disabled: user.status === 'INACTIVE',
|
||||
},
|
||||
]
|
||||
: [];
|
||||
}
|
||||
|
||||
statusToggle.value = true;
|
||||
|
|
@ -387,7 +373,11 @@ function undo() {
|
|||
assignFormData(infoPersonId.value);
|
||||
}
|
||||
|
||||
function onClose() {
|
||||
function onClose(excludeDialog?: boolean) {
|
||||
if (excludeDialog) {
|
||||
infoDrawer.value = excludeDialog || false;
|
||||
return;
|
||||
}
|
||||
hqId.value = '';
|
||||
brId.value = '';
|
||||
userId.value = '';
|
||||
|
|
@ -398,17 +388,17 @@ function onClose() {
|
|||
agencyFile.value = [];
|
||||
modal.value = false;
|
||||
isEdit.value = false;
|
||||
infoDrawer.value = false;
|
||||
profileSubmit.value = false;
|
||||
statusToggle.value = true;
|
||||
isImageEdit.value = false;
|
||||
currentUser.value = undefined;
|
||||
Object.assign(formData.value, defaultFormData);
|
||||
mapUserType(selectorLabel.value);
|
||||
imageList.value = { selectedImage: '', list: [] };
|
||||
onCreateImageList.value = { selectedImage: '', list: [] };
|
||||
flowStore.rotate();
|
||||
}
|
||||
async function onSubmit() {
|
||||
formData.value.profileImage = profileFileImg.value as File;
|
||||
|
||||
async function onSubmit(excludeDialog?: boolean) {
|
||||
if (isEdit.value && userId.value) {
|
||||
if (!userId.value) return;
|
||||
|
||||
|
|
@ -441,7 +431,7 @@ async function onSubmit() {
|
|||
if (res) {
|
||||
userStats.value = res;
|
||||
}
|
||||
onClose();
|
||||
onClose(excludeDialog);
|
||||
} else {
|
||||
if (!hqId.value) return;
|
||||
|
||||
|
|
@ -456,7 +446,10 @@ async function onSubmit() {
|
|||
: hqId.value
|
||||
? hqId.value
|
||||
: '';
|
||||
const result = await userStore.create(formData.value);
|
||||
const result = await userStore.create(
|
||||
formData.value,
|
||||
onCreateImageList.value,
|
||||
);
|
||||
|
||||
if (result && formData.value.userType === 'AGENCY') {
|
||||
if (!agencyFile.value) return;
|
||||
|
|
@ -558,7 +551,6 @@ async function assignFormData(idEdit: string) {
|
|||
currentUser.value = foundUser;
|
||||
if (currentUser.value) {
|
||||
infoPersonId.value = currentUser.value.id;
|
||||
imageUrl.value = currentUser.value.profileImageUrl;
|
||||
}
|
||||
formData.value = {
|
||||
branchId: foundUser.branch[0]?.id,
|
||||
|
|
@ -591,6 +583,7 @@ async function assignFormData(idEdit: string) {
|
|||
checkpointEN: foundUser.checkpointEN,
|
||||
responsibleArea: foundUser.responsibleArea,
|
||||
status: foundUser.status,
|
||||
selectedImage: foundUser.selectedImage,
|
||||
licenseExpireDate:
|
||||
(foundUser.licenseExpireDate &&
|
||||
new Date(foundUser.licenseExpireDate)) ||
|
||||
|
|
@ -619,14 +612,14 @@ async function assignFormData(idEdit: string) {
|
|||
}
|
||||
|
||||
userCode.value = foundUser.code;
|
||||
urlProfile.value = `${apiBaseUrl}/user/${foundUser.id}/image`;
|
||||
urlProfile.value = `${baseUrl}/user/${foundUser.id}/profile-image/${foundUser.selectedImage}`;
|
||||
|
||||
isEdit.value = true;
|
||||
profileSubmit.value = true;
|
||||
hqId.value && (await userStore.fetchBrOption(hqId.value));
|
||||
if (infoPersonCard.value) {
|
||||
infoPersonCard.value[0].img = foundUser.profileImageUrl;
|
||||
}
|
||||
|
||||
await fetchImageList(foundUser.id, foundUser.selectedImage);
|
||||
|
||||
if (formData.value.districtId) {
|
||||
await adrressStore.fetchSubDistrictByProvinceId(
|
||||
formData.value.districtId,
|
||||
|
|
@ -635,10 +628,6 @@ async function assignFormData(idEdit: string) {
|
|||
}
|
||||
}
|
||||
|
||||
function openImageDialog() {
|
||||
imageDialog.value = true;
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
utilsStore.currentTitle.title = 'personnel.title';
|
||||
utilsStore.currentTitle.path = [{ text: 'personnel.caption', i18n: true }];
|
||||
|
|
@ -667,6 +656,15 @@ function mapRole(value: string) {
|
|||
return option ? option.label : '-';
|
||||
}
|
||||
|
||||
async function fetchImageList(id: string, selectedName: string) {
|
||||
const res = await userStore.fetchImageListById(id);
|
||||
imageList.value = {
|
||||
selectedImage: selectedName,
|
||||
list: res.map((n: string) => `user/${id}/profile-image/${n}`),
|
||||
};
|
||||
return res;
|
||||
}
|
||||
|
||||
watch(
|
||||
() => selectorLabel.value,
|
||||
async (label) => {
|
||||
|
|
@ -1145,7 +1143,7 @@ watch(
|
|||
<q-img
|
||||
class="text-center"
|
||||
:ratio="1"
|
||||
:src="`${apiBaseUrl}/user/${props.row.id}/image?ts=${Date.now()}`"
|
||||
:src="`${baseUrl}/user/${props.row.id}/profile-image/${props.row.selectedImage}?ts=${Date.now()}`"
|
||||
>
|
||||
<template #error>
|
||||
<div
|
||||
|
|
@ -1314,7 +1312,6 @@ watch(
|
|||
:prefix-id="props.row.username"
|
||||
:data="{
|
||||
code: props.row.code,
|
||||
|
||||
name:
|
||||
$i18n.locale === 'eng'
|
||||
? `${props.row.firstNameEN} ${props.row.lastNameEN}`.trim()
|
||||
|
|
@ -1366,7 +1363,7 @@ watch(
|
|||
<q-img
|
||||
class="text-center"
|
||||
:ratio="1"
|
||||
:src="`${apiBaseUrl}/user/${props.row.id}/image?ts=${Date.now()}`"
|
||||
:src="`${baseUrl}/user/${props.row.id}/profile-image/${props.row.selectedImage}?ts=${Date.now()}`"
|
||||
style="
|
||||
object-fit: cover;
|
||||
width: 100%;
|
||||
|
|
@ -1532,12 +1529,13 @@ watch(
|
|||
v-model:toggle-status="formData.status"
|
||||
hideFade
|
||||
:menu="formMenuIcon"
|
||||
:readonly="!infoDrawerEdit"
|
||||
:toggleTitle="$t('status.title')"
|
||||
:title="`${$i18n.locale === 'eng' ? `${formData.firstNameEN} ${formData.lastNameEN}` : `${formData.firstName} ${formData.lastName}`}`"
|
||||
:caption="userCode"
|
||||
:img="
|
||||
urlProfile ||
|
||||
`${baseUrl}/user/${currentUser.id}/profile-image/${formData.selectedImage}`.concat(
|
||||
refreshImageState ? `?ts=${Date.now()}` : '',
|
||||
) ||
|
||||
{
|
||||
male: '/no-img-man.png',
|
||||
female: '/no-img-female.png',
|
||||
|
|
@ -1549,8 +1547,13 @@ watch(
|
|||
female: '/no-img-female.png',
|
||||
}[formData.gender]
|
||||
"
|
||||
@view="openImageDialog"
|
||||
@edit="refImageUpload && refImageUpload.browse()"
|
||||
@view="
|
||||
() => {
|
||||
imageDialog = true;
|
||||
isImageEdit = false;
|
||||
}
|
||||
"
|
||||
@edit="imageDialog = isImageEdit = true"
|
||||
@update:toggle-status="
|
||||
async (v) => {
|
||||
await triggerChangeStatus(infoPersonId, v);
|
||||
|
|
@ -1779,8 +1782,13 @@ watch(
|
|||
}[formData.gender]
|
||||
"
|
||||
hideFade
|
||||
@view="imageDialog = true"
|
||||
@edit="refImageUpload && refImageUpload.browse()"
|
||||
@view="
|
||||
() => {
|
||||
imageDialog = true;
|
||||
isImageEdit = false;
|
||||
}
|
||||
"
|
||||
@edit="imageDialog = isImageEdit = true"
|
||||
@update:toggle-status="
|
||||
() => {
|
||||
formData.status =
|
||||
|
|
@ -1914,10 +1922,59 @@ watch(
|
|||
v-model:dialogState="imageDialog"
|
||||
v-model:file="profileFileImg"
|
||||
v-model:image-url="urlProfile"
|
||||
:hiddenFooter="!isImageEdit && !modal"
|
||||
@save="imageDialog = false"
|
||||
clearButton
|
||||
v-model:data-list="imageList"
|
||||
v-model:on-create-data-list="onCreateImageList"
|
||||
:on-create="modal"
|
||||
:hiddenFooter="!isImageEdit"
|
||||
@add-image="
|
||||
async (v) => {
|
||||
if (!v) return;
|
||||
if (!currentUser) return;
|
||||
const res = await userStore.addImageList(
|
||||
v,
|
||||
currentUser?.id,
|
||||
Date.now(),
|
||||
);
|
||||
await fetchImageList(currentUser?.id, res);
|
||||
}
|
||||
"
|
||||
@remove-image="
|
||||
async (v) => {
|
||||
if (!v) return;
|
||||
if (!currentUser) return;
|
||||
|
||||
const name = v.split('/').pop() || '';
|
||||
await userStore.deleteImageByName(currentUser?.id, name);
|
||||
await fetchImageList(currentUser?.id, name);
|
||||
}
|
||||
"
|
||||
@submit="
|
||||
async (v) => {
|
||||
if (modal) {
|
||||
urlProfile = v;
|
||||
imageDialog = false;
|
||||
} else {
|
||||
refreshImageState = true;
|
||||
formData.selectedImage = v;
|
||||
imageList ? (imageList.selectedImage = v) : '';
|
||||
urlProfile = `${baseUrl}/user/${currentUser && currentUser.id}/profile-image/${v}`;
|
||||
await onSubmit(true);
|
||||
imageDialog = false;
|
||||
refreshImageState = false;
|
||||
}
|
||||
}
|
||||
"
|
||||
>
|
||||
<template #title>
|
||||
<span v-if="!modal" class="justify-center flex text-bold">
|
||||
{{ $t('general.image') }}
|
||||
{{
|
||||
$i18n.locale === 'eng'
|
||||
? `${formData.firstNameEN} ${formData.lastNameEN}`
|
||||
: `${formData.firstName} ${formData.lastName}`
|
||||
}}
|
||||
</span>
|
||||
</template>
|
||||
<template #error>
|
||||
<div class="full-height full-width" style="background: white">
|
||||
<div
|
||||
|
|
@ -1938,7 +1995,7 @@ watch(
|
|||
/>
|
||||
<q-icon
|
||||
v-else
|
||||
size="7vw"
|
||||
size="3rem"
|
||||
:name="
|
||||
infoDrawer ? 'mdi-account-outline' : 'mdi-account-plus-outline'
|
||||
"
|
||||
|
|
|
|||
|
|
@ -178,6 +178,14 @@ const dialogCreateCustomerItem = [
|
|||
},
|
||||
];
|
||||
|
||||
// image
|
||||
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: [] });
|
||||
|
||||
watch(() => route.name, init);
|
||||
watch(
|
||||
[currentTab, currentStatus, inputSearch, customerTypeSelected],
|
||||
|
|
@ -475,6 +483,7 @@ async function openHistory(id: string) {
|
|||
async function editCustomerForm(id: string) {
|
||||
await customerFormStore.assignFormData(id);
|
||||
await fetchListOfOptionBranch();
|
||||
await fetchImageList(id, customerFormData.value.selectedImage || '');
|
||||
customerFormState.value.dialogType = 'edit';
|
||||
customerFormState.value.drawerModal = true;
|
||||
customerFormState.value.editCustomerId = id;
|
||||
|
|
@ -563,6 +572,15 @@ function returnCountryCode(country: string) {
|
|||
return tempValue?.value;
|
||||
}
|
||||
|
||||
async function fetchImageList(id: string, selectedName: string) {
|
||||
const res = await customerStore.fetchImageListById(id);
|
||||
imageList.value = {
|
||||
selectedImage: selectedName,
|
||||
list: res.map((n: string) => `customer/${id}/image/${n}`),
|
||||
};
|
||||
return res;
|
||||
}
|
||||
|
||||
// TODO: When in employee form, if select address same as customer then auto fill
|
||||
|
||||
watch(
|
||||
|
|
@ -705,6 +723,14 @@ watch(
|
|||
},
|
||||
);
|
||||
|
||||
watch(
|
||||
() => customerFormData.value.image,
|
||||
() => {
|
||||
if (customerFormData.value.image !== null)
|
||||
customerFormState.value.isImageEdit = true;
|
||||
},
|
||||
);
|
||||
|
||||
const emptyCreateDialog = ref(false);
|
||||
</script>
|
||||
|
||||
|
|
@ -1161,7 +1187,7 @@ const emptyCreateDialog = ref(false);
|
|||
<div class="branch-card__icon">
|
||||
<q-avatar size="md">
|
||||
<q-img
|
||||
:src="`${baseUrl}/customer/${props.row.id}/image`"
|
||||
:src="`${baseUrl}/customer/${props.row.id}/image/${props.row.selectedImage}`"
|
||||
class="full-height full-width"
|
||||
>
|
||||
<template #error>
|
||||
|
|
@ -1371,7 +1397,7 @@ const emptyCreateDialog = ref(false);
|
|||
$i18n.locale === 'eng'
|
||||
? `${props.row.firstNameEN} ${props.row.lastNameEN} `.trim()
|
||||
: `${props.row.firstName} ${props.row.lastName} `.trim(),
|
||||
img: `${baseUrl}/customer/${props.row.id}/image`,
|
||||
img: `${baseUrl}/customer/${props.row.id}/image/${props.row.selectedImage}`,
|
||||
fallbackImg: `/images/customer-${props.row.customerType}-avartar-${props.row.gender}.png`,
|
||||
male: undefined,
|
||||
female: undefined,
|
||||
|
|
@ -1750,8 +1776,15 @@ const emptyCreateDialog = ref(false);
|
|||
? 'mdi-account-plus-outline'
|
||||
: 'mdi-office-building-outline'
|
||||
"
|
||||
@view="customerFormState.imageDialog = true"
|
||||
@edit="dialogCustomerImageUpload?.browse()"
|
||||
@view="
|
||||
() => {
|
||||
customerFormState.imageDialog = true;
|
||||
customerFormState.isImageEdit = false;
|
||||
}
|
||||
"
|
||||
@edit="
|
||||
customerFormState.imageDialog = customerFormState.isImageEdit = true
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
|
|
@ -1804,7 +1837,7 @@ const emptyCreateDialog = ref(false);
|
|||
<q-form
|
||||
@submit.prevent="
|
||||
async () => {
|
||||
await customerFormStore.submitFormCustomer();
|
||||
await customerFormStore.submitFormCustomer(onCreateImageList);
|
||||
customerFormState.readonly = true;
|
||||
notify('create', $t('general.success'));
|
||||
await fetchListCustomer();
|
||||
|
|
@ -2629,18 +2662,69 @@ const emptyCreateDialog = ref(false);
|
|||
v-model:dialog-state="customerFormState.imageDialog"
|
||||
v-model:file="customerFormData.image"
|
||||
v-model:image-url="customerFormState.customerImageUrl"
|
||||
v-model:data-list="imageList"
|
||||
v-model:on-create-data-list="onCreateImageList"
|
||||
:on-create="customerFormState.dialogModal"
|
||||
:default-url="customerFormState.defaultCustomerImageUrl"
|
||||
clear-button
|
||||
@save="
|
||||
:hiddenFooter="!customerFormState.isImageEdit"
|
||||
@add-image="
|
||||
async (v) => {
|
||||
if (v && customerFormState.editCustomerId) {
|
||||
await customerStore.setImage(customerFormState.editCustomerId, v);
|
||||
await fetchListCustomer();
|
||||
if (!v) return;
|
||||
if (!customerFormState.editCustomerId) return;
|
||||
await customerStore.addImageList(
|
||||
v,
|
||||
customerFormState.editCustomerId,
|
||||
Date.now(),
|
||||
);
|
||||
await fetchImageList(
|
||||
customerFormState.editCustomerId,
|
||||
customerFormData.selectedImage || '',
|
||||
);
|
||||
}
|
||||
"
|
||||
@remove-image="
|
||||
async (v) => {
|
||||
if (!v) return;
|
||||
if (!customerFormState.editCustomerId) return;
|
||||
const name = v.split('/').pop() || '';
|
||||
await customerStore.deleteImageByName(
|
||||
customerFormState.editCustomerId,
|
||||
name,
|
||||
);
|
||||
await fetchImageList(customerFormState.editCustomerId, name);
|
||||
}
|
||||
"
|
||||
@submit="
|
||||
async (v) => {
|
||||
if (customerFormState.dialogModal) {
|
||||
customerFormState.customerImageUrl = v;
|
||||
customerFormState.imageDialog = false;
|
||||
} else {
|
||||
refreshImageState = true;
|
||||
customerFormData.selectedImage = v;
|
||||
imageList ? (imageList.selectedImage = v) : '';
|
||||
customerFormState.customerImageUrl = `${baseUrl}/customer/${customerFormState.editCustomerId && customerFormState.editCustomerId}/image/${v}`;
|
||||
customerFormStore.resetForm();
|
||||
await customerFormStore.submitFormCustomer();
|
||||
customerFormState.imageDialog = false;
|
||||
refreshImageState = false;
|
||||
}
|
||||
}
|
||||
"
|
||||
>
|
||||
<template #title>
|
||||
<span
|
||||
v-if="!customerFormState.dialogModal"
|
||||
class="justify-center flex text-bold"
|
||||
>
|
||||
{{ $t('general.image') }}
|
||||
{{
|
||||
$i18n.locale === 'eng'
|
||||
? `${customerFormData.firstNameEN} ${customerFormData.lastNameEN}`
|
||||
: `${customerFormData.firstName} ${customerFormData.lastName}`
|
||||
}}
|
||||
</span>
|
||||
</template>
|
||||
<template #error>
|
||||
<div class="full-height full-width" style="background: white">
|
||||
<div
|
||||
|
|
@ -2663,7 +2747,7 @@ const emptyCreateDialog = ref(false);
|
|||
class="full-width full-height column items-center justify-center"
|
||||
>
|
||||
<q-icon
|
||||
size="7vw"
|
||||
size="3rem"
|
||||
:name="
|
||||
customerFormData.customerType === 'PERS'
|
||||
? 'mdi-account-plus-outline'
|
||||
|
|
@ -2766,8 +2850,9 @@ const emptyCreateDialog = ref(false);
|
|||
hide-fade
|
||||
:fallback-cover="`/images/customer-${customerFormData.customerType}-banner-bg.jpg`"
|
||||
:img="
|
||||
customerFormState.customerImageUrl ||
|
||||
`/images/customer-${customerFormData.customerType}-avartar-${customerFormData.gender}.png`
|
||||
`${baseUrl}/customer/${customerFormState.editCustomerId}/image/${customerFormData.selectedImage}`.concat(
|
||||
refreshImageState ? `?ts=${Date.now()}` : '',
|
||||
) || null
|
||||
"
|
||||
:fallbackImg="`/images/customer-${customerFormData.customerType}-avartar-${customerFormData.gender}.png`"
|
||||
:color="`hsla(var(--${customerFormData.customerType === 'PERS' ? 'teal-10-hsl' : 'violet-11-hsl'})/1)`"
|
||||
|
|
@ -2777,8 +2862,15 @@ const emptyCreateDialog = ref(false);
|
|||
? 'mdi-account-plus-outline'
|
||||
: 'mdi-office-building-outline'
|
||||
"
|
||||
@view="customerFormState.imageDialog = true"
|
||||
@edit="dialogCustomerImageUpload?.browse()"
|
||||
@view="
|
||||
() => {
|
||||
customerFormState.imageDialog = true;
|
||||
customerFormState.isImageEdit = false;
|
||||
}
|
||||
"
|
||||
@edit="
|
||||
customerFormState.imageDialog = customerFormState.isImageEdit = true
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ export const useCustomerForm = defineStore('form-customer', () => {
|
|||
registeredBranchId: branchStore.currentMyBranch?.id || '',
|
||||
customerBranch: [],
|
||||
image: null,
|
||||
selectedImage: '',
|
||||
};
|
||||
let resetFormData = structuredClone(defaultFormData);
|
||||
|
||||
|
|
@ -50,6 +51,7 @@ export const useCustomerForm = defineStore('form-customer', () => {
|
|||
editCustomerBranchId?: string;
|
||||
treeFile: { label: string; file: { label: string }[] }[];
|
||||
formDataOcr: Record<string, any>;
|
||||
isImageEdit: boolean;
|
||||
}>({
|
||||
dialogType: 'info',
|
||||
dialogOpen: false,
|
||||
|
|
@ -65,6 +67,7 @@ export const useCustomerForm = defineStore('form-customer', () => {
|
|||
defaultCustomerImageUrl: '',
|
||||
treeFile: [],
|
||||
formDataOcr: {},
|
||||
isImageEdit: false,
|
||||
});
|
||||
|
||||
watch(
|
||||
|
|
@ -110,8 +113,9 @@ export const useCustomerForm = defineStore('form-customer', () => {
|
|||
if (state.value.dialogType === 'create') {
|
||||
state.value.editCustomerId = '';
|
||||
}
|
||||
|
||||
const currentImg = currentFormData.value.selectedImage;
|
||||
currentFormData.value = structuredClone(resetFormData);
|
||||
currentFormData.value.selectedImage = currentImg;
|
||||
}
|
||||
|
||||
async function assignFormData(id?: string) {
|
||||
|
|
@ -129,8 +133,8 @@ export const useCustomerForm = defineStore('form-customer', () => {
|
|||
state.value.dialogType = 'edit';
|
||||
state.value.editCustomerId = id;
|
||||
state.value.editCustomerCode = data.code;
|
||||
state.value.customerImageUrl = `${apiBaseUrl}/customer/${id}/image`;
|
||||
state.value.defaultCustomerImageUrl = `${apiBaseUrl}/customer/${id}/image`;
|
||||
state.value.customerImageUrl = `${apiBaseUrl}/customer/${id}/image/${data.selectedImage}`;
|
||||
state.value.defaultCustomerImageUrl = `${apiBaseUrl}/customer/${id}/image/${data.selectedImage}`;
|
||||
|
||||
resetFormData.registeredBranchId = data.registeredBranchId;
|
||||
resetFormData.code = data.code || '';
|
||||
|
|
@ -144,6 +148,7 @@ export const useCustomerForm = defineStore('form-customer', () => {
|
|||
resetFormData.gender = data.gender;
|
||||
resetFormData.birthDate = new Date(data.birthDate);
|
||||
resetFormData.image = null;
|
||||
resetFormData.selectedImage = data.selectedImage;
|
||||
|
||||
resetFormData.customerBranch = await Promise.all(
|
||||
data.branch.map(async (v) => ({
|
||||
|
|
@ -259,11 +264,14 @@ export const useCustomerForm = defineStore('form-customer', () => {
|
|||
(currentFormData.value.customerBranch?.length || 0) - 1;
|
||||
}
|
||||
|
||||
async function submitFormCustomer() {
|
||||
async function submitFormCustomer(imgList?: {
|
||||
selectedImage: string;
|
||||
list: { url: string; imgFile: File | null; name: string }[];
|
||||
}) {
|
||||
if (state.value.dialogType === 'info') return;
|
||||
|
||||
if (state.value.dialogType === 'create') {
|
||||
const _data = await customerStore.create(currentFormData.value);
|
||||
const _data = await customerStore.create(currentFormData.value, imgList);
|
||||
|
||||
if (_data) await assignFormData(_data.id);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue