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:
puriphatt 2024-09-11 16:43:41 +07:00
parent ab0b3bb4f3
commit 62fc7055dd
13 changed files with 925 additions and 254 deletions

View file

@ -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'
"