fix(01): dialog drawer form

This commit is contained in:
puriphatt 2024-08-02 03:52:56 +00:00
parent ef9aeb930a
commit 073635c95b
5 changed files with 227 additions and 105 deletions

View file

@ -35,7 +35,7 @@ defineEmits<{
}" }"
class="col-12 row branch-form-show-qr-code" class="col-12 row branch-form-show-qr-code"
> >
<div class="col-12 flex flex-center q-py-md"> <div class="col-12 column flex-center q-py-md">
<q-img <q-img
v-if="qr" v-if="qr"
:src="qr as string" :src="qr as string"
@ -52,18 +52,17 @@ defineEmits<{
</q-img> </q-img>
<q-btn <q-btn
@click="$emit('upload')"
class="branch-form-btn-qr-code"
:class="{ 'dark-form-btn-qr-code': $q.dark.isActive }"
v-else v-else
@click="$emit('upload')"
class="branch-form-btn-qr-code q-mb-md"
:class="{ 'dark-form-btn-qr-code': $q.dark.isActive }"
unelevated unelevated
:color="$q.dark.isActive ? 'black' : 'grey-2'" :color="$q.dark.isActive ? 'black' : 'grey-2'"
:text-color="$q.dark.isActive ? 'white' : 'grey-5'" :text-color="$q.dark.isActive ? 'white' : 'grey-5'"
> >
<Icon icon="teenyicons:add-outline" width="30px" height="50px" /> <Icon icon="teenyicons:add-outline" width="30px" height="50px" />
</q-btn> </q-btn>
</div>
<div class="col-12 flex flex-center q-pb-md">
<q-btn <q-btn
v-if="!readonly" v-if="!readonly"
:text-color="$q.dark.isActive ? 'black' : 'white'" :text-color="$q.dark.isActive ? 'black' : 'white'"

View file

@ -51,26 +51,20 @@ const employeeTab = defineModel<string>('employeeTab');
</q-tabs> </q-tabs>
</div> </div>
<div <div class="row col full-width scroll">
class="col full-height q-pa-md full-width" <!-- prepend -->
:class="{ row: $q.screen.gt.sm, column: $q.screen.lt.md }" <div class="col" v-if="$slots.prepend">
> <slot name="prepend"></slot>
<div class="col-md-2 q-mr-md" v-if="$slots['person-card']">
<slot name="person-card"></slot>
</div> </div>
<div <!-- center -->
class="rounded scroll full-height col full-width" <div class="col column full-height">
:class="{ <slot></slot>
'q-mt-md': $q.screen.lt.md, </div>
}"
> <!-- append -->
<div <div class="col" v-if="$slots.append">
class="row q-col-gutter-y-md surface-1 rounded bordered" <slot name="append"></slot>
:class="{ 'q-pa-md': !noPaddingTab }"
>
<slot></slot>
</div>
</div> </div>
</div> </div>
</div> </div>

View file

