feat: manual (#191)
Some checks failed
Spell Check / Spell Check with Typos (push) Failing after 6s

* feat: add markdown render deps

* feat: add manual route

* feat: example toc

* feat: add highlight js dependency

* feat: add view page

* feat: add translations for property and manual in English and Thai

* feat: enhance drawer menu with internationalization support and manual section

* feat: add conditional internationalization for sub-menu labels

* feat: add video support

* refactor: add stores and type

* fix: wrong path

* feat: improve layout structure and enhance scroll functionality in ViewPage

* fix: scroll not working

* chore: change variable name

* feat: show sub tile of manual

* feat: add translation for 'Table of Contents' in English and Thai

* feat: enhance layout and add conditional rendering for Table of Contents in ViewPage

* chore: clean

* refactor: use expansion

* refactor: show icon

* refactor: spacing

---------

Co-authored-by: Methapon2001 <61303214+Methapon2001@users.noreply.github.com>
Co-authored-by: Thanaphon Frappet <thanaphon@frappet.com>
This commit is contained in:
puriphatt 2025-03-18 09:58:45 +07:00 committed by GitHub
parent 364a0c807d
commit dc9f2b9e75
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 788 additions and 41 deletions

View file

@ -6,6 +6,7 @@ import { Icon } from '@iconify/vue';
import useMyBranch from 'stores/my-branch';
import { getUserId, getRole } from 'src/services/keycloak';
import { useQuasar } from 'quasar';
import { useI18n } from 'vue-i18n';
type Menu = {
label: string;
@ -14,11 +15,13 @@ type Menu = {
hidden?: boolean;
disabled?: boolean;
isax?: boolean;
noI18n?: boolean;
children?: Menu[];
};
const router = useRouter();
const $q = useQuasar();
const { locale } = useI18n();
const userBranch = useMyBranch();
const { currentMyBranch } = storeToRefs(userBranch);
@ -58,39 +61,7 @@ function branchSetting() {
//TODO: click setting (cog icon) on drawer menu
}
watch(
() => currentPath.value,
() => {
if (currentPath.value === '/') {
menuActive.value.fill(false);
menuActive.value[0] = true;
} else reActiveMenu();
},
);
watch(
() => props.mini,
() => {
if (props.mini) {
reActiveMenu();
}
},
);
onMounted(async () => {
const uid = getUserId();
role.value = getRole();
if (!uid) return;
if (role.value.includes('system')) {
const result = await userBranch.fetchListOptionBranch();
if (result && result.total > 0) currentMyBranch.value = result.result[0];
}
const result = await userBranch.fetchListMyBranch(uid);
if (result && result.total > 0) currentMyBranch.value = result.result[0];
function initMenu() {
menuData.value = [
{
label: 'menu.manage',
@ -185,7 +156,61 @@ onMounted(async () => {
{ label: 'dashboard', route: '/dash-board' },
],
},
{
label: 'menu.manual',
icon: 'mdi-book-open-variant-outline',
children: [
{
label: 'usage',
route: `/manual`,
},
],
},
];
}
watch(
() => currentPath.value,
() => {
if (currentPath.value === '/') {
menuActive.value.fill(false);
menuActive.value[0] = true;
} else reActiveMenu();
},
);
watch(
() => props.mini,
() => {
if (props.mini) {
reActiveMenu();
}
},
);
watch(
() => locale.value,
() => {
initMenu();
},
);
onMounted(async () => {
const uid = getUserId();
role.value = getRole();
if (!uid) return;
if (role.value.includes('system')) {
const result = await userBranch.fetchListOptionBranch();
if (result && result.total > 0) currentMyBranch.value = result.result[0];
}
const result = await userBranch.fetchListMyBranch(uid);
if (result && result.total > 0) currentMyBranch.value = result.result[0];
initMenu();
menuActive.value = menuData.value.map(() => false);
@ -266,10 +291,10 @@ onMounted(async () => {
style="white-space: nowrap"
:style="!menuActive[i] && `color: var(--foreground)`"
>
{{ $t(`${menu.label}.title`) }}
{{ menu.noI18n ? menu.label : $t(`${menu.label}.title`) }}
</span>
<q-tooltip :delay="500">
{{ $t(`${menu.label}.title`) }}
{{ menu.noI18n ? menu.label : $t(`${menu.label}.title`) }}
</q-tooltip>
<q-menu
@ -298,7 +323,11 @@ onMounted(async () => {
:id="`sub-menu-${sub.label}`"
>
<span style="white-space: nowrap">
{{ $t(`${menu.label}.${sub.label}`) }}
{{
sub.noI18n
? sub.label
: $t(`${menu.label}.${sub.label}`)
}}
</span>
</q-item>
</template>
@ -320,12 +349,16 @@ onMounted(async () => {
<nav
class="row items-center no-wrap"
:class="{
active: currentPath === sub.route,
active: sub.route && currentPath.includes(sub.route),
disabled: sub.disabled,
}"
>
<span class="q-px-md" style="white-space: nowrap">
{{ $t(`${menu.label}.${sub.label}`) }}
{{
sub.noI18n
? sub.label
: $t(`${menu.label}.${sub.label}`)
}}
</span>
</nav>
</div>