fix(02): view fallback image & change status

This commit is contained in:
puriphatt 2024-08-05 06:55:56 +00:00
parent 15a8e0bbde
commit 693c2fcb9a
5 changed files with 238 additions and 115 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 KiB

After

Width:  |  Height:  |  Size: 95 KiB

Before After
Before After

View file

@ -76,7 +76,7 @@ function deleteFile(name: string) {
size="xs"
class="q-pa-sm rounded q-mr-xs"
color="info"
name="mdi-bank"
name="mdi-briefcase"
style="background-color: var(--surface-3)"
/>
{{ $t('formDialogTitleByType') }}

View file

@ -221,7 +221,7 @@ onMounted(async () => {
v-model="userRole"
:readonly="readonly"
:hide-dropdown-icon="readonly"
:label="$t('formDialogPrefixName')"
:label="$t('userRole')"
:options="roleOptions"
:rules="[
(val: string) => !!val || $t('formDialogInputPrefixNameValidate'),

View file

@ -1,4 +1,5 @@
<script setup lang="ts">
import { QSelect } from 'quasar';
import useOptionStore from 'src/stores/options';
import { selectFilterOptionRefMod } from 'src/stores/utils';
import {
@ -7,7 +8,7 @@ import {
parseAndFormatDate,
disabledAfterToday,
} from 'src/utils/datetime';
import { ref } from 'vue';
import { ref, onMounted, watch } from 'vue';
import { useI18n } from 'vue-i18n';
const { locale } = useI18n();
@ -23,27 +24,6 @@ const gender = defineModel<string>('gender');
const birthDate = defineModel<Date | string | null>('birthDate');
const nationality = defineModel<string>('nationality');
const prefixNameOptions = ref<Record<string, unknown>[]>([]);
const prefixNameFilter = selectFilterOptionRefMod(
ref(optionStore.globalOption.prefix),
prefixNameOptions,
'label',
);
const genderOptions = ref<Record<string, unknown>[]>([]);
const genderFilter = selectFilterOptionRefMod(
ref(optionStore.globalOption.gender),
genderOptions,
'label',
);
const nationalityOptions = ref<Record<string, unknown>[]>([]);
const nationalityFilter = selectFilterOptionRefMod(
ref(optionStore.globalOption.nationality),
nationalityOptions,
'label',
);
defineProps<{
dense?: boolean;
outlined?: boolean;
@ -53,6 +33,63 @@ defineProps<{
title?: string;
prefixId: string;
}>();
const prefixNameOptions = ref<Record<string, unknown>[]>([]);
let prefixNameFilter: (
value: string,
update: (callbackFn: () => void, afterFn?: (ref: QSelect) => void) => void,
) => void;
const genderOptions = ref<Record<string, unknown>[]>([]);
let genderFilter: (
value: string,
update: (callbackFn: () => void, afterFn?: (ref: QSelect) => void) => void,
) => void;
const nationalityOptions = ref<Record<string, unknown>[]>([]);
let nationalityFilter: (
value: string,
update: (callbackFn: () => void, afterFn?: (ref: QSelect) => void) => void,
) => void;
onMounted(() => {
prefixNameFilter = selectFilterOptionRefMod(
ref(optionStore.globalOption.prefix),
prefixNameOptions,
'label',
);
genderFilter = selectFilterOptionRefMod(
ref(optionStore.globalOption.gender),
genderOptions,
'label',
);
nationalityFilter = selectFilterOptionRefMod(
ref(optionStore.globalOption.nationality),
nationalityOptions,
'label',
);
});
watch(
() => optionStore.globalOption,
() => {
prefixNameFilter = selectFilterOptionRefMod(
ref(optionStore.globalOption.prefix),
prefixNameOptions,
'label',
);
genderFilter = selectFilterOptionRefMod(
ref(optionStore.globalOption.gender),
genderOptions,
'label',
);
nationalityFilter = selectFilterOptionRefMod(
ref(optionStore.globalOption.nationality),
nationalityOptions,
'label',
);
},
);
</script>
<template>
<div class="row col-12">

View file

@ -36,6 +36,7 @@ import ProfileBanner from 'src/components/ProfileBanner.vue';
import SideMenu from 'src/components/SideMenu.vue';
import ImageUploadDialog from 'src/components/ImageUploadDialog.vue';
import FormAddress from 'src/components/02_personnel-management/FormAddress.vue';
import DialogForm from 'src/components/DialogForm.vue';
const { locale, t } = useI18n();
const $q = useQuasar();
@ -135,6 +136,7 @@ const fieldSelected = ref<
('name' | 'type' | 'telephoneNo' | 'birthDate' | 'email' | 'userRole')[]
>(['name', 'type', 'telephoneNo', 'birthDate', 'email', 'userRole']);
const refImageUpload = ref<InstanceType<typeof ImageUploadDialog>>();
const fieldDisplay = ref();
const hideStat = ref(false);
const userCode = ref<string>();
@ -516,7 +518,10 @@ async function toggleStatus(id: string) {
const res = await userStore.editById(record.id, {
status: record.status !== 'INACTIVE' ? 'INACTIVE' : 'ACTIVE',
});
if (res) record.status = res.status;
if (res) {
record.status = res.status;
formData.value.status = res.status;
}
}
async function triggerChangeStatus(id: string, status: string) {
@ -700,12 +705,12 @@ async function fetchUserList() {
}
async function handleImageUpload(file: File | null, url: string | null) {
if (!infoDrawerEdit.value) {
if (!infoDrawerEdit.value && !modal.value) {
infoDrawerEdit.value = true;
await onSubmit();
infoDrawerEdit.value = false;
}
if (infoDrawerEdit.value) {
if (infoDrawerEdit.value && !modal.value) {
await onSubmit();
}
imageDialog.value = false;
@ -1129,6 +1134,7 @@ watch(
<div class="branch-card__icon">
<q-avatar size="md">
<q-img
:ratio="1"
:src="
props.row.profileImageUrl
? props.row.profileImageUrl
@ -1539,31 +1545,40 @@ watch(
>
<div class="q-mx-lg q-mt-lg">
<ProfileBanner
active
hideFade
:active="formData.status !== 'INACTIVE'"
useToggle
color="hsla(var(--pink-6-hsl)/1)"
bgColor="hsla(var(--pink-6-hsl)/0.15)"
v-model:cover-url="urlProfile"
v-model:toggle-status="formData.status"
:menu="formMenuIcon"
:cover="urlProfile || null"
:readonly="!infoDrawerEdit"
:toggleTitle="$t('formDialogTitleUserStatus')"
:title="`${formData.firstName} ${formData.lastName}`"
:caption="`${formData.firstNameEN} ${formData.lastNameEN}`"
:hideFade="urlProfile === '' || urlProfile === undefined"
:img="
imageUrl ||
urlProfile ||
{
male: '/no-img-man.png',
female: '/no-img-female.png',
}[formData.gender]
"
:cover="imageUrl || null"
:title="`${formData.firstName} ${formData.lastName}`"
:caption="`${formData.firstNameEN} ${formData.lastNameEN}`"
color="hsla(var(--pink-6-hsl)/1)"
bgColor="hsla(var(--pink-6-hsl)/0.15)"
@view="openImageDialog"
@edit="inputFileImg.click()"
:readonly="!infoDrawerEdit"
:menu="formMenuIcon"
@update:toggle-status="
async (v) => {
await triggerChangeStatus(infoPersonId, v);
}
"
/>
</div>
<!-- อนกล -->
<div
class="col surface-1 q-ma-lg rounded bordered scroll row"
id="personnel-form"
id="personnel-info"
>
<div class="col">
<div style="position: sticky; top: 0" class="q-pa-sm">
@ -1571,19 +1586,19 @@ watch(
:menu="[
{
name: $t('formDialogTitleInformation'),
anchor: 'form-information',
anchor: 'info-information',
},
{
name: $t('formDialogTitlePersonal'),
anchor: 'form-personal',
anchor: 'info-personal',
},
{
name: $t('formDialogTitleAddressPersonnel'),
anchor: 'form-address',
anchor: 'info-address',
},
{
name: $t('formDialogTitleByType'),
anchor: 'form-work',
anchor: 'info-work',
},
]"
background="transparent"
@ -1591,14 +1606,14 @@ watch(
background: 'hsla(var(--blue-6-hsl) / .2)',
foreground: 'var(--blue-6)',
}"
scroll-element="#personnel-form"
scroll-element="#personnel-info"
/>
</div>
</div>
<div class="col-10 q-pa-md q-gutter-y-xl">
<FormInformation
id="form-information"
id="info-information"
v-model:hq-id="hqId"
v-model:br-id="brId"
v-model:user-type="formData.userType"
@ -1608,22 +1623,22 @@ watch(
dense
outlined
separator
:title="$t('formDialogTitleInformation')"
:title="'formDialogTitleInformation'"
:readonly="!infoDrawerEdit"
:usernameReadonly="isEdit"
/>
<FormPerson
id="form-personal"
id="info-personal"
v-model:first-name="formData.firstName"
v-model:last-name="formData.lastName"
v-model:first-name-en="formData.firstNameEN"
v-model:last-name-en="formData.lastNameEN"
v-model:first-name-e-n="formData.firstNameEN"
v-model:last-name-e-n="formData.lastNameEN"
v-model:telephone-no="formData.telephoneNo"
v-model:email="formData.email"
v-model:gender="formData.gender"
v-model:birth-date="formData.birthDate"
:title="$t('formDialogTitlePersonal')"
:title="'formDialogTitlePersonal'"
prefix-id="drawer-info-personnel"
dense
outlined
@ -1632,22 +1647,22 @@ watch(
/>
<FormAddress
id="form-address"
v-model:modal="modal"
id="info-address"
v-model:address="formData.address"
v-model:addressEN="formData.addressEN"
v-model:provinceId="formData.provinceId"
v-model:districtId="formData.districtId"
v-model:subDistrictId="formData.subDistrictId"
v-model:zipCode="formData.zipCode"
:readonly="!infoDrawerEdit"
prefix-id="drawer-info-personnel"
dense
/>
<FormByType
dense
outlined
separator
id="info-work"
:readonly="!infoDrawerEdit"
v-model:userType="formData.userType"
v-model:registrationNo="formData.registrationNo"
@ -1670,23 +1685,38 @@ watch(
</DrawerInfo>
<!-- form -->
<FormDialog
<DialogForm
removeDialog
ref="formDialogRef"
:badgeClass="formData.gender === 'male' ? 'app-bg-male' : 'app-bg-female'"
:badgeLabel="userCode"
:title="$t('personnelAdd')"
v-model:modal="modal"
v-model:address="formData.address"
v-model:addressEN="formData.addressEN"
v-model:provinceId="formData.provinceId"
v-model:districtId="formData.districtId"
v-model:subDistrictId="formData.subDistrictId"
v-model:zipCode="formData.zipCode"
:addressSeparator="formData.userType !== ''"
:submit="() => onSubmit()"
:close="() => onClose()"
>
<!-- :title="formData.name"
:caption="formData.nameEN" -->
<div class="q-mx-lg q-mt-lg">
<ProfileBanner
active
useToggle
color="white"
icon="mdi-account-plus"
bgColor="linear-gradient(135deg, rgba(43,137,223,1) 0%, rgba(230,51,81,1) 100%)"
v-model:cover-url="urlProfile"
v-model:toggle-status="formData.status"
:menu="formMenuIcon"
:img="urlProfile || undefined"
:toggleTitle="$t('formDialogTitleUserStatus')"
:title="`${formData.firstName} ${formData.lastName}`"
:hideFade="urlProfile === '' || urlProfile === undefined"
:caption="`${formData.firstNameEN} ${formData.lastNameEN}`"
@view="imageDialog = true"
@edit="refImageUpload && refImageUpload.browse()"
/>
</div>
<!-- <template #prepend>
<ProfileUpload
prefix-id="form-dialog-personnel"
@ -1696,64 +1726,108 @@ watch(
@input-file="inputFileImg.click()"
@cancel-file="inputFileImg.value = ''"
/>
</template>
<template #information>
<FormInformation
dense
outlined
separator
:usernameReadonly="isEdit"
v-model:hqId="hqId"
v-model:brId="brId"
v-model:userType="formData.userType"
v-model:userRole="formData.userRole"
v-model:username="formData.username"
v-model:userCode="userCode"
/>
</template>
<template #person>
<FormPerson
prefix-id="form-dialog-personnel"
dense
outlined
separator
v-model:firstName="formData.firstName"
v-model:lastName="formData.lastName"
v-model:firstNameEN="formData.firstNameEN"
v-model:lastNameEN="formData.lastNameEN"
v-model:telephoneNo="formData.telephoneNo"
v-model:email="formData.email"
v-model:gender="formData.gender"
v-model:birthDate="formData.birthDate"
/>
</template>
<template #by-type>
<FormByType
dense
outlined
separator
v-model:userType="formData.userType"
v-model:registrationNo="formData.registrationNo"
v-model:startDate="formData.startDate"
v-model:retireDate="formData.retireDate"
v-model:responsibleArea="formData.responsibleArea"
v-model:discountCondition="formData.discountCondition"
v-model:sourceNationality="formData.sourceNationality"
v-model:importNationality="formData.importNationality"
v-model:trainingPlace="formData.trainingPlace"
v-model:checkpoint="formData.checkpoint"
v-model:checkpointEN="formData.checkpointEN"
v-model:agencyFile="agencyFile"
/>
</template> -->
</FormDialog>
<div
class="col surface-1 q-ma-lg rounded bordered scroll row"
id="personnel-form"
>
<div class="col">
<div style="position: sticky; top: 0" class="q-pa-sm">
<SideMenu
:menu="[
{
name: $t('formDialogTitleInformation'),
anchor: 'form-information',
},
{
name: $t('formDialogTitlePersonal'),
anchor: 'form-personal',
},
{
name: $t('formDialogTitleAddressPersonnel'),
anchor: 'form-address',
},
{
name: $t('formDialogTitleByType'),
anchor: 'form-work',
},
]"
background="transparent"
:active="{
background: 'hsla(var(--blue-6-hsl) / .2)',
foreground: 'var(--blue-6)',
}"
scroll-element="#personnel-form"
/>
</div>
</div>
<div class="col-10 q-pa-md q-gutter-y-xl">
<FormInformation
dense
outlined
separator
:title="'formDialogTitleInformation'"
:usernameReadonly="isEdit"
v-model:hqId="hqId"
v-model:brId="brId"
v-model:userType="formData.userType"
v-model:userRole="formData.userRole"
v-model:username="formData.username"
v-model:userCode="userCode"
/>
<FormPerson
prefix-id="form-dialog-personnel"
dense
outlined
separator
:title="'formDialogTitlePersonal'"
v-model:firstName="formData.firstName"
v-model:lastName="formData.lastName"
v-model:firstNameEN="formData.firstNameEN"
v-model:lastNameEN="formData.lastNameEN"
v-model:telephoneNo="formData.telephoneNo"
v-model:email="formData.email"
v-model:gender="formData.gender"
v-model:birthDate="formData.birthDate"
/>
<FormAddress
id="form-address"
v-model:address="formData.address"
v-model:addressEN="formData.addressEN"
v-model:provinceId="formData.provinceId"
v-model:districtId="formData.districtId"
v-model:subDistrictId="formData.subDistrictId"
v-model:zipCode="formData.zipCode"
prefix-id="drawer-info-personnel"
dense
/>
<FormByType
dense
outlined
separator
v-model:userType="formData.userType"
v-model:registrationNo="formData.registrationNo"
v-model:startDate="formData.startDate"
v-model:retireDate="formData.retireDate"
v-model:responsibleArea="formData.responsibleArea"
v-model:discountCondition="formData.discountCondition"
v-model:sourceNationality="formData.sourceNationality"
v-model:importNationality="formData.importNationality"
v-model:trainingPlace="formData.trainingPlace"
v-model:checkpoint="formData.checkpoint"
v-model:checkpointEN="formData.checkpointEN"
v-model:agencyFile="agencyFile"
/>
</div>
</div>
</DialogForm>
<ImageUploadDialog
ref="refImageUpload"
v-model:dialogState="imageDialog"
v-model:file="profileFileImg as File"
v-model:image-url="imageUrl"
v-model:file="profileFileImg"
v-model:image-url="urlProfile"
:hiddenFooter="!isImageEdit"
clearButton
@save="handleImageUpload"
@ -1762,12 +1836,24 @@ watch(
<div class="full-height full-width" style="background: white">
<div
class="full-height full-width flex justify-center items-center"
style="background: hsla(var(--gray-8-hsl) / 0.15)"
style=""
:style="`background: ${
modal
? 'linear-gradient(135deg,rgba(43, 137, 223, 1) 0%,rgba(230, 51, 81, 1) 100%)'
: formData.gender === 'male'
? '#78afb0'
: '#c0bfe2'
}`"
>
<q-img
v-if="!modal"
:src="`/no-img-${formData.gender === 'male' ? 'man' : 'female'}.png`"
/>
<q-icon
v-else
size="15rem"
name="mdi-account-outline"
style="color: hsla(var(--gray-5-hsl) / 1)"
name="mdi-account-plus"
style="color: white"
/>
</div>
</div>