99 lines
3.7 KiB
Vue
99 lines
3.7 KiB
Vue
<template>
|
|
<!--
|
|
ConfigProvider supplies ant-design-vue's OWN strings and text direction.
|
|
Without it ant rendered its built-in copy — pagination ("items/page"), table
|
|
filter menus ("Reset"/"OK"), Select's "No Data", Popconfirm's default
|
|
buttons — in ENGLISH inside an otherwise fully Farsi RTL panel.
|
|
|
|
NOTE this covers ant's own chrome only. Jalali dates still come from
|
|
moment-jalaali via components/input/DateInput.vue, which is unaffected.
|
|
-->
|
|
<a-config-provider :locale="faIR" direction="rtl">
|
|
<div id="app" :class="vueAppClasses">
|
|
<router-view @setAppClasses="setAppClasses" />
|
|
</div>
|
|
</a-config-provider>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
// Ported from legacy henza_admin/src/App.vue.
|
|
// Dropped (Vue-2-only or dead in legacy): the VeeValidate Farsi dictionary (`$validator`
|
|
// has no Vue 3 equivalent and validation is re-done per-form with ant-design-vue rules),
|
|
// the commented-out Firebase/service-worker block, and the `$vs.rtl` watcher (Vuesax).
|
|
// RTL now comes from themeConfig.rtl directly, which is the same value legacy fed Vuesax.
|
|
import { onMounted, onUnmounted, ref, watch } from 'vue';
|
|
import { notification } from 'ant-design-vue';
|
|
import faIR from 'ant-design-vue/es/locale/fa_IR';
|
|
import themeConfig from './themeConfig';
|
|
import { useLayoutStore } from './stores/layout';
|
|
import { userName } from './utils';
|
|
|
|
const layout = useLayoutStore();
|
|
const vueAppClasses = ref<string[]>([]);
|
|
|
|
function toggleClassInBody(className: string) {
|
|
if (className === 'dark') {
|
|
if (document.body.className.match('theme-semi-dark')) document.body.classList.remove('theme-semi-dark');
|
|
document.body.classList.add('theme-dark');
|
|
} else if (className === 'semi-dark') {
|
|
if (document.body.className.match('theme-dark')) document.body.classList.remove('theme-dark');
|
|
document.body.classList.add('theme-semi-dark');
|
|
} else {
|
|
if (document.body.className.match('theme-dark')) document.body.classList.remove('theme-dark');
|
|
if (document.body.className.match('theme-semi-dark')) document.body.classList.remove('theme-semi-dark');
|
|
}
|
|
}
|
|
|
|
function setAppClasses(classesStr: string) {
|
|
vueAppClasses.value.push(classesStr);
|
|
}
|
|
|
|
function handleWindowResize() {
|
|
layout.updateWindowWidth(window.innerWidth);
|
|
// Set --vh property
|
|
document.documentElement.style.setProperty('--vh', `${window.innerHeight * 0.01}px`);
|
|
}
|
|
|
|
function handleScroll() {
|
|
layout.updateWindowScrollY(window.scrollY);
|
|
}
|
|
|
|
watch(() => layout.theme, (val) => toggleClassInBody(val));
|
|
|
|
// legacy created(): set dir before first paint
|
|
document.documentElement.setAttribute('dir', themeConfig.rtl ? 'rtl' : 'ltr');
|
|
|
|
onMounted(() => {
|
|
// legacy showed a one-shot welcome toast when a `login` flag was left in localStorage
|
|
const rawUser = localStorage.getItem(userName);
|
|
const user = rawUser ? JSON.parse(rawUser) : undefined;
|
|
const login = localStorage.getItem('login') || undefined;
|
|
if (user && login) {
|
|
notification.open({
|
|
message: `${user && user.name ? user.name : ' کاربر '} عزیز `,
|
|
placement: 'topLeft',
|
|
description: 'به هنزاگلد خوش آمدید',
|
|
style: {
|
|
color: 'var(--primary-color)',
|
|
marginLeft: `20px`,
|
|
},
|
|
});
|
|
localStorage.removeItem('login');
|
|
}
|
|
|
|
toggleClassInBody(themeConfig.theme);
|
|
layout.updateWindowWidth(window.innerWidth);
|
|
|
|
const vh = window.innerHeight * 0.01;
|
|
document.documentElement.style.setProperty('--vh', `${vh}px`);
|
|
|
|
window.addEventListener('resize', handleWindowResize);
|
|
window.addEventListener('scroll', handleScroll);
|
|
});
|
|
|
|
onUnmounted(() => {
|
|
window.removeEventListener('resize', handleWindowResize);
|
|
window.removeEventListener('scroll', handleScroll);
|
|
});
|
|
</script>
|