refactor: branch form

This commit is contained in:
puriphatt 2024-08-01 08:44:40 +00:00 committed by Net
parent a1f691a613
commit fb076fc074
15 changed files with 651 additions and 274 deletions

View file

@ -17,17 +17,26 @@ defineProps<{
</script>
<template>
<div class="row col-12">
<div class="col-md-3 col-12 app-text-muted q-pb-sm">
{{ $t(`${title}`) }}
<div class="col-12 q-pb-sm text-weight-bold text-body1">
<q-icon
flat
size="xs"
class="q-pa-sm rounded q-mr-xs"
color="info"
name="mdi-phone"
style="background-color: var(--surface-3)"
/>
{{ $t(`${title}`) }}
</div>
<div class="col-md-9 col-12 row q-col-gutter-md">
<div class="col-12 row q-col-gutter-sm">
<q-input
lazy-rules="ondemand"
:dense="dense"
outlined
:readonly="readonly"
hide-bottom-space
class="col-md-5 col-12"
class="col-md-3 col-12"
:label="
typeBranch === 'headOffice'
? $t('formDialogInputEmailHq')
@ -35,7 +44,11 @@ defineProps<{
"
v-model="email"
for="input-email"
/>
>
<template #prepend>
<q-icon color="primary" name="mdi-email" size="xs" class="q-mr-xs" />
</template>
</q-input>
<q-input
lazy-rules="ondemand"
@ -43,7 +56,7 @@ defineProps<{
outlined
:readonly="readonly"
hide-bottom-space
class="col-md-7 col-12"
class="col-md-3 col-12"
:label="
typeBranch === 'headOffice'
? $t('formDialogInputTelephoneHq')
@ -51,7 +64,11 @@ defineProps<{
"
v-model="telephoneNo"
for="input-telephone-no"
/>
>
<template #prepend>
<q-icon color="primary" name="mdi-phone" size="xs" class="q-mr-xs" />
</template>
</q-input>
<q-input
lazy-rules="ondemand"
@ -59,7 +76,7 @@ defineProps<{
outlined
:readonly="readonly"
hide-bottom-space
class="col-md-5 col-12"
class="col-md-3 col-12"
:label="$t('formDialogInputContactName')"
v-model="contactName"
for="input-contact-name"
@ -71,11 +88,15 @@ defineProps<{
outlined
:readonly="readonly"
hide-bottom-space
class="col-7"
class="col-3"
:label="$t('formDialogInputTelephoneContact')"
v-model="contact"
for="input-contact"
/>
>
<template #prepend>
<q-icon color="primary" name="mdi-phone" size="xs" class="q-mr-xs" />
</template>
</q-input>
<q-input
lazy-rules="ondemand"
@ -83,16 +104,11 @@ defineProps<{
outlined
:readonly="readonly"
hide-bottom-space
class="col-5"
class="col-3"
label="Line ID"
v-model="lineId"
for="input-line-id"
/>
</div>
<q-separator
v-if="separator"
class="col-12 q-mt-xl q-mb-md"
style="padding-block: 0.5px"
/>
</div>
</template>

View file

@ -11,25 +11,34 @@ defineProps<{
dense?: boolean;
outlined?: boolean;
readonly?: boolean;
separator?: boolean;
view?: boolean;
}>();
</script>
<template>
<div class="row col-12">
<div class="col-md-3 col-12 app-text-muted q-pb-sm">
{{ $t(`${title}`) }}
<div class="col-12 q-pb-sm text-weight-bold text-body1">
<q-icon
flat
size="xs"
class="q-pa-sm rounded q-mr-xs"
color="info"
name="mdi-office-building-outline"
style="background-color: var(--surface-3)"
/>
{{ $t(`${title}`) }}
</div>
<div class="col-md-9 col-12 row q-col-gutter-md">
<div class="col-12 row q-col-gutter-sm">
<q-input
lazy-rules="ondemand"
:dense="dense"
outlined
readonly
:disable="!readonly"
hide-bottom-space
:class="{
'col-12': $q.screen.xs,
'col-6': typeBranch == 'headOffice',
'col-3': typeBranch == 'headOffice',
'col-4': typeBranch != 'headOffice',
}"
:label="$t('formDialogInputCode')"
@ -46,7 +55,7 @@ defineProps<{
hide-bottom-space
:class="{
'col-12': $q.screen.xs,
'col-6': typeBranch == 'headOffice',
'col-3': typeBranch == 'headOffice',
'col-4': typeBranch != 'headOffice',
}"
:label="$t('branchLabelCode')"
@ -62,7 +71,7 @@ defineProps<{
hide-bottom-space
:class="{
'col-12': $q.screen.xs,
'col-6': typeBranch === 'headOffice',
'col-3': typeBranch === 'headOffice',
'col-4': typeBranch !== 'headOffice',
}"
:label="$t('formDialogInputTaxNo')"
@ -81,7 +90,7 @@ defineProps<{
outlined
:readonly="readonly"
hide-bottom-space
class="col-12"
class="col-3"
:label="
typeBranch === 'headOffice'
? $t('formDialogInputNameHq')
@ -103,7 +112,7 @@ defineProps<{
outlined
:readonly="readonly"
hide-bottom-space
class="col-12"
class="col-3"
v-model="nameEN"
:label="
typeBranch === 'headOffice'
@ -119,10 +128,5 @@ defineProps<{
for="input-name-en"
/>
</div>
<q-separator
v-if="separator"
class="col-12 q-mt-xl q-mb-md"
style="padding-block: 0.5px"
/>
</div>
</template>

View file

@ -18,52 +18,57 @@ defineProps<{
}>();
</script>
<template>
<div class="col-md-3 col-12 app-text-muted"> {{ $t(`${title}`) }}</div>
<div
class="col-md-9 col-12 bordered rounded row no-padding"
:class="{ 'q-mt-lg': !$q.screen.xs, 'q-mt-sm': $q.screen.xs }"
>
<div class="col-12 q-pl-md q-py-sm app-text-muted">location</div>
<div v-if="!!longitude && !!latitude" class="col-12 flex flex-center">
<iframe
:src="`https://maps.google.com/maps?q=${latitude}, ${longitude}&z=15&output=embed`"
width="100%"
frameborder="0"
style="border: 0"
></iframe>
<div class="col-12">
<div class="col-12 q-pb-sm text-weight-bold text-body1">
<q-icon
flat
size="xs"
class="q-pa-sm rounded q-mr-xs"
color="info"
name="mdi-map-legend"
style="background-color: var(--surface-3)"
/>
{{ $t(`${title}`) }}
</div>
<div
v-else
class="col-12 flex flex-center"
style="
height: 100px;
background-image: url(/map.png);
background-position: center center;
background-size: 1500px 850px;
"
>
<q-btn
:text-color="$q.dark.isActive ? 'black' : 'white'"
<div class="col-12 bordered rounded column">
<div class="q-pl-md q-py-sm app-text-muted bordered-b">location</div>
<div v-if="!!longitude && !!latitude" class="col flex flex-center">
<iframe
:src="`https://maps.google.com/maps?q=${latitude}, ${longitude}&z=15&output=embed`"
width="100%"
frameborder="0"
style="border: 0"
></iframe>
</div>
<div
v-else
class="col-12 flex flex-center"
style="
background: var(--blue-5);
color: var(--blue-0);
font-size: 12px;
width: 150px;
height: 150px;
background-image: url(/map.png);
background-position: center center;
background-size: cover;
background-repeat: no-repeat;
"
unelevated
rounded
:label="$t('formDialogBtnLocation')"
@click="getLocation()"
id="btn-get-location"
/>
>
<q-btn
:text-color="$q.dark.isActive ? 'black' : 'white'"
style="
background: var(--blue-5);
color: var(--blue-0);
font-size: 12px;
width: 150px;
"
unelevated
rounded
:label="$t('formDialogBtnLocation')"
@click="getLocation()"
id="btn-get-location"
/>
</div>
</div>
</div>
<q-separator
v-if="separator"
class="col-12 q-mt-xl q-mb-md"
style="padding-block: 0.5px"
/>
</template>

View file

@ -16,57 +16,71 @@ defineEmits<{
}>();
</script>
<template>
<div class="col-md-3 col-12 app-text-muted"> {{ title }}</div>
<div
:class="{
'dark-form-show-qr-code': $q.dark.isActive,
'q-mt-lg': !$q.screen.xs,
'q-mt-sm': $q.screen.xs,
}"
class="col-md-9 col-12 row branch-form-show-qr-code"
>
<div class="col-12 flex flex-center">
<q-img v-if="qr" :src="qr as string" style="width: 150px; height: 150px">
<template #error>
<div
style="background: none"
class="full-width full-height items-center justify-center flex"
>
<q-img src="/no-data.png" width="5rem" />
</div>
</template>
</q-img>
<q-btn
@click="$emit('upload')"
class="branch-form-btn-qr-code"
:class="{ 'dark-form-btn-qr-code': $q.dark.isActive }"
v-else
unelevated
:color="$q.dark.isActive ? 'black' : 'grey-2'"
:text-color="$q.dark.isActive ? 'white' : 'grey-5'"
>
<Icon icon="teenyicons:add-outline" width="30px" height="50px" />
</q-btn>
</div>
<div class="col-12 flex flex-center q-py-md">
<q-btn
v-if="!readonly"
:text-color="$q.dark.isActive ? 'black' : 'white'"
style="background: var(--blue-5); color: var(--blue-0); font-size: 12px"
unelevated
rounded
:label="$t('formDialogUploadQrCode')"
@click="$emit('upload')"
id="btn-upload-qr-code"
<div class="row col-12">
<div class="col-12 q-pb-sm text-weight-bold text-body1">
<q-icon
flat
size="xs"
class="q-pa-sm rounded q-mr-xs"
color="info"
name="mdi-qrcode"
style="background-color: var(--surface-3)"
/>
{{ title }}
</div>
<div
:class="{
'dark-form-show-qr-code': $q.dark.isActive,
}"
class="col-12 row branch-form-show-qr-code"
>
<div class="col-12 flex flex-center q-py-md">
<q-img
v-if="qr"
:src="qr as string"
style="width: 150px; height: 150px"
>
<template #error>
<div
style="background: none"
class="full-width full-height items-center justify-center flex"
>
<q-img src="/no-data.png" width="5rem" />
</div>
</template>
</q-img>
<q-btn
@click="$emit('upload')"
class="branch-form-btn-qr-code"
:class="{ 'dark-form-btn-qr-code': $q.dark.isActive }"
v-else
unelevated
:color="$q.dark.isActive ? 'black' : 'grey-2'"
:text-color="$q.dark.isActive ? 'white' : 'grey-5'"
>
<Icon icon="teenyicons:add-outline" width="30px" height="50px" />
</q-btn>
</div>
<div class="col-12 flex flex-center q-pb-md">
<q-btn
v-if="!readonly"
:text-color="$q.dark.isActive ? 'black' : 'white'"
style="
background: var(--blue-5);
color: var(--blue-0);
font-size: 12px;
"
unelevated
rounded
:label="$t('formDialogUploadQrCode')"
@click="$emit('upload')"
id="btn-upload-qr-code"
/>
</div>
</div>
</div>
<q-separator
v-if="separator"
class="col-12 q-mt-xl q-mb-md"
style="padding-block: 0.5px"
/>
</template>
<style scoped>

View file

@ -18,7 +18,7 @@ defineProps<{
separator?: boolean;
employee?: boolean;
disabledRule?: boolean;
id?: number;
indexId?: number;
prefixId: string;
}>();
@ -147,10 +147,17 @@ watch(districtId, fetchSubDistrict);
</script>
<template>
<div class="col-12">
<div class="col-12 app-text-muted row items-center q-mb-md">
<span class="q-mr-lg">
{{ title || $t('formDialogTitlePersonnelAddress') }}
</span>
<div class="col-12 q-pb-sm text-weight-bold text-body1">
<q-icon
size="xs"
class="q-pa-sm rounded q-mr-xs"
color="info"
name="mdi-map-marker-radius"
style="background-color: var(--surface-3)"
/>
{{ title || $t('formDialogTitlePersonnelAddress') }}
<div
v-if="employee"
class="surface-3 q-px-sm q-py-xs row"
@ -184,13 +191,11 @@ watch(districtId, fetchSubDistrict);
</div>
<div class="col-12 row q-col-gutter-y-md">
<div
class="col-md-3 col-12 app-text-muted"
:class="{ 'q-pl-xl': !$q.screen.xs }"
>
<div class="col-12 app-text-muted-2">
<q-icon size="xs" class="q-mr-xs" name="mdi-map-marker" />
{{ addressTitle || $t('formDialogTitleAddressPure') }}
</div>
<div class="col-md-9 col-12 row q-col-gutter-md">
<div class="col-12 row q-col-gutter-sm">
<q-input
outlined
hide-bottom-space
@ -200,7 +205,7 @@ watch(districtId, fetchSubDistrict);
:dense="dense"
:label="$t('address')"
:readonly="readonly || sameWithEmployer"
:for="`${prefixId}-${id !== undefined ? `input-address-${id}` : 'input-address'}`"
:for="`${prefixId}-${indexId !== undefined ? `input-address-${indexId}` : 'input-address'}`"
:rules="
disabledRule
? []
@ -231,7 +236,7 @@ watch(districtId, fetchSubDistrict);
:options="provinceOptions"
:readonly="readonly || sameWithEmployer"
:hide-dropdown-icon="readonly || sameWithEmployer"
:for="`${prefixId}-${id !== undefined ? `select-province-${id}` : 'select-province'}`"
:for="`${prefixId}-${indexId !== undefined ? `select-province-${indexId}` : 'select-province'}`"
:rules="
disabledRule
? []
@ -273,7 +278,7 @@ watch(districtId, fetchSubDistrict);
:options="districtOptions"
:readonly="readonly || sameWithEmployer"
:hide-dropdown-icon="readonly || sameWithEmployer"
:for="`${prefixId}-${id !== undefined ? `select-district-${id}` : 'select-district'}`"
:for="`${prefixId}-${indexId !== undefined ? `select-district-${indexId}` : 'select-district'}`"
:rules="
disabledRule
? []
@ -314,7 +319,7 @@ watch(districtId, fetchSubDistrict);
:options="subDistrictOptions"
:readonly="readonly || sameWithEmployer"
:hide-dropdown-icon="readonly || sameWithEmployer"
:for="`${prefixId}-${id !== undefined ? `select-sub-district-${id}` : 'select-sub-district'}`"
:for="`${prefixId}-${indexId !== undefined ? `select-sub-district-${indexId}` : 'select-sub-district'}`"
:rules="
disabledRule
? []
@ -337,25 +342,25 @@ watch(districtId, fetchSubDistrict);
</q-select>
<q-input
lazy-rules="ondemand"
:for="`${prefixId}-${id !== undefined ? `input-zip-code-${id}` : 'input-zip-code'}`"
:for="`${prefixId}-${indexId !== undefined ? `input-zip-code-${indexId}` : 'input-zip-code'}`"
:dense="dense"
outlined
:disable="!readonly"
readonly
:label="$t('zipCode')"
class="col-md-3 col-6"
class="col-md-2 col-6"
v-model="zipCode"
/>
</div>
<div
class="col-md-3 col-12 app-text-muted"
:class="{ 'q-pl-xl': !$q.screen.xs }"
>
{{ addressTitleEN || $t('formDialogTitleAddressPureEN') }}
<div class="col-12 app-text-muted-2">
<q-icon size="xs" class="q-mr-xs" name="mdi-map-marker" />
{{ addressTitle || $t('formDialogTitleAddressPureEN') }}
</div>
<div class="col-md-9 col-12 row q-col-gutter-md">
<div class="col-12 row q-col-gutter-sm">
<q-input
lazy-rules="ondemand"
:for="`${prefixId}-${id !== undefined ? `input-address-en-${id}` : 'input-address-en'}`"
:for="`${prefixId}-${indexId !== undefined ? `input-address-en-${indexId}` : 'input-address-en'}`"
:dense="dense"
:readonly="readonly || sameWithEmployer"
outlined
@ -393,7 +398,7 @@ watch(districtId, fetchSubDistrict);
:options="provinceOptions"
:readonly="readonly || sameWithEmployer"
:hide-dropdown-icon="readonly || sameWithEmployer"
:for="`${prefixId}-${id !== undefined ? `select-province-en-${id}` : 'select-province-en'}`"
:for="`${prefixId}-${indexId !== undefined ? `select-province-en-${indexId}` : 'select-province-en'}`"
:rules="
disabledRule
? []
@ -434,7 +439,7 @@ watch(districtId, fetchSubDistrict);
:options="districtOptions"
:readonly="readonly || sameWithEmployer"
:hide-dropdown-icon="readonly || sameWithEmployer"
:for="`${prefixId}-${id !== undefined ? `select-district-en-${id}` : 'select-district-en'}`"
:for="`${prefixId}-${indexId !== undefined ? `select-district-en-${indexId}` : 'select-district-en'}`"
:rules="
disabledRule
? []
@ -475,7 +480,7 @@ watch(districtId, fetchSubDistrict);
:options="subDistrictOptions"
:readonly="readonly || sameWithEmployer"
:hide-dropdown-icon="readonly || sameWithEmployer"
:for="`${prefixId}-${id !== undefined ? `select-sub-district-en-${id}` : 'select-sub-district-en'}`"
:for="`${prefixId}-${indexId !== undefined ? `select-sub-district-en-${indexId}` : 'select-sub-district-en'}`"
:rules="
disabledRule
? []
@ -499,23 +504,19 @@ watch(districtId, fetchSubDistrict);
<q-input
lazy-rules="ondemand"
hide-bottom-space
:for="`${prefixId}-${id !== undefined ? `input-zip-code-${id}` : 'input-zip-code'}`"
:for="`${prefixId}-${indexId !== undefined ? `input-zip-code-${indexId}` : 'input-zip-code'}`"
:dense="dense"
outlined
readonly
:disable="!readonly"
zip="zip-en"
:label="$t('zipCode')"
class="col-md-3 col-6"
class="col-md-2 col-6"
v-model="zipCode"
/>
</div>
</div>
</div>
<q-separator
v-if="separator"
class="col-12 q-mb-md"
style="padding-block: 0.5px; margin-top: 32px"
/>
</template>
<style lang="scss" scoped>

View file

@ -69,33 +69,7 @@ const employeeTab = defineModel<string>('employeeTab');
class="row q-col-gutter-y-md surface-1 rounded bordered"
:class="{ 'q-pa-md': !noPaddingTab }"
>
<slot name="information"></slot>
<slot name="person"></slot>
<slot name="address" v-if="!noAddress">
<FormAddress
dense
outlined
separator
prefix-id="default"
:employee="employee"
:readonly="readonly"
:disabledRule="disabledRule"
v-model:address="address"
v-model:addressEN="addressEN"
v-model:provinceId="provinceId"
v-model:districtId="districtId"
v-model:subDistrictId="subDistrictId"
v-model:zipCode="zipCode"
v-model:same-with-employer="sameWithEmployer"
:title="titleFormAddress"
:addressTitle="addressTitle || ''"
:addressTitleEN="addressTitleEN || ''"
v-if="!$slots.address"
/>
</slot>
<slot name="qr-code"></slot>
<slot name="location"></slot>
<slot name="by-type"></slot>
<slot></slot>
</div>
</div>
</div>

View file

@ -0,0 +1,286 @@
<script setup lang="ts">
defineProps<{
title: string;
titleFormAddress?: string;
addressTitle?: string;
addressTitleEN?: string;
addressSeparator?: boolean;
branchStatus?: string;
badgeLabel?: string;
customerLabel?: string;
badgeClass?: string;
noFooter?: boolean;
noAppBox?: boolean;
noPaddingTab?: boolean;
maxWidth?: string;
width?: string;
height?: string;
employee?: boolean;
noAddress?: boolean;
disabledRule?: boolean;
edit?: boolean;
isEdit?: boolean;
tabsList?: { name: string; label: string }[];
editData?: (...args: unknown[]) => void;
deleteData?: (...args: unknown[]) => void;
submit?: (...args: unknown[]) => void;
close?: (...args: unknown[]) => void;
undo?: (...args: unknown[]) => void;
}>();
const modal = defineModel('modal', { default: false });
const currentTab = defineModel<string>('currentTab');
</script>
<template>
<q-dialog v-model="modal" @hide="close">
<div
class="surface-1"
style="padding: 0; border-radius: var(--radius-2); height: 100%"
:style="`max-width:${$q.screen.xs ? '100%' : maxWidth ? maxWidth : '85%'}; width: ${$q.screen.xs ? '100%' : width ? width : '85%'}; height: ${height ? height : '85vh'} `"
>
<q-form
greedy
@submit.prevent
@validation-success="submit"
class="column full-height"
>
<!-- header -->
<div class="form-header q-py-sm q-px-lg">
<div class="row items-center">
<div v-if="isEdit && edit" class="row">
<q-btn
round
flat
id="closeDialog"
icon="mdi-arrow-left"
padding="xs"
class="q-mr-md"
:class="{ dark: $q.dark.isActive }"
style="color: var(--brand-1)"
@click="undo"
/>
<div style="width: 31.98px"></div>
</div>
<div v-if="!isEdit && edit">
<q-btn
round
flat
id="editDialog"
icon="mdi-pencil-outline"
padding="xs"
class="q-mr-md"
:class="{ dark: $q.dark.isActive }"
style="color: var(--brand-1)"
@click="editData"
/>
<q-btn
v-if="edit"
round
flat
id="deleteDialog"
icon="mdi-trash-can-outline"
padding="xs"
:class="{ dark: $q.dark.isActive }"
style="color: hsl(var(--negative-bg))"
@click="deleteData"
/>
</div>
<div style="width: 31.98px"></div>
<div class="col text-subtitle1 text-weight-bold text-center">
{{ title }}
<text v-if="customerLabel">
:
<text
class="text-customer"
:class="{ 'dark-text': $q.dark.isActive }"
:style="`color: ${customerLabel === 'CORP' ? 'var(--purple-8)' : 'var(--green-9)'} `"
>
{{
$t(
customerLabel === 'CORP'
? 'customerLegalEntity'
: 'customerNaturalPerson',
)
}}
</text>
</text>
<text v-if="branchStatus">
{{ branchStatus }}
</text>
<text
v-if="badgeLabel"
class="badge-label q-px-sm text-caption"
:class="badgeClass"
>
{{ badgeLabel }}
</text>
</div>
<q-btn
round
flat
id="closeDialog"
icon="mdi-close"
padding="xs"
class="close-btn"
:class="{ dark: $q.dark.isActive }"
@click="close"
/>
</div>
</div>
<!-- body -->
<div
class="col full-height column full-width"
:class="{
dark: $q.dark.isActive,
'surface-2': !employee,
'surface-tab': employee || tabsList,
}"
>
<div
v-if="tabsList && tabsList.length > 0"
class="row surface-2 q-px-md q-pt-md full-width"
style="border-bottom: 1px solid var(--brand-1)"
>
<q-tabs
inline-label
mobile-arrows
dense
class="app-text-muted full-width"
v-model="currentTab"
active-class="active-tab"
indicator-color="transparent"
align="left"
>
<q-tab
:id="`tab-${tab.label}`"
v-for="tab in tabsList"
v-bind:key="tab.name"
class="content-tab text-capitalize"
:name="tab.name"
:label="$t(tab.label)"
/>
</q-tabs>
</div>
<div class="row col full-width scroll">
<!-- prepend -->
<div class="col" v-if="$slots.prepend">
<slot name="prepend"></slot>
</div>
<!-- center -->
<div class="col column full-height">
<slot></slot>
</div>
<!-- append -->
<div class="col" v-if="$slots.append">
<slot name="append"></slot>
</div>
</div>
</div>
<!-- footer -->
<div
v-if="!noFooter"
class="form-footer row items-center full-width justify-between q-px-md q-py-md surface-1"
style="z-index: 3"
>
<div>
<slot name="footer"></slot>
</div>
<div class="row flex justify-end q-gutter-x-md">
<q-btn
id="cancelBtn"
unelevated
class="col btn-cancel-dialog"
color="grey-4"
text-color="grey-10"
@click="close"
:label="$t('cancel')"
v-close-popup
/>
<q-btn
dense
unelevated
id="submitBtn"
type="submit"
color="primary"
class="q-px-md"
:label="$t('save')"
/>
</div>
</div>
</q-form>
</div>
</q-dialog>
</template>
<style scoped lang="scss">
.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));
}
}
.form-header {
border-bottom: 1px solid var(--border-color);
}
.form-body {
--_body-bg: var(--sand-0);
background-color: var(--_body-bg);
&.dark {
--_body-bg: var(--gray-10);
}
}
.form-footer {
border-top: 1px solid var(--border-color);
}
.badge-label {
display: inline-block;
border-radius: var(--radius-6);
background-color: var(--surface-2);
text-wrap: nowrap;
}
.text-customer {
--_var-filter: grayscale(30%);
filter: var(--_var-filter);
&.dark-text {
--_var-filter: grayscale(0%);
}
}
.active-tab {
color: var(--brand-1);
background-color: var(--surface-tab);
border-top: 1px solid var(--brand-1);
border-left: 1px solid var(--brand-1);
border-right: 1px solid var(--brand-1);
border-top-left-radius: var(--radius-2);
border-top-right-radius: var(--radius-2);
margin-bottom: -1.5px;
border-bottom: 3px solid var(--surface-tab);
}
.content-tab {
border-top-left-radius: var(--radius-2);
border-top-right-radius: var(--radius-2);
position: relative;
}
</style>

View file

@ -1,6 +1,5 @@
<script setup lang="ts">
import { computed, ref } from 'vue';
import AppBox from './app/AppBox.vue';
import { ref } from 'vue';
withDefaults(
defineProps<{

View file

@ -211,7 +211,6 @@ const currentTab = defineModel<string>('currentTab');
<!-- center -->
<div
v-if="!noAppBox"
bordered
class="column surface-1 bordered rounded col"
:class="`${$slots.prepend ? ($q.screen.gt.sm ? 'col-10' : 'col-12') : $slots.append ? 'col-6' : 'col-12'} ${!noPaddingTab && 'q-pt-lg q-pl-lg'} ${$q.screen.gt.sm && 'full-height scroll'}`"
style="padding-right: 0; padding-bottom: 16px"

View file

@ -23,7 +23,7 @@ const props = defineProps<{
};
}>();
const scrollElement = ref<Element | HTMLElement>();
const currentScrollElement = ref<Element | HTMLElement>();
function handleClick(menu: Menu) {
const element = document.getElementById(menu.anchor);
@ -41,9 +41,9 @@ const activeMenu = ref(props.menu.at(0)?.anchor || '');
function onScroll() {
let current = '';
if (!scrollElement.value) return;
if (!currentScrollElement.value) return;
const container = scrollElement.value;
const container = currentScrollElement.value;
props.menu.forEach((v) => {
if (!v.element) v.element = document.getElementById(v.anchor) || undefined;
@ -56,22 +56,21 @@ function onScroll() {
current = v.anchor;
}
});
activeMenu.value = current;
}
onMounted(() => {
if (typeof props.scrollElement === 'string' || !props.scrollElement) {
const element = document.querySelector(props.scrollElement || 'body');
if (element) scrollElement.value = element;
if (element) currentScrollElement.value = element;
} else {
scrollElement.value = props.scrollElement;
currentScrollElement.value = props.scrollElement;
}
scrollElement.value?.addEventListener('scroll', onScroll);
currentScrollElement.value?.addEventListener('scroll', onScroll);
});
onUnmounted(() => {
scrollElement.value?.removeEventListener('scroll', onScroll);
currentScrollElement.value?.removeEventListener('scroll', onScroll);
});
</script>
@ -87,6 +86,7 @@ onUnmounted(() => {
class="side-menu__item"
:class="{ 'side-menu__active': activeMenu === v.anchor }"
v-for="v in menu"
:key="v.anchor"
@click="handleClick(v)"
>
{{ v.name }}