This commit is contained in:
Viet An
2026-07-02 13:56:28 +07:00
parent 976816d408
commit 6d9dce38cb
5 changed files with 90 additions and 18 deletions

View File

@@ -47,17 +47,16 @@
> >
<div class="navbar-start is-gap-1 is-align-items-center"> <div class="navbar-start is-gap-1 is-align-items-center">
<template <template
v-for="(v, i) in leftmenu" v-for="(v, i) in leftmenuVisible"
:key="i" :key="i"
:id="v.code" :id="v.code"
> >
<a <a
v-if="!v.submenu" v-if="!v.submenu"
:class="[ :class="[
'navbar-item rounded-lg is-clipped font-medium', 'navbar-item rounded-lg is-clipped fs-13 font-medium',
currentTab.code === v.code ? 'has-text-primary-50 has-background-primary-95' : 'has-text-grey-35', currentTab.code === v.code ? 'has-text-primary-50 has-background-primary-95' : 'has-text-grey-35',
]" ]"
style="font-size: 13.5px"
@click="changeTab(v)" @click="changeTab(v)"
> >
{{ v[lang] }} {{ v[lang] }}
@@ -68,11 +67,10 @@
> >
<a <a
:class="[ :class="[
'navbar-link rounded-lg is-arrowless font-medium', 'navbar-link rounded-lg is-arrowless fs-13 font-medium',
currentTab.code === v.code ? 'has-text-primary-50 has-background-primary-95' : 'has-text-grey-35', currentTab.code === v.code ? 'has-text-primary-50 has-background-primary-95' : 'has-text-grey-35',
]" ]"
@click="changeTab(v)" @click="changeTab(v)"
style="font-size: 13.5px"
> >
<p class="is-flex is-align-items-center"> <p class="is-flex is-align-items-center">
<span>{{ v[lang] }}</span> <span>{{ v[lang] }}</span>
@@ -96,25 +94,81 @@
</template> </template>
</div> </div>
<div class="navbar-end is-gap-1 is-align-items-center"> <div class="navbar-end is-gap-1 is-align-items-center">
<!-- v-if="tabConfig" --> <div
v-if="leftmenuHidden"
class="navbar-item has-dropdown is-hoverable"
>
<a class="navbar-link rounded-lg is-arrowless font-medium has-text-grey-35 p-2">
<Icon
name="material-symbols:menu-rounded"
:size="20"
/>
</a>
<div
class="navbar-dropdown is-right"
style="border-top: none"
>
<template v-for="item in leftmenuHidden">
<a <a
class="navbar-item rounded-lg p-1.5" v-if="!item.submenu"
@click="changeTab(tabConfig)" @click="changeTab(item)"
:class="[
'navbar-item font-medium',
currentTab.code === item.code ? 'has-text-primary-50 has-background-primary-95' : 'has-text-grey-35',
]"
>
{{ item[lang] }}
</a>
<div v-else>
<a
:class="[
'navbar-item fs-13 font-medium',
currentTab.code === item.code
? 'has-text-primary-50 has-background-primary-95'
: 'has-text-grey-35',
]"
@click="changeTab(item)"
>
<p class="is-flex is-align-items-center">
<span>{{ item[lang] }}</span>
<Icon
name="material-symbols:keyboard-arrow-down-rounded"
:size="20"
/>
</p>
</a>
<a
v-for="(submenu, i) in item.submenu"
:key="i"
class="navbar-item"
@click="changeTab(item, submenu)"
>
{{ submenu[lang] }}
</a>
<hr class="my-0" />
</div>
</template>
</div>
</div>
<a
class="navbar-item rounded-lg p-1.5 is-flex"
@click="tabConfig && changeTab(tabConfig)"
> >
<Icon <Icon
name="material-symbols:settings-outline-rounded" name="material-symbols:settings-outline-rounded"
:size="20" :size="20"
class="has-text-grey-60" class="has-text-grey-45"
/> />
</a> </a>
<!-- @click="openProfile()" v-if="avatar" -->
<a <a
@click="openProfile()"
v-if="true /* avatar */"
class="navbar-item rounded-full p-0 max-w-full is-flex is-gap-2 is-justify-content-space-between is-align-items-center" class="navbar-item rounded-full p-0 max-w-full is-flex is-gap-2 is-justify-content-space-between is-align-items-center"
> >
<Avatarbox <Avatarbox
text="Q" text="Q"
type="findata" type="findata"
size="two" :size="9"
/> />
</a> </a>
</div> </div>
@@ -147,6 +201,20 @@ topmenus.forEach((topmenu) => {
}); });
const leftmenu = $filter(topmenus, { category: "topmenu", classify: "left" }); const leftmenu = $filter(topmenus, { category: "topmenu", classify: "left" });
const splitMenu = computed(() => {
let cutoffIdx = 0;
if ($store.viewport < 1 || $store.viewport > 3) return [leftmenu];
if ($store.viewport === 3) cutoffIdx = 8;
if ($store.viewport === 2) cutoffIdx = 5;
if ($store.viewport === 1) cutoffIdx = 3;
return [leftmenu.slice(0, cutoffIdx), leftmenu.slice(cutoffIdx)];
});
const leftmenuVisible = computed(() => splitMenu.value[0]);
const leftmenuHidden = computed(() => splitMenu.value[1]);
const currentTab = ref(leftmenu[0]); const currentTab = ref(leftmenu[0]);
const subTab = ref(); const subTab = ref();
const tabConfig = $find(topmenus, { code: "configuration" }); const tabConfig = $find(topmenus, { code: "configuration" });
@@ -187,8 +255,8 @@ function changeTab(tab, subtab) {
function openProfile() { function openProfile() {
$store.commit("showmodal", { $store.commit("showmodal", {
component: "user/Profile", component: "user/Profile",
width: "1100px", width: "1000px",
height: "360px", height: "auto",
title: $store.lang === "vi" ? "Thông tin cá nhân" : "User profile", title: $store.lang === "vi" ? "Thông tin cá nhân" : "User profile",
}); });
} }
@@ -241,7 +309,8 @@ a[class^="navbar"] {
} }
} }
@media screen and (max-width: 1023px) { /* follow $navbar-breakpoint */
@media screen and (max-width: 500px) {
.navbar-brand { .navbar-brand {
margin-right: 0 !important; margin-right: 0 !important;
} }

View File

@@ -35,7 +35,9 @@ function getViewport() {
const width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; const width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
// Follow Bulma's breakpoints: https://bulma.io/documentation/start/responsiveness/#breakpoints // Follow Bulma's breakpoints: https://bulma.io/documentation/start/responsiveness/#breakpoints
if (width <= 768) if (width <= 500)
viewport = 0; // custom
else if (width <= 768)
viewport = 1; // mobile viewport = 1; // mobile
else if (width <= 1023) else if (width <= 1023)
viewport = 2; // tablet viewport = 2; // tablet

View File

@@ -10,6 +10,7 @@ export const useStore = defineStore("erp-dev", {
snackbar: null, snackbar: null,
settings: [], settings: [],
lang: "vi", lang: "vi",
tabinfo: {},
// set by api-loader // set by api-loader
common: null, common: null,
tablesetting: null, tablesetting: null,

View File

@@ -11635,7 +11635,7 @@ a.navbar-item.is-active, a.navbar-item.is-selected,
margin: 0.5rem 0; margin: 0.5rem 0;
} }
@media screen and (max-width: 1199px) { @media screen and (max-width: 499px) {
.navbar > .container { .navbar > .container {
display: block; display: block;
} }
@@ -11684,7 +11684,7 @@ a.navbar-item.is-active, a.navbar-item.is-selected,
padding-bottom: var(--bulma-navbar-height); padding-bottom: var(--bulma-navbar-height);
} }
} }
@media screen and (min-width: 1200px) { @media screen and (min-width: 500px) {
.navbar, .navbar,
.navbar-menu, .navbar-menu,
.navbar-start, .navbar-start,

View File

@@ -13,7 +13,7 @@ $grey: #69748c;
@use "bulma/sass" with ( @use "bulma/sass" with (
$family-primary: string.unquote("'Inter', 'SF Pro', 'Helvetica', 'Arial', sans-serif"), $family-primary: string.unquote("'Inter', 'SF Pro', 'Helvetica', 'Arial', sans-serif"),
$family-monospace: string.unquote("'Roboto Mono', monospace"), $family-monospace: string.unquote("'Roboto Mono', monospace"),
$navbar-breakpoint: 1200px, $navbar-breakpoint: 500px,
$primary: $blue, $primary: $blue,
$link: $blue, $link: $blue,
$info: $cyan, $info: $cyan,