@ -24,7 +24,7 @@ const file = defineModel<File | null>('file', {
required: true, required: true,
}); });
defineEmits<{ defineEmits<{
(e: 'save', v: File | null): void; (e: 'save', file: File | null, url: string | null): void;
}>(); }>();
const reader = new FileReader(); const reader = new FileReader();
@ -131,7 +131,7 @@ function change(e: Event) {
type="submit" type="submit"
color="primary" color="primary"
class="q-px-md" class="q-px-md"
@click="$emit('save', inputFile?.files?.[0] || null)" @click="$emit('save', inputFile?.files?.[0] || null, imageUrl)"
:label="$t('save')" :label="$t('save')"
/> />
</div> </div>
@ -190,4 +190,14 @@ function change(e: Event) {
.image-container > :deep(*:not(:first-child)) { .image-container > :deep(*:not(:first-child)) {
display: none; display: none;
} }
.close-btn {
color: hsl(var(--negative-bg));
background-color: hsla(var(--negative-bg) / 0.1);
&.dark {
background-color: transparent;
border: 1px solid hsl(var(--negative-bg));
}
}
</style> </style>

View file

@ -4,11 +4,11 @@ import { ref } from 'vue';
defineProps<{ defineProps<{
icon?: string; icon?: string;
color?: string; color?: string;
img?: string; img?: string | null;
bgColor?: string; bgColor?: string;
title?: string; title?: string;
caption?: string; caption?: string;
cover?: string; cover?: string | null;
hideFade?: boolean; hideFade?: boolean;
active?: boolean; active?: boolean;
@ -40,7 +40,11 @@ const showOverlay = ref(false);
<div class="absolute-top flex items-center full-height q-pl-lg"> <div class="absolute-top flex items-center full-height q-pl-lg">
<div <div
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);
overflow: hidden;
"
> >
<div <div
class="avatar__status" class="avatar__status"
@ -51,7 +55,7 @@ const showOverlay = ref(false);
size="6rem" size="6rem"
font-size="3rem" font-size="3rem"
class="cursor-pointer" class="cursor-pointer"
style="z-index: 1; overflow: hidden" style="z-index: 1"
:style="`background-color: ${img ? 'white' : bgColor || 'var(--brand-1)'}; color: ${color || 'white'}`" :style="`background-color: ${img ? 'white' : bgColor || 'var(--brand-1)'}; color: ${color || 'white'}`"
@mouseover="showOverlay = true" @mouseover="showOverlay = true"
@mouseleave="showOverlay = false" @mouseleave="showOverlay = false"

View file

@ -29,6 +29,7 @@ import InfoForm from 'components/02_personnel-management/InfoForm.vue';
import TreeCompoent from 'src/components/TreeCompoent.vue'; import TreeCompoent from 'src/components/TreeCompoent.vue';
import ProfileBanner from 'src/components/ProfileBanner.vue'; import ProfileBanner from 'src/components/ProfileBanner.vue';
import SideMenu from 'src/components/SideMenu.vue'; import SideMenu from 'src/components/SideMenu.vue';
import ImageUploadDialog from 'src/components/ImageUploadDialog.vue';
const $q = useQuasar(); const $q = useQuasar();
const { t } = useI18n(); const { t } = useI18n();
@ -69,10 +70,44 @@ const modal = ref<boolean>(false);
const hideStat = ref(false); const hideStat = ref(false);
const currentStatus = ref<Status | 'All'>('All'); const currentStatus = ref<Status | 'All'>('All');
const expandedTree = ref<string[]>([]); const expandedTree = ref<string[]>([]);
const formMenuIcon = ref<{ icon: string; color: string; bgColor: string }[]>([
{
icon: 'mdi-office-building-outline',
color: 'hsl(var(--info-bg))',
bgColor: 'var(--surface-1)',
},
{
icon: 'mdi-phone',
color: 'hsl(var(--info-bg))',
bgColor: 'var(--surface-1)',
},
{
icon: 'mdi-map-marker-radius',
color: 'hsl(var(--info-bg))',
bgColor: 'var(--surface-1)',
},
{
icon: 'mdi-map-legend',
color: 'hsl(var(--info-bg))',
bgColor: 'var(--surface-1)',
},
{
icon: 'mdi-qrcode',
color: 'hsl(var(--info-bg))',
bgColor: 'var(--surface-1)',
},
{
icon: 'mdi-piggy-bank-outline',
color: 'hsl(var(--info-bg))',
bgColor: 'var(--surface-1)',
},
]);
const profileFileImg = ref<File | undefined>(undefined); const isImageEdit = ref(false);
const profileFileImg = ref<File | null>(null);
const imageUrl = ref<string | null>(''); const imageUrl = ref<string | null>('');
const currentNode = ref<BranchWithChildren>(); const currentNode = ref<BranchWithChildren>();
const imageDialog = ref(false);
const inputFileImg = (() => { const inputFileImg = (() => {
const element = document.createElement('input'); const element = document.createElement('input');
@ -532,6 +567,25 @@ function handleHold(node: BranchWithChildren) {
}; };
} }
function openImageDialog(isEdit?: boolean) {
if (isEdit) isImageEdit.value = true;
else isImageEdit.value = false;
imageDialog.value = true;
}
function handleImageUpload(file: File | null, url: string | null) {
imageUrl.value = url;
imageDialog.value = false;
// profileFileImg = file;
}
watch(
() => profileFileImg.value,
() => {
if (profileFileImg.value !== null) isImageEdit.value = true;
},
);
watch(locale, () => { watch(locale, () => {
fieldSelectedBranch.value = { fieldSelectedBranch.value = {
label: t(`${fieldSelectedBranch.value.label}`), label: t(`${fieldSelectedBranch.value.label}`),
@ -1394,41 +1448,22 @@ watch(currentHq, () => {
onSubmit(); onSubmit();
} }
" "
:close="() => (modal = false)" :close="() => ((modal = false), (profileFileImg = null))"
> >
<div class="q-mx-lg q-mt-lg"> <div class="q-mx-lg q-mt-lg">
<!-- title="บริษัทจ๊อบส์ เวิร์คเกอร์ เซอร์วิส จำกัด" <!-- title="บริษัทจ๊อบส์ เวิร์คเกอร์ เซอร์วิส จำกัด"
caption="Jobs Worker Service Co., Ltd." --> caption="Jobs Worker Service Co., Ltd." -->
<ProfileBanner <ProfileBanner
active active
hideFade :hideFade="imageUrl === '' || imageUrl === null"
:img="imageUrl || null"
:cover="imageUrl || null"
icon="mdi-office-building-outline" icon="mdi-office-building-outline"
color="hsla(var(--pink-6-hsl)/1)" color="hsla(var(--pink-6-hsl)/1)"
bgColor="hsla(var(--pink-6-hsl)/0.15)" bgColor="hsla(var(--pink-6-hsl)/0.15)"
@view="console.log('view')" @view="openImageDialog"
@edit="console.log('edit')" @edit="inputFileImg.click()"
:menu="[ :menu="formMenuIcon"
{
icon: 'mdi-phone',
color: 'hsl(var(--info-bg))',
bgColor: 'var(--surface-1)',
},
{
icon: 'mdi-qrcode',
color: 'hsl(var(--info-bg))',
bgColor: 'var(--surface-1)',
},
{
icon: 'mdi-image-filter-hdr',
color: 'hsl(var(--info-bg))',
bgColor: 'var(--surface-1)',
},
{
icon: 'mdi-map-legend',
color: 'hsl(var(--info-bg))',
bgColor: 'var(--surface-1)',
},
]"
/> />
</div> </div>
<div <div
@ -1441,27 +1476,27 @@ watch(currentHq, () => {
:menu="[ :menu="[
{ {
name: $t('formDialogTitleInformation'), name: $t('formDialogTitleInformation'),
anchor: 'information', anchor: 'form-information',
}, },
{ {
name: $t('formDialogTitleContact'), name: $t('formDialogTitleContact'),
anchor: 'contact', anchor: 'form-contact',
}, },
{ {
name: $t('formDialogTitleAddress'), name: $t('formDialogTitleAddress'),
anchor: 'address', anchor: 'form-address',
}, },
{ {
name: $t('formDialogTitleLocation'), name: $t('formDialogTitleLocation'),
anchor: 'location', anchor: 'form-location',
}, },
{ {
name: 'QR Code', name: 'QR Code',
anchor: 'qr', anchor: 'form-qr',
}, },
{ {
name: $t('bankBook'), name: $t('bankBook'),
anchor: 'bankBook', anchor: 'form-bankBook',
}, },
]" ]"
background="transparent" background="transparent"
@ -1476,7 +1511,7 @@ watch(currentHq, () => {
<div class="col-10 q-pa-md q-gutter-y-xl"> <div class="col-10 q-pa-md q-gutter-y-xl">
<FormBranchInformation <FormBranchInformation
id="information" id="form-information"
v-model:code="formData.codeHeadOffice" v-model:code="formData.codeHeadOffice"
v-model:code-sub-branch="currentEdit.code" v-model:code-sub-branch="currentEdit.code"
v-model:taxNo="formData.taxNo" v-model:taxNo="formData.taxNo"
@ -1490,7 +1525,7 @@ watch(currentHq, () => {
title="formDialogTitleInformation" title="formDialogTitleInformation"
/> />
<FormBranchContact <FormBranchContact
id="contact" id="form-contact"
v-model:type-branch="formTypeBranch" v-model:type-branch="formTypeBranch"
v-model:telephone-no="formData.telephoneNo" v-model:telephone-no="formData.telephoneNo"
v-model:contact="formData.contact" v-model:contact="formData.contact"
@ -1503,7 +1538,7 @@ watch(currentHq, () => {
:outlined="true" :outlined="true"
/> />
<FormAddress <FormAddress
id="address" id="form-address"
dense dense
outlined outlined
separator separator
@ -1517,7 +1552,7 @@ watch(currentHq, () => {
v-model:zip-code="formData.zipCode" v-model:zip-code="formData.zipCode"
/> />
<FormLocation <FormLocation
id="location" id="form-location"
:readonly="formType === 'view'" :readonly="formType === 'view'"
:separator="true" :separator="true"
v-model:latitude="formData.latitude" v-model:latitude="formData.latitude"
@ -1525,7 +1560,7 @@ watch(currentHq, () => {
title="formDialogTitleLocation" title="formDialogTitleLocation"
/> />
<FormQr <FormQr
id="qr" id="form-qr"
title="QR Code" title="QR Code"
:separator="true" :separator="true"
:qr="qrCodeimageUrl" :qr="qrCodeimageUrl"
@ -1564,21 +1599,71 @@ watch(currentHq, () => {
:close="() => ((modalDrawer = false), flowStore.rotate())" :close="() => ((modalDrawer = false), flowStore.rotate())"
:statusBranch="formData.status" :statusBranch="formData.status"
> >
<template #info> <InfoForm>
<InfoForm <div class="q-mx-lg q-mt-lg">
v-model:address="formData.address" <ProfileBanner
v-model:addressEN="formData.addressEN" active
v-model:province-id="formData.provinceId" hideFade
v-model:district-id="formData.districtId" :img="imageUrl || null"
v-model:sub-district-id="formData.subDistrictId" :cover="imageUrl || null"
v-model:zip-code="formData.zipCode" :title="formData.name"
:title-form-address="$t('formDialogTitleAddress')" :caption="formData.nameEN"
:address-title="$t('formDialogAddress')" icon="mdi-office-building-outline"
:address-title-e-n="$t('formDialogAddressEN')" color="hsla(var(--pink-6-hsl)/1)"
:readonly="formType === 'view'" bgColor="hsla(var(--pink-6-hsl)/0.15)"
@view="openImageDialog"
@edit="inputFileImg.click()"
:readonly="formType === 'view'"
:menu="formMenuIcon"
/>
</div>
<div
class="col surface-1 q-ma-lg rounded bordered scroll row"
id="branch-info"
> >
<template #information> <div class="col">
<div style="position: sticky; top: 0" class="q-pa-sm">
<SideMenu
:menu="[
{
name: $t('formDialogTitleInformation'),
anchor: 'info-information',
},
{
name: $t('formDialogTitleContact'),
anchor: 'info-contact',
},
{
name: $t('formDialogTitleAddress'),
anchor: 'info-address',
},
{
name: $t('formDialogTitleLocation'),
anchor: 'info-location',
},
{
name: 'QR Code',
anchor: 'info-qr',
},
{
name: $t('bankBook'),
anchor: 'info-bankBook',
},
]"
background="transparent"
:active="{
background: 'hsla(var(--blue-6-hsl) / .2)',
foreground: 'var(--blue-6)',
}"
scroll-element="#branch-info"
/>
</div>
</div>
<div class="col-10 q-pa-md q-gutter-y-xl">
<FormBranchInformation <FormBranchInformation
id="info-information"
v-model:code="formData.codeHeadOffice" v-model:code="formData.codeHeadOffice"
v-model:code-sub-branch="currentEdit.code" v-model:code-sub-branch="currentEdit.code"
v-model:taxNo="formData.taxNo" v-model:taxNo="formData.taxNo"
@ -1592,10 +1677,8 @@ watch(currentHq, () => {
:view="formType === 'view'" :view="formType === 'view'"
title="formDialogTitleInformation" title="formDialogTitleInformation"
/> />
</template>
<template #person>
<FormBranchContact <FormBranchContact
id="info-contact"
title="formDialogTitleContact" title="formDialogTitleContact"
v-model:telephone-no="formData.telephoneNo" v-model:telephone-no="formData.telephoneNo"
v-model:contact="formData.contact" v-model:contact="formData.contact"
@ -1608,10 +1691,31 @@ watch(currentHq, () => {
:dense="true" :dense="true"
:outlined="true" :outlined="true"
/> />
</template> <FormAddress
id="info-address"
<template #qr-code> dense
outlined
separator
prefix-id="default"
:title="$t('formDialogTitleAddress')"
:readonly="formType === 'view'"
v-model:address="formData.address"
v-model:addressEN="formData.addressEN"
v-model:province-id="formData.provinceId"
v-model:district-id="formData.districtId"
v-model:sub-district-id="formData.subDistrictId"
v-model:zip-code="formData.zipCode"
/>
<FormLocation
id="info-location"
title="formDialogTitleLocation"
v-model:latitude="formData.latitude"
v-model:longitude="formData.longitude"
:readonly="formType === 'view'"
:separator="true"
/>
<FormQr <FormQr
id="info-qr"
:readonly="formType === 'view'" :readonly="formType === 'view'"
title="QR Code" title="QR Code"
:separator="true" :separator="true"
@ -1622,20 +1726,7 @@ watch(currentHq, () => {
} }
" "
/> />
</template> <!-- <FormImage
<template #location>
<FormLocation
title="formDialogTitleLocation"
v-model:latitude="formData.latitude"
v-model:longitude="formData.longitude"
:readonly="formType === 'view'"
:separator="true"
/>
</template>
<template #by-type>
<FormImage
@upload=" @upload="
() => { () => {
inputFileImg.click(); inputFileImg.click();
@ -1644,10 +1735,10 @@ watch(currentHq, () => {
v-model:image="imageUrl" v-model:image="imageUrl"
:title="$t('formDialogTitleImg')" :title="$t('formDialogTitleImg')"
:readonly="formType === 'view'" :readonly="formType === 'view'"
/> /> -->
</template> </div>
</InfoForm> </div>
</template> </InfoForm>
</DrawerInfo> </DrawerInfo>
<q-dialog v-model="holdDialog" position="bottom"> <q-dialog v-model="holdDialog" position="bottom">
@ -1779,6 +1870,30 @@ watch(currentHq, () => {
</q-list> </q-list>
</div> </div>
</q-dialog> </q-dialog>
<ImageUploadDialog
v-model:dialogState="imageDialog"
v-model:file="profileFileImg"
v-model:image-url="imageUrl"
:hiddenFooter="!isImageEdit"
clearButton
@save="handleImageUpload"
>
<template #error>
<div class="full-height full-width" style="background: white">
<div
class="full-height full-width flex justify-center items-center"
style="background: hsla(var(--pink-6-hsl) / 0.15)"
>
<q-icon
size="15rem"
name="mdi-office-building-outline"
style="color: hsla(var(--pink-6-hsl) / 1)"
></q-icon>
</div>
</div>
</template>
</ImageUploadDialog>
</template> </template>
<style scoped> <style scoped>